Skip to content

Commit 021f681

Browse files
committed
libxdp: add selftest for dispatcher v2 compatibility
Signed-off-by: Jalal Mostafa <[email protected]>
1 parent 5bbc0a9 commit 021f681

File tree

6 files changed

+149
-36
lines changed

6 files changed

+149
-36
lines changed

lib/libxdp/tests/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
22

33
USER_TARGETS := test_xsk_refcnt check_kern_compat test_xdp_devbound test_xdp_frags test_dispatcher_versions test_link_detach test_xsk_umem_flags
4-
BPF_TARGETS := xdp_dispatcher_v1 xdp_pass
4+
BPF_TARGETS := xdp_dispatcher_v1 xdp_dispatcher_v2 xdp_pass
55
USER_LIBS := -lpthread
66

7-
EXTRA_DEPS += xdp_dispatcher_v1.h
7+
EXTRA_DEPS += xdp_dispatcher.h
88
EXTRA_USER_DEPS += test_utils.h
99

1010
TEST_FILE := ./test-libxdp.sh

lib/libxdp/tests/test_dispatcher_versions.c

Lines changed: 73 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
#include "test_utils.h"
1717
#include "../libxdp_internal.h"
18-
#include "xdp_dispatcher_v1.h"
18+
#include "xdp_dispatcher.h"
1919

2020
#include <xdp/libxdp.h>
2121
#include <bpf/libbpf.h>
@@ -29,6 +29,15 @@
2929

3030
#define PROG_RUN_PRIO 42
3131
#define PROG_CHAIN_CALL_ACTIONS (1 << XDP_DROP)
32+
#define DISPATCHER_V1_FILE "xdp_dispatcher_v1.o"
33+
#define DISPATCHER_V2_FILE "xdp_dispatcher_v2.o"
34+
35+
static void print_test_result(const char *func, int ret)
36+
{
37+
fflush(stderr);
38+
fprintf(stderr, "%s:\t%s\n", func, ret ? "FAILED" : "PASSED");
39+
fflush(stdout);
40+
}
3241

3342
int get_prog_id(int prog_fd)
3443
{
@@ -43,9 +52,26 @@ int get_prog_id(int prog_fd)
4352
return info.id;
4453
}
4554

46-
int load_dispatcher_v1(int ifindex)
55+
static char* get_dispatcher_file(unsigned int dispatcher_version)
56+
{
57+
switch (dispatcher_version) {
58+
case XDP_DISPATCHER_VERSION_V1:
59+
return DISPATCHER_V1_FILE;
60+
61+
case XDP_DISPATCHER_VERSION_V2:
62+
return DISPATCHER_V2_FILE;
63+
64+
default:
65+
break;
66+
}
67+
return NULL;
68+
}
69+
70+
int load_dispatcher(int ifindex, unsigned int dispatcher_version)
4771
{
48-
struct xdp_dispatcher_config_v1 dispatcher_config = {};
72+
struct xdp_dispatcher_config_v1 dispatcher_config_v1 = {};
73+
struct xdp_dispatcher_config_v2 dispatcher_config_v2 = {};
74+
char *dispatcher_file = get_dispatcher_file(dispatcher_version);
4975
struct bpf_object *obj_dispatcher, *obj_prog = NULL;
5076
DECLARE_LIBBPF_OPTS(bpf_link_create_opts, opts);
5177
struct bpf_program *dispatcher_prog, *xdp_prog;
@@ -54,10 +80,10 @@ int load_dispatcher_v1(int ifindex)
5480
const char *attach_func = "prog0";
5581
struct bpf_map *map;
5682

57-
if (!ifindex)
83+
if (!ifindex || !dispatcher_file)
5884
return -ENOENT;
5985

60-
obj_dispatcher = bpf_object__open("xdp_dispatcher_v1.o");
86+
obj_dispatcher = bpf_object__open(dispatcher_file);
6187
if (!obj_dispatcher)
6288
return -errno;
6389

@@ -76,22 +102,38 @@ int load_dispatcher_v1(int ifindex)
76102
}
77103

