From c808801b3b7061b42ed44d9a3f10ef4e96b8ecb3 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Wed, 2 Oct 2024 16:21:40 +0200 Subject: [PATCH] xdp-forward: splict fwd-mode in fib-mode and fwd-mode Signed-off-by: Lorenzo Bianconi --- xdp-forward/README.org | 36 ++++++++++++++++------- xdp-forward/tests/test-xdp-forward.sh | 4 +-- xdp-forward/xdp-forward.8 | 41 +++++++++++++++++++-------- xdp-forward/xdp-forward.c | 39 ++++++++++++++++--------- xdp-forward/xdp_flowtable.bpf.c | 18 ++++++++++-- 5 files changed, 97 insertions(+), 41 deletions(-) diff --git a/xdp-forward/README.org b/xdp-forward/README.org index bb2dfff8..ab30906b 100644 --- a/xdp-forward/README.org +++ b/xdp-forward/README.org @@ -56,7 +56,11 @@ Specifies which forwarding mode =xdp-forward= should operate in. Depending on the mode selected, =xdp-forward= will perform forwarding in different ways, which can lead to different behaviour, including which subset of kernel configuration (such as firewall rules) is respected during forwarding. See the -section *OPERATING MODES* below for a full description of each mode. +section *FORWARDING MODES* below for a full description of each mode. + +** -F, --fib-mode +Specifies how =xdp-forward= performs routing table lookup in the linux kernel. +See the section *FIB MODES* below for a full description of each mode. ** -m, --mode Specifies which mode to load the XDP program to be loaded in. The valid values @@ -98,12 +102,12 @@ Enable debug logging. Specify twice for even more verbosity. ** -h, --help Display a summary of the available options -* OPERATING MODES -The =xdp-forward= utility supports the following operating modes (selected by +* FORWARDING MODES +The =xdp-forward= utility supports the following forwarding modes (selected by the =--fwd-mode= parameter to =xdp-forward load=. -** fib-full (default) -In the =fib-full= operating mode, =xdp-forward= will perform a full lookup in +** fib (default) +In the =fib= forwarding mode, =xdp-forward= will perform a lookup in the kernel routing table (or FIB) for each packet, and forward packets between the configured interfaces based on the result of the lookup. Any packet where the lookup fails will be passed up to the stack. This includes packets that @@ -115,12 +119,6 @@ Note that no checks other than the FIB lookup is performed; in particular, this completely bypasses the netfilter subsystem, so firewall rules will not be checked before forwarding. -** fib-direct -The =fib-direct= mode functions like =fib-full=, except it passes the -=BPF_FIB_LOOKUP_DIRECT= flag to the FIB lookup routine. This means that any -policy routing rules configured will be skipped during the lookup, which can -improve performance (but won't obey the policy of those rules, obviously). - ** flowtable The =flowtable= operating mode offloads netfilter sw flowtable logic in the XDP layer if the hardware flowtable is not available. @@ -128,6 +126,22 @@ At the moment =xdp-forward= is able to offload just TCP or UDP netfilter flowtable entries to XDP. The user is supposed to configure the flowtable separately. +* FIB MODES +The =xdp-forward= utility supports the following fib modes (selected by +the =--fib-mode= parameter to =xdp-forward load=. + +** full (default) +In the =full= operating mode, =xdp-forward= will perform a full lookup in +the kernel routing table (or FIB) for each packet, and forward packets between +the configured interfaces based on the result of the lookup. In particular, +it will apply any policy routing rules configured by the user. + +** direct +The =direct= mode functions like =full=, except it passes the +=BPF_FIB_LOOKUP_DIRECT= flag to the FIB lookup routine. This means that any +policy routing rules configured will be skipped during the lookup, which can +improve performance (but won't obey the policy of those rules, obviously). + * Examples In order to enable flowtable offloading for tcp and udp traffic between NICs diff --git a/xdp-forward/tests/test-xdp-forward.sh b/xdp-forward/tests/test-xdp-forward.sh index f3a4b080..68fe0a0a 100644 --- a/xdp-forward/tests/test-xdp-forward.sh +++ b/xdp-forward/tests/test-xdp-forward.sh @@ -26,7 +26,7 @@ test_fwd_full() # veth NAPI GRO support added this symbol; forwarding won't work without it skip_if_missing_kernel_symbol veth_set_features - check_run $XDP_FORWARD load -f fib-full ${NS_NAMES[@]} + check_run $XDP_FORWARD load -f fib -F full ${NS_NAMES[@]} for ip in "${ALL_INSIDE_IP4[@]}"; do check_run ns_exec ping -c 1 -W 2 $ip done @@ -41,7 +41,7 @@ test_fwd_direct() # veth NAPI GRO support added this symbol; forwarding won't work without it skip_if_missing_kernel_symbol veth_set_features - check_run $XDP_FORWARD load -f fib-direct ${NS_NAMES[@]} + check_run $XDP_FORWARD load -f fib -F direct ${NS_NAMES[@]} for ip in "${ALL_INSIDE_IP4[@]}"; do check_run ns_exec ping -c 1 -W 2 $ip done diff --git a/xdp-forward/xdp-forward.8 b/xdp-forward/xdp-forward.8 index 64ec2de6..3c8f7804 100644 --- a/xdp-forward/xdp-forward.8 +++ b/xdp-forward/xdp-forward.8 @@ -62,7 +62,12 @@ Specifies which forwarding mode \fIxdp\-forward\fP should operate in. Depending the mode selected, \fIxdp\-forward\fP will perform forwarding in different ways, which can lead to different behaviour, including which subset of kernel configuration (such as firewall rules) is respected during forwarding. See the -section \fBOPERATING MODES\fP below for a full description of each mode. +section \fBFORWARDING MODES\fP below for a full description of each mode. + +.SS "-F, --fib-mode " +.PP +Specifies how \fIxdp\-forward\fP performs routing table lookup in the linux kernel. +See the section \fBFIB MODES\fP below for a full description of each mode. .SS "-m, --mode " .PP @@ -114,14 +119,14 @@ Enable debug logging. Specify twice for even more verbosity. .PP Display a summary of the available options -.SH "OPERATING MODES" +.SH "FORWARDING MODES" .PP -The \fIxdp\-forward\fP utility supports the following operating modes (selected by +The \fIxdp\-forward\fP utility supports the following forwarding modes (selected by the \fI\-\-fwd\-mode\fP parameter to \fIxdp\-forward load\fP. -.SS "fib-full (default)" +.SS "fib (default)" .PP -In the \fIfib\-full\fP operating mode, \fIxdp\-forward\fP will perform a full lookup in +In the \fIfib\fP forwarding mode, \fIxdp\-forward\fP will perform a lookup in the kernel routing table (or FIB) for each packet, and forward packets between the configured interfaces based on the result of the lookup. Any packet where the lookup fails will be passed up to the stack. This includes packets that @@ -134,13 +139,6 @@ Note that no checks other than the FIB lookup is performed; in particular, this completely bypasses the netfilter subsystem, so firewall rules will not be checked before forwarding. -.SS "fib-direct" -.PP -The \fIfib\-direct\fP mode functions like \fIfib\-full\fP, except it passes the -\fIBPF_FIB_LOOKUP_DIRECT\fP flag to the FIB lookup routine. This means that any -policy routing rules configured will be skipped during the lookup, which can -improve performance (but won't obey the policy of those rules, obviously). - .SS "flowtable" .PP The \fIflowtable\fP operating mode offloads netfilter sw flowtable logic in @@ -149,6 +147,25 @@ At the moment \fIxdp\-forward\fP is able to offload just TCP or UDP netfilter flowtable entries to XDP. The user is supposed to configure the flowtable separately. +.SH "FIB MODES" +.PP +The \fIxdp\-forward\fP utility supports the following fib modes (selected by +the \fI\-\-fib\-mode\fP parameter to \fIxdp\-forward load\fP. + +.SS "full (default)" +.PP +In the \fIfull\fP operating mode, \fIxdp\-forward\fP will perform a full lookup in +the kernel routing table (or FIB) for each packet, and forward packets between +the configured interfaces based on the result of the lookup. In particular, +it will apply any policy routing rules configured by the user. + +.SS "direct" +.PP +The \fIdirect\fP mode functions like \fIfull\fP, except it passes the +\fIBPF_FIB_LOOKUP_DIRECT\fP flag to the FIB lookup routine. This means that any +policy routing rules configured will be skipped during the lookup, which can +improve performance (but won't obey the policy of those rules, obviously). + .SH "Examples" .PP In order to enable flowtable offloading for tcp and udp traffic between NICs diff --git a/xdp-forward/xdp-forward.c b/xdp-forward/xdp-forward.c index c44e5c66..5549e6f4 100644 --- a/xdp-forward/xdp-forward.c +++ b/xdp-forward/xdp-forward.c @@ -37,16 +37,23 @@ struct enum_val xdp_modes[] = { { "native", XDP_MODE_NATIVE }, { NULL, 0 } }; enum fwd_mode { - FWD_FIB_DIRECT, - FWD_FIB_FULL, + FWD_FIB, FWD_FLOWTABLE, }; -struct enum_val fwd_modes[] = { { "fib-direct", FWD_FIB_DIRECT }, - { "fib-full", FWD_FIB_FULL }, +struct enum_val fwd_modes[] = { { "fib", FWD_FIB }, { "flowtable", FWD_FLOWTABLE }, { NULL, 0 } }; +enum fib_mode { + FIB_DIRECT, + FIB_FULL, +}; + +struct enum_val fib_modes[] = { { "direct", FIB_DIRECT }, + { "full", FIB_FULL }, + { NULL, 0 } }; + static int find_prog(struct iface *iface, bool detach) { struct xdp_program *prog = NULL; @@ -88,16 +95,22 @@ static int find_prog(struct iface *iface, bool detach) struct load_opts { enum fwd_mode fwd_mode; + enum fib_mode fib_mode; enum xdp_attach_mode xdp_mode; struct iface *ifaces; -} defaults_load = { .fwd_mode = FWD_FIB_FULL }; +} defaults_load = { .fwd_mode = FWD_FIB, .fib_mode = FIB_FULL, }; struct prog_option load_options[] = { DEFINE_OPTION("fwd-mode", OPT_ENUM, struct load_opts, fwd_mode, .short_opt = 'f', .typearg = fwd_modes, - .metavar = "", - .help = "Forward mode to run in; see man page. Default fib-full"), + .metavar = "", + .help = "Forward mode to run in; see man page. Default fib"), + DEFINE_OPTION("fib-mode", OPT_ENUM, struct load_opts, fib_mode, + .short_opt = 'F', + .typearg = fib_modes, + .metavar = "", + .help = "Fib mode to run in; see man page. Default full"), DEFINE_OPTION("xdp-mode", OPT_ENUM, struct load_opts, xdp_mode, .short_opt = 'm', .typearg = xdp_modes, @@ -138,14 +151,14 @@ static int do_load(const void *cfg, __unused const char *pin_root_path) void *skel; switch (opt->fwd_mode) { - case FWD_FIB_FULL: - opts.prog_name = "xdp_fwd_fib_full"; - break; - case FWD_FIB_DIRECT: - opts.prog_name = "xdp_fwd_fib_direct"; + case FWD_FIB: + opts.prog_name = opt->fib_mode == FIB_DIRECT + ? "xdp_fwd_fib_direct" : "xdp_fwd_fib_full"; break; case FWD_FLOWTABLE: - opts.prog_name = "xdp_fwd_flowtable"; + opts.prog_name = opt->fib_mode == FIB_DIRECT + ? "xdp_fwd_flowtable_direct" + : "xdp_fwd_flowtable_full"; break; default: goto end; diff --git a/xdp-forward/xdp_flowtable.bpf.c b/xdp-forward/xdp_flowtable.bpf.c index 32f627d7..192c50b6 100644 --- a/xdp-forward/xdp_flowtable.bpf.c +++ b/xdp-forward/xdp_flowtable.bpf.c @@ -478,8 +478,8 @@ xdp_flowtable_forward_ipv6(const struct flow_offload *flow, void *data, ip6h->hop_limit--; } -SEC("xdp") -int xdp_fwd_flowtable(struct xdp_md *ctx) +static __always_inline int xdp_flowtable_flags(struct xdp_md *ctx, + __u32 fib_flags) { void *data_end = (void *)(long)ctx->data_end; struct flow_offload_tuple_rhash *tuplehash; @@ -585,7 +585,7 @@ int xdp_fwd_flowtable(struct xdp_md *ctx) xdp_flowtable_get_dnat_ip(&tuple.ipv4_dst, flow, dir); } - if (bpf_fib_lookup(ctx, &tuple, sizeof(tuple), 0) != + if (bpf_fib_lookup(ctx, &tuple, sizeof(tuple), fib_flags) != BPF_FIB_LKUP_RET_SUCCESS) return XDP_PASS; @@ -606,4 +606,16 @@ int xdp_fwd_flowtable(struct xdp_md *ctx) return bpf_redirect_map(&xdp_tx_ports, tuple.ifindex, 0); } +SEC("xdp") +int xdp_fwd_flowtable_full(struct xdp_md *ctx) +{ + return xdp_flowtable_flags(ctx, 0); +} + +SEC("xdp") +int xdp_fwd_flowtable_direct(struct xdp_md *ctx) +{ + return xdp_flowtable_flags(ctx, BPF_FIB_LOOKUP_DIRECT); +} + char _license[] SEC("license") = "GPL";