samples/bpf: Convert XDP samples to libbpf usage
authorMaciej Fijalkowski <maciejromanfijalkowski@gmail.com>
Fri, 1 Feb 2019 21:42:25 +0000 (22:42 +0100)
committerDaniel Borkmann <daniel@iogearbox.net>
Fri, 1 Feb 2019 22:37:51 +0000 (23:37 +0100)
Some of XDP samples that are attaching the bpf program to the interface
via libbpf's bpf_set_link_xdp_fd are still using the bpf_load.c for
loading and manipulating the ebpf program and maps. Convert them to do
this through libbpf usage and remove bpf_load from the picture.

While at it remove what looks like debug leftover in
xdp_redirect_map_user.c

In xdp_redirect_cpu, change the way that the program to be loaded onto
interface is chosen - user now needs to pass the program's section name
instead of the relative number. In case of typo print out the section
names to choose from.

Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Acked-by: Jesper Dangaard Brouer <brouer@redhat.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
samples/bpf/Makefile
samples/bpf/xdp_redirect_cpu_user.c
samples/bpf/xdp_redirect_map_user.c
samples/bpf/xdp_redirect_user.c
samples/bpf/xdp_router_ipv4_user.c
samples/bpf/xdp_tx_iptunnel_user.c

index db1a91dfa70253dd6ca90e0bcf0a3c3afd5bb850..a0ef7eddd0b335255442582c0c1688b58c61b908 100644 (file)
@@ -87,18 +87,18 @@ test_cgrp2_sock2-objs := bpf_load.o test_cgrp2_sock2.o
 xdp1-objs := xdp1_user.o
 # reuse xdp1 source intentionally
 xdp2-objs := xdp1_user.o
-xdp_router_ipv4-objs := bpf_load.o xdp_router_ipv4_user.o
+xdp_router_ipv4-objs := xdp_router_ipv4_user.o
 test_current_task_under_cgroup-objs := bpf_load.o $(CGROUP_HELPERS) \
                                       test_current_task_under_cgroup_user.o
 trace_event-objs := bpf_load.o trace_event_user.o $(TRACE_HELPERS)
 sampleip-objs := bpf_load.o sampleip_user.o $(TRACE_HELPERS)
 tc_l2_redirect-objs := bpf_load.o tc_l2_redirect_user.o
 lwt_len_hist-objs := bpf_load.o lwt_len_hist_user.o
-xdp_tx_iptunnel-objs := bpf_load.o xdp_tx_iptunnel_user.o
+xdp_tx_iptunnel-objs := xdp_tx_iptunnel_user.o
 test_map_in_map-objs := bpf_load.o test_map_in_map_user.o
 per_socket_stats_example-objs := cookie_uid_helper_example.o
-xdp_redirect-objs := bpf_load.o xdp_redirect_user.o
-xdp_redirect_map-objs := bpf_load.o xdp_redirect_map_user.o
+xdp_redirect-objs := xdp_redirect_user.o
+xdp_redirect_map-objs := xdp_redirect_map_user.o
 xdp_redirect_cpu-objs := bpf_load.o xdp_redirect_cpu_user.o
 xdp_monitor-objs := bpf_load.o xdp_monitor_user.o
 xdp_rxq_info-objs := xdp_rxq_info_user.o
index f141e752ca0a7279061a43de9af0a7bf2c4ff1f9..8645ddc2da0e0c20aefe9f61ae0540d2f8847af3 100644 (file)
@@ -24,12 +24,8 @@ static const char *__doc__ =
 /* How many xdp_progs are defined in _kern.c */
 #define MAX_PROG 6
 
-/* Wanted to get rid of bpf_load.h and fake-"libbpf.h" (and instead
- * use bpf/libbpf.h), but cannot as (currently) needed for XDP
- * attaching to a device via bpf_set_link_xdp_fd()
- */
 #include <bpf/bpf.h>
-#include "bpf_load.h"
+#include "bpf/libbpf.h"
 
 #include "bpf_util.h"
 
@@ -38,6 +34,15 @@ static char ifname_buf[IF_NAMESIZE];
 static char *ifname;
 
 static __u32 xdp_flags;
+static int cpu_map_fd;
+static int rx_cnt_map_fd;
+static int redirect_err_cnt_map_fd;
+static int cpumap_enqueue_cnt_map_fd;
+static int cpumap_kthread_cnt_map_fd;
+static int cpus_available_map_fd;
+static int cpus_count_map_fd;
+static int cpus_iterator_map_fd;
+static int exception_cnt_map_fd;
 
 /* Exit return codes */
 #define EXIT_OK                0
