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
This commit is contained in:
parent
2e49527e52
commit
90806ccc90
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <test_progs.h>
|
||||
#include "cgroup_helpers.h"
|
||||
#include "testing_helpers.h"
|
||||
#include "test_cgroup_link.skel.h"
|
||||
|
||||
static __u32 duration = 0;
|
||||
|
@ -37,7 +38,8 @@ void test_cgroup_link(void)
|
|||
int last_cg = ARRAY_SIZE(cgs) - 1, cg_nr = ARRAY_SIZE(cgs);
|
||||
DECLARE_LIBBPF_OPTS(bpf_link_update_opts, link_upd_opts);
|
||||
struct bpf_link *links[ARRAY_SIZE(cgs)] = {}, *tmp_link;
|
||||
__u32 prog_ids[ARRAY_SIZE(cgs)], prog_cnt = 0, attach_flags;
|
||||
__u32 prog_ids[ARRAY_SIZE(cgs)], prog_cnt = 0, attach_flags, prog_id;
|
||||
struct bpf_link_info info;
|
||||
int i = 0, err, prog_fd;
|
||||
bool detach_legacy = false;
|
||||
|
||||
|
@ -219,6 +221,22 @@ void test_cgroup_link(void)
|
|||
/* BPF programs should still get called */
|
||||
ping_and_check(0, cg_nr);
|
||||
|
||||
prog_id = link_info_prog_id(links[0], &info);
|
||||
CHECK(prog_id == 0, "link_info", "failed\n");
|
||||
CHECK(info.cgroup.cgroup_id == 0, "cgroup_id", "unexpected %llu\n", info.cgroup.cgroup_id);
|
||||
|
||||
err = bpf_link__detach(links[0]);
|
||||
if (CHECK(err, "link_detach", "failed %d\n", err))
|
||||
goto cleanup;
|
||||
|
||||
/* cgroup_id should be zero in link_info */
|
||||
prog_id = link_info_prog_id(links[0], &info);
|
||||
CHECK(prog_id == 0, "link_info", "failed\n");
|
||||
CHECK(info.cgroup.cgroup_id != 0, "cgroup_id", "unexpected %llu\n", info.cgroup.cgroup_id);
|
||||
|
||||
/* First BPF program shouldn't be called anymore */
|
||||
ping_and_check(0, cg_nr - 1);
|
||||
|
||||
/* leave cgroup and remove them, don't detach programs */
|
||||
cleanup_cgroup_environment();
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "bpf_util.h"
|
||||
#include "cgroup_helpers.h"
|
||||
#include "network_helpers.h"
|
||||
#include "testing_helpers.h"
|
||||
#include "test_sk_lookup.skel.h"
|
||||
|
||||
/* External (address, port) pairs the client sends packets to. */
|
||||
|
@ -469,34 +470,10 @@ static int update_lookup_map(struct bpf_map *map, int index, int sock_fd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static __u32 link_info_prog_id(struct bpf_link *link)
|
||||
{
|
||||
struct bpf_link_info info = {};
|
||||
__u32 info_len = sizeof(info);
|
||||
int link_fd, err;
|
||||
|
||||
link_fd = bpf_link__fd(link);
|
||||
if (CHECK(link_fd < 0, "bpf_link__fd", "failed\n")) {
|
||||
errno = -link_fd;
|
||||
log_err("bpf_link__fd failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = bpf_obj_get_info_by_fd(link_fd, &info, &info_len);
|
||||
if (CHECK(err, "bpf_obj_get_info_by_fd", "failed\n")) {
|
||||
log_err("bpf_obj_get_info_by_fd");
|
||||
return 0;
|
||||
}
|
||||
if (CHECK(info_len != sizeof(info), "bpf_obj_get_info_by_fd",
|
||||
"unexpected info len %u\n", info_len))
|
||||
return 0;
|
||||
|
||||
return info.prog_id;
|
||||
}
|
||||
|
||||
static void query_lookup_prog(struct test_sk_lookup *skel)
|
||||
{
|
||||
struct bpf_link *link[3] = {};
|
||||
struct bpf_link_info info;
|
||||
__u32 attach_flags = 0;
|
||||
__u32 prog_ids[3] = {};
|
||||
__u32 prog_cnt = 3;
|
||||
|
@ -534,18 +511,36 @@ static void query_lookup_prog(struct test_sk_lookup *skel)
|
|||
if (CHECK(prog_cnt != 3, "bpf_prog_query",
|
||||
"wrong program count on query: %u", prog_cnt))
|
||||
goto detach;
|
||||
prog_id = link_info_prog_id(link[0]);
|
||||
prog_id = link_info_prog_id(link[0], &info);
|
||||
CHECK(prog_ids[0] != prog_id, "bpf_prog_query",
|
||||
"invalid program #0 id on query: %u != %u\n",
|
||||
prog_ids[0], prog_id);
|
||||
prog_id = link_info_prog_id(link[1]);
|
||||
CHECK(info.netns.netns_ino == 0, "netns_ino",
|
||||
"unexpected netns_ino: %u\n", info.netns.netns_ino);
|
||||
prog_id = link_info_prog_id(link[1], &info);
|
||||
CHECK(prog_ids[1] != prog_id, "bpf_prog_query",
|
||||
"invalid program #1 id on query: %u != %u\n",
|
||||
prog_ids[1], prog_id);
|
||||
prog_id = link_info_prog_id(link[2]);
|
||||
CHECK(info.netns.netns_ino == 0, "netns_ino",
|
||||
"unexpected netns_ino: %u\n", info.netns.netns_ino);
|
||||
prog_id = link_info_prog_id(link[2], &info);
|
||||
CHECK(prog_ids[2] != prog_id, "bpf_prog_query",
|
||||
"invalid program #2 id on query: %u != %u\n",
|
||||
prog_ids[2], prog_id);
|
||||
CHECK(info.netns.netns_ino == 0, "netns_ino",
|
||||
"unexpected netns_ino: %u\n", info.netns.netns_ino);
|
||||
|
||||
err = bpf_link__detach(link[0]);
|
||||
if (CHECK(err, "link_detach", "failed %d\n", err))
|
||||
goto detach;
|
||||
|
||||
/* prog id is still there, but netns_ino is zeroed out */
|
||||
prog_id = link_info_prog_id(link[0], &info);
|
||||
CHECK(prog_ids[0] != prog_id, "bpf_prog_query",
|
||||
"invalid program #0 id on query: %u != %u\n",
|
||||
prog_ids[0], prog_id);
|
||||
CHECK(info.netns.netns_ino != 0, "netns_ino",
|
||||
"unexpected netns_ino: %u\n", info.netns.netns_ino);
|
||||
|
||||
detach:
|
||||
if (link[2])
|
||||
|
|
|
@ -131,6 +131,20 @@ void test_xdp_link(void)
|
|||
CHECK(link_info.xdp.ifindex != IFINDEX_LO, "link_ifindex",
|
||||
"got %u != exp %u\n", link_info.xdp.ifindex, IFINDEX_LO);
|
||||
|
||||
err = bpf_link__detach(link);
|
||||
if (CHECK(err, "link_detach", "failed %d\n", err))
|
||||
goto cleanup;
|
||||
|
||||
memset(&link_info, 0, sizeof(link_info));
|
||||
err = bpf_obj_get_info_by_fd(bpf_link__fd(link), &link_info, &link_info_len);
|
||||
if (CHECK(err, "link_info", "failed: %d\n", err))
|
||||
goto cleanup;
|
||||
CHECK(link_info.prog_id != id1, "link_prog_id",
|
||||
"got %u != exp %u\n", link_info.prog_id, id1);
|
||||
/* ifindex should be zeroed out */
|
||||
CHECK(link_info.xdp.ifindex != 0, "link_ifindex",
|
||||
"got %u != exp %u\n", link_info.xdp.ifindex, 0);
|
||||
|
||||
cleanup:
|
||||
test_xdp_link__destroy(skel1);
|
||||
test_xdp_link__destroy(skel2);
|
||||
|
|
|
@ -64,3 +64,17 @@ int parse_num_list(const char *s, bool **num_set, int *num_set_len)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__u32 link_info_prog_id(const struct bpf_link *link, struct bpf_link_info *info)
|
||||
{
|
||||
__u32 info_len = sizeof(*info);
|
||||
int err;
|
||||
|
||||
memset(info, 0, sizeof(*info));
|
||||
err = bpf_obj_get_info_by_fd(bpf_link__fd(link), info, &info_len);
|
||||
if (err) {
|
||||
printf("failed to get link info: %d\n", -errno);
|
||||
return 0;
|
||||
}
|
||||
return info->prog_id;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
|
||||
/* Copyright (C) 2020 Facebook, Inc. */
|
||||
#include <stdbool.h>
|
||||
#include <bpf/bpf.h>
|
||||
#include <bpf/libbpf.h>
|
||||
|
||||
int parse_num_list(const char *s, bool **set, int *set_len);
|
||||
__u32 link_info_prog_id(const struct bpf_link *link, struct bpf_link_info *info);
|
||||
|
|
Loading…
Reference in New Issue