78104
dispatcher_prog = bpf_object__find_program_by_name(obj_dispatcher,
79-
"xdp_dispatcher");
105+
"xdp_dispatcher");
80106
if (!dispatcher_prog) {
81107
ret = -errno;
82108
goto out;
83109
}
84110

85-
dispatcher_config.num_progs_enabled = 1;
86-
dispatcher_config.chain_call_actions[0] = PROG_CHAIN_CALL_ACTIONS;
87-
dispatcher_config.run_prios[0] = PROG_RUN_PRIO;
111+
switch (dispatcher_version) {
112+
case XDP_DISPATCHER_VERSION_V1:
113+
dispatcher_config_v1.num_progs_enabled = 1;
114+
dispatcher_config_v1.chain_call_actions[0] = PROG_CHAIN_CALL_ACTIONS;
115+
dispatcher_config_v1.run_prios[0] = PROG_RUN_PRIO;
116+
117+
ret = bpf_map__set_initial_value(map, &dispatcher_config_v1,
118+
sizeof(dispatcher_config_v1));
119+
break;
120+
121+
case XDP_DISPATCHER_VERSION_V2:
122+
dispatcher_config_v2.magic = XDP_DISPATCHER_MAGIC;
123+
dispatcher_config_v2.num_progs_enabled = 1;
124+
dispatcher_config_v2.chain_call_actions[0] = PROG_CHAIN_CALL_ACTIONS;
125+
dispatcher_config_v2.run_prios[0] = PROG_RUN_PRIO;
126+
dispatcher_config_v2.is_xdp_frags = 0;
127+
dispatcher_config_v2.program_flags[0] = 0;
128+
dispatcher_config_v2.dispatcher_version = XDP_DISPATCHER_VERSION_V2;
129+
130+
ret = bpf_map__set_initial_value(map, &dispatcher_config_v2,
131+
sizeof(dispatcher_config_v2));
132+
}
88133

89-
ret = bpf_map__set_initial_value(map, &dispatcher_config,
90-
sizeof(dispatcher_config));
91134
if (ret)
92135
goto out;
93136

94-
95137
ret = bpf_object__load(obj_dispatcher);
96138
if (ret)
97139
goto out;
@@ -190,14 +232,14 @@ int load_dispatcher_v1(int ifindex)
190232
goto out;
191233
}
192234

193-
int check_old_dispatcher(int ifindex)
235+
int check_old_dispatcher(int ifindex, unsigned int dispatcher_version)
194236
{
195237
struct xdp_multiprog *mp = NULL;
196238
struct xdp_program *xdp_prog;
197239
char buf[100];
198240
int ret;
199241

200-
ret = load_dispatcher_v1(ifindex);
242+
ret = load_dispatcher(ifindex, dispatcher_version);
201243
if (ret)
202244
goto out;
203245

@@ -276,6 +318,20 @@ static void usage(char *progname)
276318
exit(EXIT_FAILURE);
277319
}
278320

321+
int check_old_dispatcher_v1(int ifindex)
322+
{
323+
int ret = check_old_dispatcher(ifindex, XDP_DISPATCHER_VERSION_V1);
324+
print_test_result(__func__, ret);
325+
return ret;
326+
}
327+
328+
int check_old_dispatcher_v2(int ifindex)
329+
{
330+
int ret = check_old_dispatcher(ifindex, XDP_DISPATCHER_VERSION_V2);
331+
print_test_result(__func__, ret);
332+
return ret;
333+
}
334+
279335
int main(int argc, char **argv)
280336
{
281337
int ifindex, ret;
@@ -294,7 +350,8 @@ int main(int argc, char **argv)
294350

295351
ifindex = if_nametoindex(argv[1]);
296352

297-
ret = check_old_dispatcher(ifindex);
353+
ret = check_old_dispatcher_v1(ifindex);
354+
ret = check_old_dispatcher_v2(ifindex) || ret;
298355

299356
return ret;
300-
}
357+
}

