Skip to content

Commit

Permalink
Merge branch 'bpf-next/master' into for-next
Browse files Browse the repository at this point in the history
No conflict.

Signed-off-by: Martin KaFai Lau <[email protected]>
  • Loading branch information
Martin KaFai Lau committed Jan 11, 2025
2 parents 6e90b32 + be339dd commit cb451fc
Show file tree
Hide file tree
Showing 10 changed files with 222 additions and 110 deletions.
1 change: 1 addition & 0 deletions tools/bpf/bpftool/cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ static bool func_add_bb_edges(struct func_node *func)

insn = bb->tail;
if (!is_jmp_insn(insn->code) ||
BPF_OP(insn->code) == BPF_CALL ||
BPF_OP(insn->code) == BPF_EXIT) {
e->dst = bb_next(bb);
e->flags |= EDGE_FLAG_FALLTHROUGH;
Expand Down
13 changes: 12 additions & 1 deletion tools/lib/bpf/libbpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -11534,7 +11534,7 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
struct bpf_link *link = NULL;
const unsigned long *addrs;
int err, link_fd, prog_fd;
bool retprobe, session;
bool retprobe, session, unique_match;
const __u64 *cookies;
const char **syms;
size_t cnt;
Expand All @@ -11553,13 +11553,16 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
addrs = OPTS_GET(opts, addrs, false);
cnt = OPTS_GET(opts, cnt, false);
cookies = OPTS_GET(opts, cookies, false);
unique_match = OPTS_GET(opts, unique_match, false);

if (!pattern && !addrs && !syms)
return libbpf_err_ptr(-EINVAL);
if (pattern && (addrs || syms || cookies || cnt))
return libbpf_err_ptr(-EINVAL);
if (!pattern && !cnt)
return libbpf_err_ptr(-EINVAL);
if (!pattern && unique_match)
return libbpf_err_ptr(-EINVAL);
if (addrs && syms)
return libbpf_err_ptr(-EINVAL);

Expand All @@ -11570,6 +11573,14 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
err = libbpf_available_kallsyms_parse(&res);
if (err)
goto error;

if (unique_match && res.cnt != 1) {
pr_warn("prog '%s': failed to find a unique match for '%s' (%zu matches)\n",
prog->name, pattern, res.cnt);
err = -EINVAL;
goto error;
}

addrs = res.addrs;
cnt = res.cnt;
}
Expand Down
4 changes: 3 additions & 1 deletion tools/lib/bpf/libbpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -552,10 +552,12 @@ struct bpf_kprobe_multi_opts {
bool retprobe;
/* create session kprobes */
bool session;
/* enforce unique match */
bool unique_match;
size_t :0;
};

#define bpf_kprobe_multi_opts__last_field session
#define bpf_kprobe_multi_opts__last_field unique_match

LIBBPF_API struct bpf_link *
bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
Expand Down
1 change: 0 additions & 1 deletion tools/testing/selftests/bpf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ TEST_FILES = xsk_prereqs.sh $(wildcard progs/btf_dump_test_case_*.c)

# Order correspond to 'make run_tests' order
TEST_PROGS := test_kmod.sh \
test_xdp_redirect.sh \
test_xdp_redirect_multi.sh \
test_tunnel.sh \
test_lwt_seg6local.sh \
Expand Down
27 changes: 27 additions & 0 deletions tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,31 @@ static void test_session_cookie_skel_api(void)
kprobe_multi_session_cookie__destroy(skel);
}

static void test_unique_match(void)
{
LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
struct kprobe_multi *skel = NULL;
struct bpf_link *link = NULL;

skel = kprobe_multi__open_and_load();
if (!ASSERT_OK_PTR(skel, "kprobe_multi__open_and_load"))
return;

opts.unique_match = true;
skel->bss->pid = getpid();
link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,
"bpf_fentry_test*", &opts);
if (!ASSERT_ERR_PTR(link, "bpf_program__attach_kprobe_multi_opts"))
bpf_link__destroy(link);

link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,
"bpf_fentry_test8*", &opts);
if (ASSERT_OK_PTR(link, "bpf_program__attach_kprobe_multi_opts"))
bpf_link__destroy(link);

kprobe_multi__destroy(skel);
}

static size_t symbol_hash(long key, void *ctx __maybe_unused)
{
return str_hash((const char *) key);
Expand Down Expand Up @@ -765,5 +790,7 @@ void test_kprobe_multi_test(void)
test_session_skel_api();
if (test__start_subtest("session_cookie"))
test_session_cookie_skel_api();
if (test__start_subtest("unique_match"))
test_unique_match();
RUN_TESTS(kprobe_multi_verifier);
}
164 changes: 164 additions & 0 deletions tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <bpf/bpf_endian.h>
#include <uapi/linux/netdev.h>
#include "test_xdp_do_redirect.skel.h"
#include "xdp_dummy.skel.h"

struct udp_packet {
struct ethhdr eth;
Expand Down Expand Up @@ -246,3 +247,166 @@ void test_xdp_do_redirect(void)
SYS_NOFAIL("ip netns del testns");
test_xdp_do_redirect__destroy(skel);
}

#define NS_NB 3
#define NS0 "NS0"
#define NS1 "NS1"
#define NS2 "NS2"
#define IPV4_NETWORK "10.1.1"
#define VETH1_INDEX 111
#define VETH2_INDEX 222

