| .. | .. |
|---|
| 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 | } |
|---|