-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
selftest: Add tests for XDP programs in devmap entries
Add tests to verify ability to add an XDP program to a entry in a DEVMAP. Add negative tests to show DEVMAP programs can not be attached to devices as a normal XDP program, and accesses to egress_ifindex require BPF_XDP_DEVMAP attach type. Signed-off-by: David Ahern <dsahern@kernel.org> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Acked-by: Toke Høiland-Jørgensen <toke@redhat.com> Link: https://lore.kernel.org/bpf/20200529220716.75383-6-dsahern@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
- Loading branch information
David Ahern
authored and
Alexei Starovoitov
committed
Jun 1, 2020
1 parent
2778797
commit d39aec7
Showing
3 changed files
with
163 additions
and
0 deletions.
There are no files selected for viewing
97 changes: 97 additions & 0 deletions
97
tools/testing/selftests/bpf/prog_tests/xdp_devmap_attach.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
#include <uapi/linux/bpf.h> | ||
#include <linux/if_link.h> | ||
#include <test_progs.h> | ||
|
||
#include "test_xdp_devmap_helpers.skel.h" | ||
#include "test_xdp_with_devmap_helpers.skel.h" | ||
|
||
#define IFINDEX_LO 1 | ||
|
||
struct bpf_devmap_val { | ||
u32 ifindex; /* device index */ | ||
union { | ||
int fd; /* prog fd on map write */ | ||
u32 id; /* prog id on map read */ | ||
} bpf_prog; | ||
}; | ||
|
||
void test_xdp_with_devmap_helpers(void) | ||
{ | ||
struct test_xdp_with_devmap_helpers *skel; | ||
struct bpf_prog_info info = {}; | ||
struct bpf_devmap_val val = { | ||
.ifindex = IFINDEX_LO, | ||
}; | ||
__u32 len = sizeof(info); | ||
__u32 duration = 0, idx = 0; | ||
int err, dm_fd, map_fd; | ||
|
||
|
||
skel = test_xdp_with_devmap_helpers__open_and_load(); | ||
if (CHECK_FAIL(!skel)) { | ||
perror("test_xdp_with_devmap_helpers__open_and_load"); | ||
return; | ||
} | ||
|
||
/* can not attach program with DEVMAPs that allow programs | ||
* as xdp generic | ||
*/ | ||
dm_fd = bpf_program__fd(skel->progs.xdp_redir_prog); | ||
err = bpf_set_link_xdp_fd(IFINDEX_LO, dm_fd, XDP_FLAGS_SKB_MODE); | ||
CHECK(err == 0, "Generic attach of program with 8-byte devmap", | ||
"should have failed\n"); | ||
|
||
dm_fd = bpf_program__fd(skel->progs.xdp_dummy_dm); | ||
map_fd = bpf_map__fd(skel->maps.dm_ports); | ||
err = bpf_obj_get_info_by_fd(dm_fd, &info, &len); | ||
if (CHECK_FAIL(err)) | ||
goto out_close; | ||
|
||
val.bpf_prog.fd = dm_fd; | ||
err = bpf_map_update_elem(map_fd, &idx, &val, 0); | ||
CHECK(err, "Add program to devmap entry", | ||
"err %d errno %d\n", err, errno); | ||
|
||
err = bpf_map_lookup_elem(map_fd, &idx, &val); | ||
CHECK(err, "Read devmap entry", "err %d errno %d\n", err, errno); | ||
CHECK(info.id != val.bpf_prog.id, "Expected program id in devmap entry", | ||
"expected %u read %u\n", info.id, val.bpf_prog.id); | ||
|
||
/* can not attach BPF_XDP_DEVMAP program to a device */ | ||
err = bpf_set_link_xdp_fd(IFINDEX_LO, dm_fd, XDP_FLAGS_SKB_MODE); | ||
CHECK(err == 0, "Attach of BPF_XDP_DEVMAP program", | ||
"should have failed\n"); | ||
|
||
val.ifindex = 1; | ||
val.bpf_prog.fd = bpf_program__fd(skel->progs.xdp_dummy_prog); | ||
err = bpf_map_update_elem(map_fd, &idx, &val, 0); | ||
CHECK(err == 0, "Add non-BPF_XDP_DEVMAP program to devmap entry", | ||
"should have failed\n"); | ||
|
||
out_close: | ||
test_xdp_with_devmap_helpers__destroy(skel); | ||
} | ||
|
||
void test_neg_xdp_devmap_helpers(void) | ||
{ | ||
struct test_xdp_devmap_helpers *skel; | ||
__u32 duration = 0; | ||
|
||
skel = test_xdp_devmap_helpers__open_and_load(); | ||
if (CHECK(skel, | ||
"Load of XDP program accessing egress ifindex without attach type", | ||
"should have failed\n")) { | ||
test_xdp_devmap_helpers__destroy(skel); | ||
} | ||
} | ||
|
||
|
||
void test_xdp_devmap_attach(void) | ||
{ | ||
if (test__start_subtest("DEVMAP with programs in entries")) | ||
test_xdp_with_devmap_helpers(); | ||
|
||
if (test__start_subtest("Verifier check of DEVMAP programs")) | ||
test_neg_xdp_devmap_helpers(); | ||
} |
22 changes: 22 additions & 0 deletions
22
tools/testing/selftests/bpf/progs/test_xdp_devmap_helpers.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* fails to load without expected_attach_type = BPF_XDP_DEVMAP | ||
* because of access to egress_ifindex | ||
*/ | ||
#include "vmlinux.h" | ||
#include <bpf/bpf_helpers.h> | ||
|
||
SEC("xdp_dm_log") | ||
int xdpdm_devlog(struct xdp_md *ctx) | ||
{ | ||
char fmt[] = "devmap redirect: dev %u -> dev %u len %u\n"; | ||
void *data_end = (void *)(long)ctx->data_end; | ||
void *data = (void *)(long)ctx->data; | ||
unsigned int len = data_end - data; | ||
|
||
bpf_trace_printk(fmt, sizeof(fmt), | ||
ctx->ingress_ifindex, ctx->egress_ifindex, len); | ||
|
||
return XDP_PASS; | ||
} | ||
|
||
char _license[] SEC("license") = "GPL"; |
44 changes: 44 additions & 0 deletions
44
tools/testing/selftests/bpf/progs/test_xdp_with_devmap_helpers.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
|
||
#include "vmlinux.h" | ||
#include <bpf/bpf_helpers.h> | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_DEVMAP); | ||
__uint(key_size, sizeof(__u32)); | ||
__uint(value_size, sizeof(struct bpf_devmap_val)); | ||
__uint(max_entries, 4); | ||
} dm_ports SEC(".maps"); | ||
|
||
SEC("xdp_redir") | ||
int xdp_redir_prog(struct xdp_md *ctx) | ||
{ | ||
return bpf_redirect_map(&dm_ports, 1, 0); | ||
} | ||
|
||
/* invalid program on DEVMAP entry; | ||
* SEC name means expected attach type not set | ||
*/ | ||
SEC("xdp_dummy") | ||
int xdp_dummy_prog(struct xdp_md *ctx) | ||
{ | ||
return XDP_PASS; | ||
} | ||
|
||
/* valid program on DEVMAP entry via SEC name; | ||
* has access to egress and ingress ifindex | ||
*/ | ||
SEC("xdp_devmap") | ||
int xdp_dummy_dm(struct xdp_md *ctx) | ||
{ | ||
char fmt[] = "devmap redirect: dev %u -> dev %u len %u\n"; | ||
void *data_end = (void *)(long)ctx->data_end; | ||
void *data = (void *)(long)ctx->data; | ||
unsigned int len = data_end - data; | ||
|
||
bpf_trace_printk(fmt, sizeof(fmt), | ||
ctx->ingress_ifindex, ctx->egress_ifindex, len); | ||
|
||
return XDP_PASS; | ||
} | ||
char _license[] SEC("license") = "GPL"; |