af_xdp: AF_XDP input plugin
[vpp.git] / src / plugins / af_xdp / af_xdp_doc.md
1 # AF_XDP Ethernet driver {#af_xdp_doc}
2
3 This driver relies on Linux AF_XDP socket to rx/tx Ethernet packets.
4
5 ## Maturity level
6 Under development: it should work, but has not been thoroughly tested.
7
8 ## Features
9  - copy and zero-copy mode
10  - multiqueue
11  - API
12  - custom eBPF program
13  - polling, interrupt and adaptive mode
14
15 ## Limitations
16 Because of AF_XDP restrictions, the MTU is limited to below PAGE_SIZE
17 (4096-bytes on most systems) minus 256-bytes, and they are additional
18 limitations depending upon specific Linux device drivers.
19 As a rule of thumb, a MTU of 3000-bytes or less should be safe.
20
21 ## Requirements
22 The Linux kernel interface must be up and have enough queues before
23 creating the VPP AF_XDP interface, otherwise Linux will deny creating
24 the AF_XDP socket.
25 The AF_XDP interface will claim NIC RX queue starting from 0, up to the
26 requested number of RX queues (only 1 by default). It means all packets
27 destined to NIC RX queue `[0, num_rx_queues[` will be received by the
28 AF_XDP interface, and only them. Depending on your configuration, there
29 will usually be several RX queues (typically 1 per core) and packets are
30 spread accross queues by RSS. In order to receive consistent traffic,
31 you **must** program the NIC dispatching accordingly. The simplest way
32 to get all the packets is to reconfigure the Linux kernel driver to use
33 only `num_rx_queues` RX queues (ie all NIC queues will be associated
34 with the AF_XDP socket):
35 ```
36 ~# ethtool -L <iface> combined <num_rx_queues>
37 ```
38 Additionally, the VPP AF_XDP interface will use a MAC address generated at
39 creation time instead of the Linux kernel interface MAC. As Linux kernel
40 interface are not in promiscuous mode by default (see below) this will
41 results in a useless configuration where the VPP AF_XDP interface only
42 receives packets destined to the Linux kernel interface MAC just to drop
43 them because the destination MAC does not match VPP AF_XDP interface MAC.
44 If you want to use the Linux interface MAC for the VPP AF_XDP interface,
45 you can change it afterwards in VPP:
46 ```
47 ~# vppctl set int mac address <iface> <mac>
48 ```
49 Finally, if you wish to receive all packets and not only the packets
50 destined to the Linux kernel interface MAC you need to set the Linux
51 kernel interface in promiscuous mode:
52 ```
53 ~# ip link set dev <iface> promisc on
54 ```
55
56 ## Security considerations
57 When creating an AF_XDP interface, it will receive all packets arriving
58 to the NIC RX queue #0. You need to configure the Linux kernel NIC
59 driver properly to ensure that only intented packets will arrive in
60 this queue. There is no way to filter the packets after-the-fact using
61 eg. netfilter or eBPF.
62
63 ## Quickstart
64 1. Setup the Linux kernel interface (enp216s0f0 here) to use 4 queues:
65 ```
66 ~# ethtool -L enp216s0f0 combined 4
67 ```
68 2. Put the Linux kernel interface up and in promiscuous mode:
69 ```
70 ~# ip l set dev enp216s0f0 promisc on up
71 ```
72 3. Create the AF_XDP interface:
73 ```
74 ~# vppctl create int af_xdp host-if enp216s0f0 num-rx-queues 4
75 ```
76 4. Use the interface as usual, eg.:
77 ```
78 ~# vppctl set int ip addr enp216s0f0/0 1.1.1.1/24
79 ~# vppctl set int st enp216s0f0/0 up
80 ~# vppctl ping 1.1.1.100`
81 ```
82
83 ## Custom eBPF XDP program
84 This driver relies on libbpf and as such relies on the `xsks_map` eBPF
85 map.  The default behavior is to use the XDP program already attached
86 to the interface if any, otherwise load the default one.
87 You can request to load a custom XDP program with the `prog` option when
88 creating the interface in VPP:
89 ```
90 ~# vppctl create int af_xdp host-if enp216s0f0 num-rx-queues 4 prog extras/bpf/af_xdp.bpf.o
91 ```
92 In that case it will replace any previously attached program.  A custom
93 XDP program example is provided in `extras/bpf/`.
94
95 ## Performance consideration
96 AF_XDP relies on the Linux kernel NIC driver to rx/tx packets. To reach
97 high-performance (10's MPPS), the Linux kernel NIC driver must support
98 zero-copy mode and its RX path must run on a dedicated core in the NUMA
99 where the NIC is physically connected.