// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB

/*
 * ibumad BPF sample user side
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General Public
 * License as published by the Free Software Foundation.
 *
 * Copyright(c) 2018 Ira Weiny, Intel Corporation
 */

#include <linux/bpf.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <limits.h>

#include <sys/resource.h>
#include <getopt.h>
#include <net/if.h>

#include <bpf/bpf.h>
#include "bpf_util.h"
#include <bpf/libbpf.h>

static struct bpf_link *tp_links[3];
static struct bpf_object *obj;
static int map_fd[2];
static int tp_cnt;

static void dump_counts(int fd)
{
	__u32 key;
	__u64 value;

	for (key = 0; key < 256; key++) {
		if (bpf_map_lookup_elem(fd, &key, &value)) {
			printf("failed to read key %u\n", key);
			continue;
		}
		if (value)
			printf("0x%02x : %llu\n", key, value);
	}
}

static void dump_all_counts(void)
{
	printf("Read 'Class : count'\n");
	dump_counts(map_fd[0]);
	printf("Write 'Class : count'\n");
	dump_counts(map_fd[1]);
}

static void dump_exit(int sig)
{
	dump_all_counts();
	/* Detach tracepoints */
	while (tp_cnt)
		bpf_link__destroy(tp_links[--tp_cnt]);

	bpf_object__close(obj);
	exit(0);
}

static const struct option long_options[] = {
	{"help",      no_argument,       NULL, 'h'},
	{"delay",     required_argument, NULL, 'd'},
};

static void usage(char *cmd)
{
	printf("eBPF test program to count packets from various IP addresses\n"
		"Usage: %s <options>\n"
		"       --help,   -h  this menu\n"
		"       --delay,  -d  <delay>  wait <delay> sec between prints [1 - 1000000]\n"
		, cmd
		);
}

int main(int argc, char **argv)
{
	struct bpf_program *prog;
	unsigned long delay = 5;
	char filename[256];
	int longindex = 0;
	int opt, err = -1;

	while ((opt = getopt_long(argc, argv, "hd:rSw",
				  long_options, &longindex)) != -1) {
		switch (opt) {
		case 'd':
			delay = strtoul(optarg, NULL, 0);
			if (delay == ULONG_MAX || delay < 0 ||
			    delay > 1000000) {
				fprintf(stderr, "ERROR: invalid delay : %s\n",
					optarg);
				usage(argv[0]);
				return 1;
			}
			break;
		default:
		case 'h':
			usage(argv[0]);
			return 1;
		}
	}

	/* Do one final dump when exiting */
	signal(SIGINT, dump_exit);
	signal(SIGTERM, dump_exit);

	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
	obj = bpf_object__open_file(filename, NULL);
	if (libbpf_get_error(obj)) {
		fprintf(stderr, "ERROR: opening BPF object file failed\n");
		return err;
	}

	/* load BPF program */
	if (bpf_object__load(obj)) {
		fprintf(stderr, "ERROR: loading BPF object file failed\n");
		goto cleanup;
	}

	map_fd[0] = bpf_object__find_map_fd_by_name(obj, "read_count");
	map_fd[1] = bpf_object__find_map_fd_by_name(obj, "write_count");
	if (map_fd[0] < 0 || map_fd[1] < 0) {
		fprintf(stderr, "ERROR: finding a map in obj file failed\n");
		goto cleanup;
	}

	bpf_object__for_each_program(prog, obj) {
		tp_links[tp_cnt] = bpf_program__attach(prog);
		if (libbpf_get_error(tp_links[tp_cnt])) {
			fprintf(stderr, "ERROR: bpf_program__attach failed\n");
			tp_links[tp_cnt] = NULL;
			goto cleanup;
		}
		tp_cnt++;
	}

	while (1) {
		sleep(delay);
		dump_all_counts();
	}
	err = 0;

cleanup:
	/* Detach tracepoints */
	while (tp_cnt)
		bpf_link__destroy(tp_links[--tp_cnt]);

	bpf_object__close(obj);
	return err;
}
