aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/af_xdp/af_xdp_doc.md
diff options
context:
space:
mode:
authorBenoît Ganne <bganne@cisco.com>2020-06-12 08:47:34 +0200
committerDamjan Marion <dmarion@me.com>2020-08-31 17:16:56 +0000
commit4a76d6f6da035220917097bc047b08bc58254803 (patch)
tree10399485df66c0ebeeaa32edbb7a1022b8baa9b3 /src/plugins/af_xdp/af_xdp_doc.md
parentbfed7c047d2807f835cd7b9ef0330d314ac0ebc5 (diff)
af_xdp: AF_XDP input plugin
Type: feature Change-Id: I85aa4ad6b68c1aa0e51938002dc691a4b11c545c Signed-off-by: Damjan Marion <damarion@cisco.com> Signed-off-by: Benoît Ganne <bganne@cisco.com>
Diffstat (limited to 'src/plugins/af_xdp/af_xdp_doc.md')
-rw-r--r--src/plugins/af_xdp/af_xdp_doc.md99
1 files changed, 99 insertions, 0 deletions
diff --git a/src/plugins/af_xdp/af_xdp_doc.md b/src/plugins/af_xdp/af_xdp_doc.md
new file mode 100644
index 00000000000..6d2dae55055
--- /dev/null
+++ b/src/plugins/af_xdp/af_xdp_doc.md
@@ -0,0 +1,99 @@
+# AF_XDP Ethernet driver {#af_xdp_doc}
+
+This driver relies on Linux AF_XDP socket to rx/tx Ethernet packets.
+
+## Maturity level
+Under development: it should work, but has not been thoroughly tested.
+
+## Features
+ - copy and zero-copy mode
+ - multiqueue
+ - API
+ - custom eBPF program
+ - polling, interrupt and adaptive mode
+
+## Limitations
+Because of AF_XDP restrictions, the MTU is limited to below PAGE_SIZE
+(4096-bytes on most systems) minus 256-bytes, and they are additional
+limitations depending upon specific Linux device drivers.
+As a rule of thumb, a MTU of 3000-bytes or less should be safe.
+
+## Requirements
+The Linux kernel interface must be up and have enough queues before
+creating the VPP AF_XDP interface, otherwise Linux will deny creating
+the AF_XDP socket.
+The AF_XDP interface will claim NIC RX queue starting from 0, up to the
+requested number of RX queues (only 1 by default). It means all packets
+destined to NIC RX queue `[0, num_rx_queues[` will be received by the
+AF_XDP interface, and only them. Depending on your configuration, there
+will usually be several RX queues (typically 1 per core) and packets are
+spread accross queues by RSS. In order to receive consistent traffic,
+you **must** program the NIC dispatching accordingly. The simplest way
+to get all the packets is to reconfigure the Linux kernel driver to use
+only `num_rx_queues` RX queues (ie all NIC queues will be associated
+with the AF_XDP socket):
+```
+~# ethtool -L <iface> combined <num_rx_queues>
+```
+Additionally, the VPP AF_XDP interface will use a MAC address generated at
+creation time instead of the Linux kernel interface MAC. As Linux kernel
+interface are not in promiscuous mode by default (see below) this will
+results in a useless configuration where the VPP AF_XDP interface only
+receives packets destined to the Linux kernel interface MAC just to drop
+them because the destination MAC does not match VPP AF_XDP interface MAC.
+If you want to use the Linux interface MAC for the VPP AF_XDP interface,
+you can change it afterwards in VPP:
+```
+~# vppctl set int mac address <iface> <mac>
+```
+Finally, if you wish to receive all packets and not only the packets
+destined to the Linux kernel interface MAC you need to set the Linux
+kernel interface in promiscuous mode:
+```
+~# ip link set dev <iface> promisc on
+```
+
+## Security considerations
+When creating an AF_XDP interface, it will receive all packets arriving
+to the NIC RX queue #0. You need to configure the Linux kernel NIC
+driver properly to ensure that only intented packets will arrive in
+this queue. There is no way to filter the packets after-the-fact using
+eg. netfilter or eBPF.
+
+## Quickstart
+1. Setup the Linux kernel interface (enp216s0f0 here) to use 4 queues:
+```
+~# ethtool -L enp216s0f0 combined 4
+```
+2. Put the Linux kernel interface up and in promiscuous mode:
+```
+~# ip l set dev enp216s0f0 promisc on up
+```
+3. Create the AF_XDP interface:
+```
+~# vppctl create int af_xdp host-if enp216s0f0 num-rx-queues 4
+```
+4. Use the interface as usual, eg.:
+```
+~# vppctl set int ip addr enp216s0f0/0 1.1.1.1/24
+~# vppctl set int st enp216s0f0/0 up
+~# vppctl ping 1.1.1.100`
+```
+
+## Custom eBPF XDP program
+This driver relies on libbpf and as such relies on the `xsks_map` eBPF
+map. The default behavior is to use the XDP program already attached
+to the interface if any, otherwise load the default one.
+You can request to load a custom XDP program with the `prog` option when
+creating the interface in VPP:
+```
+~# vppctl create int af_xdp host-if enp216s0f0 num-rx-queues 4 prog extras/bpf/af_xdp.bpf.o
+```
+In that case it will replace any previously attached program. A custom
+XDP program example is provided in `extras/bpf/`.
+
+## Performance consideration
+AF_XDP relies on the Linux kernel NIC driver to rx/tx packets. To reach
+high-performance (10's MPPS), the Linux kernel NIC driver must support
+zero-copy mode and its RX path must run on a dedicated core in the NUMA
+where the NIC is physically connected.