mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-18 11:17:07 +00:00
Merge branch 'bpf-xdp-fwd-sample-improvements'
Jesper Dangaard Brouer says: ==================== V3: Hopefully fixed all issues point out by Yonghong Song V2: Addressed issues point out by Yonghong Song - Please ACK patch 2/3 again - Added ACKs and reviewed-by to other patches This patchset is focused on improvements for XDP forwarding sample named xdp_fwd, which leverage the existing FIB routing tables as described in LPC2018[1] talk by David Ahern. The primary motivation is to illustrate how Toke's recent work improves usability of XDP_REDIRECT via lookups in devmap. The other patches are to help users understand the sample. I have more improvements to xdp_fwd, but those might requires changes to libbpf. Thus, sending these patches first as they are isolated. [1] http://vger.kernel.org/lpc-networking2018.html#session-1 ==================== Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
This commit is contained in:
commit
9f30cd568b
@ -23,7 +23,8 @@
|
|||||||
|
|
||||||
#define IPV6_FLOWINFO_MASK cpu_to_be32(0x0FFFFFFF)
|
#define IPV6_FLOWINFO_MASK cpu_to_be32(0x0FFFFFFF)
|
||||||
|
|
||||||
struct bpf_map_def SEC("maps") tx_port = {
|
/* For TX-traffic redirect requires net_device ifindex to be in this devmap */
|
||||||
|
struct bpf_map_def SEC("maps") xdp_tx_ports = {
|
||||||
.type = BPF_MAP_TYPE_DEVMAP,
|
.type = BPF_MAP_TYPE_DEVMAP,
|
||||||
.key_size = sizeof(int),
|
.key_size = sizeof(int),
|
||||||
.value_size = sizeof(int),
|
.value_size = sizeof(int),
|
||||||
@ -102,14 +103,34 @@ static __always_inline int xdp_fwd_flags(struct xdp_md *ctx, u32 flags)
|
|||||||
fib_params.ifindex = ctx->ingress_ifindex;
|
fib_params.ifindex = ctx->ingress_ifindex;
|
||||||
|
|
||||||
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
|
* Some rc (return codes) from bpf_fib_lookup() are important,
|
||||||
* TO-DO bpf_map_lookup_elem(&tx_port, &key) fails with
|
* to understand how this XDP-prog interacts with network stack.
|
||||||
* cannot pass map_type 14 into func bpf_map_lookup_elem#1:
|
*
|
||||||
* NOTE: without verification that egress index supports XDP
|
* BPF_FIB_LKUP_RET_NO_NEIGH:
|
||||||
* forwarding packets are dropped.
|
* Even if route lookup was a success, then the MAC-addresses are also
|
||||||
|
* needed. This is obtained from arp/neighbour table, but if table is
|
||||||
|
* (still) empty then BPF_FIB_LKUP_RET_NO_NEIGH is returned. To avoid
|
||||||
|
* doing ARP lookup directly from XDP, then send packet to normal
|
||||||
|
* network stack via XDP_PASS and expect it will do ARP resolution.
|
||||||
|
*
|
||||||
|
* BPF_FIB_LKUP_RET_FWD_DISABLED:
|
||||||
|
* The bpf_fib_lookup respect sysctl net.ipv{4,6}.conf.all.forwarding
|
||||||
|
* setting, and will return BPF_FIB_LKUP_RET_FWD_DISABLED if not
|
||||||
|
* enabled this on ingress device.
|
||||||
*/
|
*/
|
||||||
if (rc == 0) {
|
if (rc == BPF_FIB_LKUP_RET_SUCCESS) {
|
||||||
|
/* 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))
|
||||||
@ -117,7 +138,7 @@ static __always_inline int xdp_fwd_flags(struct xdp_md *ctx, u32 flags)
|
|||||||
|
|
||||||
memcpy(eth->h_dest, fib_params.dmac, ETH_ALEN);
|
memcpy(eth->h_dest, fib_params.dmac, ETH_ALEN);
|
||||||
memcpy(eth->h_source, fib_params.smac, ETH_ALEN);
|
memcpy(eth->h_source, fib_params.smac, ETH_ALEN);
|
||||||
return bpf_redirect_map(&tx_port, fib_params.ifindex, 0);
|
return bpf_redirect_map(&xdp_tx_ports, fib_params.ifindex, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return XDP_PASS;
|
return XDP_PASS;
|
||||||
|
@ -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)
|
|||||||
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)
|
|||||||
};
|
};
|
||||||
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)
|
|||||||
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);
|
||||||
@ -113,16 +128,12 @@ int main(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
map_fd = bpf_map__fd(bpf_object__find_map_by_name(obj,
|
map_fd = bpf_map__fd(bpf_object__find_map_by_name(obj,
|
||||||
"tx_port"));
|
"xdp_tx_ports"));
|
||||||
if (map_fd < 0) {
|
if (map_fd < 0) {
|
||||||
printf("map not found: %s\n", strerror(map_fd));
|
printf("map not found: %s\n", strerror(map_fd));
|
||||||
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)
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user