// SPDX-License-Identifier: GPL-2.0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <sys/sysinfo.h>
#include <sys/time.h>

#include <linux/bpf.h>
#include <bpf/bpf.h>
#include <bpf/libbpf.h>

#include "cgroup_helpers.h"
#include "bpf_rlimit.h"
#include "netcnt_common.h"

#define BPF_PROG "./netcnt_prog.o"
#define TEST_CGROUP "/test-network-counters/"

static int bpf_find_map(const char *test, struct bpf_object *obj,
			const char *name)
{
	struct bpf_map *map;

	map = bpf_object__find_map_by_name(obj, name);
	if (!map) {
		printf("%s:FAIL:map '%s' not found\n", test, name);
		return -1;
	}
	return bpf_map__fd(map);
}

int main(int argc, char **argv)
{
	struct percpu_net_cnt *percpu_netcnt;
	struct bpf_cgroup_storage_key key;
	int map_fd, percpu_map_fd;
	int error = EXIT_FAILURE;
	struct net_cnt netcnt;
	struct bpf_object *obj;
	int prog_fd, cgroup_fd;
	unsigned long packets;
	unsigned long bytes;
	int cpu, nproc;
	__u32 prog_cnt;

	nproc = get_nprocs_conf();
	percpu_netcnt = malloc(sizeof(*percpu_netcnt) * nproc);
	if (!percpu_netcnt) {
		printf("Not enough memory for per-cpu area (%d cpus)\n", nproc);
		goto err;
	}

	if (bpf_prog_load(BPF_PROG, BPF_PROG_TYPE_CGROUP_SKB,
			  &obj, &prog_fd)) {
		printf("Failed to load bpf program\n");
		goto out;
	}

	cgroup_fd = cgroup_setup_and_join(TEST_CGROUP);
	if (cgroup_fd < 0)
		goto err;

	/* Attach bpf program */
	if (bpf_prog_attach(prog_fd, cgroup_fd, BPF_CGROUP_INET_EGRESS, 0)) {
		printf("Failed to attach bpf program");
		goto err;
	}

	if (system("which ping6 &>/dev/null") == 0)
		assert(!system("ping6 ::1 -c 10000 -f -q > /dev/null"));
	else
		assert(!system("ping -6 ::1 -c 10000 -f -q > /dev/null"));

	if (bpf_prog_query(cgroup_fd, BPF_CGROUP_INET_EGRESS, 0, NULL, NULL,
			   &prog_cnt)) {
		printf("Failed to query attached programs");
		goto err;
	}

	map_fd = bpf_find_map(__func__, obj, "netcnt");
	if (map_fd < 0) {
		printf("Failed to find bpf map with net counters");
		goto err;
	}

	percpu_map_fd = bpf_find_map(__func__, obj, "percpu_netcnt");
	if (percpu_map_fd < 0) {
		printf("Failed to find bpf map with percpu net counters");
		goto err;
	}

	if (bpf_map_get_next_key(map_fd, NULL, &key)) {
		printf("Failed to get key in cgroup storage\n");
		goto err;
	}

	if (bpf_map_lookup_elem(map_fd, &key, &netcnt)) {
		printf("Failed to lookup cgroup storage\n");
		goto err;
	}

	if (bpf_map_lookup_elem(percpu_map_fd, &key, &percpu_netcnt[0])) {
		printf("Failed to lookup percpu cgroup storage\n");
		goto err;
	}

	/* Some packets can be still in per-cpu cache, but not more than
	 * MAX_PERCPU_PACKETS.
	 */
	packets = netcnt.packets;
	bytes = netcnt.bytes;
	for (cpu = 0; cpu < nproc; cpu++) {
		if (percpu_netcnt[cpu].packets > MAX_PERCPU_PACKETS) {
			printf("Unexpected percpu value: %llu\n",
			       percpu_netcnt[cpu].packets);
			goto err;
		}

		packets += percpu_netcnt[cpu].packets;
		bytes += percpu_netcnt[cpu].bytes;
	}

	/* No packets should be lost */
	if (packets != 10000) {
		printf("Unexpected packet count: %lu\n", packets);
		goto err;
	}

	/* Let's check that bytes counter matches the number of packets
	 * multiplied by the size of ipv6 ICMP packet.
	 */
	if (bytes != packets * 104) {
		printf("Unexpected bytes count: %lu\n", bytes);
		goto err;
	}

	error = 0;
	printf("test_netcnt:PASS\n");

err:
	cleanup_cgroup_environment();
	free(percpu_netcnt);

out:
	return error;
}