@@ -52,7 +57,7 @@ static const struct option long_options[] = {
        {"dev",         required_argument,      NULL, 'd' },
        {"skb-mode",    no_argument,            NULL, 'S' },
        {"sec",         required_argument,      NULL, 's' },
-       {"prognum",     required_argument,      NULL, 'p' },
+       {"progname",    required_argument,      NULL, 'p' },
        {"qsize",       required_argument,      NULL, 'q' },
        {"cpu",         required_argument,      NULL, 'c' },
        {"stress-mode", no_argument,            NULL, 'x' },
@@ -70,7 +75,17 @@ static void int_exit(int sig)
        exit(EXIT_OK);
 }
 
-static void usage(char *argv[])
+static void print_avail_progs(struct bpf_object *obj)
+{
+       struct bpf_program *pos;
+
+       bpf_object__for_each_program(pos, obj) {
+               if (bpf_program__is_xdp(pos))
+                       printf(" %s\n", bpf_program__title(pos, false));
+       }
+}
+
+static void usage(char *argv[], struct bpf_object *obj)
 {
        int i;
 
@@ -88,6 +103,8 @@ static void usage(char *argv[])
                                long_options[i].val);
                printf("\n");
        }
+       printf("\n Programs to be used for --progname:\n");
+       print_avail_progs(obj);
        printf("\n");
 }
 
