Skip to content

Commit b4b8a3b

Browse files
jsitnickiAlexei Starovoitov
authored andcommitted
selftests/bpf: Convert test_flow_dissector to use BPF skeleton
Switch flow dissector test setup from custom BPF object loader to BPF skeleton to save boilerplate and prepare for testing higher-level API for attaching flow dissector with bpf_link. To avoid depending on program order in the BPF object when populating the flow dissector PROG_ARRAY map, change the program section names to contain the program index into the map. This follows the example set by tailcall tests. Signed-off-by: Jakub Sitnicki <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent b8215dc commit b4b8a3b

File tree

2 files changed

+55
-15
lines changed

2 files changed

+55
-15
lines changed

tools/testing/selftests/bpf/prog_tests/flow_dissector.c

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include <linux/if_tun.h>
77
#include <sys/uio.h>
88

9+
#include "bpf_flow.skel.h"
10+
911
#ifndef IP_MF
1012
#define IP_MF 0x2000
1113
#endif
@@ -444,17 +446,54 @@ static int ifup(const char *ifname)
444446
return 0;
445447
}
446448

449+
static int init_prog_array(struct bpf_object *obj, struct bpf_map *prog_array)
450+
{
451+
int i, err, map_fd, prog_fd;
452+
struct bpf_program *prog;
453+
char prog_name[32];
454+
455+
map_fd = bpf_map__fd(prog_array);
456+
if (map_fd < 0)
457+
return -1;
458+
459+
for (i = 0; i < bpf_map__def(prog_array)->max_entries; i++) {
460+
snprintf(prog_name, sizeof(prog_name), "flow_dissector/%i", i);
461+
462+
prog = bpf_object__find_program_by_title(obj, prog_name);
463+
if (!prog)
464+
return -1;
465+
466+
prog_fd = bpf_program__fd(prog);
467+
if (prog_fd < 0)
468+
return -1;
469+
470+
err = bpf_map_update_elem(map_fd, &i, &prog_fd, BPF_ANY);
471+
if (err)
472+
return -1;
473+
}
474+
return 0;
475+
}
476+
447477
void test_flow_dissector(void)
448478
{
449479
int i, err, prog_fd, keys_fd = -1, tap_fd;
450-
struct bpf_object *obj;
480+
struct bpf_flow *skel;
451481
__u32 duration = 0;
452482

453-
err = bpf_flow_load(&obj, "./bpf_flow.o", "flow_dissector",
454-
"jmp_table", "last_dissection", &prog_fd, &keys_fd);
455-
if (CHECK_FAIL(err))
483+
skel = bpf_flow__open_and_load();
484+
if (CHECK(!skel, "skel", "failed to open/load skeleton\n"))
456485
return;
457486

487+
prog_fd = bpf_program__fd(skel->progs._dissect);
488+
if (CHECK(prog_fd < 0, "bpf_program__fd", "err %d\n", prog_fd))
489+
goto out_destroy_skel;
490+
keys_fd = bpf_map__fd(skel->maps.last_dissection);
491+
if (CHECK(keys_fd < 0, "bpf_map__fd", "err %d\n", keys_fd))
492+
goto out_destroy_skel;
493+
err = init_prog_array(skel->obj, skel->maps.jmp_table);
494+
if (CHECK(err, "init_prog_array", "err %d\n", err))
495+
goto out_destroy_skel;
496+
458497
for (i = 0; i < ARRAY_SIZE(tests); i++) {
459498
struct bpf_flow_keys flow_keys;
460499
struct bpf_prog_test_run_attr tattr = {
@@ -526,5 +565,6 @@ void test_flow_dissector(void)
526565

527566
close(tap_fd);
528567
bpf_prog_detach(prog_fd, BPF_FLOW_DISSECTOR);
529-
bpf_object__close(obj);
568+
out_destroy_skel:
569+
bpf_flow__destroy(skel);
530570
}

tools/testing/selftests/bpf/progs/bpf_flow.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,20 @@
2020
#include <bpf/bpf_endian.h>
2121

2222
int _version SEC("version") = 1;
23-
#define PROG(F) SEC(#F) int bpf_func_##F
23+
#define PROG(F) PROG_(F, _##F)
24+
#define PROG_(NUM, NAME) SEC("flow_dissector/"#NUM) int bpf_func##NAME
2425

2526
/* These are the identifiers of the BPF programs that will be used in tail
2627
* calls. Name is limited to 16 characters, with the terminating character and
2728
* bpf_func_ above, we have only 6 to work with, anything after will be cropped.
2829
*/
29-
enum {
30-
IP,
31-
IPV6,
32-
IPV6OP, /* Destination/Hop-by-Hop Options IPv6 Extension header */
33-
IPV6FR, /* Fragmentation IPv6 Extension Header */
34-
MPLS,
35-
VLAN,
36-
};
30+
#define IP 0
31+
#define IPV6 1
32+
#define IPV6OP 2 /* Destination/Hop-by-Hop Options IPv6 Ext. Header */
33+
#define IPV6FR 3 /* Fragmentation IPv6 Extension Header */
34+
#define MPLS 4
35+
#define VLAN 5
36+
#define MAX_PROG 6
3737

3838
#define IP_MF 0x2000
3939
#define IP_OFFSET 0x1FFF
@@ -59,7 +59,7 @@ struct frag_hdr {
5959

6060
struct {
6161
__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
62-
__uint(max_entries, 8);
62+
__uint(max_entries, MAX_PROG);
6363
__uint(key_size, sizeof(__u32));
6464
__uint(value_size, sizeof(__u32));
6565
} jmp_table SEC(".maps");

0 commit comments

Comments
 (0)