aboutsummaryrefslogtreecommitdiffstats
path: root/samples
diff options
context:
space:
mode:
authorMaciej Fijalkowski <maciejromanfijalkowski@gmail.com>2019-02-01 16:42:25 -0500
committerDaniel Borkmann <daniel@iogearbox.net>2019-02-01 17:37:51 -0500
commitbbaf6029c49ccf2dc93d9564af58a20d125947a1 (patch)
treed01db083bd2806709339c7a78bf82daf0fde26c8 /samples
parent7313798b144c5b945dc47502a233cabb7022cb70 (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/Makefile8
-rw-r--r--samples/bpf/xdp_redirect_cpu_user.c145
-rw-r--r--samples/bpf/xdp_redirect_map_user.c47
-rw-r--r--samples/bpf/xdp_redirect_user.c44
-rw-r--r--samples/bpf/xdp_router_ipv4_user.c75
-rw-r--r--samples/bpf/xdp_tx_iptunnel_user.c37
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
87xdp1-objs := xdp1_user.o 87xdp1-objs := xdp1_user.o
88# reuse xdp1 source intentionally 88# reuse xdp1 source intentionally
89xdp2-objs := xdp1_user.o 89xdp2-objs := xdp1_user.o
90xdp_router_ipv4-objs := bpf_load.o xdp_router_ipv4_user.o 90xdp_router_ipv4-objs := xdp_router_ipv4_user.o
91test_current_task_under_cgroup-objs := bpf_load.o $(CGROUP_HELPERS) \ 91test_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
93trace_event-objs := bpf_load.o trace_event_user.o $(TRACE_HELPERS) 93trace_event-objs := bpf_load.o trace_event_user.o $(TRACE_HELPERS)
94sampleip-objs := bpf_load.o sampleip_user.o $(TRACE_HELPERS) 94sampleip-objs := bpf_load.o sampleip_user.o $(TRACE_HELPERS)
95tc_l2_redirect-objs := bpf_load.o tc_l2_redirect_user.o 95tc_l2_redirect-objs := bpf_load.o tc_l2_redirect_user.o
96lwt_len_hist-objs := bpf_load.o lwt_len_hist_user.o 96lwt_len_hist-objs := bpf_load.o lwt_len_hist_user.o
97xdp_tx_iptunnel-objs := bpf_load.o xdp_tx_iptunnel_user.o 97xdp_tx_iptunnel-objs := xdp_tx_iptunnel_user.o
98test_map_in_map-objs := bpf_load.o test_map_in_map_user.o 98test_map_in_map-objs := bpf_load.o test_map_in_map_user.o
99per_socket_stats_example-objs := cookie_uid_helper_example.o 99per_socket_stats_example-objs := cookie_uid_helper_example.o
100xdp_redirect-objs := bpf_load.o xdp_redirect_user.o 100xdp_redirect-objs := xdp_redirect_user.o
101xdp_redirect_map-objs := bpf_load.o xdp_redirect_map_user.o 101xdp_redirect_map-objs := xdp_redirect_map_user.o
102xdp_redirect_cpu-objs := bpf_load.o xdp_redirect_cpu_user.o 102xdp_redirect_cpu-objs := bpf_load.o xdp_redirect_cpu_user.o
103xdp_monitor-objs := bpf_load.o xdp_monitor_user.o 103xdp_monitor-objs := bpf_load.o xdp_monitor_user.o
104xdp_rxq_info-objs := xdp_rxq_info_user.o 104xdp_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];
38static char *ifname; 34static char *ifname;
39 35
40static __u32 xdp_flags; 36static __u32 xdp_flags;
37static int cpu_map_fd;
38static int rx_cnt_map_fd;
39static int redirect_err_cnt_map_fd;
40static int cpumap_enqueue_cnt_map_fd;
41static int cpumap_kthread_cnt_map_fd;
42static int cpus_available_map_fd;
43static int cpus_count_map_fd;
44static int cpus_iterator_map_fd;
45static 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
73static void usage(char *argv[]) 78static 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
88static 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
263static void stats_print(struct stats_record *stats_rec, 280static 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
533static void stats_poll(int interval, bool use_separators, int prog_num, 549static 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
575static 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
559int main(int argc, char **argv) 603int 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
29static int ifindex_in; 29static int ifindex_in;
30static int ifindex_out; 30static int ifindex_out;
31static bool ifindex_out_xdp_dummy_attached = true; 31static bool ifindex_out_xdp_dummy_attached = true;
32 32
33static __u32 xdp_flags; 33static __u32 xdp_flags;
34static int rxcnt_map_fd;
34 35
35static void int_exit(int sig) 36static 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)
76int main(int argc, char **argv) 77int 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
29static int ifindex_in; 29static int ifindex_in;
30static int ifindex_out; 30static int ifindex_out;
31static bool ifindex_out_xdp_dummy_attached = true; 31static bool ifindex_out_xdp_dummy_attached = true;
32 32
33static __u32 xdp_flags; 33static __u32 xdp_flags;
34static int rxcnt_map_fd;
34 35
35static void int_exit(int sig) 36static 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)
77int main(int argc, char **argv) 78int 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
29int sock, sock_arp, flags = 0; 29int sock, sock_arp, flags = 0;
30static int total_ifindex; 30static int total_ifindex;
31int *ifindex_list; 31int *ifindex_list;
32char buf[8192]; 32char buf[8192];
33static int lpm_map_fd;
34static int rxcnt_map_fd;
35static int arp_table_map_fd;
36static int exact_match_map_fd;
37static int tx_port_map_fd;
33 38
34static int get_route_table(int rtm_family); 39static int get_route_table(int rtm_family);
35static void int_exit(int sig) 40static 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
597int main(int ac, char **argv) 610int 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
27static int ifindex = -1; 27static int ifindex = -1;
28static __u32 xdp_flags = 0; 28static __u32 xdp_flags = 0;
29static int rxcnt_map_fd;
29 30
30static void int_exit(int sig) 31static 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
139int main(int argc, char **argv) 141int 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 }