Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ include config.mk
UTILS := xdp-filter xdp-loader xdp-dump

ifneq ($(BPFTOOL),)
UTILS += xdp-bench xdp-monitor xdp-trafficgen
UTILS += xdp-bench xdp-forward xdp-monitor xdp-trafficgen
endif

SUBDIRS := lib $(UTILS)
Expand Down
5 changes: 3 additions & 2 deletions lib/testing/test_runner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -472,12 +472,13 @@ else
fi
fi

export XDPDUMP
export XDP_BENCH
export XDP_FILTER
export XDP_FORWARD
export XDP_LOADER
export XDP_BENCH
export XDP_MONITOR
export XDP_TRAFFICGEN
export XDPDUMP

TEST_DEFINITIONS="${1:-}"
[ -f "$TEST_DEFINITIONS" ] || usage
Expand Down
1 change: 1 addition & 0 deletions xdp-forward/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
xdp-forward
15 changes: 15 additions & 0 deletions xdp-forward/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# SPDX-License-Identifier: GPL-2.0

XDP_TARGETS := xdp_forward.bpf
BPF_SKEL_TARGETS := $(XDP_TARGETS)

XDP_OBJ_INSTALL :=

TOOL_NAME := xdp-forward
MAN_PAGE := xdp-forward.8
TEST_FILE := tests/test-xdp-forward.sh
USER_TARGETS := xdp-forward

LIB_DIR := ../lib

include $(LIB_DIR)/common.mk
136 changes: 136 additions & 0 deletions xdp-forward/README.org
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
#+EXPORT_FILE_NAME: xdp-forward
#+TITLE: xdp-forward
#+OPTIONS: ^:nil
#+MAN_CLASS_OPTIONS: :section-id "8\" \"DATE\" \"VERSION\" \"XDP program loader"
# This file serves both as a README on github, and as the source for the man
# page; the latter through the org-mode man page export support.
# .
# To export the man page, simply use the org-mode exporter; (require 'ox-man) if
# it's not available. There's also a Makefile rule to export it.

* xdp-forward - the XDP forwarding plane

xdp-forward is an XDP forwarding plane, which will accelerate packet forwarding
using XDP. To use it, simply load it on the set of interfaces to accelerate
forwarding between. The userspace component of xdp-forward will then configure
and load XDP programs on those interfaces, and forward packets between them
using XDP_REDIRECT, using the kernel routing table to determine the destination
if each packet.

Any packets that xdp-forward does not know how to forward will be passed up to
the networking stack and handled by the kernel like normal. Depending on the
mode xdp-forward is loaded in, this leads to different forwarding behaviours.
See the sectinon on *Operating modes* below.

** Running xdp-forward
The syntax for running xdp-forward is:

#+begin_src sh
xdp-forward COMMAND [options]

Where COMMAND can be one of:
load - Load the XDP forwarding plane
unload - Unload the XDP forwarding plane
help - show the list of available commands
#+end_src

Each command, and its options are explained below. Or use =xdp-forward COMMAND
--help= to see the options for each command.

* The LOAD command
The =load= command loads the XDP forwarding plane on a list of interfaces.

The syntax for the =load= command is:

=xdp-forward load [options] <ifname...>=

Where =<ifname...>= is the name of the set of interfaces to forward packets
between. An XDP program will be loaded on each interface, configured to forward
packets to all other interfaces in the set (using the kernel routing table to
determine the destination interface of each packet).

The supported options are:

** -f, --fwd-mode <mode>
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.

** -m, --mode <mode>
Specifies which mode to load the XDP program to be loaded in. The valid values
are 'native', which is the default in-driver XDP mode, 'skb', which causes the
so-called /skb mode/ (also known as /generic XDP/) to be used, 'hw' which causes
the program to be offloaded to the hardware, or 'unspecified' which leaves it up
to the kernel to pick a mode (which it will do by picking native mode if the
driver supports it, or generic mode otherwise). Note that using 'unspecified'
can make it difficult to predict what mode a program will end up being loaded
in. For this reason, the default is 'native'. Note that hardware with support
for the 'hw' mode is rare: Solarflare cards (using the 'sfc' driver) are the
only devices with support for this in the mainline Linux kernel.

