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