hc
2024-10-09 05e59e5fb0064c97a1c10921ecd549f2d4a58565
kernel/samples/bpf/xdp_rxq_info_user.c
....@@ -22,15 +22,16 @@
2222 #include <arpa/inet.h>
2323 #include <linux/if_link.h>
2424
25
-#include "bpf/bpf.h"
26
-#include "bpf/libbpf.h"
25
+#include <bpf/bpf.h>
26
+#include <bpf/libbpf.h>
2727 #include "bpf_util.h"
2828
2929 static int ifindex = -1;
3030 static char ifname_buf[IF_NAMESIZE];
3131 static char *ifname;
32
+static __u32 prog_id;
3233
33
-static __u32 xdp_flags;
34
+static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
3435
3536 static struct bpf_map *stats_global_map;
3637 static struct bpf_map *rx_queue_index_map;
....@@ -50,18 +51,32 @@
5051 {"sec", required_argument, NULL, 's' },
5152 {"no-separators", no_argument, NULL, 'z' },
5253 {"action", required_argument, NULL, 'a' },
53
- {"readmem", no_argument, NULL, 'r' },
54
- {"swapmac", no_argument, NULL, 'm' },
54
+ {"readmem", no_argument, NULL, 'r' },
55
+ {"swapmac", no_argument, NULL, 'm' },
56
+ {"force", no_argument, NULL, 'F' },
5557 {0, 0, NULL, 0 }
5658 };
5759
5860 static void int_exit(int sig)
5961 {
60
- fprintf(stderr,
61
- "Interrupted: Removing XDP program on ifindex:%d device:%s\n",
62
- ifindex, ifname);
63
- if (ifindex > -1)
64
- bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
62
+ __u32 curr_prog_id = 0;
63
+
64
+ if (ifindex > -1) {
65
+ if (bpf_get_link_xdp_id(ifindex, &curr_prog_id, xdp_flags)) {
66
+ printf("bpf_get_link_xdp_id failed\n");
67
+ exit(EXIT_FAIL);
68
+ }
69
+ if (prog_id == curr_prog_id) {
70
+ fprintf(stderr,
71
+ "Interrupted: Removing XDP program on ifindex:%d device:%s\n",
72
+ ifindex, ifname);
73
+ bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
74
+ } else if (!curr_prog_id) {
75
+ printf("couldn't find a prog id on a given iface\n");
76
+ } else {
77
+ printf("program on interface changed, not removing\n");
78
+ }
79
+ }
6580 exit(EXIT_OK);
6681 }
6782
....@@ -183,11 +198,8 @@
183198 {
184199 unsigned int nr_cpus = bpf_num_possible_cpus();
185200 struct datarec *array;
186
- size_t size;
187201
188
- size = sizeof(struct datarec) * nr_cpus;
189
- array = malloc(size);
190
- memset(array, 0, size);
202
+ array = calloc(nr_cpus, sizeof(struct datarec));
191203 if (!array) {
192204 fprintf(stderr, "Mem alloc error (nr_cpus:%u)\n", nr_cpus);
193205 exit(EXIT_FAIL_MEM);
....@@ -199,11 +211,8 @@
199211 {
200212 unsigned int nr_rxqs = bpf_map__def(rx_queue_index_map)->max_entries;
201213 struct record *array;
202
- size_t size;
203214
204
- size = sizeof(struct record) * nr_rxqs;
205
- array = malloc(size);
206
- memset(array, 0, size);
215
+ array = calloc(nr_rxqs, sizeof(struct record));
207216 if (!array) {
208217 fprintf(stderr, "Mem alloc error (nr_rxqs:%u)\n", nr_rxqs);
209218 exit(EXIT_FAIL_MEM);
....@@ -217,8 +226,7 @@
217226 struct stats_record *rec;
218227 int i;
219228
220
- rec = malloc(sizeof(*rec));
221
- memset(rec, 0, sizeof(*rec));
229
+ rec = calloc(1, sizeof(struct stats_record));
222230 if (!rec) {
223231 fprintf(stderr, "Mem alloc error\n");
224232 exit(EXIT_FAIL_MEM);
....@@ -442,10 +450,12 @@
442450 int main(int argc, char **argv)
443451 {
444452 __u32 cfg_options= NO_TOUCH ; /* Default: Don't touch packet memory */
445
- struct rlimit r = {10 * 1024 * 1024, RLIM_INFINITY};
453
+ struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
446454 struct bpf_prog_load_attr prog_load_attr = {
447455 .prog_type = BPF_PROG_TYPE_XDP,
448456 };
457
+ struct bpf_prog_info info = {};
458
+ __u32 info_len = sizeof(info);
449459 int prog_fd, map_fd, opt, err;
450460 bool use_separators = true;
451461 struct config cfg = { 0 };
....@@ -482,12 +492,12 @@
482492 map_fd = bpf_map__fd(map);
483493
484494 if (!prog_fd) {
485
- fprintf(stderr, "ERR: load_bpf_file: %s\n", strerror(errno));
495
+ fprintf(stderr, "ERR: bpf_prog_load_xattr: %s\n", strerror(errno));
486496 return EXIT_FAIL;
487497 }
488498
489499 /* Parse commands line args */
490
- while ((opt = getopt_long(argc, argv, "hSd:",
500
+ while ((opt = getopt_long(argc, argv, "FhSrmzd:s:a:",
491501 long_options, &longindex)) != -1) {
492502 switch (opt) {
493503 case 'd':
....@@ -524,6 +534,9 @@
524534 case 'm':
525535 cfg_options |= SWAP_MAC;
526536 break;
537
+ case 'F':
538
+ xdp_flags &= ~XDP_FLAGS_UPDATE_IF_NOEXIST;
539
+ break;
527540 case 'h':
528541 error:
529542 default:
....@@ -531,6 +544,10 @@
531544 return EXIT_FAIL_OPTION;
532545 }
533546 }
547
+
548
+ if (!(xdp_flags & XDP_FLAGS_SKB_MODE))
549
+ xdp_flags |= XDP_FLAGS_DRV_MODE;
550
+
534551 /* Required option */
535552 if (ifindex == -1) {
536553 fprintf(stderr, "ERR: required option --dev missing\n");
....@@ -576,6 +593,13 @@
576593 return EXIT_FAIL_XDP;
577594 }
578595
596
+ err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
597
+ if (err) {
598
+ printf("can't get prog info - %s\n", strerror(errno));
599
+ return err;
600
+ }
601
+ prog_id = info.id;
602
+
579603 stats_poll(interval, action, cfg_options);
580604 return EXIT_OK;
581605 }