** -v, --verbose
Enable debug logging. Specify twice for even more verbosity.

** -h, --help
Display a summary of the available options

* The UNLOAD command
The =unload= command is used for unloading programs from an interface.

The syntax for the =unload= command is:

=xdp-forward unload [options] <ifname...>=

Where =<ifname...>= is the list of interfaces to unload the XDP forwarding plane
from. Note that while =xdp-forward= will examine the XDP programs loaded on each
interface and make sure to only unload its own program, it will not check that
the list of supplied interfaces is the same as the one supplied during load. As
such, it is possible to perform a partial unload by supplying a different list
of interfaces, which may lead to unexpected behaviour.

The supported options are:

** -v, --verbose
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
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
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
require neighbour discovery for the next hop, meaning that packets will
periodically pass up the kernel stack for next hop discovery (initially, and
when the nexthop entry expires).

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

* SEE ALSO
=libxdp(3)= for details on the XDP loading semantics and kernel compatibility
requirements.

* BUGS

Please report any bugs on Github: https://github.com/xdp-project/xdp-tools/issues

* AUTHOR

xdp-forward is written by Toke Høiland-Jørgensen, based on the xdp_fwd kernel
sample, which was originally written by David Ahern. This man page was written
by Toke Høiland-Jørgensen.
59 changes: 59 additions & 0 deletions xdp-forward/tests/test-xdp-forward.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
XDP_LOADER=${XDP_LOADER:-./xdp-loader}
XDP_FORWARD=${XDP_FORWARD:-./xdp-forward}
ALL_TESTS="test_ping test_load test_fwd_full test_fwd_direct"


test_ping()
{
for ip in "${ALL_INSIDE_IP4[@]}"; do
check_run ping -c 1 -W 2 $ip
check_run ns_exec ping -c 1 -W 2 $ip
done
for ip in "${ALL_INSIDE_IP6[@]}"; do
check_run $PING6 -c 1 -W 2 $ip
check_run ns_exec $PING6 -c 1 -W 2 $ip
done
}

test_load()
{

check_run $XDP_FORWARD load ${NS_NAMES[@]}
check_run $XDP_FORWARD unload ${NS_NAMES[@]}
}

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[@]}
for ip in "${ALL_INSIDE_IP4[@]}"; do
check_run ns_exec ping -c 1 -W 2 $ip
done
for ip in "${ALL_INSIDE_IP4[@]}"; do
check_run ns_exec ping -c 1 -W 2 $ip
done
check_run $XDP_FORWARD unload ${NS_NAMES[@]}
}

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[@]}
for ip in "${ALL_INSIDE_IP4[@]}"; do
check_run ns_exec ping -c 1 -W 2 $ip
done
for ip in "${ALL_INSIDE_IP4[@]}"; do
check_run ns_exec ping -c 1 -W 2 $ip
done
check_run $XDP_FORWARD unload ${NS_NAMES[@]}
}

cleanup_tests()
{
$XDP_FORWARD unload ${NS_NAMES[@]} >/dev/null 2>&1
$XDP_LOADER unload $NS --all >/dev/null 2>&1
}
157 changes: 157 additions & 0 deletions xdp-forward/xdp-forward.8
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
.TH "xdp-forward" "8" "JULY 30, 2024" "V1.4.2" "XDP program loader"

.SH "NAME"
xdp-forward \- the XDP forwarding plane
.SH "SYNOPSIS"
.PP
xdp-forward is an XDP forwarding plane, which will accelerate packet forwarding
using XDP. To use it, simply load it on the set of interfaces to accelerate
forwarding between. The userspace component of xdp-forward will then configure
and load XDP programs on those interfaces, and forward packets between them
using XDP_REDIRECT, using the kernel routing table to determine the destination
if each packet.

