Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: freplace tests for tracking of changes_packet_data

Try different combinations of global functions replacement:
- replace function that changes packet data with one that doesn't;
- replace function that changes packet data with one that does;
- replace function that doesn't change packet data with one that does;
- replace function that doesn't change packet data with one that doesn't;

Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20241210041100.1898468-7-eddyz87@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Eduard Zingerman and committed by
Alexei Starovoitov
89ff4089 81f6d053

+120
+76
tools/testing/selftests/bpf/prog_tests/changes_pkt_data.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include "bpf/libbpf.h" 3 + #include "changes_pkt_data_freplace.skel.h" 4 + #include "changes_pkt_data.skel.h" 5 + #include <test_progs.h> 6 + 7 + static void print_verifier_log(const char *log) 8 + { 9 + if (env.verbosity >= VERBOSE_VERY) 10 + fprintf(stdout, "VERIFIER LOG:\n=============\n%s=============\n", log); 11 + } 12 + 13 + static void test_aux(const char *main_prog_name, const char *freplace_prog_name, bool expect_load) 14 + { 15 + struct changes_pkt_data_freplace *freplace = NULL; 16 + struct bpf_program *freplace_prog = NULL; 17 + LIBBPF_OPTS(bpf_object_open_opts, opts); 18 + struct changes_pkt_data *main = NULL; 19 + char log[16*1024]; 20 + int err; 21 + 22 + opts.kernel_log_buf = log; 23 + opts.kernel_log_size = sizeof(log); 24 + if (env.verbosity >= VERBOSE_SUPER) 25 + opts.kernel_log_level = 1 | 2 | 4; 26 + main = changes_pkt_data__open_opts(&opts); 27 + if (!ASSERT_OK_PTR(main, "changes_pkt_data__open")) 28 + goto out; 29 + err = changes_pkt_data__load(main); 30 + print_verifier_log(log); 31 + if (!ASSERT_OK(err, "changes_pkt_data__load")) 32 + goto out; 33 + freplace = changes_pkt_data_freplace__open_opts(&opts); 34 + if (!ASSERT_OK_PTR(freplace, "changes_pkt_data_freplace__open")) 35 + goto out; 36 + freplace_prog = bpf_object__find_program_by_name(freplace->obj, freplace_prog_name); 37 + if (!ASSERT_OK_PTR(freplace_prog, "freplace_prog")) 38 + goto out; 39 + bpf_program__set_autoload(freplace_prog, true); 40 + bpf_program__set_autoattach(freplace_prog, true); 41 + bpf_program__set_attach_target(freplace_prog, 42 + bpf_program__fd(main->progs.dummy), 43 + main_prog_name); 44 + err = changes_pkt_data_freplace__load(freplace); 45 + print_verifier_log(log); 46 + if (expect_load) { 47 + ASSERT_OK(err, "changes_pkt_data_freplace__load"); 48 + } else { 49 + ASSERT_ERR(err, "changes_pkt_data_freplace__load"); 50 + ASSERT_HAS_SUBSTR(log, "Extension program changes packet data", "error log"); 51 + } 52 + 53 + out: 54 + changes_pkt_data_freplace__destroy(freplace); 55 + changes_pkt_data__destroy(main); 56 + } 57 + 58 + /* There are two global subprograms in both changes_pkt_data.skel.h: 59 + * - one changes packet data; 60 + * - another does not. 61 + * It is ok to freplace subprograms that change packet data with those 62 + * that either do or do not. It is only ok to freplace subprograms 63 + * that do not change packet data with those that do not as well. 64 + * The below tests check outcomes for each combination of such freplace. 65 + */ 66 + void test_changes_pkt_data_freplace(void) 67 + { 68 + if (test__start_subtest("changes_with_changes")) 69 + test_aux("changes_pkt_data", "changes_pkt_data", true); 70 + if (test__start_subtest("changes_with_doesnt_change")) 71 + test_aux("changes_pkt_data", "does_not_change_pkt_data", true); 72 + if (test__start_subtest("doesnt_change_with_changes")) 73 + test_aux("does_not_change_pkt_data", "changes_pkt_data", false); 74 + if (test__start_subtest("doesnt_change_with_doesnt_change")) 75 + test_aux("does_not_change_pkt_data", "does_not_change_pkt_data", true); 76 + }
+26
tools/testing/selftests/bpf/progs/changes_pkt_data.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <linux/bpf.h> 4 + #include <bpf/bpf_helpers.h> 5 + 6 + __noinline 7 + long changes_pkt_data(struct __sk_buff *sk, __u32 len) 8 + { 9 + return bpf_skb_pull_data(sk, len); 10 + } 11 + 12 + __noinline __weak 13 + long does_not_change_pkt_data(struct __sk_buff *sk, __u32 len) 14 + { 15 + return 0; 16 + } 17 + 18 + SEC("tc") 19 + int dummy(struct __sk_buff *sk) 20 + { 21 + changes_pkt_data(sk, 0); 22 + does_not_change_pkt_data(sk, 0); 23 + return 0; 24 + } 25 + 26 + char _license[] SEC("license") = "GPL";
+18
tools/testing/selftests/bpf/progs/changes_pkt_data_freplace.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <linux/bpf.h> 4 + #include <bpf/bpf_helpers.h> 5 + 6 + SEC("?freplace") 7 + long changes_pkt_data(struct __sk_buff *sk, __u32 len) 8 + { 9 + return bpf_skb_pull_data(sk, len); 10 + } 11 + 12 + SEC("?freplace") 13 + long does_not_change_pkt_data(struct __sk_buff *sk, __u32 len) 14 + { 15 + return 0; 16 + } 17 + 18 + char _license[] SEC("license") = "GPL";