lib/libxdp/tests/xdp_dispatcher.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
3+
#ifndef __XDP_DISPATCHER_H
4+
#define __XDP_DISPATCHER_H
5+
6+
#ifndef MAX_DISPATCHER_ACTIONS
7+
#define MAX_DISPATCHER_ACTIONS 10
8+
#endif
9+
10+
struct xdp_dispatcher_config_v1 {
11+
__u8 num_progs_enabled;
12+
__u32 chain_call_actions[MAX_DISPATCHER_ACTIONS];
13+
__u32 run_prios[MAX_DISPATCHER_ACTIONS];
14+
};
15+
16+
#define XDP_DISPATCHER_VERSION_V1 1
17+
18+
struct xdp_dispatcher_config_v2 {
19+
__u8 magic; /* Set to XDP_DISPATCHER_MAGIC */
20+
__u8 dispatcher_version; /* Set to XDP_DISPATCHER_VERSION */
21+
__u8 num_progs_enabled; /* Number of active program slots */
22+
__u8 is_xdp_frags; /* Whether this dispatcher is loaded with XDP frags support */
23+
__u32 chain_call_actions[MAX_DISPATCHER_ACTIONS];
24+
__u32 run_prios[MAX_DISPATCHER_ACTIONS];
25+
__u32 program_flags[MAX_DISPATCHER_ACTIONS];
26+
};
27+
28+
#define XDP_DISPATCHER_MAGIC 236
29+
#define XDP_DISPATCHER_VERSION_V2 2
30+
31+
#endif

lib/libxdp/tests/xdp_dispatcher_v1.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44
#include <bpf/bpf_helpers.h>
55
#include <bpf/bpf_endian.h>
66

7-
#include "xdp_dispatcher_v1.h"
7+
#include "xdp_dispatcher.h"
88

99
#define XDP_METADATA_SECTION "xdp_metadata"
10-
#define XDP_DISPATCHER_VERSION_V1 1
1110
#define XDP_DISPATCHER_RETVAL 31
1211

1312

lib/libxdp/tests/xdp_dispatcher_v1.h

Lines changed: 0 additions & 16 deletions
This file was deleted.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
3+
#include <linux/bpf.h>
4+
#include <bpf/bpf_helpers.h>
5+
#include <bpf/bpf_endian.h>
6+
7+
#include "xdp_dispatcher.h"
8+
9+
#define XDP_METADATA_SECTION "xdp_metadata"
10+
#define XDP_DISPATCHER_RETVAL 31
11+
12+
13+
static volatile const struct xdp_dispatcher_config_v2 conf = {};
14+
15+
__attribute__ ((noinline))
16+
int prog0(struct xdp_md *ctx) {
17+
volatile int ret = XDP_DISPATCHER_RETVAL;
18+
19+
if (!ctx)
20+
return XDP_ABORTED;
21+
return ret;
22+
}
23+
__attribute__ ((noinline))
24+
25+
SEC("xdp")
26+
int xdp_dispatcher(struct xdp_md *ctx)
27+
{
28+
__u8 num_progs_enabled = conf.num_progs_enabled;
29+
int ret;
30+
31+
if (num_progs_enabled < 1)
32+
goto out;
33+
ret = prog0(ctx);
34+
if (!((1U << ret) & conf.chain_call_actions[0]))
35+
return ret;
36+
37+
out:
38+
return XDP_PASS;
39+
}
40+
41+
char _license[] SEC("license") = "GPL";
42+
__uint(dispatcher_version, XDP_DISPATCHER_VERSION_V2) SEC(XDP_METADATA_SECTION);

0 commit comments

Comments
 (0)