.PP
Any packets that xdp-forward does not know how to forward will be passed up to
the networking stack and handled by the kernel like normal. Depending on the
mode xdp-forward is loaded in, this leads to different forwarding behaviours.
See the sectinon on \fBOperating modes\fP below.

.SS "Running xdp-forward"
.PP
The syntax for running xdp-forward is:

.RS
.nf
\fCxdp-forward COMMAND [options]

Where COMMAND can be one of:
load - Load the XDP forwarding plane
unload - Unload the XDP forwarding plane
help - show the list of available commands
\fP
.fi
.RE

.PP
Each command, and its options are explained below. Or use \fIxdp\-forward COMMAND
\-\-help\fP to see the options for each command.

.SH "The LOAD command"
.PP
The \fIload\fP command loads the XDP forwarding plane on a list of interfaces.

.PP
The syntax for the \fIload\fP command is:

.PP
\fIxdp\-forward load [options] <ifname...>\fP

.PP
Where \fI<ifname...>\fP is the name of the set of interfaces to forward packets
between. An XDP program will be loaded on each interface, configured to forward
packets to all other interfaces in the set (using the kernel routing table to
determine the destination interface of each packet).

.PP
The supported options are:

.SS "-f, --fwd-mode <mode>"
.PP
Specifies which forwarding mode \fIxdp\-forward\fP should operate in. Depending on
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.

.SS "-m, --mode <mode>"
.PP
Specifies which mode to load the XDP program to be loaded in. The valid values
are 'native', which is the default in-driver XDP mode, 'skb', which causes the
so-called \fIskb mode\fP (also known as \fIgeneric XDP\fP) to be used, 'hw' which causes
the program to be offloaded to the hardware, or 'unspecified' which leaves it up
to the kernel to pick a mode (which it will do by picking native mode if the
driver supports it, or generic mode otherwise). Note that using 'unspecified'
can make it difficult to predict what mode a program will end up being loaded
in. For this reason, the default is 'native'. Note that hardware with support
for the 'hw' mode is rare: Solarflare cards (using the 'sfc' driver) are the
only devices with support for this in the mainline Linux kernel.

.SS "-v, --verbose"
.PP
Enable debug logging. Specify twice for even more verbosity.

.SS "-h, --help"
.PP
Display a summary of the available options

.SH "The UNLOAD command"
.PP
The \fIunload\fP command is used for unloading programs from an interface.

.PP
The syntax for the \fIunload\fP command is:

.PP
\fIxdp\-forward unload [options] <ifname...>\fP

.PP
Where \fI<ifname...>\fP is the list of interfaces to unload the XDP forwarding plane
from. Note that while \fIxdp\-forward\fP will examine the XDP programs loaded on each
interface and make sure to only unload its own program, it will not check that
the list of supplied interfaces is the same as the one supplied during load. As
such, it is possible to perform a partial unload by supplying a different list
of interfaces, which may lead to unexpected behaviour.

.PP
The supported options are:

.SS "-v, --verbose"
.PP
Enable debug logging. Specify twice for even more verbosity.

.SS "-h, --help"
.PP
Display a summary of the available options

.SH "OPERATING MODES"
.PP
The \fIxdp\-forward\fP utility supports the following operating modes (selected by
the \fI\-\-fwd\-mode\fP parameter to \fIxdp\-forward load\fP.

.SS "fib-full (default)"
.PP
In the \fIfib\-full\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. Any packet where
the lookup fails will be passed up to the stack. This includes packets that
require neighbour discovery for the next hop, meaning that packets will
periodically pass up the kernel stack for next hop discovery (initially, and
when the nexthop entry expires).

.PP
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).

.SH "SEE ALSO"
.PP
\fIlibxdp(3)\fP for details on the XDP loading semantics and kernel compatibility
requirements.

.SH "BUGS"
.PP
Please report any bugs on Github: \fIhttps://github.com/xdp-project/xdp-tools/issues\fP

.SH "AUTHOR"
.PP
xdp-forward is written by Toke Høiland-Jørgensen, based on the xdp_fwd kernel
sample, which was originally written by David Ahern. This man page was written
by Toke Høiland-Jørgensen.
Loading