diff options
author | Maciej Fijalkowski <maciejromanfijalkowski@gmail.com> | 2019-02-01 16:42:25 -0500 |
---|---|---|
committer | Daniel Borkmann <daniel@iogearbox.net> | 2019-02-01 17:37:51 -0500 |
commit | bbaf6029c49ccf2dc93d9564af58a20d125947a1 (patch) | |
tree | d01db083bd2806709339c7a78bf82daf0fde26c8 /samples | |
parent | 7313798b144c5b945dc47502a233cabb7022cb70 (diff) |
samples/bpf: Convert XDP samples to libbpf usage
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>
Diffstat (limited to 'samples')
-rw-r--r-- | samples/bpf/Makefile | 8 | ||||
-rw-r--r-- | samples/bpf/xdp_redirect_cpu_user.c | 145 | ||||
-rw-r--r-- | samples/bpf/xdp_redirect_map_user.c | 47 | ||||
-rw-r--r-- | samples/bpf/xdp_redirect_user.c | 44 | ||||
-rw-r--r-- | samples/bpf/xdp_router_ipv4_user.c | 75 | ||||
-rw-r--r-- | samples/bpf/xdp_tx_iptunnel_user.c | 37 |
6 files changed, 253 insertions, 103 deletions
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index db1a91dfa702..a0ef7eddd0b3 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile | |||
@@ -87,18 +87,18 @@ test_cgrp2_sock2-objs := bpf_load.o test_cgrp2_sock2.o | |||
87 | xdp1-objs := xdp1_user.o | 87 | xdp1-objs := xdp1_user.o |
88 | # reuse xdp1 source intentionally | 88 | # reuse xdp1 source intentionally |
89 | xdp2-objs := xdp1_user.o | 89 | xdp2-objs := xdp1_user.o |
90 | xdp_router_ipv4-objs := bpf_load.o xdp_router_ipv4_user.o | 90 | xdp_router_ipv4-objs := xdp_router_ipv4_user.o |
91 | test_current_task_under_cgroup-objs := bpf_load.o $(CGROUP_HELPERS) \ | 91 | test_current_task_under_cgroup-objs := bpf_load.o $(CGROUP_HELPERS) \ |
92 | test_current_task_under_cgroup_user.o | 92 | test_current_task_under_cgroup_user.o |
93 | trace_event-objs := bpf_load.o trace_event_user.o $(TRACE_HELPERS) | 93 | trace_event-objs := bpf_load.o trace_event_user.o $(TRACE_HELPERS) |
94 | sampleip-objs := bpf_load.o sampleip_user.o $(TRACE_HELPERS) | 94 | sampleip-objs := bpf_load.o sampleip_user.o $(TRACE_HELPERS) |
95 | tc_l2_redirect-objs := bpf_load.o tc_l2_redirect_user.o | 95 | tc_l2_redirect-objs := bpf_load.o tc_l2_redirect_user.o |
96 | lwt_len_hist-objs := bpf_load.o lwt_len_hist_user.o | 96 | lwt_len_hist-objs := bpf_load.o lwt_len_hist_user.o |
97 | xdp_tx_iptunnel-objs := bpf_load.o xdp_tx_iptunnel_user.o | 97 | xdp_tx_iptunnel-objs := xdp_tx_iptunnel_user.o |
98 | test_map_in_map-objs := bpf_load.o test_map_in_map_user.o | 98 | test_map_in_map-objs := bpf_load.o test_map_in_map_user.o |
99 | per_socket_stats_example-objs := cookie_uid_helper_example.o | 99 | per_socket_stats_example-objs := cookie_uid_helper_example.o |
100 | xdp_redirect-objs := bpf_load.o xdp_redirect_user.o | 100 | xdp_redirect-objs := xdp_redirect_user.o |
101 | xdp_redirect_map-objs := bpf_load.o xdp_redirect_map_user.o | 101 | xdp_redirect_map-objs := xdp_redirect_map_user.o |
102 | xdp_redirect_cpu-objs := bpf_load.o xdp_redirect_cpu_user.o | 102 | xdp_redirect_cpu-objs := bpf_load.o xdp_redirect_cpu_user.o |
103 | xdp_monitor-objs := bpf_load.o xdp_monitor_user.o | 103 | xdp_monitor-objs := bpf_load.o xdp_monitor_user.o |
104 | xdp_rxq_info-objs := xdp_rxq_info_user.o | 104 | xdp_rxq_info-objs := xdp_rxq_info_user.o |
diff --git a/samples/bpf/xdp_redirect_cpu_user.c b/samples/bpf/xdp_redirect_cpu_user.c index f141e752ca0a..8645ddc2da0e 100644 --- a/samples/bpf/xdp_redirect_cpu_user.c +++ b/samples/bpf/xdp_redirect_cpu_user.c | |||
@@ -24,12 +24,8 @@ static const char *__doc__ = | |||
24 | /* How many xdp_progs are defined in _kern.c */ | 24 | /* How many xdp_progs are defined in _kern.c */ |
25 | #define MAX_PROG 6 | 25 | #define MAX_PROG 6 |
26 | 26 | ||
27 | /* Wanted to get rid of bpf_load.h and fake-"libbpf.h" (and instead | ||
28 | * use bpf/libbpf.h), but cannot as (currently) needed for XDP | ||
29 | * attaching to a device via bpf_set_link_xdp_fd() | ||
30 | */ | ||
31 | #include <bpf/bpf.h> | 27 | #include <bpf/bpf.h> |
32 | #include "bpf_load.h" | 28 | #include "bpf/libbpf.h" |
33 | 29 | ||
34 | #include "bpf_util.h" | 30 | #include "bpf_util.h" |
35 | 31 | ||
@@ -38,6 +34,15 @@ static char ifname_buf[IF_NAMESIZE]; | |||
38 | static char *ifname; | 34 | static char *ifname; |
39 | 35 | ||
40 | static __u32 xdp_flags; | 36 | static __u32 xdp_flags; |
37 | static int cpu_map_fd; | ||
38 | static int rx_cnt_map_fd; | ||
39 | static int redirect_err_cnt_map_fd; | ||
40 | static int cpumap_enqueue_cnt_map_fd; | ||
41 | static int cpumap_kthread_cnt_map_fd; | ||
42 | static int cpus_available_map_fd; | ||
43 | static int cpus_count_map_fd; | ||
44 | static int cpus_iterator_map_fd; | ||
45 | static int exception_cnt_map_fd; | ||
41 | 46 | ||
42 | /* Exit return codes */ | 47 | /* Exit return codes */ |
43 | #define EXIT_OK 0 | 48 | #define EXIT_OK 0 |
@@ -52,7 +57,7 @@ static const struct option long_options[] = { | |||
52 | {"dev", required_argument, NULL, 'd' }, | 57 | {"dev", required_argument, NULL, 'd' }, |
53 | {"skb-mode", no_argument, NULL, 'S' }, | 58 | {"skb-mode", no_argument, NULL, 'S' }, |
54 | {"sec", required_argument, NULL, 's' }, | 59 | {"sec", required_argument, NULL, 's' }, |
55 | {"prognum", required_argument, NULL, 'p' }, | 60 | {"progname", required_argument, NULL, 'p' }, |
56 | {"qsize", required_argument, NULL, 'q' }, | 61 | {"qsize", required_argument, NULL, 'q' }, |
57 | {"cpu", required_argument, NULL, 'c' }, | 62 | {"cpu", required_argument, NULL, 'c' }, |
58 | {"stress-mode", no_argument, NULL, 'x' }, | 63 | {"stress-mode", no_argument, NULL, 'x' }, |
@@ -70,7 +75,17 @@ static void int_exit(int sig) | |||
70 | exit(EXIT_OK); | 75 | exit(EXIT_OK); |
71 | } | 76 | } |
72 | 77 | ||
73 | static void usage(char *argv[]) | 78 | static void print_avail_progs(struct bpf_object *obj) |
79 | { | ||
80 | struct bpf_program *pos; | ||
81 | |||
82 | bpf_object__for_each_program(pos, obj) { | ||
83 | if (bpf_program__is_xdp(pos)) | ||
84 | printf(" %s\n", bpf_program__title(pos, false)); | ||
85 | } | ||
86 | } | ||
87 | |||
88 | static void usage(char *argv[], struct bpf_object *obj) | ||
74 | { | 89 | { |
75 | int i; | 90 | int i; |
76 | 91 | ||
@@ -88,6 +103,8 @@ static void usage(char *argv[]) | |||
88 | long_options[i].val); | 103 | long_options[i].val); |
89 | printf("\n"); | 104 | printf("\n"); |
90 | } | 105 | } |
106 | printf("\n Programs to be used for --progname:\n"); | ||
107 | print_avail_progs(obj); | ||
91 | printf("\n"); | 108 | printf("\n"); |
92 | } | 109 | } |
93 | 110 | ||
@@ -262,7 +279,7 @@ static __u64 calc_errs_pps(struct datarec *r, | |||
262 | 279 | ||
263 | static void stats_print(struct stats_record *stats_rec, | 280 | static void stats_print(struct stats_record *stats_rec, |
264 | struct stats_record *stats_prev, | 281 | struct stats_record *stats_prev, |
265 | int prog_num) | 282 | char *prog_name) |
266 | { | 283 | { |
267 | unsigned int nr_cpus = bpf_num_possible_cpus(); | 284 | unsigned int nr_cpus = bpf_num_possible_cpus(); |
268 | double pps = 0, drop = 0, err = 0; | 285 | double pps = 0, drop = 0, err = 0; |
@@ -272,7 +289,7 @@ static void stats_print(struct stats_record *stats_rec, | |||
272 | int i; | 289 | int i; |
273 | 290 | ||
274 | /* Header */ | 291 | /* Header */ |
275 | printf("Running XDP/eBPF prog_num:%d\n", prog_num); | 292 | printf("Running XDP/eBPF prog_name:%s\n", prog_name); |
276 | printf("%-15s %-7s %-14s %-11s %-9s\n", | 293 | printf("%-15s %-7s %-14s %-11s %-9s\n", |
277 | "XDP-cpumap", "CPU:to", "pps", "drop-pps", "extra-info"); | 294 | "XDP-cpumap", "CPU:to", "pps", "drop-pps", "extra-info"); |
278 | 295 | ||
@@ -423,20 +440,20 @@ static void stats_collect(struct stats_record *rec) | |||
423 | { | 440 | { |
424 | int fd, i; | 441 | int fd, i; |
425 | 442 | ||
426 | fd = map_fd[1]; /* map: rx_cnt */ | 443 | fd = rx_cnt_map_fd; |
427 | map_collect_percpu(fd, 0, &rec->rx_cnt); | 444 | map_collect_percpu(fd, 0, &rec->rx_cnt); |
428 | 445 | ||
429 | fd = map_fd[2]; /* map: redirect_err_cnt */ | 446 | fd = redirect_err_cnt_map_fd; |
430 | map_collect_percpu(fd, 1, &rec->redir_err); | 447 | map_collect_percpu(fd, 1, &rec->redir_err); |
431 | 448 | ||
432 | fd = map_fd[3]; /* map: cpumap_enqueue_cnt */ | 449 | fd = cpumap_enqueue_cnt_map_fd; |
433 | for (i = 0; i < MAX_CPUS; i++) | 450 | for (i = 0; i < MAX_CPUS; i++) |
434 | map_collect_percpu(fd, i, &rec->enq[i]); | 451 | map_collect_percpu(fd, i, &rec->enq[i]); |
435 | 452 | ||
436 | fd = map_fd[4]; /* map: cpumap_kthread_cnt */ | 453 | fd = cpumap_kthread_cnt_map_fd; |
437 | map_collect_percpu(fd, 0, &rec->kthread); | 454 | map_collect_percpu(fd, 0, &rec->kthread); |
438 | 455 | ||
439 | fd = map_fd[8]; /* map: exception_cnt */ | 456 | fd = exception_cnt_map_fd; |
440 | map_collect_percpu(fd, 0, &rec->exception); | 457 | map_collect_percpu(fd, 0, &rec->exception); |
441 | } | 458 | } |
442 | 459 | ||
@@ -461,7 +478,7 @@ static int create_cpu_entry(__u32 cpu, __u32 queue_size, | |||
461 | /* Add a CPU entry to cpumap, as this allocate a cpu entry in | 478 | /* Add a CPU entry to cpumap, as this allocate a cpu entry in |
462 | * the kernel for the cpu. | 479 | * the kernel for the cpu. |
463 | */ | 480 | */ |
464 | ret = bpf_map_update_elem(map_fd[0], &cpu, &queue_size, 0); | 481 | ret = bpf_map_update_elem(cpu_map_fd, &cpu, &queue_size, 0); |
465 | if (ret) { | 482 | if (ret) { |
466 | fprintf(stderr, "Create CPU entry failed (err:%d)\n", ret); | 483 | fprintf(stderr, "Create CPU entry failed (err:%d)\n", ret); |
467 | exit(EXIT_FAIL_BPF); | 484 | exit(EXIT_FAIL_BPF); |
@@ -470,23 +487,22 @@ static int create_cpu_entry(__u32 cpu, __u32 queue_size, | |||
470 | /* Inform bpf_prog's that a new CPU is available to select | 487 | /* Inform bpf_prog's that a new CPU is available to select |
471 | * from via some control maps. | 488 | * from via some control maps. |
472 | */ | 489 | */ |
473 | /* map_fd[5] = cpus_available */ | 490 | ret = bpf_map_update_elem(cpus_available_map_fd, &avail_idx, &cpu, 0); |
474 | ret = bpf_map_update_elem(map_fd[5], &avail_idx, &cpu, 0); | ||
475 | if (ret) { | 491 | if (ret) { |
476 | fprintf(stderr, "Add to avail CPUs failed\n"); | 492 | fprintf(stderr, "Add to avail CPUs failed\n"); |
477 | exit(EXIT_FAIL_BPF); | 493 | exit(EXIT_FAIL_BPF); |
478 | } | 494 | } |
479 | 495 | ||
480 | /* When not replacing/updating existing entry, bump the count */ | 496 | /* When not replacing/updating existing entry, bump the count */ |
481 | /* map_fd[6] = cpus_count */ | 497 | ret = bpf_map_lookup_elem(cpus_count_map_fd, &key, &curr_cpus_count); |
482 | ret = bpf_map_lookup_elem(map_fd[6], &key, &curr_cpus_count); | ||
483 | if (ret) { | 498 | if (ret) { |
484 | fprintf(stderr, "Failed reading curr cpus_count\n"); | 499 | fprintf(stderr, "Failed reading curr cpus_count\n"); |
485 | exit(EXIT_FAIL_BPF); | 500 | exit(EXIT_FAIL_BPF); |
486 | } | 501 | } |
487 | if (new) { | 502 | if (new) { |
488 | curr_cpus_count++; | 503 | curr_cpus_count++; |
489 | ret = bpf_map_update_elem(map_fd[6], &key, &curr_cpus_count, 0); | 504 | ret = bpf_map_update_elem(cpus_count_map_fd, &key, |
505 | &curr_cpus_count, 0); | ||
490 | if (ret) { | 506 | if (ret) { |
491 | fprintf(stderr, "Failed write curr cpus_count\n"); | 507 | fprintf(stderr, "Failed write curr cpus_count\n"); |
492 | exit(EXIT_FAIL_BPF); | 508 | exit(EXIT_FAIL_BPF); |
@@ -509,8 +525,8 @@ static void mark_cpus_unavailable(void) | |||
509 | int ret, i; | 525 | int ret, i; |
510 | 526 | ||
511 | for (i = 0; i < MAX_CPUS; i++) { | 527 | for (i = 0; i < MAX_CPUS; i++) { |
512 | /* map_fd[5] = cpus_available */ | 528 | ret = bpf_map_update_elem(cpus_available_map_fd, &i, |
513 | ret = bpf_map_update_elem(map_fd[5], &i, &invalid_cpu, 0); | 529 | &invalid_cpu, 0); |
514 | if (ret) { | 530 | if (ret) { |
515 | fprintf(stderr, "Failed marking CPU unavailable\n"); | 531 | fprintf(stderr, "Failed marking CPU unavailable\n"); |
516 | exit(EXIT_FAIL_BPF); | 532 | exit(EXIT_FAIL_BPF); |
@@ -530,7 +546,7 @@ static void stress_cpumap(void) | |||
530 | create_cpu_entry(1, 16000, 0, false); | 546 | create_cpu_entry(1, 16000, 0, false); |
531 | } | 547 | } |
532 | 548 | ||
533 | static void stats_poll(int interval, bool use_separators, int prog_num, | 549 | static void stats_poll(int interval, bool use_separators, char *prog_name, |
534 | bool stress_mode) | 550 | bool stress_mode) |
535 | { | 551 | { |
536 | struct stats_record *record, *prev; | 552 | struct stats_record *record, *prev; |
@@ -546,7 +562,7 @@ static void stats_poll(int interval, bool use_separators, int prog_num, | |||
546 | while (1) { | 562 | while (1) { |
547 | swap(&prev, &record); | 563 | swap(&prev, &record); |
548 | stats_collect(record); | 564 | stats_collect(record); |
549 | stats_print(record, prev, prog_num); | 565 | stats_print(record, prev, prog_name); |
550 | sleep(interval); | 566 | sleep(interval); |
551 | if (stress_mode) | 567 | if (stress_mode) |
552 | stress_cpumap(); | 568 | stress_cpumap(); |
@@ -556,17 +572,51 @@ static void stats_poll(int interval, bool use_separators, int prog_num, | |||
556 | free_stats_record(prev); | 572 | free_stats_record(prev); |
557 | } | 573 | } |
558 | 574 | ||
575 | static int init_map_fds(struct bpf_object *obj) | ||
576 | { | ||
577 | cpu_map_fd = bpf_object__find_map_fd_by_name(obj, "cpu_map"); | ||
578 | rx_cnt_map_fd = bpf_object__find_map_fd_by_name(obj, "rx_cnt"); | ||
579 | redirect_err_cnt_map_fd = | ||
580 | bpf_object__find_map_fd_by_name(obj, "redirect_err_cnt"); | ||
581 | cpumap_enqueue_cnt_map_fd = | ||
582 | bpf_object__find_map_fd_by_name(obj, "cpumap_enqueue_cnt"); | ||
583 | cpumap_kthread_cnt_map_fd = | ||
584 | bpf_object__find_map_fd_by_name(obj, "cpumap_kthread_cnt"); | ||
585 | cpus_available_map_fd = | ||
586 | bpf_object__find_map_fd_by_name(obj, "cpus_available"); | ||
587 | cpus_count_map_fd = bpf_object__find_map_fd_by_name(obj, "cpus_count"); | ||
588 | cpus_iterator_map_fd = | ||
589 | bpf_object__find_map_fd_by_name(obj, "cpus_iterator"); | ||
590 | exception_cnt_map_fd = | ||
591 | bpf_object__find_map_fd_by_name(obj, "exception_cnt"); | ||
592 | |||
593 | if (cpu_map_fd < 0 || rx_cnt_map_fd < 0 || | ||
594 | redirect_err_cnt_map_fd < 0 || cpumap_enqueue_cnt_map_fd < 0 || | ||
595 | cpumap_kthread_cnt_map_fd < 0 || cpus_available_map_fd < 0 || | ||
596 | cpus_count_map_fd < 0 || cpus_iterator_map_fd < 0 || | ||
597 | exception_cnt_map_fd < 0) | ||
598 | return -ENOENT; | ||
599 | |||
600 | return 0; | ||
601 | } | ||
602 | |||
559 | int main(int argc, char **argv) | 603 | int main(int argc, char **argv) |
560 | { | 604 | { |
561 | struct rlimit r = {10 * 1024 * 1024, RLIM_INFINITY}; | 605 | struct rlimit r = {10 * 1024 * 1024, RLIM_INFINITY}; |
606 | char *prog_name = "xdp_cpu_map5_lb_hash_ip_pairs"; | ||
607 | struct bpf_prog_load_attr prog_load_attr = { | ||
608 | .prog_type = BPF_PROG_TYPE_UNSPEC, | ||
609 | }; | ||
562 | bool use_separators = true; | 610 | bool use_separators = true; |
563 | bool stress_mode = false; | 611 | bool stress_mode = false; |
612 | struct bpf_program *prog; | ||
613 | struct bpf_object *obj; | ||
564 | char filename[256]; | 614 | char filename[256]; |
565 | int added_cpus = 0; | 615 | int added_cpus = 0; |
566 | int longindex = 0; | 616 | int longindex = 0; |
567 | int interval = 2; | 617 | int interval = 2; |
568 | int prog_num = 5; | ||
569 | int add_cpu = -1; | 618 | int add_cpu = -1; |
619 | int prog_fd; | ||
570 | __u32 qsize; | 620 | __u32 qsize; |
571 | int opt; | 621 | int opt; |
572 | 622 | ||
@@ -579,22 +629,25 @@ int main(int argc, char **argv) | |||
579 | qsize = 128+64; | 629 | qsize = 128+64; |
580 | 630 | ||
581 | snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); | 631 | snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); |
632 | prog_load_attr.file = filename; | ||
582 | 633 | ||
583 | if (setrlimit(RLIMIT_MEMLOCK, &r)) { | 634 | if (setrlimit(RLIMIT_MEMLOCK, &r)) { |
584 | perror("setrlimit(RLIMIT_MEMLOCK)"); | 635 | perror("setrlimit(RLIMIT_MEMLOCK)"); |
585 | return 1; | 636 | return 1; |
586 | } | 637 | } |
587 | 638 | ||
588 | if (load_bpf_file(filename)) { | 639 | if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd)) |
589 | fprintf(stderr, "ERR in load_bpf_file(): %s", bpf_log_buf); | ||
590 | return EXIT_FAIL; | 640 | return EXIT_FAIL; |
591 | } | ||
592 | 641 | ||
593 | if (!prog_fd[0]) { | 642 | if (prog_fd < 0) { |
594 | fprintf(stderr, "ERR: load_bpf_file: %s\n", strerror(errno)); | 643 | fprintf(stderr, "ERR: bpf_prog_load_xattr: %s\n", |
644 | strerror(errno)); | ||
645 | return EXIT_FAIL; | ||
646 | } | ||
647 | if (init_map_fds(obj) < 0) { | ||
648 | fprintf(stderr, "bpf_object__find_map_fd_by_name failed\n"); | ||
595 | return EXIT_FAIL; | 649 | return EXIT_FAIL; |
596 | } | 650 | } |
597 | |||
598 | mark_cpus_unavailable(); | 651 | mark_cpus_unavailable(); |
599 | 652 | ||
600 | /* Parse commands line args */ | 653 | /* Parse commands line args */ |
@@ -630,13 +683,7 @@ int main(int argc, char **argv) | |||
630 | break; | 683 | break; |
631 | case 'p': | 684 | case 'p': |
632 | /* Selecting eBPF prog to load */ | 685 | /* Selecting eBPF prog to load */ |
633 | prog_num = atoi(optarg); | 686 | prog_name = optarg; |
634 | if (prog_num < 0 || prog_num >= MAX_PROG) { | ||
635 | fprintf(stderr, | ||
636 | "--prognum too large err(%d):%s\n", | ||
637 | errno, strerror(errno)); | ||
638 | goto error; | ||
639 | } | ||
640 | break; | 687 | break; |
641 | case 'c': | 688 | case 'c': |
642 | /* Add multiple CPUs */ | 689 | /* Add multiple CPUs */ |
@@ -656,21 +703,21 @@ int main(int argc, char **argv) | |||
656 | case 'h': | 703 | case 'h': |
657 | error: | 704 | error: |
658 | default: | 705 | default: |
659 | usage(argv); | 706 | usage(argv, obj); |
660 | return EXIT_FAIL_OPTION; | 707 | return EXIT_FAIL_OPTION; |
661 | } | 708 | } |
662 | } | 709 | } |
663 | /* Required option */ | 710 | /* Required option */ |
664 | if (ifindex == -1) { | 711 | if (ifindex == -1) { |
665 | fprintf(stderr, "ERR: required option --dev missing\n"); | 712 | fprintf(stderr, "ERR: required option --dev missing\n"); |
666 | usage(argv); | 713 | usage(argv, obj); |
667 | return EXIT_FAIL_OPTION; | 714 | return EXIT_FAIL_OPTION; |
668 | } | 715 | } |
669 | /* Required option */ | 716 | /* Required option */ |
670 | if (add_cpu == -1) { | 717 | if (add_cpu == -1) { |
671 | fprintf(stderr, "ERR: required option --cpu missing\n"); | 718 | fprintf(stderr, "ERR: required option --cpu missing\n"); |
672 | fprintf(stderr, " Specify multiple --cpu option to add more\n"); | 719 | fprintf(stderr, " Specify multiple --cpu option to add more\n"); |
673 | usage(argv); | 720 | usage(argv, obj); |
674 | return EXIT_FAIL_OPTION; | 721 | return EXIT_FAIL_OPTION; |
675 | } | 722 | } |
676 | 723 | ||
@@ -678,11 +725,23 @@ int main(int argc, char **argv) | |||
678 | signal(SIGINT, int_exit); | 725 | signal(SIGINT, int_exit); |
679 | signal(SIGTERM, int_exit); | 726 | signal(SIGTERM, int_exit); |
680 | 727 | ||
681 | if (bpf_set_link_xdp_fd(ifindex, prog_fd[prog_num], xdp_flags) < 0) { | 728 | prog = bpf_object__find_program_by_title(obj, prog_name); |
729 | if (!prog) { | ||
730 | fprintf(stderr, "bpf_object__find_program_by_title failed\n"); | ||
731 | return EXIT_FAIL; | ||
732 | } | ||
733 | |||
734 | prog_fd = bpf_program__fd(prog); | ||
735 | if (prog_fd < 0) { | ||
736 | fprintf(stderr, "bpf_program__fd failed\n"); | ||
737 | return EXIT_FAIL; | ||
738 | } | ||
739 | |||
740 | if (bpf_set_link_xdp_fd(ifindex, prog_fd, xdp_flags) < 0) { | ||
682 | fprintf(stderr, "link set xdp fd failed\n"); | 741 | fprintf(stderr, "link set xdp fd failed\n"); |
683 | return EXIT_FAIL_XDP; | 742 | return EXIT_FAIL_XDP; |
684 | } | 743 | } |
685 | 744 | ||
686 | stats_poll(interval, use_separators, prog_num, stress_mode); | 745 | stats_poll(interval, use_separators, prog_name, stress_mode); |
687 | return EXIT_OK; | 746 | return EXIT_OK; |
688 | } | 747 | } |
diff --git a/samples/bpf/xdp_redirect_map_user.c b/samples/bpf/xdp_redirect_map_user.c index 4445e76854b5..60d46eea225b 100644 --- a/samples/bpf/xdp_redirect_map_user.c +++ b/samples/bpf/xdp_redirect_map_user.c | |||
@@ -22,15 +22,16 @@ | |||
22 | #include <libgen.h> | 22 | #include <libgen.h> |
23 | #include <sys/resource.h> | 23 | #include <sys/resource.h> |
24 | 24 | ||
25 | #include "bpf_load.h" | ||
26 | #include "bpf_util.h" | 25 | #include "bpf_util.h" |
27 | #include <bpf/bpf.h> | 26 | #include <bpf/bpf.h> |
27 | #include "bpf/libbpf.h" | ||
28 | 28 | ||
29 | static int ifindex_in; | 29 | static int ifindex_in; |
30 | static int ifindex_out; | 30 | static int ifindex_out; |
31 | static bool ifindex_out_xdp_dummy_attached = true; | 31 | static bool ifindex_out_xdp_dummy_attached = true; |
32 | 32 | ||
33 | static __u32 xdp_flags; | 33 | static __u32 xdp_flags; |
34 | static int rxcnt_map_fd; | ||
34 | 35 | ||
35 | static void int_exit(int sig) | 36 | static void int_exit(int sig) |
36 | { | 37 | { |
@@ -53,7 +54,7 @@ static void poll_stats(int interval, int ifindex) | |||
53 | int i; | 54 | int i; |
54 | 55 | ||
55 | sleep(interval); | 56 | sleep(interval); |
56 | assert(bpf_map_lookup_elem(map_fd[1], &key, values) == 0); | 57 | assert(bpf_map_lookup_elem(rxcnt_map_fd, &key, values) == 0); |
57 | for (i = 0; i < nr_cpus; i++) | 58 | for (i = 0; i < nr_cpus; i++) |
58 | sum += (values[i] - prev[i]); | 59 | sum += (values[i] - prev[i]); |
59 | if (sum) | 60 | if (sum) |
@@ -76,9 +77,16 @@ static void usage(const char *prog) | |||
76 | int main(int argc, char **argv) | 77 | int main(int argc, char **argv) |
77 | { | 78 | { |
78 | struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; | 79 | struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; |
80 | struct bpf_prog_load_attr prog_load_attr = { | ||
81 | .prog_type = BPF_PROG_TYPE_XDP, | ||
82 | }; | ||
83 | struct bpf_program *prog, *dummy_prog; | ||
84 | int prog_fd, dummy_prog_fd; | ||
79 | const char *optstr = "SN"; | 85 | const char *optstr = "SN"; |
80 | char filename[256]; | 86 | struct bpf_object *obj; |
81 | int ret, opt, key = 0; | 87 | int ret, opt, key = 0; |
88 | char filename[256]; | ||
89 | int tx_port_map_fd; | ||
82 | 90 | ||
83 | while ((opt = getopt(argc, argv, optstr)) != -1) { | 91 | while ((opt = getopt(argc, argv, optstr)) != -1) { |
84 | switch (opt) { | 92 | switch (opt) { |
@@ -109,24 +117,40 @@ int main(int argc, char **argv) | |||
109 | printf("input: %d output: %d\n", ifindex_in, ifindex_out); | 117 | printf("input: %d output: %d\n", ifindex_in, ifindex_out); |
110 | 118 | ||
111 | snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); | 119 | snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); |
120 | prog_load_attr.file = filename; | ||
121 | |||
122 | if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd)) | ||
123 | return 1; | ||
112 | 124 | ||
113 | if (load_bpf_file(filename)) { | 125 | prog = bpf_program__next(NULL, obj); |
114 | printf("%s", bpf_log_buf); | 126 | dummy_prog = bpf_program__next(prog, obj); |
127 | if (!prog || !dummy_prog) { | ||
128 | printf("finding a prog in obj file failed\n"); | ||
129 | return 1; | ||
130 | } | ||
131 | /* bpf_prog_load_xattr gives us the pointer to first prog's fd, | ||
132 | * so we're missing only the fd for dummy prog | ||
133 | */ | ||
134 | dummy_prog_fd = bpf_program__fd(dummy_prog); | ||
135 | if (prog_fd < 0 || dummy_prog_fd < 0) { | ||
136 | printf("bpf_prog_load_xattr: %s\n", strerror(errno)); | ||
115 | return 1; | 137 | return 1; |
116 | } | 138 | } |
117 | 139 | ||
118 | if (!prog_fd[0]) { | 140 | tx_port_map_fd = bpf_object__find_map_fd_by_name(obj, "tx_port"); |
119 | printf("load_bpf_file: %s\n", strerror(errno)); | 141 | rxcnt_map_fd = bpf_object__find_map_fd_by_name(obj, "rxcnt"); |
142 | if (tx_port_map_fd < 0 || rxcnt_map_fd < 0) { | ||
143 | printf("bpf_object__find_map_fd_by_name failed\n"); | ||
120 | return 1; | 144 | return 1; |
121 | } | 145 | } |
122 | 146 | ||
123 | if (bpf_set_link_xdp_fd(ifindex_in, prog_fd[0], xdp_flags) < 0) { | 147 | if (bpf_set_link_xdp_fd(ifindex_in, prog_fd, xdp_flags) < 0) { |
124 | printf("ERROR: link set xdp fd failed on %d\n", ifindex_in); | 148 | printf("ERROR: link set xdp fd failed on %d\n", ifindex_in); |
125 | return 1; | 149 | return 1; |
126 | } | 150 | } |
127 | 151 | ||
128 | /* Loading dummy XDP prog on out-device */ | 152 | /* Loading dummy XDP prog on out-device */ |
129 | if (bpf_set_link_xdp_fd(ifindex_out, prog_fd[1], | 153 | if (bpf_set_link_xdp_fd(ifindex_out, dummy_prog_fd, |
130 | (xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST)) < 0) { | 154 | (xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST)) < 0) { |
131 | printf("WARN: link set xdp fd failed on %d\n", ifindex_out); | 155 | printf("WARN: link set xdp fd failed on %d\n", ifindex_out); |
132 | ifindex_out_xdp_dummy_attached = false; | 156 | ifindex_out_xdp_dummy_attached = false; |
@@ -135,11 +159,8 @@ int main(int argc, char **argv) | |||
135 | signal(SIGINT, int_exit); | 159 | signal(SIGINT, int_exit); |
136 | signal(SIGTERM, int_exit); | 160 | signal(SIGTERM, int_exit); |
137 | 161 | ||
138 | printf("map[0] (vports) = %i, map[1] (map) = %i, map[2] (count) = %i\n", | ||
139 | map_fd[0], map_fd[1], map_fd[2]); | ||
140 | |||
141 | /* populate virtual to physical port map */ | 162 | /* populate virtual to physical port map */ |
142 | ret = bpf_map_update_elem(map_fd[0], &key, &ifindex_out, 0); | 163 | ret = bpf_map_update_elem(tx_port_map_fd, &key, &ifindex_out, 0); |
143 | if (ret) { | 164 | if (ret) { |
144 | perror("bpf_update_elem"); | 165 | perror("bpf_update_elem"); |
145 | goto out; | 166 | goto out; |
diff --git a/samples/bpf/xdp_redirect_user.c b/samples/bpf/xdp_redirect_user.c index 81a69e36cb78..93404820df68 100644 --- a/samples/bpf/xdp_redirect_user.c +++ b/samples/bpf/xdp_redirect_user.c | |||
@@ -22,15 +22,16 @@ | |||
22 | #include <libgen.h> | 22 | #include <libgen.h> |
23 | #include <sys/resource.h> | 23 | #include <sys/resource.h> |
24 | 24 | ||
25 | #include "bpf_load.h" | ||
26 | #include "bpf_util.h" | 25 | #include "bpf_util.h" |
27 | #include <bpf/bpf.h> | 26 | #include <bpf/bpf.h> |
27 | #include "bpf/libbpf.h" | ||
28 | 28 | ||
29 | static int ifindex_in; | 29 | static int ifindex_in; |
30 | static int ifindex_out; | 30 | static int ifindex_out; |
31 | static bool ifindex_out_xdp_dummy_attached = true; | 31 | static bool ifindex_out_xdp_dummy_attached = true; |
32 | 32 | ||
33 | static __u32 xdp_flags; | 33 | static __u32 xdp_flags; |
34 | static int rxcnt_map_fd; | ||
34 | 35 | ||
35 | static void int_exit(int sig) | 36 | static void int_exit(int sig) |
36 | { | 37 | { |
@@ -53,7 +54,7 @@ static void poll_stats(int interval, int ifindex) | |||
53 | int i; | 54 | int i; |
54 | 55 | ||
55 | sleep(interval); | 56 | sleep(interval); |
56 | assert(bpf_map_lookup_elem(map_fd[1], &key, values) == 0); | 57 | assert(bpf_map_lookup_elem(rxcnt_map_fd, &key, values) == 0); |
57 | for (i = 0; i < nr_cpus; i++) | 58 | for (i = 0; i < nr_cpus; i++) |
58 | sum += (values[i] - prev[i]); | 59 | sum += (values[i] - prev[i]); |
59 | if (sum) | 60 | if (sum) |
@@ -77,9 +78,16 @@ static void usage(const char *prog) | |||
77 | int main(int argc, char **argv) | 78 | int main(int argc, char **argv) |
78 | { | 79 | { |
79 | struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; | 80 | struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; |
81 | struct bpf_prog_load_attr prog_load_attr = { | ||
82 | .prog_type = BPF_PROG_TYPE_XDP, | ||
83 | }; | ||
84 | struct bpf_program *prog, *dummy_prog; | ||
85 | int prog_fd, tx_port_map_fd, opt; | ||
80 | const char *optstr = "SN"; | 86 | const char *optstr = "SN"; |
87 | struct bpf_object *obj; | ||
81 | char filename[256]; | 88 | char filename[256]; |
82 | int ret, opt, key = 0; | 89 | int dummy_prog_fd; |
90 | int ret, key = 0; | ||
83 | 91 | ||
84 | while ((opt = getopt(argc, argv, optstr)) != -1) { | 92 | while ((opt = getopt(argc, argv, optstr)) != -1) { |
85 | switch (opt) { | 93 | switch (opt) { |
@@ -110,24 +118,40 @@ int main(int argc, char **argv) | |||
110 | printf("input: %d output: %d\n", ifindex_in, ifindex_out); | 118 | printf("input: %d output: %d\n", ifindex_in, ifindex_out); |
111 | 119 | ||
112 | snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); | 120 | snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); |
121 | prog_load_attr.file = filename; | ||
113 | 122 | ||
114 | if (load_bpf_file(filename)) { | 123 | if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd)) |
115 | printf("%s", bpf_log_buf); | 124 | return 1; |
125 | |||
126 | prog = bpf_program__next(NULL, obj); | ||
127 | dummy_prog = bpf_program__next(prog, obj); | ||
128 | if (!prog || !dummy_prog) { | ||
129 | printf("finding a prog in obj file failed\n"); | ||
130 | return 1; | ||
131 | } | ||
132 | /* bpf_prog_load_xattr gives us the pointer to first prog's fd, | ||
133 | * so we're missing only the fd for dummy prog | ||
134 | */ | ||
135 | dummy_prog_fd = bpf_program__fd(dummy_prog); | ||
136 | if (prog_fd < 0 || dummy_prog_fd < 0) { | ||
137 | printf("bpf_prog_load_xattr: %s\n", strerror(errno)); | ||
116 | return 1; | 138 | return 1; |
117 | } | 139 | } |
118 | 140 | ||
119 | if (!prog_fd[0]) { | 141 | tx_port_map_fd = bpf_object__find_map_fd_by_name(obj, "tx_port"); |
120 | printf("load_bpf_file: %s\n", strerror(errno)); | 142 | rxcnt_map_fd = bpf_object__find_map_fd_by_name(obj, "rxcnt"); |
143 | if (tx_port_map_fd < 0 || rxcnt_map_fd < 0) { | ||
144 | printf("bpf_object__find_map_fd_by_name failed\n"); | ||
121 | return 1; | 145 | return 1; |
122 | } | 146 | } |
123 | 147 | ||
124 | if (bpf_set_link_xdp_fd(ifindex_in, prog_fd[0], xdp_flags) < 0) { | 148 | if (bpf_set_link_xdp_fd(ifindex_in, prog_fd, xdp_flags) < 0) { |
125 | printf("ERROR: link set xdp fd failed on %d\n", ifindex_in); | 149 | printf("ERROR: link set xdp fd failed on %d\n", ifindex_in); |
126 | return 1; | 150 | return 1; |
127 | } | 151 | } |
128 | 152 | ||
129 | /* Loading dummy XDP prog on out-device */ | 153 | /* Loading dummy XDP prog on out-device */ |
130 | if (bpf_set_link_xdp_fd(ifindex_out, prog_fd[1], | 154 | if (bpf_set_link_xdp_fd(ifindex_out, dummy_prog_fd, |
131 | (xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST)) < 0) { | 155 | (xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST)) < 0) { |
132 | printf("WARN: link set xdp fd failed on %d\n", ifindex_out); | 156 | printf("WARN: link set xdp fd failed on %d\n", ifindex_out); |
133 | ifindex_out_xdp_dummy_attached = false; | 157 | ifindex_out_xdp_dummy_attached = false; |
@@ -137,7 +161,7 @@ int main(int argc, char **argv) | |||
137 | signal(SIGTERM, int_exit); | 161 | signal(SIGTERM, int_exit); |
138 | 162 | ||
139 | /* bpf redirect port */ | 163 | /* bpf redirect port */ |
140 | ret = bpf_map_update_elem(map_fd[0], &key, &ifindex_out, 0); | 164 | ret = bpf_map_update_elem(tx_port_map_fd, &key, &ifindex_out, 0); |
141 | if (ret) { | 165 | if (ret) { |
142 | perror("bpf_update_elem"); | 166 | perror("bpf_update_elem"); |
143 | goto out; | 167 | goto out; |
diff --git a/samples/bpf/xdp_router_ipv4_user.c b/samples/bpf/xdp_router_ipv4_user.c index b2b4dfa776c8..cea2306f5ab7 100644 --- a/samples/bpf/xdp_router_ipv4_user.c +++ b/samples/bpf/xdp_router_ipv4_user.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <string.h> | 15 | #include <string.h> |
16 | #include <sys/socket.h> | 16 | #include <sys/socket.h> |
17 | #include <unistd.h> | 17 | #include <unistd.h> |
18 | #include "bpf_load.h" | ||
19 | #include <bpf/bpf.h> | 18 | #include <bpf/bpf.h> |
20 | #include <arpa/inet.h> | 19 | #include <arpa/inet.h> |
21 | #include <fcntl.h> | 20 | #include <fcntl.h> |
@@ -25,11 +24,17 @@ | |||
25 | #include <sys/ioctl.h> | 24 | #include <sys/ioctl.h> |
26 | #include <sys/syscall.h> | 25 | #include <sys/syscall.h> |
27 | #include "bpf_util.h" | 26 | #include "bpf_util.h" |
27 | #include "bpf/libbpf.h" | ||
28 | 28 | ||
29 | int sock, sock_arp, flags = 0; | 29 | int sock, sock_arp, flags = 0; |
30 | static int total_ifindex; | 30 | static int total_ifindex; |
31 | int *ifindex_list; | 31 | int *ifindex_list; |
32 | char buf[8192]; | 32 | char buf[8192]; |
33 | static int lpm_map_fd; | ||
34 | static int rxcnt_map_fd; | ||
35 | static int arp_table_map_fd; | ||
36 | static int exact_match_map_fd; | ||
37 | static int tx_port_map_fd; | ||
33 | 38 | ||
34 | static int get_route_table(int rtm_family); | 39 | static int get_route_table(int rtm_family); |
35 | static void int_exit(int sig) | 40 | static void int_exit(int sig) |
@@ -186,7 +191,8 @@ static void read_route(struct nlmsghdr *nh, int nll) | |||
186 | bpf_set_link_xdp_fd(ifindex_list[i], -1, flags); | 191 | bpf_set_link_xdp_fd(ifindex_list[i], -1, flags); |
187 | exit(0); | 192 | exit(0); |
188 | } | 193 | } |
189 | assert(bpf_map_update_elem(map_fd[4], &route.iface, &route.iface, 0) == 0); | 194 | assert(bpf_map_update_elem(tx_port_map_fd, |
195 | &route.iface, &route.iface, 0) == 0); | ||
190 | if (rtm_family == AF_INET) { | 196 | if (rtm_family == AF_INET) { |
191 | struct trie_value { | 197 | struct trie_value { |
192 | __u8 prefix[4]; | 198 | __u8 prefix[4]; |
@@ -207,11 +213,16 @@ static void read_route(struct nlmsghdr *nh, int nll) | |||
207 | direct_entry.arp.dst = 0; | 213 | direct_entry.arp.dst = 0; |
208 | if (route.dst_len == 32) { | 214 | if (route.dst_len == 32) { |
209 | if (nh->nlmsg_type == RTM_DELROUTE) { | 215 | if (nh->nlmsg_type == RTM_DELROUTE) { |
210 | assert(bpf_map_delete_elem(map_fd[3], &route.dst) == 0); | 216 | assert(bpf_map_delete_elem(exact_match_map_fd, |
217 | &route.dst) == 0); | ||
211 | } else { | 218 | } else { |
212 | if (bpf_map_lookup_elem(map_fd[2], &route.dst, &direct_entry.arp.mac) == 0) | 219 | if (bpf_map_lookup_elem(arp_table_map_fd, |
220 | &route.dst, | ||
221 | &direct_entry.arp.mac) == 0) | ||
213 | direct_entry.arp.dst = route.dst; | 222 | direct_entry.arp.dst = route.dst; |
214 | assert(bpf_map_update_elem(map_fd[3], &route.dst, &direct_entry, 0) == 0); | 223 | assert(bpf_map_update_elem(exact_match_map_fd, |
224 | &route.dst, | ||
225 | &direct_entry, 0) == 0); | ||
215 | } | 226 | } |
216 | } | 227 | } |
217 | for (i = 0; i < 4; i++) | 228 | for (i = 0; i < 4; i++) |
@@ -225,7 +236,7 @@ static void read_route(struct nlmsghdr *nh, int nll) | |||
225 | route.gw, route.dst_len, | 236 | route.gw, route.dst_len, |
226 | route.metric, | 237 | route.metric, |
227 | route.iface_name); | 238 | route.iface_name); |
228 | if (bpf_map_lookup_elem(map_fd[0], prefix_key, | 239 | if (bpf_map_lookup_elem(lpm_map_fd, prefix_key, |
229 | prefix_value) < 0) { | 240 | prefix_value) < 0) { |
230 | for (i = 0; i < 4; i++) | 241 | for (i = 0; i < 4; i++) |
231 | prefix_value->prefix[i] = prefix_key->data[i]; | 242 | prefix_value->prefix[i] = prefix_key->data[i]; |
@@ -234,7 +245,7 @@ static void read_route(struct nlmsghdr *nh, int nll) | |||
234 | prefix_value->gw = route.gw; | 245 | prefix_value->gw = route.gw; |
235 | prefix_value->metric = route.metric; | 246 | prefix_value->metric = route.metric; |
236 | 247 | ||
237 | assert(bpf_map_update_elem(map_fd[0], | 248 | assert(bpf_map_update_elem(lpm_map_fd, |
238 | prefix_key, | 249 | prefix_key, |
239 | prefix_value, 0 | 250 | prefix_value, 0 |
240 | ) == 0); | 251 | ) == 0); |
@@ -247,7 +258,7 @@ static void read_route(struct nlmsghdr *nh, int nll) | |||
247 | prefix_key->data[2], | 258 | prefix_key->data[2], |
248 | prefix_key->data[3], | 259 | prefix_key->data[3], |
249 | prefix_key->prefixlen); | 260 | prefix_key->prefixlen); |
250 | assert(bpf_map_delete_elem(map_fd[0], | 261 | assert(bpf_map_delete_elem(lpm_map_fd, |
251 | prefix_key | 262 | prefix_key |
252 | ) == 0); | 263 | ) == 0); |
253 | /* Rereading the route table to check if | 264 | /* Rereading the route table to check if |
@@ -275,8 +286,7 @@ static void read_route(struct nlmsghdr *nh, int nll) | |||
275 | prefix_value->ifindex = route.iface; | 286 | prefix_value->ifindex = route.iface; |
276 | prefix_value->gw = route.gw; | 287 | prefix_value->gw = route.gw; |
277 | prefix_value->metric = route.metric; | 288 | prefix_value->metric = route.metric; |
278 | assert(bpf_map_update_elem( | 289 | assert(bpf_map_update_elem(lpm_map_fd, |
279 | map_fd[0], | ||
280 | prefix_key, | 290 | prefix_key, |
281 | prefix_value, | 291 | prefix_value, |
282 | 0) == 0); | 292 | 0) == 0); |
@@ -401,7 +411,8 @@ static void read_arp(struct nlmsghdr *nh, int nll) | |||
401 | arp_entry.mac = atol(mac); | 411 | arp_entry.mac = atol(mac); |
402 | printf("%x\t\t%llx\n", arp_entry.dst, arp_entry.mac); | 412 | printf("%x\t\t%llx\n", arp_entry.dst, arp_entry.mac); |
403 | if (ndm_family == AF_INET) { | 413 | if (ndm_family == AF_INET) { |
404 | if (bpf_map_lookup_elem(map_fd[3], &arp_entry.dst, | 414 | if (bpf_map_lookup_elem(exact_match_map_fd, |
415 | &arp_entry.dst, | ||
405 | &direct_entry) == 0) { | 416 | &direct_entry) == 0) { |
406 | if (nh->nlmsg_type == RTM_DELNEIGH) { | 417 | if (nh->nlmsg_type == RTM_DELNEIGH) { |
407 | direct_entry.arp.dst = 0; | 418 | direct_entry.arp.dst = 0; |
@@ -410,16 +421,17 @@ static void read_arp(struct nlmsghdr *nh, int nll) | |||
410 | direct_entry.arp.dst = arp_entry.dst; | 421 | direct_entry.arp.dst = arp_entry.dst; |
411 | direct_entry.arp.mac = arp_entry.mac; | 422 | direct_entry.arp.mac = arp_entry.mac; |
412 | } | 423 | } |
413 | assert(bpf_map_update_elem(map_fd[3], | 424 | assert(bpf_map_update_elem(exact_match_map_fd, |
414 | &arp_entry.dst, | 425 | &arp_entry.dst, |
415 | &direct_entry, 0 | 426 | &direct_entry, 0 |
416 | ) == 0); | 427 | ) == 0); |
417 | memset(&direct_entry, 0, sizeof(direct_entry)); | 428 | memset(&direct_entry, 0, sizeof(direct_entry)); |
418 | } | 429 | } |
419 | if (nh->nlmsg_type == RTM_DELNEIGH) { | 430 | if (nh->nlmsg_type == RTM_DELNEIGH) { |
420 | assert(bpf_map_delete_elem(map_fd[2], &arp_entry.dst) == 0); | 431 | assert(bpf_map_delete_elem(arp_table_map_fd, |
432 | &arp_entry.dst) == 0); | ||
421 | } else if (nh->nlmsg_type == RTM_NEWNEIGH) { | 433 | } else if (nh->nlmsg_type == RTM_NEWNEIGH) { |
422 | assert(bpf_map_update_elem(map_fd[2], | 434 | assert(bpf_map_update_elem(arp_table_map_fd, |
423 | &arp_entry.dst, | 435 | &arp_entry.dst, |
424 | &arp_entry.mac, 0 | 436 | &arp_entry.mac, 0 |
425 | ) == 0); | 437 | ) == 0); |
@@ -553,7 +565,8 @@ static int monitor_route(void) | |||
553 | for (key = 0; key < nr_keys; key++) { | 565 | for (key = 0; key < nr_keys; key++) { |
554 | __u64 sum = 0; | 566 | __u64 sum = 0; |
555 | 567 | ||
556 | assert(bpf_map_lookup_elem(map_fd[1], &key, values) == 0); | 568 | assert(bpf_map_lookup_elem(rxcnt_map_fd, |
569 | &key, values) == 0); | ||
557 | for (i = 0; i < nr_cpus; i++) | 570 | for (i = 0; i < nr_cpus; i++) |
558 | sum += (values[i] - prev[key][i]); | 571 | sum += (values[i] - prev[key][i]); |
559 | if (sum) | 572 | if (sum) |
@@ -596,11 +609,18 @@ cleanup: | |||
596 | 609 | ||
597 | int main(int ac, char **argv) | 610 | int main(int ac, char **argv) |
598 | { | 611 | { |
612 | struct bpf_prog_load_attr prog_load_attr = { | ||
613 | .prog_type = BPF_PROG_TYPE_XDP, | ||
614 | }; | ||
615 | struct bpf_object *obj; | ||
599 | char filename[256]; | 616 | char filename[256]; |
600 | char **ifname_list; | 617 | char **ifname_list; |
618 | int prog_fd; | ||
601 | int i = 1; | 619 | int i = 1; |
602 | 620 | ||
603 | snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); | 621 | snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); |
622 | prog_load_attr.file = filename; | ||
623 | |||
604 | if (ac < 2) { | 624 | if (ac < 2) { |
605 | printf("usage: %s [-S] Interface name list\n", argv[0]); | 625 | printf("usage: %s [-S] Interface name list\n", argv[0]); |
606 | return 1; | 626 | return 1; |
@@ -614,15 +634,28 @@ int main(int ac, char **argv) | |||
614 | total_ifindex = ac - 1; | 634 | total_ifindex = ac - 1; |
615 | ifname_list = (argv + 1); | 635 | ifname_list = (argv + 1); |
616 | } | 636 | } |
617 | if (load_bpf_file(filename)) { | 637 | |
618 | printf("%s", bpf_log_buf); | 638 | if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd)) |
619 | return 1; | 639 | return 1; |
620 | } | 640 | |
621 | printf("\n**************loading bpf file*********************\n\n\n"); | 641 | printf("\n**************loading bpf file*********************\n\n\n"); |
622 | if (!prog_fd[0]) { | 642 | if (!prog_fd) { |
623 | printf("load_bpf_file: %s\n", strerror(errno)); | 643 | printf("bpf_prog_load_xattr: %s\n", strerror(errno)); |
624 | return 1; | 644 | return 1; |
625 | } | 645 | } |
646 | |||
647 | lpm_map_fd = bpf_object__find_map_fd_by_name(obj, "lpm_map"); | ||
648 | rxcnt_map_fd = bpf_object__find_map_fd_by_name(obj, "rxcnt"); | ||
649 | arp_table_map_fd = bpf_object__find_map_fd_by_name(obj, "arp_table"); | ||
650 | exact_match_map_fd = bpf_object__find_map_fd_by_name(obj, | ||
651 | "exact_match"); | ||
652 | tx_port_map_fd = bpf_object__find_map_fd_by_name(obj, "tx_port"); | ||
653 | if (lpm_map_fd < 0 || rxcnt_map_fd < 0 || arp_table_map_fd < 0 || | ||
654 | exact_match_map_fd < 0 || tx_port_map_fd < 0) { | ||
655 | printf("bpf_object__find_map_fd_by_name failed\n"); | ||
656 | return 1; | ||
657 | } | ||
658 | |||
626 | ifindex_list = (int *)malloc(total_ifindex * sizeof(int *)); | 659 | ifindex_list = (int *)malloc(total_ifindex * sizeof(int *)); |
627 | for (i = 0; i < total_ifindex; i++) { | 660 | for (i = 0; i < total_ifindex; i++) { |
628 | ifindex_list[i] = if_nametoindex(ifname_list[i]); | 661 | ifindex_list[i] = if_nametoindex(ifname_list[i]); |
@@ -633,7 +666,7 @@ int main(int ac, char **argv) | |||
633 | } | 666 | } |
634 | } | 667 | } |
635 | for (i = 0; i < total_ifindex; i++) { | 668 | for (i = 0; i < total_ifindex; i++) { |
636 | if (bpf_set_link_xdp_fd(ifindex_list[i], prog_fd[0], flags) < 0) { | 669 | if (bpf_set_link_xdp_fd(ifindex_list[i], prog_fd, flags) < 0) { |
637 | printf("link set xdp fd failed\n"); | 670 | printf("link set xdp fd failed\n"); |
638 | int recovery_index = i; | 671 | int recovery_index = i; |
639 | 672 | ||
diff --git a/samples/bpf/xdp_tx_iptunnel_user.c b/samples/bpf/xdp_tx_iptunnel_user.c index a4ccc33adac0..5093d8220da5 100644 --- a/samples/bpf/xdp_tx_iptunnel_user.c +++ b/samples/bpf/xdp_tx_iptunnel_user.c | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <netinet/ether.h> | 17 | #include <netinet/ether.h> |
18 | #include <unistd.h> | 18 | #include <unistd.h> |
19 | #include <time.h> | 19 | #include <time.h> |
20 | #include "bpf_load.h" | 20 | #include "bpf/libbpf.h" |
21 | #include <bpf/bpf.h> | 21 | #include <bpf/bpf.h> |
22 | #include "bpf_util.h" | 22 | #include "bpf_util.h" |
23 | #include "xdp_tx_iptunnel_common.h" | 23 | #include "xdp_tx_iptunnel_common.h" |
@@ -26,6 +26,7 @@ | |||
26 | 26 | ||
27 | static int ifindex = -1; | 27 | static int ifindex = -1; |
28 | static __u32 xdp_flags = 0; | 28 | static __u32 xdp_flags = 0; |
29 | static int rxcnt_map_fd; | ||
29 | 30 | ||
30 | static void int_exit(int sig) | 31 | static void int_exit(int sig) |
31 | { | 32 | { |
@@ -53,7 +54,8 @@ static void poll_stats(unsigned int kill_after_s) | |||
53 | for (proto = 0; proto < nr_protos; proto++) { | 54 | for (proto = 0; proto < nr_protos; proto++) { |
54 | __u64 sum = 0; | 55 | __u64 sum = 0; |
55 | 56 | ||
56 | assert(bpf_map_lookup_elem(map_fd[0], &proto, values) == 0); | 57 | assert(bpf_map_lookup_elem(rxcnt_map_fd, &proto, |
58 | values) == 0); | ||
57 | for (i = 0; i < nr_cpus; i++) | 59 | for (i = 0; i < nr_cpus; i++) |
58 | sum += (values[i] - prev[proto][i]); | 60 | sum += (values[i] - prev[proto][i]); |
59 | 61 | ||
@@ -138,15 +140,19 @@ static int parse_ports(const char *port_str, int *min_port, int *max_port) | |||
138 | 140 | ||
139 | int main(int argc, char **argv) | 141 | int main(int argc, char **argv) |
140 | { | 142 | { |
143 | struct bpf_prog_load_attr prog_load_attr = { | ||
144 | .prog_type = BPF_PROG_TYPE_XDP, | ||
145 | }; | ||
146 | struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; | ||
147 | int min_port = 0, max_port = 0, vip2tnl_map_fd; | ||
148 | const char *optstr = "i:a:p:s:d:m:T:P:SNh"; | ||
141 | unsigned char opt_flags[256] = {}; | 149 | unsigned char opt_flags[256] = {}; |
142 | unsigned int kill_after_s = 0; | 150 | unsigned int kill_after_s = 0; |
143 | const char *optstr = "i:a:p:s:d:m:T:P:SNh"; | ||
144 | int min_port = 0, max_port = 0; | ||
145 | struct iptnl_info tnl = {}; | 151 | struct iptnl_info tnl = {}; |
146 | struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; | 152 | struct bpf_object *obj; |
147 | struct vip vip = {}; | 153 | struct vip vip = {}; |
148 | char filename[256]; | 154 | char filename[256]; |
149 | int opt; | 155 | int opt, prog_fd; |
150 | int i; | 156 | int i; |
151 | 157 | ||
152 | tnl.family = AF_UNSPEC; | 158 | tnl.family = AF_UNSPEC; |
@@ -232,29 +238,36 @@ int main(int argc, char **argv) | |||
232 | } | 238 | } |
233 | 239 | ||
234 | snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); | 240 | snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); |
241 | prog_load_attr.file = filename; | ||
235 | 242 | ||
236 | if (load_bpf_file(filename)) { | 243 | if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd)) |
237 | printf("%s", bpf_log_buf); | ||
238 | return 1; | 244 | return 1; |
239 | } | ||
240 | 245 | ||
241 | if (!prog_fd[0]) { | 246 | if (!prog_fd) { |
242 | printf("load_bpf_file: %s\n", strerror(errno)); | 247 | printf("load_bpf_file: %s\n", strerror(errno)); |
243 | return 1; | 248 | return 1; |
244 | } | 249 | } |
245 | 250 | ||
251 | rxcnt_map_fd = bpf_object__find_map_fd_by_name(obj, "rxcnt"); | ||
252 | vip2tnl_map_fd = bpf_object__find_map_fd_by_name(obj, "vip2tnl"); | ||
253 | if (vip2tnl_map_fd < 0 || rxcnt_map_fd < 0) { | ||
254 | printf("bpf_object__find_map_fd_by_name failed\n"); | ||
255 | return 1; | ||
256 | } | ||
257 | |||
246 | signal(SIGINT, int_exit); | 258 | signal(SIGINT, int_exit); |
247 | signal(SIGTERM, int_exit); | 259 | signal(SIGTERM, int_exit); |
248 | 260 | ||
249 | while (min_port <= max_port) { | 261 | while (min_port <= max_port) { |
250 | vip.dport = htons(min_port++); | 262 | vip.dport = htons(min_port++); |
251 | if (bpf_map_update_elem(map_fd[1], &vip, &tnl, BPF_NOEXIST)) { | 263 | if (bpf_map_update_elem(vip2tnl_map_fd, &vip, &tnl, |
264 | BPF_NOEXIST)) { | ||
252 | perror("bpf_map_update_elem(&vip2tnl)"); | 265 | perror("bpf_map_update_elem(&vip2tnl)"); |
253 | return 1; | 266 | return 1; |
254 | } | 267 | } |
255 | } | 268 | } |
256 | 269 | ||
257 | if (bpf_set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) { | 270 | if (bpf_set_link_xdp_fd(ifindex, prog_fd, xdp_flags) < 0) { |
258 | printf("link set xdp fd failed\n"); | 271 | printf("link set xdp fd failed\n"); |
259 | return 1; | 272 | return 1; |
260 | } | 273 | } |