@@ -262,7 +279,7 @@ static __u64 calc_errs_pps(struct datarec *r,
 
 static void stats_print(struct stats_record *stats_rec,
                        struct stats_record *stats_prev,
-                       int prog_num)
+                       char *prog_name)
 {
        unsigned int nr_cpus = bpf_num_possible_cpus();
        double pps = 0, drop = 0, err = 0;
@@ -272,7 +289,7 @@ static void stats_print(struct stats_record *stats_rec,
        int i;
 
        /* Header */
-       printf("Running XDP/eBPF prog_num:%d\n", prog_num);
+       printf("Running XDP/eBPF prog_name:%s\n", prog_name);
        printf("%-15s %-7s %-14s %-11s %-9s\n",
               "XDP-cpumap", "CPU:to", "pps", "drop-pps", "extra-info");
 
@@ -423,20 +440,20 @@ static void stats_collect(struct stats_record *rec)
 {
        int fd, i;
 
-       fd = map_fd[1]; /* map: rx_cnt */
+       fd = rx_cnt_map_fd;
        map_collect_percpu(fd, 0, &rec->rx_cnt);
 
-       fd = map_fd[2]; /* map: redirect_err_cnt */
+       fd = redirect_err_cnt_map_fd;
        map_collect_percpu(fd, 1, &rec->redir_err);
 
-       fd = map_fd[3]; /* map: cpumap_enqueue_cnt */
+       fd = cpumap_enqueue_cnt_map_fd;
        for (i = 0; i < MAX_CPUS; i++)
                map_collect_percpu(fd, i, &rec->enq[i]);
 
-       fd = map_fd[4]; /* map: cpumap_kthread_cnt */
+       fd = cpumap_kthread_cnt_map_fd;
        map_collect_percpu(fd, 0, &rec->kthread);
 
-       fd = map_fd[8]; /* map: exception_cnt */
+       fd = exception_cnt_map_fd;
        map_collect_percpu(fd, 0, &rec->exception);
 }
 
@@ -461,7 +478,7 @@ static int create_cpu_entry(__u32 cpu, __u32 queue_size,
        /* Add a CPU entry to cpumap, as this allocate a cpu entry in
         * the kernel for the cpu.
         */
-       ret = bpf_map_update_elem(map_fd[0], &cpu, &queue_size, 0);
+       ret = bpf_map_update_elem(cpu_map_fd, &cpu, &queue_size, 0);
        if (ret) {
                fprintf(stderr, "Create CPU entry failed (err:%d)\n", ret);
                exit(EXIT_FAIL_BPF);
@@ -470,23 +487,22 @@ static int create_cpu_entry(__u32 cpu, __u32 queue_size,
        /* Inform bpf_prog's that a new CPU is available to select
         * from via some control maps.
         */
-       /* map_fd[5] = cpus_available */
-       ret = bpf_map_update_elem(map_fd[5], &avail_idx, &cpu, 0);
+       ret = bpf_map_update_elem(cpus_available_map_fd, &avail_idx, &cpu, 0);
        if (ret) {
                fprintf(stderr, "Add to avail CPUs failed\n");
                exit(EXIT_FAIL_BPF);
        }
 
        /* When not replacing/updating existing entry, bump the count */
-       /* map_fd[6] = cpus_count */
-       ret = bpf_map_lookup_elem(map_fd[6], &key, &curr_cpus_count);
+       ret = bpf_map_lookup_elem(cpus_count_map_fd, &key, &curr_cpus_count);
        if (ret) {
                fprintf(stderr, "Failed reading curr cpus_count\n");
                exit(EXIT_FAIL_BPF);
        }
        if (new) {
                curr_cpus_count++;
-               ret = bpf_map_update_elem(map_fd[6], &key, &curr_cpus_count, 0);
+               ret = bpf_map_update_elem(cpus_count_map_fd, &key,
+                                         &curr_cpus_count, 0);
                if (ret) {
                        fprintf(stderr, "Failed write curr cpus_count\n");
                        exit(EXIT_FAIL_BPF);
@@ -509,8 +525,8 @@ static void mark_cpus_unavailable(void)
        int ret, i;
 
        for (i = 0; i < MAX_CPUS; i++) {
-               /* map_fd[5] = cpus_available */
-               ret = bpf_map_update_elem(map_fd[5], &i, &invalid_cpu, 0);
+               ret = bpf_map_update_elem(cpus_available_map_fd, &i,
+                                         &invalid_cpu, 0);
                if (ret) {
                        fprintf(stderr, "Failed marking CPU unavailable\n");
                        exit(EXIT_FAIL_BPF);
@@ -530,7 +546,7 @@ static void stress_cpumap(void)
        create_cpu_entry(1, 16000, 0, false);
 }
 
-static void stats_poll(int interval, bool use_separators, int prog_num,
+static void stats_poll(int interval, bool use_separators, char *prog_name,
                       bool stress_mode)
 {
        struct stats_record *record, *prev;
@@ -546,7 +562,7 @@ static void stats_poll(int interval, bool use_separators, int prog_num,
        while (1) {
                swap(&prev, &record);
                stats_collect(record);
-               stats_print(record, prev, prog_num);
+               stats_print(record, prev, prog_name);
                sleep(interval);
                if (stress_mode)
                        stress_cpumap();
@@ -556,17 +572,51 @@ static void stats_poll(int interval, bool use_separators, int prog_num,
        free_stats_record(prev);
 }
 
+static int init_map_fds(struct bpf_object *obj)
+{
+       cpu_map_fd = bpf_object__find_map_fd_by_name(obj, "cpu_map");
+       rx_cnt_map_fd = bpf_object__find_map_fd_by_name(obj, "rx_cnt");
+       redirect_err_cnt_map_fd =
+               bpf_object__find_map_fd_by_name(obj, "redirect_err_cnt");
+       cpumap_enqueue_cnt_map_fd =
+               bpf_object__find_map_fd_by_name(obj, "cpumap_enqueue_cnt");
+       cpumap_kthread_cnt_map_fd =
+               bpf_object__find_map_fd_by_name(obj, "cpumap_kthread_cnt");
+       cpus_available_map_fd =
+               bpf_object__find_map_fd_by_name(obj, "cpus_available");
+       cpus_count_map_fd = bpf_object__find_map_fd_by_name(obj, "cpus_count");
+       cpus_iterator_map_fd =
+               bpf_object__find_map_fd_by_name(obj, "cpus_iterator");
+       exception_cnt_map_fd =
+               bpf_object__find_map_fd_by_name(obj, "exception_cnt");
+
+       if (cpu_map_fd < 0 || rx_cnt_map_fd < 0 ||
+           redirect_err_cnt_map_fd < 0 || cpumap_enqueue_cnt_map_fd < 0 ||
+           cpumap_kthread_cnt_map_fd < 0 || cpus_available_map_fd < 0 ||
+           cpus_count_map_fd < 0 || cpus_iterator_map_fd < 0 ||
+           exception_cnt_map_fd < 0)
+               return -ENOENT;
+
+       return 0;
+}
+
 int main(int argc, char **argv)
 {
        struct rlimit r = {10 * 1024 * 1024, RLIM_INFINITY};
+       char *prog_name = "xdp_cpu_map5_lb_hash_ip_pairs";
+       struct bpf_prog_load_attr prog_load_attr = {
+               .prog_type      = BPF_PROG_TYPE_UNSPEC,
+       };
        bool use_separators = true;
        bool stress_mode = false;
+       struct bpf_program *prog;
+       struct bpf_object *obj;
        char filename[256];
        int added_cpus = 0;
        int longindex = 0;
        int interval = 2;
-       int prog_num = 5;
        int add_cpu = -1;
+       int prog_fd;
        __u32 qsize;
        int opt;
 
@@ -579,22 +629,25 @@ int main(int argc, char **argv)
        qsize = 128+64;
 
        snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
+       prog_load_attr.file = filename;
 
        if (setrlimit(RLIMIT_MEMLOCK, &r)) {
                perror("setrlimit(RLIMIT_MEMLOCK)");
                return 1;
        }
 
-       if (load_bpf_file(filename)) {
-               fprintf(stderr, "ERR in load_bpf_file(): %s", bpf_log_buf);
+       if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd))
                return EXIT_FAIL;
-       }
 
-       if (!prog_fd[0]) {
-               fprintf(stderr, "ERR: load_bpf_file: %s\n", strerror(errno));
+       if (prog_fd < 0) {
+               fprintf(stderr, "ERR: bpf_prog_load_xattr: %s\n",
+                       strerror(errno));
+               return EXIT_FAIL;
+       }
+       if (init_map_fds(obj) < 0) {
+               fprintf(stderr, "bpf_object__find_map_fd_by_name failed\n");
                return EXIT_FAIL;
        }
-
        mark_cpus_unavailable();
 
        /* Parse commands line args */
@@ -630,13 +683,7 @@ int main(int argc, char **argv)
                        break;
                case 'p':
                        /* Selecting eBPF prog to load */
-                       prog_num = atoi(optarg);
-                       if (prog_num < 0 || prog_num >= MAX_PROG) {
-                               fprintf(stderr,
-                                       "--prognum too large err(%d):%s\n",
-                                       errno, strerror(errno));
-                               goto error;
-                       }
+                       prog_name = optarg;
                        break;
                case 'c':
                        /* Add multiple CPUs */
@@ -656,21 +703,21 @@ int main(int argc, char **argv)
                case 'h':
                error:
                default:
-                       usage(argv);
+                       usage(argv, obj);
                        return EXIT_FAIL_OPTION;
                }
        }
        /* Required option */
        if (ifindex == -1) {
                fprintf(stderr, "ERR: required option --dev missing\n");
-               usage(argv);
+               usage(argv, obj);
                return EXIT_FAIL_OPTION;
        }
        /* Required option */
        if (add_cpu == -1) {
                fprintf(stderr, "ERR: required option --cpu missing\n");
                fprintf(stderr, " Specify multiple --cpu option to add more\n");
-               usage(argv);
+               usage(argv, obj);
                return EXIT_FAIL_OPTION;
        }
 
@@ -678,11 +725,23 @@ int main(int argc, char **argv)
        signal(SIGINT, int_exit);
        signal(SIGTERM, int_exit);
 
-       if (bpf_set_link_xdp_fd(ifindex, prog_fd[prog_num], xdp_flags) < 0) {
+       prog = bpf_object__find_program_by_title(obj, prog_name);
+       if (!prog) {
+               fprintf(stderr, "bpf_object__find_program_by_title failed\n");
+               return EXIT_FAIL;
+       }
+
+       prog_fd = bpf_program__fd(prog);
+       if (prog_fd < 0) {
+               fprintf(stderr, "bpf_program__fd failed\n");
+               return EXIT_FAIL;
+       }
+
+       if (bpf_set_link_xdp_fd(ifindex, prog_fd, xdp_flags) < 0) {
                fprintf(stderr, "link set xdp fd failed\n");
                return EXIT_FAIL_XDP;
        }
 
-       stats_poll(interval, use_separators, prog_num, stress_mode);
+       stats_poll(interval, use_separators, prog_name, stress_mode);
        return EXIT_OK;
 }
index 4445e76854b59dbd3b66b137f89e4eb24665fc89..60d46eea225b2770ef75d5b61bb0c38361d3a5ce 100644 (file)
 #include <libgen.h>
 #include <sys/resource.h>
 
-#include "bpf_load.h"
 #include "bpf_util.h"
 #include <bpf/bpf.h>
+#include "bpf/libbpf.h"
 
 static int ifindex_in;
 static int ifindex_out;
 static bool ifindex_out_xdp_dummy_attached = true;
 
 static __u32 xdp_flags;
+static int rxcnt_map_fd;
 
 static void int_exit(int sig)
 {
@@ -53,7 +54,7 @@ static void poll_stats(int interval, int ifindex)
                int i;
 
                sleep(interval);
-               assert(bpf_map_lookup_elem(map_fd[1], &key, values) == 0);
+               assert(bpf_map_lookup_elem(rxcnt_map_fd, &key, values) == 0);
                for (i = 0; i < nr_cpus; i++)
                        sum += (values[i] - prev[i]);
                if (sum)
@@ -76,9 +77,16 @@ static void usage(const char *prog)
 int main(int argc, char **argv)
 {
        struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
+       struct bpf_prog_load_attr prog_load_attr = {
+               .prog_type      = BPF_PROG_TYPE_XDP,
+       };
+       struct bpf_program *prog, *dummy_prog;
+       int prog_fd, dummy_prog_fd;
        const char *optstr = "SN";
-       char filename[256];
+       struct bpf_object *obj;
        int ret, opt, key = 0;
+       char filename[256];
+       int tx_port_map_fd;
 
        while ((opt = getopt(argc, argv, optstr)) != -1) {
                switch (opt) {
@@ -109,24 +117,40 @@ int main(int argc, char **argv)
        printf("input: %d output: %d\n", ifindex_in, ifindex_out);
 
        snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
+       prog_load_attr.file = filename;
+
+       if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd))
+               return 1;
 
-       if (load_bpf_file(filename)) {
-               printf("%s", bpf_log_buf);
+       prog = bpf_program__next(NULL, obj);
+       dummy_prog = bpf_program__next(prog, obj);
+       if (!prog || !dummy_prog) {
+               printf("finding a prog in obj file failed\n");
+               return 1;
+       }
+       /* bpf_prog_load_xattr gives us the pointer to first prog's fd,
+        * so we're missing only the fd for dummy prog
+        */
+       dummy_prog_fd = bpf_program__fd(dummy_prog);
+       if (prog_fd < 0 || dummy_prog_fd < 0) {
+               printf("bpf_prog_load_xattr: %s\n", strerror(errno));
                return 1;
        }
 
-       if (!prog_fd[0]) {
-               printf("load_bpf_file: %s\n", strerror(errno));
+       tx_port_map_fd = bpf_object__find_map_fd_by_name(obj, "tx_port");
+       rxcnt_map_fd = bpf_object__find_map_fd_by_name(obj, "rxcnt");
+       if (tx_port_map_fd < 0 || rxcnt_map_fd < 0) {
+               printf("bpf_object__find_map_fd_by_name failed\n");
                return 1;
        }
 
-       if (bpf_set_link_xdp_fd(ifindex_in, prog_fd[0], xdp_flags) < 0) {
+       if (bpf_set_link_xdp_fd(ifindex_in, prog_fd, xdp_flags) < 0) {
                printf("ERROR: link set xdp fd failed on %d\n", ifindex_in);
                return 1;
        }
 
        /* Loading dummy XDP prog on out-device */
-       if (bpf_set_link_xdp_fd(ifindex_out, prog_fd[1],
+       if (bpf_set_link_xdp_fd(ifindex_out, dummy_prog_fd,
                            (xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST)) < 0) {
                printf("WARN: link set xdp fd failed on %d\n", ifindex_out);
                ifindex_out_xdp_dummy_attached = false;
@@ -135,11 +159,8 @@ int main(int argc, char **argv)
        signal(SIGINT, int_exit);
        signal(SIGTERM, int_exit);
 
-       printf("map[0] (vports) = %i, map[1] (map) = %i, map[2] (count) = %i\n",
-               map_fd[0], map_fd[1], map_fd[2]);
-
        /* populate virtual to physical port map */
-       ret = bpf_map_update_elem(map_fd[0], &key, &ifindex_out, 0);
+       ret = bpf_map_update_elem(tx_port_map_fd, &key, &ifindex_out, 0);
        if (ret) {
                perror("bpf_update_elem");
                goto out;
index 81a69e36cb788cbfa99b1a8a71b9ede1d1d0cca9..93404820df689516aba92e6357d69a99ee03e41c 100644 (file)
 #include <libgen.h>
 #include <sys/resource.h>
 
-#include "bpf_load.h"
 #include "bpf_util.h"
 #include <bpf/bpf.h>
+#include "bpf/libbpf.h"
 
 static int ifindex_in;
 static int ifindex_out;
 static bool ifindex_out_xdp_dummy_attached = true;
 
 static __u32 xdp_flags;
+static int rxcnt_map_fd;
 
 static void int_exit(int sig)
 {
@@ -53,7 +54,7 @@ static void poll_stats(int interval, int ifindex)
                int i;
 
                sleep(interval);
-               assert(bpf_map_lookup_elem(map_fd[1], &key, values) == 0);
+               assert(bpf_map_lookup_elem(rxcnt_map_fd, &key, values) == 0);
                for (i = 0; i < nr_cpus; i++)
                        sum += (values[i] - prev[i]);
                if (sum)
@@ -77,9 +78,16 @@ static void usage(const char *prog)
 int main(int argc, char **argv)
 {
        struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
+       struct bpf_prog_load_attr prog_load_attr = {
+               .prog_type      = BPF_PROG_TYPE_XDP,
+       };
+       struct bpf_program *prog, *dummy_prog;
+       int prog_fd, tx_port_map_fd, opt;
        const char *optstr = "SN";
+       struct bpf_object *obj;
        char filename[256];
-       int ret, opt, key = 0;
+       int dummy_prog_fd;
+       int ret, key = 0;
 
        while ((opt = getopt(argc, argv, optstr)) != -1) {
                switch (opt) {
@@ -110,24 +118,40 @@ int main(int argc, char **argv)
        printf("input: %d output: %d\n", ifindex_in, ifindex_out);
 
        snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
+       prog_load_attr.file = filename;
 
-       if (load_bpf_file(filename)) {
-               printf("%s", bpf_log_buf);
+       if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd))
+               return 1;
+
+       prog = bpf_program__next(NULL, obj);
+       dummy_prog = bpf_program__next(prog, obj);
+       if (!prog || !dummy_prog) {
+               printf("finding a prog in obj file failed\n");
+               return 1;
+       }
+       /* bpf_prog_load_xattr gives us the pointer to first prog's fd,
+        * so we're missing only the fd for dummy prog
+        */
+       dummy_prog_fd = bpf_program__fd(dummy_prog);
+       if (prog_fd < 0 || dummy_prog_fd < 0) {
+               printf("bpf_prog_load_xattr: %s\n", strerror(errno));
                return 1;
        }
 
-       if (!prog_fd[0]) {
-               printf("load_bpf_file: %s\n", strerror(errno));
+       tx_port_map_fd = bpf_object__find_map_fd_by_name(obj, "tx_port");
+       rxcnt_map_fd = bpf_object__find_map_fd_by_name(obj, "rxcnt");
+       if (tx_port_map_fd < 0 || rxcnt_map_fd < 0) {
+               printf("bpf_object__find_map_fd_by_name failed\n");
                return 1;
        }
 
-       if (bpf_set_link_xdp_fd(ifindex_in, prog_fd[0], xdp_flags) < 0) {
+       if (bpf_set_link_xdp_fd(ifindex_in, prog_fd, xdp_flags) < 0) {
                printf("ERROR: link set xdp fd failed on %d\n", ifindex_in);
                return 1;
        }
 
        /* Loading dummy XDP prog on out-device */
-       if (bpf_set_link_xdp_fd(ifindex_out, prog_fd[1],
+       if (bpf_set_link_xdp_fd(ifindex_out, dummy_prog_fd,
                            (xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST)) < 0) {
                printf("WARN: link set xdp fd failed on %d\n", ifindex_out);
                ifindex_out_xdp_dummy_attached = false;
@@ -137,7 +161,7 @@ int main(int argc, char **argv)
        signal(SIGTERM, int_exit);
 
        /* bpf redirect port */
-       ret = bpf_map_update_elem(map_fd[0], &key, &ifindex_out, 0);
+       ret = bpf_map_update_elem(tx_port_map_fd, &key, &ifindex_out, 0);
        if (ret) {
                perror("bpf_update_elem");
                goto out;
index b2b4dfa776c8c1a40fa04bac053dc36a49c9d550..cea2306f5ab75e34fd525b113daa3f699dd2c4d5 100644 (file)
@@ -15,7 +15,6 @@
 #include <string.h>
 #include <sys/socket.h>
 #include <unistd.h>
-#include "bpf_load.h"
 #include <bpf/bpf.h>
 #include <arpa/inet.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
 #include <sys/syscall.h>
 #include "bpf_util.h"
+#include "bpf/libbpf.h"
 
 int sock, sock_arp, flags = 0;
 static int total_ifindex;
 int *ifindex_list;
 char buf[8192];
+static int lpm_map_fd;
+static int rxcnt_map_fd;
+static int arp_table_map_fd;
+static int exact_match_map_fd;
+static int tx_port_map_fd;
 
 static int get_route_table(int rtm_family);
 static void int_exit(int sig)
@@ -186,7 +191,8 @@ static void read_route(struct nlmsghdr *nh, int nll)
                                bpf_set_link_xdp_fd(ifindex_list[i], -1, flags);
                        exit(0);
                }
-               assert(bpf_map_update_elem(map_fd[4], &route.iface, &route.iface, 0) == 0);
+               assert(bpf_map_update_elem(tx_port_map_fd,
+                                          &route.iface, &route.iface, 0) == 0);
                if (rtm_family == AF_INET) {
                        struct trie_value {
                                __u8 prefix[4];
@@ -207,11 +213,16 @@ static void read_route(struct nlmsghdr *nh, int nll)
                        direct_entry.arp.dst = 0;
                        if (route.dst_len == 32) {
                                if (nh->nlmsg_type == RTM_DELROUTE) {
-                                       assert(bpf_map_delete_elem(map_fd[3], &route.dst) == 0);
+                                       assert(bpf_map_delete_elem(exact_match_map_fd,
+                                                                  &route.dst) == 0);
                                } else {
-                                       if (bpf_map_lookup_elem(map_fd[2], &route.dst, &direct_entry.arp.mac) == 0)
+                                       if (bpf_map_lookup_elem(arp_table_map_fd,
+                                                               &route.dst,
+                                                               &direct_entry.arp.mac) == 0)
                                                direct_entry.arp.dst = route.dst;
-                                       assert(bpf_map_update_elem(map_fd[3], &route.dst, &direct_entry, 0) == 0);
+                                       assert(bpf_map_update_elem(exact_match_map_fd,
+                                                                  &route.dst,
+                                                                  &direct_entry, 0) == 0);
                                }
                        }
                        for (i = 0; i < 4; i++)
@@ -225,7 +236,7 @@ static void read_route(struct nlmsghdr *nh, int nll)
                               route.gw, route.dst_len,
                               route.metric,
                               route.iface_name);
-                       if (bpf_map_lookup_elem(map_fd[0], prefix_key,
+                       if (bpf_map_lookup_elem(lpm_map_fd, prefix_key,
                                                prefix_value) < 0) {
                                for (i = 0; i < 4; i++)
                                        prefix_value->prefix[i] = prefix_key->data[i];
@@ -234,7 +245,7 @@ static void read_route(struct nlmsghdr *nh, int nll)
                                prefix_value->gw = route.gw;
                                prefix_value->metric = route.metric;
 
-                               assert(bpf_map_update_elem(map_fd[0],
+                               assert(bpf_map_update_elem(lpm_map_fd,
                                                           prefix_key,
                                                           prefix_value, 0
                                                           ) == 0);
@@ -247,7 +258,7 @@ static void read_route(struct nlmsghdr *nh, int nll)
                                               prefix_key->data[2],
                                               prefix_key->data[3],
                                               prefix_key->prefixlen);
-                                       assert(bpf_map_delete_elem(map_fd[0],
+                                       assert(bpf_map_delete_elem(lpm_map_fd,
                                                                   prefix_key
                                                                   ) == 0);
                                        /* Rereading the route table to check if
@@ -275,8 +286,7 @@ static void read_route(struct nlmsghdr *nh, int nll)
                                        prefix_value->ifindex = route.iface;
                                        prefix_value->gw = route.gw;
                                        prefix_value->metric = route.metric;
-                                       assert(bpf_map_update_elem(
-                                                                  map_fd[0],
+                                       assert(bpf_map_update_elem(lpm_map_fd,
                                                                   prefix_key,
                                                                   prefix_value,
                                                                   0) == 0);
@@ -401,7 +411,8 @@ static void read_arp(struct nlmsghdr *nh, int nll)
                arp_entry.mac = atol(mac);
                printf("%x\t\t%llx\n", arp_entry.dst, arp_entry.mac);
                if (ndm_family == AF_INET) {
-                       if (bpf_map_lookup_elem(map_fd[3], &arp_entry.dst,
+                       if (bpf_map_lookup_elem(exact_match_map_fd,
+                                               &arp_entry.dst,
                                                &direct_entry) == 0) {
                                if (nh->nlmsg_type == RTM_DELNEIGH) {
                                        direct_entry.arp.dst = 0;
@@ -410,16 +421,17 @@ static void read_arp(struct nlmsghdr *nh, int nll)
                                        direct_entry.arp.dst = arp_entry.dst;
                                        direct_entry.arp.mac = arp_entry.mac;
                                }
-                               assert(bpf_map_update_elem(map_fd[3],
+                               assert(bpf_map_update_elem(exact_match_map_fd,
                                                           &arp_entry.dst,
                                                           &direct_entry, 0
                                                           ) == 0);
                                memset(&direct_entry, 0, sizeof(direct_entry));
                        }
                        if (nh->nlmsg_type == RTM_DELNEIGH) {
-                               assert(bpf_map_delete_elem(map_fd[2], &arp_entry.dst) == 0);
+                               assert(bpf_map_delete_elem(arp_table_map_fd,
+                                                          &arp_entry.dst) == 0);
                        } else if (nh->nlmsg_type == RTM_NEWNEIGH) {
-                               assert(bpf_map_update_elem(map_fd[2],
+                               assert(bpf_map_update_elem(arp_table_map_fd,
                                                           &arp_entry.dst,
                                                           &arp_entry.mac, 0
                                                           ) == 0);
@@ -553,7 +565,8 @@ static int monitor_route(void)
                for (key = 0; key < nr_keys; key++) {
                        __u64 sum = 0;
 
-                       assert(bpf_map_lookup_elem(map_fd[1], &key, values) == 0);
+                       assert(bpf_map_lookup_elem(rxcnt_map_fd,
+                                                  &key, values) == 0);
                        for (i = 0; i < nr_cpus; i++)
                                sum += (values[i] - prev[key][i]);
                        if (sum)
@@ -596,11 +609,18 @@ cleanup:
 
 int main(int ac, char **argv)
 {
+       struct bpf_prog_load_attr prog_load_attr = {
+               .prog_type      = BPF_PROG_TYPE_XDP,
+       };
+       struct bpf_object *obj;
        char filename[256];
        char **ifname_list;
+       int prog_fd;
        int i = 1;
 
        snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
+       prog_load_attr.file = filename;
+
        if (ac < 2) {
                printf("usage: %s [-S] Interface name list\n", argv[0]);
                return 1;
@@ -614,15 +634,28 @@ int main(int ac, char **argv)
                total_ifindex = ac - 1;
                ifname_list = (argv + 1);
        }
-       if (load_bpf_file(filename)) {
-               printf("%s", bpf_log_buf);
+
+       if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd))
                return 1;
-       }
+
        printf("\n**************loading bpf file*********************\n\n\n");
-       if (!prog_fd[0]) {
-               printf("load_bpf_file: %s\n", strerror(errno));
+       if (!prog_fd) {
+               printf("bpf_prog_load_xattr: %s\n", strerror(errno));
                return 1;
        }
+
+       lpm_map_fd = bpf_object__find_map_fd_by_name(obj, "lpm_map");
+       rxcnt_map_fd = bpf_object__find_map_fd_by_name(obj, "rxcnt");
+       arp_table_map_fd = bpf_object__find_map_fd_by_name(obj, "arp_table");
+       exact_match_map_fd = bpf_object__find_map_fd_by_name(obj,
+                                                            "exact_match");
+       tx_port_map_fd = bpf_object__find_map_fd_by_name(obj, "tx_port");
+       if (lpm_map_fd < 0 || rxcnt_map_fd < 0 || arp_table_map_fd < 0 ||
+           exact_match_map_fd < 0 || tx_port_map_fd < 0) {
+               printf("bpf_object__find_map_fd_by_name failed\n");
+               return 1;
+       }
+
        ifindex_list = (int *)malloc(total_ifindex * sizeof(int *));
        for (i = 0; i < total_ifindex; i++) {
                ifindex_list[i] = if_nametoindex(ifname_list[i]);
@@ -633,7 +666,7 @@ int main(int ac, char **argv)
                }
        }
        for (i = 0; i < total_ifindex; i++) {
-               if (bpf_set_link_xdp_fd(ifindex_list[i], prog_fd[0], flags) < 0) {
+               if (bpf_set_link_xdp_fd(ifindex_list[i], prog_fd, flags) < 0) {
                        printf("link set xdp fd failed\n");
                        int recovery_index = i;
 
index a4ccc33adac016a11c8f37c6637b27f6cab1664d..5093d8220da538d0079c7e440e2470596d1eca58 100644 (file)
@@ -17,7 +17,7 @@
 #include <netinet/ether.h>
 #include <unistd.h>
 #include <time.h>
-#include "bpf_load.h"
+#include "bpf/libbpf.h"
 #include <bpf/bpf.h>
 #include "bpf_util.h"
 #include "xdp_tx_iptunnel_common.h"
@@ -26,6 +26,7 @@
 
 static int ifindex = -1;
 static __u32 xdp_flags = 0;
+static int rxcnt_map_fd;
 
 static void int_exit(int sig)
 {
@@ -53,7 +54,8 @@ static void poll_stats(unsigned int kill_after_s)
                for (proto = 0; proto < nr_protos; proto++) {
                        __u64 sum = 0;
 
-                       assert(bpf_map_lookup_elem(map_fd[0], &proto, values) == 0);
+                       assert(bpf_map_lookup_elem(rxcnt_map_fd, &proto,
+                                                  values) == 0);
                        for (i = 0; i < nr_cpus; i++)
                                sum += (values[i] - prev[proto][i]);
 
@@ -138,15 +140,19 @@ static int parse_ports(const char *port_str, int *min_port, int *max_port)
 
 int main(int argc, char **argv)
 {
+       struct bpf_prog_load_attr prog_load_attr = {
+               .prog_type      = BPF_PROG_TYPE_XDP,
+       };
+       struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
+       int min_port = 0, max_port = 0, vip2tnl_map_fd;
+       const char *optstr = "i:a:p:s:d:m:T:P:SNh";
        unsigned char opt_flags[256] = {};
        unsigned int kill_after_s = 0;
-       const char *optstr = "i:a:p:s:d:m:T:P:SNh";
-       int min_port = 0, max_port = 0;
        struct iptnl_info tnl = {};
-       struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
+       struct bpf_object *obj;
        struct vip vip = {};
        char filename[256];
-       int opt;
+       int opt, prog_fd;
        int i;
 
        tnl.family = AF_UNSPEC;
@@ -232,29 +238,36 @@ int main(int argc, char **argv)
        }
 
        snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
+       prog_load_attr.file = filename;
 
-       if (load_bpf_file(filename)) {
-               printf("%s", bpf_log_buf);
+       if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd))
                return 1;
-       }
 
-       if (!prog_fd[0]) {
+       if (!prog_fd) {
                printf("load_bpf_file: %s\n", strerror(errno));
                return 1;
        }
 
+       rxcnt_map_fd = bpf_object__find_map_fd_by_name(obj, "rxcnt");
+       vip2tnl_map_fd = bpf_object__find_map_fd_by_name(obj, "vip2tnl");
+       if (vip2tnl_map_fd < 0 || rxcnt_map_fd < 0) {
+               printf("bpf_object__find_map_fd_by_name failed\n");
+               return 1;
+       }
+
        signal(SIGINT, int_exit);
        signal(SIGTERM, int_exit);
 
        while (min_port <= max_port) {
                vip.dport = htons(min_port++);
-               if (bpf_map_update_elem(map_fd[1], &vip, &tnl, BPF_NOEXIST)) {
+               if (bpf_map_update_elem(vip2tnl_map_fd, &vip, &tnl,
+                                       BPF_NOEXIST)) {
                        perror("bpf_map_update_elem(&vip2tnl)");
                        return 1;
                }
        }
 
-       if (bpf_set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
+       if (bpf_set_link_xdp_fd(ifindex, prog_fd, xdp_flags) < 0) {
                printf("link set xdp fd failed\n");
                return 1;
        }