Commit a32a32cb authored by Jesper Dangaard Brouer's avatar Jesper Dangaard Brouer Committed by Daniel Borkmann

samples/bpf: make xdp_fwd more practically usable via devmap lookup

This address the TODO in samples/bpf/xdp_fwd_kern.c, which points out
that the chosen egress index should be checked for existence in the
devmap. This can now be done via taking advantage of Toke's work in
commit 0cdbb4b0 ("devmap: Allow map lookups from eBPF").

This change makes xdp_fwd more practically usable, as this allows for
a mixed environment, where IP-forwarding fallback to network stack, if
the egress device isn't configured to use XDP.
Signed-off-by: default avatarJesper Dangaard Brouer <brouer@redhat.com>
Reviewed-by: default avatarDavid Ahern <dsahern@gmail.com>
Reviewed-by: default avatarToke Høiland-Jørgensen <toke@redhat.com>
Acked-by: default avatarYonghong Song <yhs@fb.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
parent 3783d437
...@@ -104,13 +104,18 @@ static __always_inline int xdp_fwd_flags(struct xdp_md *ctx, u32 flags) ...@@ -104,13 +104,18 @@ static __always_inline int xdp_fwd_flags(struct xdp_md *ctx, u32 flags)
rc = bpf_fib_lookup(ctx, &fib_params, sizeof(fib_params), flags); rc = bpf_fib_lookup(ctx, &fib_params, sizeof(fib_params), flags);
/* verify egress index has xdp support
* TO-DO bpf_map_lookup_elem(&tx_port, &key) fails with
* cannot pass map_type 14 into func bpf_map_lookup_elem#1:
* NOTE: without verification that egress index supports XDP
* forwarding packets are dropped.
*/
if (rc == 0) { if (rc == 0) {
/* Verify egress index has been configured as TX-port.
* (Note: User can still have inserted an egress ifindex that
* doesn't support XDP xmit, which will result in packet drops).
*
* Note: lookup in devmap supported since 0cdbb4b09a0.
* If not supported will fail with:
* cannot pass map_type 14 into func bpf_map_lookup_elem#1:
*/
if (!bpf_map_lookup_elem(&xdp_tx_ports, &fib_params.ifindex))
return XDP_PASS;
if (h_proto == htons(ETH_P_IP)) if (h_proto == htons(ETH_P_IP))
ip_decrease_ttl(iph); ip_decrease_ttl(iph);
else if (h_proto == htons(ETH_P_IPV6)) else if (h_proto == htons(ETH_P_IPV6))
......
...@@ -27,14 +27,20 @@ ...@@ -27,14 +27,20 @@
#include "libbpf.h" #include "libbpf.h"
#include <bpf/bpf.h> #include <bpf/bpf.h>
static int do_attach(int idx, int prog_fd, int map_fd, const char *name)
static int do_attach(int idx, int fd, const char *name)
{ {
int err; int err;
err = bpf_set_link_xdp_fd(idx, fd, 0); err = bpf_set_link_xdp_fd(idx, prog_fd, 0);
if (err < 0) if (err < 0) {
printf("ERROR: failed to attach program to %s\n", name); printf("ERROR: failed to attach program to %s\n", name);
return err;
}
/* Adding ifindex as a possible egress TX port */
err = bpf_map_update_elem(map_fd, &idx, &idx, 0);
if (err)
printf("ERROR: failed using device %s as TX-port\n", name);
return err; return err;
} }
...@@ -47,6 +53,9 @@ static int do_detach(int idx, const char *name) ...@@ -47,6 +53,9 @@ static int do_detach(int idx, const char *name)
if (err < 0) if (err < 0)
printf("ERROR: failed to detach program from %s\n", name); printf("ERROR: failed to detach program from %s\n", name);
/* TODO: Remember to cleanup map, when adding use of shared map
* bpf_map_delete_elem((map_fd, &idx);
*/
return err; return err;
} }
...@@ -67,10 +76,10 @@ int main(int argc, char **argv) ...@@ -67,10 +76,10 @@ int main(int argc, char **argv)
}; };
const char *prog_name = "xdp_fwd"; const char *prog_name = "xdp_fwd";
struct bpf_program *prog; struct bpf_program *prog;
int prog_fd, map_fd = -1;
char filename[PATH_MAX]; char filename[PATH_MAX];
struct bpf_object *obj; struct bpf_object *obj;
int opt, i, idx, err; int opt, i, idx, err;
int prog_fd, map_fd;
int attach = 1; int attach = 1;
int ret = 0; int ret = 0;
...@@ -103,8 +112,14 @@ int main(int argc, char **argv) ...@@ -103,8 +112,14 @@ int main(int argc, char **argv)
return 1; return 1;
} }
if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd)) err = bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd);
if (err) {
printf("Does kernel support devmap lookup?\n");
/* If not, the error message will be:
* "cannot pass map_type 14 into func bpf_map_lookup_elem#1"
*/
return 1; return 1;
}
prog = bpf_object__find_program_by_title(obj, prog_name); prog = bpf_object__find_program_by_title(obj, prog_name);
prog_fd = bpf_program__fd(prog); prog_fd = bpf_program__fd(prog);
...@@ -119,10 +134,6 @@ int main(int argc, char **argv) ...@@ -119,10 +134,6 @@ int main(int argc, char **argv)
return 1; return 1;
} }
} }
if (attach) {
for (i = 1; i < 64; ++i)
bpf_map_update_elem(map_fd, &i, &i, 0);
}
for (i = optind; i < argc; ++i) { for (i = optind; i < argc; ++i) {
idx = if_nametoindex(argv[i]); idx = if_nametoindex(argv[i]);
...@@ -138,7 +149,7 @@ int main(int argc, char **argv) ...@@ -138,7 +149,7 @@ int main(int argc, char **argv)
if (err) if (err)
ret = err; ret = err;
} else { } else {
err = do_attach(idx, prog_fd, argv[i]); err = do_attach(idx, prog_fd, map_fd, argv[i]);
if (err) if (err)
ret = err; ret = err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment