diff options
| -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 | } |
