]> git.baikalelectronics.ru Git - kernel.git/commitdiff
selftests/bpf: Convert test_flow_dissector to use BPF skeleton
authorJakub Sitnicki <jakub@cloudflare.com>
Sun, 31 May 2020 08:28:45 +0000 (10:28 +0200)
committerAlexei Starovoitov <ast@kernel.org>
Mon, 1 Jun 2020 22:21:03 +0000 (15:21 -0700)
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 <jakub@cloudflare.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20200531082846.2117903-12-jakub@cloudflare.com
tools/testing/selftests/bpf/prog_tests/flow_dissector.c
tools/testing/selftests/bpf/progs/bpf_flow.c

index ef5aab2f60b592b6f925614cc60bb6e83984bbf6..b6370c0b3b7af776946c408f02e0b6616ab4b041 100644 (file)
@@ -6,6 +6,8 @@
 #include <linux/if_tun.h>
 #include <sys/uio.h>
 
+#include "bpf_flow.skel.h"
+
 #ifndef IP_MF
 #define IP_MF 0x2000
 #endif
@@ -444,17 +446,54 @@ static int ifup(const char *ifname)
        return 0;
 }
 
+static int init_prog_array(struct bpf_object *obj, struct bpf_map *prog_array)
+{
+       int i, err, map_fd, prog_fd;
+       struct bpf_program *prog;
+       char prog_name[32];
+
+       map_fd = bpf_map__fd(prog_array);
+       if (map_fd < 0)
+               return -1;
+
+       for (i = 0; i < bpf_map__def(prog_array)->max_entries; i++) {
+               snprintf(prog_name, sizeof(prog_name), "flow_dissector/%i", i);
+
+               prog = bpf_object__find_program_by_title(obj, prog_name);
+               if (!prog)
+                       return -1;
+
+               prog_fd = bpf_program__fd(prog);
+               if (prog_fd < 0)
+                       return -1;
+
+               err = bpf_map_update_elem(map_fd, &i, &prog_fd, BPF_ANY);
+               if (err)
+                       return -1;
+       }
+       return 0;
+}
+
 void test_flow_dissector(void)
 {
        int i, err, prog_fd, keys_fd = -1, tap_fd;
-       struct bpf_object *obj;
+       struct bpf_flow *skel;
        __u32 duration = 0;
 
-       err = bpf_flow_load(&obj, "./bpf_flow.o", "flow_dissector",
-                           "jmp_table", "last_dissection", &prog_fd, &keys_fd);
-       if (CHECK_FAIL(err))
+       skel = bpf_flow__open_and_load();
+       if (CHECK(!skel, "skel", "failed to open/load skeleton\n"))
                return;
 
+       prog_fd = bpf_program__fd(skel->progs._dissect);
+       if (CHECK(prog_fd < 0, "bpf_program__fd", "err %d\n", prog_fd))
+               goto out_destroy_skel;
+       keys_fd = bpf_map__fd(skel->maps.last_dissection);
+       if (CHECK(keys_fd < 0, "bpf_map__fd", "err %d\n", keys_fd))
+               goto out_destroy_skel;
+       err = init_prog_array(skel->obj, skel->maps.jmp_table);
+       if (CHECK(err, "init_prog_array", "err %d\n", err))
+               goto out_destroy_skel;
+
        for (i = 0; i < ARRAY_SIZE(tests); i++) {
                struct bpf_flow_keys flow_keys;
                struct bpf_prog_test_run_attr tattr = {
@@ -526,5 +565,6 @@ void test_flow_dissector(void)
 
        close(tap_fd);
        bpf_prog_detach(prog_fd, BPF_FLOW_DISSECTOR);
-       bpf_object__close(obj);
+out_destroy_skel:
+       bpf_flow__destroy(skel);
 }
index 9941f0ba471e72f1b893b68172d43f518cf41ae9..de6de9221518053ebd1c7e79220ace83501f1c2f 100644 (file)
 #include <bpf/bpf_endian.h>
 
 int _version SEC("version") = 1;
-#define PROG(F) SEC(#F) int bpf_func_##F
+#define PROG(F) PROG_(F, _##F)
+#define PROG_(NUM, NAME) SEC("flow_dissector/"#NUM) int bpf_func##NAME
 
 /* These are the identifiers of the BPF programs that will be used in tail
  * calls. Name is limited to 16 characters, with the terminating character and
  * bpf_func_ above, we have only 6 to work with, anything after will be cropped.
  */
-enum {
-       IP,
-       IPV6,
-       IPV6OP, /* Destination/Hop-by-Hop Options IPv6 Extension header */
-       IPV6FR, /* Fragmentation IPv6 Extension Header */
-       MPLS,
-       VLAN,
-};
+#define IP             0
+#define IPV6           1
+#define IPV6OP         2 /* Destination/Hop-by-Hop Options IPv6 Ext. Header */
+#define IPV6FR         3 /* Fragmentation IPv6 Extension Header */
+#define MPLS           4
+#define VLAN           5
+#define MAX_PROG       6
 
 #define IP_MF          0x2000
 #define IP_OFFSET      0x1FFF
@@ -59,7 +59,7 @@ struct frag_hdr {
 
 struct {
        __uint(type, BPF_MAP_TYPE_PROG_ARRAY);
-       __uint(max_entries, 8);
+       __uint(max_entries, MAX_PROG);
        __uint(key_size, sizeof(__u32));
        __uint(value_size, sizeof(__u32));
 } jmp_table SEC(".maps");