aboutsummaryrefslogtreecommitdiff
path: root/tools/testing/selftests/bpf/prog_tests/queue_stack_map.c
diff options
context:
space:
mode:
authorAlexei Starovoitov <[email protected]>2019-03-02 11:10:41 -0800
committerAlexei Starovoitov <[email protected]>2019-03-02 11:10:41 -0800
commitea5bade929bf04355aeed58a3c9f5ef2c3afe2ac (patch)
tree3b643e34c41fc8c294309130f8b0b19b1890c53c /tools/testing/selftests/bpf/prog_tests/queue_stack_map.c
parent0d7f68270b05c97464a14abab4a2cbe6de00f0d7 (diff)
parent886225bb0868fcf763bea62d18e57e4b5ef08a42 (diff)
Merge branch 'split-test_progs'
Stanislav Fomichev says: ==================== Recently we had linux-next bpf/bpf-next conflict when we added new functionality to the test_progs.c at the same location. Let's split test_progs.c the same way we recently split test_verifier.c. I follow the same patten we did in commit 2dfb40121ee8 ("selftests: bpf: prepare for break up of verifier tests") for verifier: create scaffolding to support dedicated files and slowly move the tests into separate files. The first patch adds scaffolding, subsequent patches move progs into separate files. In theory, many of the standalone tests can be migrated to this new framework as well. They get the benefit of common CHECK macro and bpf_find_map function which a lot of standalone tests need to redefine. v3 changes: * respin on top of commit ebace0e981b2 ("selftests/bpf: use __bpf_constant_htons in test_prog.c for flow dissector") * put bpf_rlimit.h into test_progs.c instead of test_progs.h v2 changes: * added cover letter, added more description about file structure ==================== Signed-off-by: Alexei Starovoitov <[email protected]>
Diffstat (limited to 'tools/testing/selftests/bpf/prog_tests/queue_stack_map.c')
-rw-r--r--tools/testing/selftests/bpf/prog_tests/queue_stack_map.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/tools/testing/selftests/bpf/prog_tests/queue_stack_map.c b/tools/testing/selftests/bpf/prog_tests/queue_stack_map.c
new file mode 100644
index 000000000000..e60cd5ff1f55
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/queue_stack_map.c
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <test_progs.h>
+
+enum {
+ QUEUE,
+ STACK,
+};
+
+static void test_queue_stack_map_by_type(int type)
+{
+ const int MAP_SIZE = 32;
+ __u32 vals[MAP_SIZE], duration, retval, size, val;
+ int i, err, prog_fd, map_in_fd, map_out_fd;
+ char file[32], buf[128];
+ struct bpf_object *obj;
+ struct iphdr *iph = (void *)buf + sizeof(struct ethhdr);
+
+ /* Fill test values to be used */
+ for (i = 0; i < MAP_SIZE; i++)
+ vals[i] = rand();
+
+ if (type == QUEUE)
+ strncpy(file, "./test_queue_map.o", sizeof(file));
+ else if (type == STACK)
+ strncpy(file, "./test_stack_map.o", sizeof(file));
+ else
+ return;
+
+ err = bpf_prog_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd);
+ if (err) {
+ error_cnt++;
+ return;
+ }
+
+ map_in_fd = bpf_find_map(__func__, obj, "map_in");
+ if (map_in_fd < 0)
+ goto out;
+
+ map_out_fd = bpf_find_map(__func__, obj, "map_out");
+ if (map_out_fd < 0)
+ goto out;
+
+ /* Push 32 elements to the input map */
+ for (i = 0; i < MAP_SIZE; i++) {
+ err = bpf_map_update_elem(map_in_fd, NULL, &vals[i], 0);
+ if (err) {
+ error_cnt++;
+ goto out;
+ }
+ }
+
+ /* The eBPF program pushes iph.saddr in the output map,
+ * pops the input map and saves this value in iph.daddr
+ */
+ for (i = 0; i < MAP_SIZE; i++) {
+ if (type == QUEUE) {
+ val = vals[i];
+ pkt_v4.iph.saddr = vals[i] * 5;
+ } else if (type == STACK) {
+ val = vals[MAP_SIZE - 1 - i];
+ pkt_v4.iph.saddr = vals[MAP_SIZE - 1 - i] * 5;
+ }
+
+ err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4),
+ buf, &size, &retval, &duration);
+ if (err || retval || size != sizeof(pkt_v4) ||
+ iph->daddr != val)
+ break;
+ }
+
+ CHECK(err || retval || size != sizeof(pkt_v4) || iph->daddr != val,
+ "bpf_map_pop_elem",
+ "err %d errno %d retval %d size %d iph->daddr %u\n",
+ err, errno, retval, size, iph->daddr);
+
+ /* Queue is empty, program should return TC_ACT_SHOT */
+ err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4),
+ buf, &size, &retval, &duration);
+ CHECK(err || retval != 2 /* TC_ACT_SHOT */|| size != sizeof(pkt_v4),
+ "check-queue-stack-map-empty",
+ "err %d errno %d retval %d size %d\n",
+ err, errno, retval, size);
+
+ /* Check that the program pushed elements correctly */
+ for (i = 0; i < MAP_SIZE; i++) {
+ err = bpf_map_lookup_and_delete_elem(map_out_fd, NULL, &val);
+ if (err || val != vals[i] * 5)
+ break;
+ }
+
+ CHECK(i != MAP_SIZE && (err || val != vals[i] * 5),
+ "bpf_map_push_elem", "err %d value %u\n", err, val);
+
+out:
+ pkt_v4.iph.saddr = 0;
+ bpf_object__close(obj);
+}
+
+void test_queue_stack_map(void)
+{
+ test_queue_stack_map_by_type(QUEUE);
+ test_queue_stack_map_by_type(STACK);
+}