struct test_data {
struct netns_obj *ns[NS_NB];
u32 xdp_flags;
};

static void cleanup(struct test_data *data)
{
int i;

for (i = 0; i < NS_NB; i++)
netns_free(data->ns[i]);
}

/**
* ping_setup -
* Create two veth peers and forward packets in-between using XDP
*
* ------------ ------------
* | NS1 | | NS2 |
* | veth0 | | veth0 |
* | 10.1.1.1 | | 10.1.1.2 |
* -----|------ ------|-----
* | |
* | |
* -----|-----------------------|-------
* | veth1 veth2 |
* | (id:111) (id:222) |
* | | | |
* | ----- xdp forwarding ----- |
* | |
* | NS0 |
* -------------------------------------
*/
static int ping_setup(struct test_data *data)
{
int i;

data->ns[0] = netns_new(NS0, false);
if (!ASSERT_OK_PTR(data->ns[0], "create ns"))
return -1;

for (i = 1; i < NS_NB; i++) {
char ns_name[4] = {};

snprintf(ns_name, 4, "NS%d", i);
data->ns[i] = netns_new(ns_name, false);
if (!ASSERT_OK_PTR(data->ns[i], "create ns"))
goto fail;

SYS(fail,
"ip -n %s link add veth%d index %d%d%d type veth peer name veth0 netns %s",
NS0, i, i, i, i, ns_name);
SYS(fail, "ip -n %s link set veth%d up", NS0, i);

SYS(fail, "ip -n %s addr add %s.%d/24 dev veth0", ns_name, IPV4_NETWORK, i);
SYS(fail, "ip -n %s link set veth0 up", ns_name);
}

return 0;

fail:
cleanup(data);
return -1;
}

static void ping_test(struct test_data *data)
{
struct test_xdp_do_redirect *skel = NULL;
struct xdp_dummy *skel_dummy = NULL;
struct nstoken *nstoken = NULL;
int i, ret;

skel_dummy = xdp_dummy__open_and_load();
if (!ASSERT_OK_PTR(skel_dummy, "open and load xdp_dummy skeleton"))
goto close;

for (i = 1; i < NS_NB; i++) {
char ns_name[4] = {};

snprintf(ns_name, 4, "NS%d", i);
nstoken = open_netns(ns_name);
if (!ASSERT_OK_PTR(nstoken, "open ns"))
goto close;

ret = bpf_xdp_attach(if_nametoindex("veth0"),
bpf_program__fd(skel_dummy->progs.xdp_dummy_prog),
data->xdp_flags, NULL);
if (!ASSERT_GE(ret, 0, "bpf_xdp_attach dummy_prog"))
goto close;

close_netns(nstoken);
nstoken = NULL;
}

skel = test_xdp_do_redirect__open_and_load();
if (!ASSERT_OK_PTR(skel, "open and load skeleton"))
goto close;

nstoken = open_netns(NS0);
if (!ASSERT_OK_PTR(nstoken, "open NS0"))
goto close;

ret = bpf_xdp_attach(VETH2_INDEX,
bpf_program__fd(skel->progs.xdp_redirect_to_111),
data->xdp_flags, NULL);
if (!ASSERT_GE(ret, 0, "bpf_xdp_attach"))
goto close;

ret = bpf_xdp_attach(VETH1_INDEX,
bpf_program__fd(skel->progs.xdp_redirect_to_222),
data->xdp_flags, NULL);
if (!ASSERT_GE(ret, 0, "bpf_xdp_attach"))
goto close;

close_netns(nstoken);
nstoken = NULL;

nstoken = open_netns(NS1);
if (!ASSERT_OK_PTR(nstoken, "open NS1"))
goto close;

SYS(close, "ping -c 1 %s.2 > /dev/null", IPV4_NETWORK);

close:
close_netns(nstoken);
xdp_dummy__destroy(skel_dummy);
test_xdp_do_redirect__destroy(skel);
}


static void xdp_redirect_ping(u32 xdp_flags)
{
struct test_data data = {};

if (ping_setup(&data) < 0)
return;

data.xdp_flags = xdp_flags;
ping_test(&data);
cleanup(&data);
}

void test_xdp_index_redirect(void)
{
if (test__start_subtest("noflag"))
xdp_redirect_ping(0);

if (test__start_subtest("drvflag"))
xdp_redirect_ping(XDP_FLAGS_DRV_MODE);

if (test__start_subtest("skbflag"))
xdp_redirect_ping(XDP_FLAGS_SKB_MODE);
}

12 changes: 12 additions & 0 deletions tools/testing/selftests/bpf/progs/test_xdp_do_redirect.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,18 @@ int xdp_count_pkts(struct xdp_md *xdp)
return XDP_DROP;
}

SEC("xdp")
int xdp_redirect_to_111(struct xdp_md *xdp)
{
return bpf_redirect(111, 0);
}

SEC("xdp")
int xdp_redirect_to_222(struct xdp_md *xdp)
{
return bpf_redirect(222, 0);
}

SEC("tc")
int tc_count_pkts(struct __sk_buff *skb)
{
Expand Down
26 changes: 0 additions & 26 deletions tools/testing/selftests/bpf/progs/test_xdp_redirect.c

This file was deleted.

Loading

0 comments on commit cb451fc

Please sign in to comment.