// SPDX-License-Identifier: GPL-2.0-or-later #include <netinet/in.h> #include <linux/netfilter.h> #include "test_progs.h" #include "test_netfilter_link_attach.skel.h" struct nf_link_test { __u32 pf; __u32 hooknum; __s32 priority; __u32 flags; bool expect_success; const char * const name; }; static const struct nf_link_test nf_hook_link_tests[] = { { .name = "allzero", }, { .pf = NFPROTO_NUMPROTO, .name = "invalid-pf", }, { .pf = NFPROTO_IPV4, .hooknum = 42, .name = "invalid-hooknum", }, { .pf = NFPROTO_IPV4, .priority = INT_MIN, .name = "invalid-priority-min", }, { .pf = NFPROTO_IPV4, .priority = INT_MAX, .name = "invalid-priority-max", }, { .pf = NFPROTO_IPV4, .flags = UINT_MAX, .name = "invalid-flags", }, { .pf = NFPROTO_INET, .priority = 1, .name = "invalid-inet-not-supported", }, { .pf = NFPROTO_IPV4, .priority = -10000, .expect_success = true, .name = "attach ipv4", }, { .pf = NFPROTO_IPV6, .priority = 10001, .expect_success = true, .name = "attach ipv6", }, }; void test_netfilter_link_attach(void) { struct test_netfilter_link_attach *skel; struct bpf_program *prog; LIBBPF_OPTS(bpf_netfilter_opts, opts); int i; skel = test_netfilter_link_attach__open_and_load(); if (!ASSERT_OK_PTR(skel, "test_netfilter_link_attach__open_and_load")) goto out; prog = skel->progs.nf_link_attach_test; if (!ASSERT_OK_PTR(prog, "attach program")) goto out; for (i = 0; i < ARRAY_SIZE(nf_hook_link_tests); i++) { struct bpf_link *link; if (!test__start_subtest(nf_hook_link_tests[i].name)) continue; #define X(opts, m, i) opts.m = nf_hook_link_tests[(i)].m X(opts, pf, i); X(opts, hooknum, i); X(opts, priority, i); X(opts, flags, i); #undef X link = bpf_program__attach_netfilter(prog, &opts); if (nf_hook_link_tests[i].expect_success) { struct bpf_link *link2; if (!ASSERT_OK_PTR(link, "program attach successful")) continue; link2 = bpf_program__attach_netfilter(prog, &opts); ASSERT_ERR_PTR(link2, "attach program with same pf/hook/priority"); if (!ASSERT_OK(bpf_link__destroy(link), "link destroy")) break; link2 = bpf_program__attach_netfilter(prog, &opts); if (!ASSERT_OK_PTR(link2, "program reattach successful")) continue; if (!ASSERT_OK(bpf_link__destroy(link2), "link destroy")) break; } else { ASSERT_ERR_PTR(link, "program load failure"); } } out: test_netfilter_link_attach__destroy(skel); }