// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2021 Facebook */

#include <sys/syscall.h>
#include <test_progs.h>
#include "bloom_filter_map.skel.h"

static void test_fail_cases(void)
{
	__u32 value;
	int fd, err;

	/* Invalid key size */
	fd = bpf_create_map(BPF_MAP_TYPE_BLOOM_FILTER, 4, sizeof(value), 100, 0);
	if (!ASSERT_LT(fd, 0, "bpf_create_map bloom filter invalid key size"))
		close(fd);

	/* Invalid value size */
	fd = bpf_create_map(BPF_MAP_TYPE_BLOOM_FILTER, 0, 0, 100, 0);
	if (!ASSERT_LT(fd, 0, "bpf_create_map bloom filter invalid value size 0"))
		close(fd);

	/* Invalid max entries size */
	fd = bpf_create_map(BPF_MAP_TYPE_BLOOM_FILTER, 0, sizeof(value), 0, 0);
	if (!ASSERT_LT(fd, 0, "bpf_create_map bloom filter invalid max entries size"))
		close(fd);

	/* Bloom filter maps do not support BPF_F_NO_PREALLOC */
	fd = bpf_create_map(BPF_MAP_TYPE_BLOOM_FILTER, 0, sizeof(value), 100,
			    BPF_F_NO_PREALLOC);
	if (!ASSERT_LT(fd, 0, "bpf_create_map bloom filter invalid flags"))
		close(fd);

	fd = bpf_create_map(BPF_MAP_TYPE_BLOOM_FILTER, 0, sizeof(value), 100, 0);
	if (!ASSERT_GE(fd, 0, "bpf_create_map bloom filter"))
		return;

	/* Test invalid flags */
	err = bpf_map_update_elem(fd, NULL, &value, -1);
	ASSERT_EQ(err, -EINVAL, "bpf_map_update_elem bloom filter invalid flags");

	err = bpf_map_update_elem(fd, NULL, &value, BPF_EXIST);
	ASSERT_EQ(err, -EINVAL, "bpf_map_update_elem bloom filter invalid flags");

	err = bpf_map_update_elem(fd, NULL, &value, BPF_F_LOCK);
	ASSERT_EQ(err, -EINVAL, "bpf_map_update_elem bloom filter invalid flags");

	err = bpf_map_update_elem(fd, NULL, &value, BPF_NOEXIST);
	ASSERT_EQ(err, -EINVAL, "bpf_map_update_elem bloom filter invalid flags");

	err = bpf_map_update_elem(fd, NULL, &value, 10000);
	ASSERT_EQ(err, -EINVAL, "bpf_map_update_elem bloom filter invalid flags");

	close(fd);
}

static void test_success_cases(void)
{
	char value[11];
	int fd, err;

	/* Create a map */
	fd = bpf_create_map(BPF_MAP_TYPE_BLOOM_FILTER, 0, sizeof(value), 100,
			    BPF_F_ZERO_SEED | BPF_F_NUMA_NODE);
	if (!ASSERT_GE(fd, 0, "bpf_create_map bloom filter success case"))
		return;

	/* Add a value to the bloom filter */
	err = bpf_map_update_elem(fd, NULL, &value, 0);
	if (!ASSERT_OK(err, "bpf_map_update_elem bloom filter success case"))
		goto done;

	 /* Lookup a value in the bloom filter */
	err = bpf_map_lookup_elem(fd, NULL, &value);
	ASSERT_OK(err, "bpf_map_update_elem bloom filter success case");

done:
	close(fd);
}

static void check_bloom(struct bloom_filter_map *skel)
{
	struct bpf_link *link;

	link = bpf_program__attach(skel->progs.check_bloom);
	if (!ASSERT_OK_PTR(link, "link"))
		return;

	syscall(SYS_getpgid);

	ASSERT_EQ(skel->bss->error, 0, "error");

	bpf_link__destroy(link);
}

