| .. | .. |
|---|
| 24 | 24 | #include <fcntl.h> |
|---|
| 25 | 25 | #include <libgen.h> |
|---|
| 26 | 26 | |
|---|
| 27 | | -#include "bpf/libbpf.h" |
|---|
| 27 | +#include <bpf/libbpf.h> |
|---|
| 28 | 28 | #include <bpf/bpf.h> |
|---|
| 29 | 29 | |
|---|
| 30 | +static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST; |
|---|
| 30 | 31 | |
|---|
| 31 | | -static int do_attach(int idx, int fd, const char *name) |
|---|
| 32 | +static int do_attach(int idx, int prog_fd, int map_fd, const char *name) |
|---|
| 32 | 33 | { |
|---|
| 33 | 34 | int err; |
|---|
| 34 | 35 | |
|---|
| 35 | | - err = bpf_set_link_xdp_fd(idx, fd, 0); |
|---|
| 36 | | - if (err < 0) |
|---|
| 36 | + err = bpf_set_link_xdp_fd(idx, prog_fd, xdp_flags); |
|---|
| 37 | + if (err < 0) { |
|---|
| 37 | 38 | printf("ERROR: failed to attach program to %s\n", name); |
|---|
| 39 | + return err; |
|---|
| 40 | + } |
|---|
| 41 | + |
|---|
| 42 | + /* Adding ifindex as a possible egress TX port */ |
|---|
| 43 | + err = bpf_map_update_elem(map_fd, &idx, &idx, 0); |
|---|
| 44 | + if (err) |
|---|
| 45 | + printf("ERROR: failed using device %s as TX-port\n", name); |
|---|
| 38 | 46 | |
|---|
| 39 | 47 | return err; |
|---|
| 40 | 48 | } |
|---|
| .. | .. |
|---|
| 43 | 51 | { |
|---|
| 44 | 52 | int err; |
|---|
| 45 | 53 | |
|---|
| 46 | | - err = bpf_set_link_xdp_fd(idx, -1, 0); |
|---|
| 54 | + err = bpf_set_link_xdp_fd(idx, -1, xdp_flags); |
|---|
| 47 | 55 | if (err < 0) |
|---|
| 48 | 56 | printf("ERROR: failed to detach program from %s\n", name); |
|---|
| 49 | 57 | |
|---|
| 58 | + /* TODO: Remember to cleanup map, when adding use of shared map |
|---|
| 59 | + * bpf_map_delete_elem((map_fd, &idx); |
|---|
| 60 | + */ |
|---|
| 50 | 61 | return err; |
|---|
| 51 | 62 | } |
|---|
| 52 | 63 | |
|---|
| .. | .. |
|---|
| 67 | 78 | }; |
|---|
| 68 | 79 | const char *prog_name = "xdp_fwd"; |
|---|
| 69 | 80 | struct bpf_program *prog; |
|---|
| 81 | + int prog_fd, map_fd = -1; |
|---|
| 70 | 82 | char filename[PATH_MAX]; |
|---|
| 71 | 83 | struct bpf_object *obj; |
|---|
| 72 | 84 | int opt, i, idx, err; |
|---|
| 73 | | - int prog_fd, map_fd; |
|---|
| 74 | 85 | int attach = 1; |
|---|
| 75 | 86 | int ret = 0; |
|---|
| 76 | 87 | |
|---|
| 77 | | - while ((opt = getopt(argc, argv, ":dD")) != -1) { |
|---|
| 88 | + while ((opt = getopt(argc, argv, ":dDSF")) != -1) { |
|---|
| 78 | 89 | switch (opt) { |
|---|
| 79 | 90 | case 'd': |
|---|
| 80 | 91 | attach = 0; |
|---|
| 92 | + break; |
|---|
| 93 | + case 'S': |
|---|
| 94 | + xdp_flags |= XDP_FLAGS_SKB_MODE; |
|---|
| 95 | + break; |
|---|
| 96 | + case 'F': |
|---|
| 97 | + xdp_flags &= ~XDP_FLAGS_UPDATE_IF_NOEXIST; |
|---|
| 81 | 98 | break; |
|---|
| 82 | 99 | case 'D': |
|---|
| 83 | 100 | prog_name = "xdp_fwd_direct"; |
|---|
| .. | .. |
|---|
| 87 | 104 | return 1; |
|---|
| 88 | 105 | } |
|---|
| 89 | 106 | } |
|---|
| 107 | + |
|---|
| 108 | + if (!(xdp_flags & XDP_FLAGS_SKB_MODE)) |
|---|
| 109 | + xdp_flags |= XDP_FLAGS_DRV_MODE; |
|---|
| 90 | 110 | |
|---|
| 91 | 111 | if (optind == argc) { |
|---|
| 92 | 112 | usage(basename(argv[0])); |
|---|
| .. | .. |
|---|
| 103 | 123 | return 1; |
|---|
| 104 | 124 | } |
|---|
| 105 | 125 | |
|---|
| 106 | | - if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd)) |
|---|
| 126 | + err = bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd); |
|---|
| 127 | + if (err) { |
|---|
| 128 | + printf("Does kernel support devmap lookup?\n"); |
|---|
| 129 | + /* If not, the error message will be: |
|---|
| 130 | + * "cannot pass map_type 14 into func bpf_map_lookup_elem#1" |
|---|
| 131 | + */ |
|---|
| 107 | 132 | return 1; |
|---|
| 133 | + } |
|---|
| 108 | 134 | |
|---|
| 109 | 135 | prog = bpf_object__find_program_by_title(obj, prog_name); |
|---|
| 110 | 136 | prog_fd = bpf_program__fd(prog); |
|---|
| .. | .. |
|---|
| 113 | 139 | return 1; |
|---|
| 114 | 140 | } |
|---|
| 115 | 141 | map_fd = bpf_map__fd(bpf_object__find_map_by_name(obj, |
|---|
| 116 | | - "tx_port")); |
|---|
| 142 | + "xdp_tx_ports")); |
|---|
| 117 | 143 | if (map_fd < 0) { |
|---|
| 118 | 144 | printf("map not found: %s\n", strerror(map_fd)); |
|---|
| 119 | 145 | return 1; |
|---|
| 120 | 146 | } |
|---|
| 121 | | - } |
|---|
| 122 | | - if (attach) { |
|---|
| 123 | | - for (i = 1; i < 64; ++i) |
|---|
| 124 | | - bpf_map_update_elem(map_fd, &i, &i, 0); |
|---|
| 125 | 147 | } |
|---|
| 126 | 148 | |
|---|
| 127 | 149 | for (i = optind; i < argc; ++i) { |
|---|
| .. | .. |
|---|
| 138 | 160 | if (err) |
|---|
| 139 | 161 | ret = err; |
|---|
| 140 | 162 | } else { |
|---|
| 141 | | - err = do_attach(idx, prog_fd, argv[i]); |
|---|
| 163 | + err = do_attach(idx, prog_fd, map_fd, argv[i]); |
|---|
| 142 | 164 | if (err) |
|---|
| 143 | 165 | ret = err; |
|---|
| 144 | 166 | } |
|---|