brintos

brintos / linux-shallow public Read only

0
0
Text · 2.8 KiB · a043af9 Raw
109 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <test_progs.h>3#include <network_helpers.h>4 5enum {6	QUEUE,7	STACK,8};9 10static void test_queue_stack_map_by_type(int type)11{12	const int MAP_SIZE = 32;13	__u32 vals[MAP_SIZE], val;14	int i, err, prog_fd, map_in_fd, map_out_fd;15	char file[32], buf[128];16	struct bpf_object *obj;17	struct iphdr iph = {};18	LIBBPF_OPTS(bpf_test_run_opts, topts,19		.data_in = &pkt_v4,20		.data_size_in = sizeof(pkt_v4),21		.data_out = buf,22		.data_size_out = sizeof(buf),23		.repeat = 1,24	);25 26	/* Fill test values to be used */27	for (i = 0; i < MAP_SIZE; i++)28		vals[i] = rand();29 30	if (type == QUEUE)31		strncpy(file, "./test_queue_map.bpf.o", sizeof(file));32	else if (type == STACK)33		strncpy(file, "./test_stack_map.bpf.o", sizeof(file));34	else35		return;36 37	err = bpf_prog_test_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd);38	if (CHECK_FAIL(err))39		return;40 41	map_in_fd = bpf_find_map(__func__, obj, "map_in");42	if (map_in_fd < 0)43		goto out;44 45	map_out_fd = bpf_find_map(__func__, obj, "map_out");46	if (map_out_fd < 0)47		goto out;48 49	/* Push 32 elements to the input map */50	for (i = 0; i < MAP_SIZE; i++) {51		err = bpf_map_update_elem(map_in_fd, NULL, &vals[i], 0);52		if (CHECK_FAIL(err))53			goto out;54	}55 56	/* The eBPF program pushes iph.saddr in the output map,57	 * pops the input map and saves this value in iph.daddr58	 */59	for (i = 0; i < MAP_SIZE; i++) {60		if (type == QUEUE) {61			val = vals[i];62			pkt_v4.iph.saddr = vals[i] * 5;63		} else if (type == STACK) {64			val = vals[MAP_SIZE - 1 - i];65			pkt_v4.iph.saddr = vals[MAP_SIZE - 1 - i] * 5;66		}67 68		topts.data_size_out = sizeof(buf);69		err = bpf_prog_test_run_opts(prog_fd, &topts);70		if (err || topts.retval ||71		    topts.data_size_out != sizeof(pkt_v4))72			break;73		memcpy(&iph, buf + sizeof(struct ethhdr), sizeof(iph));74		if (iph.daddr != val)75			break;76	}77 78	ASSERT_OK(err, "bpf_map_pop_elem");79	ASSERT_OK(topts.retval, "bpf_map_pop_elem test retval");80	ASSERT_EQ(topts.data_size_out, sizeof(pkt_v4),81		  "bpf_map_pop_elem data_size_out");82	ASSERT_EQ(iph.daddr, val, "bpf_map_pop_elem iph.daddr");83 84	/* Queue is empty, program should return TC_ACT_SHOT */85	topts.data_size_out = sizeof(buf);86	err = bpf_prog_test_run_opts(prog_fd, &topts);87	ASSERT_OK(err, "check-queue-stack-map-empty");88	ASSERT_EQ(topts.retval, 2  /* TC_ACT_SHOT */,89		  "check-queue-stack-map-empty test retval");90	ASSERT_EQ(topts.data_size_out, sizeof(pkt_v4),91		  "check-queue-stack-map-empty data_size_out");92 93	/* Check that the program pushed elements correctly */94	for (i = 0; i < MAP_SIZE; i++) {95		err = bpf_map_lookup_and_delete_elem(map_out_fd, NULL, &val);96		ASSERT_OK(err, "bpf_map_lookup_and_delete_elem");97		ASSERT_EQ(val, vals[i] * 5, "bpf_map_push_elem val");98	}99out:100	pkt_v4.iph.saddr = 0;101	bpf_object__close(obj);102}103 104void test_queue_stack_map(void)105{106	test_queue_stack_map_by_type(QUEUE);107	test_queue_stack_map_by_type(STACK);108}109