Skip to content

Commit

Permalink
xdp-forward: splict fwd-mode in fib-mode and fwd-mode
Browse files Browse the repository at this point in the history
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  • Loading branch information
LorenzoBianconi committed Oct 2, 2024
1 parent 590ccb2 commit d3e5563
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 41 deletions.
36 changes: 25 additions & 11 deletions xdp-forward/README.org
Original file line number Diff line number Diff line change
Expand Up @@ -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 <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 <mode>
Specifies which mode to load the XDP program to be loaded in. The valid values
Expand Down Expand Up @@ -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
Expand All @@ -115,19 +119,29 @@ 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.
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
Expand Down
4 changes: 2 additions & 2 deletions xdp-forward/tests/test-xdp-forward.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,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
Expand All @@ -42,7 +42,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
Expand Down
41 changes: 29 additions & 12 deletions xdp-forward/xdp-forward.8
Original file line number Diff line number Diff line change
Expand Up @@ -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 <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 <mode>"
.PP
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
39 changes: 26 additions & 13 deletions xdp-forward/xdp-forward.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 = "<mode>",
.help = "Forward mode to run in; see man page. Default fib-full"),
.metavar = "<fwd-mode>",
.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 = "<fib-mode>",
.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,
Expand Down Expand Up @@ -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;
Expand Down
18 changes: 15 additions & 3 deletions xdp-forward/xdp_flowtable.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -471,8 +471,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;
Expand Down Expand Up @@ -578,7 +578,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;

Expand All @@ -595,4 +595,16 @@ int xdp_fwd_flowtable(struct xdp_md *ctx)
return bpf_redirect(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";

0 comments on commit d3e5563

Please sign in to comment.