.. | .. |
---|
22 | 22 | #include <arpa/inet.h> |
---|
23 | 23 | #include <linux/if_link.h> |
---|
24 | 24 | |
---|
25 | | -#include "bpf/bpf.h" |
---|
26 | | -#include "bpf/libbpf.h" |
---|
| 25 | +#include <bpf/bpf.h> |
---|
| 26 | +#include <bpf/libbpf.h> |
---|
27 | 27 | #include "bpf_util.h" |
---|
28 | 28 | |
---|
29 | 29 | static int ifindex = -1; |
---|
30 | 30 | static char ifname_buf[IF_NAMESIZE]; |
---|
31 | 31 | static char *ifname; |
---|
| 32 | +static __u32 prog_id; |
---|
32 | 33 | |
---|
33 | | -static __u32 xdp_flags; |
---|
| 34 | +static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST; |
---|
34 | 35 | |
---|
35 | 36 | static struct bpf_map *stats_global_map; |
---|
36 | 37 | static struct bpf_map *rx_queue_index_map; |
---|
.. | .. |
---|
50 | 51 | {"sec", required_argument, NULL, 's' }, |
---|
51 | 52 | {"no-separators", no_argument, NULL, 'z' }, |
---|
52 | 53 | {"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' }, |
---|
55 | 57 | {0, 0, NULL, 0 } |
---|
56 | 58 | }; |
---|
57 | 59 | |
---|
58 | 60 | static void int_exit(int sig) |
---|
59 | 61 | { |
---|
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 | + } |
---|
65 | 80 | exit(EXIT_OK); |
---|
66 | 81 | } |
---|
67 | 82 | |
---|
.. | .. |
---|
183 | 198 | { |
---|
184 | 199 | unsigned int nr_cpus = bpf_num_possible_cpus(); |
---|
185 | 200 | struct datarec *array; |
---|
186 | | - size_t size; |
---|
187 | 201 | |
---|
188 | | - size = sizeof(struct datarec) * nr_cpus; |
---|
189 | | - array = malloc(size); |
---|
190 | | - memset(array, 0, size); |
---|
| 202 | + array = calloc(nr_cpus, sizeof(struct datarec)); |
---|
191 | 203 | if (!array) { |
---|
192 | 204 | fprintf(stderr, "Mem alloc error (nr_cpus:%u)\n", nr_cpus); |
---|
193 | 205 | exit(EXIT_FAIL_MEM); |
---|
.. | .. |
---|
199 | 211 | { |
---|
200 | 212 | unsigned int nr_rxqs = bpf_map__def(rx_queue_index_map)->max_entries; |
---|
201 | 213 | struct record *array; |
---|
202 | | - size_t size; |
---|
203 | 214 | |
---|
204 | | - size = sizeof(struct record) * nr_rxqs; |
---|
205 | | - array = malloc(size); |
---|
206 | | - memset(array, 0, size); |
---|
| 215 | + array = calloc(nr_rxqs, sizeof(struct record)); |
---|
207 | 216 | if (!array) { |
---|
208 | 217 | fprintf(stderr, "Mem alloc error (nr_rxqs:%u)\n", nr_rxqs); |
---|
209 | 218 | exit(EXIT_FAIL_MEM); |
---|
.. | .. |
---|
217 | 226 | struct stats_record *rec; |
---|
218 | 227 | int i; |
---|
219 | 228 | |
---|
220 | | - rec = malloc(sizeof(*rec)); |
---|
221 | | - memset(rec, 0, sizeof(*rec)); |
---|
| 229 | + rec = calloc(1, sizeof(struct stats_record)); |
---|
222 | 230 | if (!rec) { |
---|
223 | 231 | fprintf(stderr, "Mem alloc error\n"); |
---|
224 | 232 | exit(EXIT_FAIL_MEM); |
---|
.. | .. |
---|
442 | 450 | int main(int argc, char **argv) |
---|
443 | 451 | { |
---|
444 | 452 | __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}; |
---|
446 | 454 | struct bpf_prog_load_attr prog_load_attr = { |
---|
447 | 455 | .prog_type = BPF_PROG_TYPE_XDP, |
---|
448 | 456 | }; |
---|
| 457 | + struct bpf_prog_info info = {}; |
---|
| 458 | + __u32 info_len = sizeof(info); |
---|
449 | 459 | int prog_fd, map_fd, opt, err; |
---|
450 | 460 | bool use_separators = true; |
---|
451 | 461 | struct config cfg = { 0 }; |
---|
.. | .. |
---|
482 | 492 | map_fd = bpf_map__fd(map); |
---|
483 | 493 | |
---|
484 | 494 | 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)); |
---|
486 | 496 | return EXIT_FAIL; |
---|
487 | 497 | } |
---|
488 | 498 | |
---|
489 | 499 | /* Parse commands line args */ |
---|
490 | | - while ((opt = getopt_long(argc, argv, "hSd:", |
---|
| 500 | + while ((opt = getopt_long(argc, argv, "FhSrmzd:s:a:", |
---|
491 | 501 | long_options, &longindex)) != -1) { |
---|
492 | 502 | switch (opt) { |
---|
493 | 503 | case 'd': |
---|
.. | .. |
---|
524 | 534 | case 'm': |
---|
525 | 535 | cfg_options |= SWAP_MAC; |
---|
526 | 536 | break; |
---|
| 537 | + case 'F': |
---|
| 538 | + xdp_flags &= ~XDP_FLAGS_UPDATE_IF_NOEXIST; |
---|
| 539 | + break; |
---|
527 | 540 | case 'h': |
---|
528 | 541 | error: |
---|
529 | 542 | default: |
---|
.. | .. |
---|
531 | 544 | return EXIT_FAIL_OPTION; |
---|
532 | 545 | } |
---|
533 | 546 | } |
---|
| 547 | + |
---|
| 548 | + if (!(xdp_flags & XDP_FLAGS_SKB_MODE)) |
---|
| 549 | + xdp_flags |= XDP_FLAGS_DRV_MODE; |
---|
| 550 | + |
---|
534 | 551 | /* Required option */ |
---|
535 | 552 | if (ifindex == -1) { |
---|
536 | 553 | fprintf(stderr, "ERR: required option --dev missing\n"); |
---|
.. | .. |
---|
576 | 593 | return EXIT_FAIL_XDP; |
---|
577 | 594 | } |
---|
578 | 595 | |
---|
| 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 | + |
---|
579 | 603 | stats_poll(interval, action, cfg_options); |
---|
580 | 604 | return EXIT_OK; |
---|
581 | 605 | } |
---|