diff options
author | Benoît Ganne <bganne@cisco.com> | 2020-06-12 08:47:34 +0200 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2020-08-31 17:16:56 +0000 |
commit | 4a76d6f6da035220917097bc047b08bc58254803 (patch) | |
tree | 10399485df66c0ebeeaa32edbb7a1022b8baa9b3 /src/plugins/af_xdp/af_xdp_doc.md | |
parent | bfed7c047d2807f835cd7b9ef0330d314ac0ebc5 (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.md | 99 |
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. |