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

selftests/bpf: Add link detach tests for cgroup, netns, and xdp bpf_links

Add bpf_link__detach() testing to selftests for cgroup, netns, and xdp
bpf_links.

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Song Liu <songliubraving@fb.com>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Link: https://lore.kernel.org/bpf/20200731182830.286260-4-andriin@fb.com

authored by

Andrii Nakryiko and committed by
Alexei Starovoitov
90806ccc 2e49527e

+73 -29
+19 -1
tools/testing/selftests/bpf/prog_tests/cgroup_link.c
··· 2 2 3 3 #include <test_progs.h> 4 4 #include "cgroup_helpers.h" 5 + #include "testing_helpers.h" 5 6 #include "test_cgroup_link.skel.h" 6 7 7 8 static __u32 duration = 0; ··· 38 37 int last_cg = ARRAY_SIZE(cgs) - 1, cg_nr = ARRAY_SIZE(cgs); 39 38 DECLARE_LIBBPF_OPTS(bpf_link_update_opts, link_upd_opts); 40 39 struct bpf_link *links[ARRAY_SIZE(cgs)] = {}, *tmp_link; 41 - __u32 prog_ids[ARRAY_SIZE(cgs)], prog_cnt = 0, attach_flags; 40 + __u32 prog_ids[ARRAY_SIZE(cgs)], prog_cnt = 0, attach_flags, prog_id; 41 + struct bpf_link_info info; 42 42 int i = 0, err, prog_fd; 43 43 bool detach_legacy = false; 44 44 ··· 220 218 221 219 /* BPF programs should still get called */ 222 220 ping_and_check(0, cg_nr); 221 + 222 + prog_id = link_info_prog_id(links[0], &info); 223 + CHECK(prog_id == 0, "link_info", "failed\n"); 224 + CHECK(info.cgroup.cgroup_id == 0, "cgroup_id", "unexpected %llu\n", info.cgroup.cgroup_id); 225 + 226 + err = bpf_link__detach(links[0]); 227 + if (CHECK(err, "link_detach", "failed %d\n", err)) 228 + goto cleanup; 229 + 230 + /* cgroup_id should be zero in link_info */ 231 + prog_id = link_info_prog_id(links[0], &info); 232 + CHECK(prog_id == 0, "link_info", "failed\n"); 233 + CHECK(info.cgroup.cgroup_id != 0, "cgroup_id", "unexpected %llu\n", info.cgroup.cgroup_id); 234 + 235 + /* First BPF program shouldn't be called anymore */ 236 + ping_and_check(0, cg_nr - 1); 223 237 224 238 /* leave cgroup and remove them, don't detach programs */ 225 239 cleanup_cgroup_environment();
+23 -28
tools/testing/selftests/bpf/prog_tests/sk_lookup.c
··· 34 34 #include "bpf_util.h" 35 35 #include "cgroup_helpers.h" 36 36 #include "network_helpers.h" 37 + #include "testing_helpers.h" 37 38 #include "test_sk_lookup.skel.h" 38 39 39 40 /* External (address, port) pairs the client sends packets to. */ ··· 470 469 return 0; 471 470 } 472 471 473 - static __u32 link_info_prog_id(struct bpf_link *link) 474 - { 475 - struct bpf_link_info info = {}; 476 - __u32 info_len = sizeof(info); 477 - int link_fd, err; 478 - 479 - link_fd = bpf_link__fd(link); 480 - if (CHECK(link_fd < 0, "bpf_link__fd", "failed\n")) { 481 - errno = -link_fd; 482 - log_err("bpf_link__fd failed"); 483 - return 0; 484 - } 485 - 486 - err = bpf_obj_get_info_by_fd(link_fd, &info, &info_len); 487 - if (CHECK(err, "bpf_obj_get_info_by_fd", "failed\n")) { 488 - log_err("bpf_obj_get_info_by_fd"); 489 - return 0; 490 - } 491 - if (CHECK(info_len != sizeof(info), "bpf_obj_get_info_by_fd", 492 - "unexpected info len %u\n", info_len)) 493 - return 0; 494 - 495 - return info.prog_id; 496 - } 497 - 498 472 static void query_lookup_prog(struct test_sk_lookup *skel) 499 473 { 500 474 struct bpf_link *link[3] = {}; 475 + struct bpf_link_info info; 501 476 __u32 attach_flags = 0; 502 477 __u32 prog_ids[3] = {}; 503 478 __u32 prog_cnt = 3; ··· 511 534 if (CHECK(prog_cnt != 3, "bpf_prog_query", 512 535 "wrong program count on query: %u", prog_cnt)) 513 536 goto detach; 514 - prog_id = link_info_prog_id(link[0]); 537 + prog_id = link_info_prog_id(link[0], &info); 515 538 CHECK(prog_ids[0] != prog_id, "bpf_prog_query", 516 539 "invalid program #0 id on query: %u != %u\n", 517 540 prog_ids[0], prog_id); 518 - prog_id = link_info_prog_id(link[1]); 541 + CHECK(info.netns.netns_ino == 0, "netns_ino", 542 + "unexpected netns_ino: %u\n", info.netns.netns_ino); 543 + prog_id = link_info_prog_id(link[1], &info); 519 544 CHECK(prog_ids[1] != prog_id, "bpf_prog_query", 520 545 "invalid program #1 id on query: %u != %u\n", 521 546 prog_ids[1], prog_id); 522 - prog_id = link_info_prog_id(link[2]); 547 + CHECK(info.netns.netns_ino == 0, "netns_ino", 548 + "unexpected netns_ino: %u\n", info.netns.netns_ino); 549 + prog_id = link_info_prog_id(link[2], &info); 523 550 CHECK(prog_ids[2] != prog_id, "bpf_prog_query", 524 551 "invalid program #2 id on query: %u != %u\n", 525 552 prog_ids[2], prog_id); 553 + CHECK(info.netns.netns_ino == 0, "netns_ino", 554 + "unexpected netns_ino: %u\n", info.netns.netns_ino); 555 + 556 + err = bpf_link__detach(link[0]); 557 + if (CHECK(err, "link_detach", "failed %d\n", err)) 558 + goto detach; 559 + 560 + /* prog id is still there, but netns_ino is zeroed out */ 561 + prog_id = link_info_prog_id(link[0], &info); 562 + CHECK(prog_ids[0] != prog_id, "bpf_prog_query", 563 + "invalid program #0 id on query: %u != %u\n", 564 + prog_ids[0], prog_id); 565 + CHECK(info.netns.netns_ino != 0, "netns_ino", 566 + "unexpected netns_ino: %u\n", info.netns.netns_ino); 526 567 527 568 detach: 528 569 if (link[2])
+14
tools/testing/selftests/bpf/prog_tests/xdp_link.c
··· 131 131 CHECK(link_info.xdp.ifindex != IFINDEX_LO, "link_ifindex", 132 132 "got %u != exp %u\n", link_info.xdp.ifindex, IFINDEX_LO); 133 133 134 + err = bpf_link__detach(link); 135 + if (CHECK(err, "link_detach", "failed %d\n", err)) 136 + goto cleanup; 137 + 138 + memset(&link_info, 0, sizeof(link_info)); 139 + err = bpf_obj_get_info_by_fd(bpf_link__fd(link), &link_info, &link_info_len); 140 + if (CHECK(err, "link_info", "failed: %d\n", err)) 141 + goto cleanup; 142 + CHECK(link_info.prog_id != id1, "link_prog_id", 143 + "got %u != exp %u\n", link_info.prog_id, id1); 144 + /* ifindex should be zeroed out */ 145 + CHECK(link_info.xdp.ifindex != 0, "link_ifindex", 146 + "got %u != exp %u\n", link_info.xdp.ifindex, 0); 147 + 134 148 cleanup: 135 149 test_xdp_link__destroy(skel1); 136 150 test_xdp_link__destroy(skel2);
+14
tools/testing/selftests/bpf/testing_helpers.c
··· 64 64 65 65 return 0; 66 66 } 67 + 68 + __u32 link_info_prog_id(const struct bpf_link *link, struct bpf_link_info *info) 69 + { 70 + __u32 info_len = sizeof(*info); 71 + int err; 72 + 73 + memset(info, 0, sizeof(*info)); 74 + err = bpf_obj_get_info_by_fd(bpf_link__fd(link), info, &info_len); 75 + if (err) { 76 + printf("failed to get link info: %d\n", -errno); 77 + return 0; 78 + } 79 + return info->prog_id; 80 + }
+3
tools/testing/selftests/bpf/testing_helpers.h
··· 1 1 /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ 2 2 /* Copyright (C) 2020 Facebook, Inc. */ 3 3 #include <stdbool.h> 4 + #include <bpf/bpf.h> 5 + #include <bpf/libbpf.h> 4 6 5 7 int parse_num_list(const char *s, bool **set, int *set_len); 8 + __u32 link_info_prog_id(const struct bpf_link *link, struct bpf_link_info *info);