static void test_inner_map(struct bloom_filter_map *skel, const __u32 *rand_vals,
			   __u32 nr_rand_vals)
{
	int outer_map_fd, inner_map_fd, err, i, key = 0;
	struct bpf_link *link;

	/* Create a bloom filter map that will be used as the inner map */
	inner_map_fd = bpf_create_map(BPF_MAP_TYPE_BLOOM_FILTER, 0, sizeof(*rand_vals),
				      nr_rand_vals, 0);
	if (!ASSERT_GE(inner_map_fd, 0, "bpf_create_map bloom filter inner map"))
		return;

	for (i = 0; i < nr_rand_vals; i++) {
		err = bpf_map_update_elem(inner_map_fd, NULL, rand_vals + i, BPF_ANY);
		if (!ASSERT_OK(err, "Add random value to inner_map_fd"))
			goto done;
	}

	/* Add the bloom filter map to the outer map */
	outer_map_fd = bpf_map__fd(skel->maps.outer_map);
	err = bpf_map_update_elem(outer_map_fd, &key, &inner_map_fd, BPF_ANY);
	if (!ASSERT_OK(err, "Add bloom filter map to outer map"))
		goto done;

	/* Attach the bloom_filter_inner_map prog */
	link = bpf_program__attach(skel->progs.inner_map);
	if (!ASSERT_OK_PTR(link, "link"))
		goto delete_inner_map;

	syscall(SYS_getpgid);

	ASSERT_EQ(skel->bss->error, 0, "error");

	bpf_link__destroy(link);

delete_inner_map:
	/* Ensure the inner bloom filter map can be deleted */
	err = bpf_map_delete_elem(outer_map_fd, &key);
	ASSERT_OK(err, "Delete inner bloom filter map");

done:
	close(inner_map_fd);
}

static int setup_progs(struct bloom_filter_map **out_skel, __u32 **out_rand_vals,
		       __u32 *out_nr_rand_vals)
{
	struct bloom_filter_map *skel;
	int random_data_fd, bloom_fd;
	__u32 *rand_vals = NULL;
	__u32 map_size, val;
	int err, i;

	/* Set up a bloom filter map skeleton */
	skel = bloom_filter_map__open_and_load();
	if (!ASSERT_OK_PTR(skel, "bloom_filter_map__open_and_load"))
		return -EINVAL;

	/* Set up rand_vals */
	map_size = bpf_map__max_entries(skel->maps.map_random_data);
	rand_vals = malloc(sizeof(*rand_vals) * map_size);
	if (!rand_vals) {
		err = -ENOMEM;
		goto error;
	}

	/* Generate random values and populate both skeletons */
	random_data_fd = bpf_map__fd(skel->maps.map_random_data);
	bloom_fd = bpf_map__fd(skel->maps.map_bloom);
	for (i = 0; i < map_size; i++) {
		val = rand();

		err = bpf_map_update_elem(random_data_fd, &i, &val, BPF_ANY);
		if (!ASSERT_OK(err, "Add random value to map_random_data"))
			goto error;

		err = bpf_map_update_elem(bloom_fd, NULL, &val, BPF_ANY);
		if (!ASSERT_OK(err, "Add random value to map_bloom"))
			goto error;

		rand_vals[i] = val;
	}

	*out_skel = skel;
	*out_rand_vals = rand_vals;
	*out_nr_rand_vals = map_size;

	return 0;

error:
	bloom_filter_map__destroy(skel);
	if (rand_vals)
		free(rand_vals);
	return err;
}

void test_bloom_filter_map(void)
{
	__u32 *rand_vals, nr_rand_vals;
	struct bloom_filter_map *skel;
	int err;

	test_fail_cases();
	test_success_cases();

	err = setup_progs(&skel, &rand_vals, &nr_rand_vals);
	if (err)
		return;

	test_inner_map(skel, rand_vals, nr_rand_vals);
	free(rand_vals);

	check_bloom(skel);

	bloom_filter_map__destroy(skel);
}
