New upstream version 18.11-rc1
[deb_dpdk.git] / doc / guides / nics / tap.rst
1 ..  SPDX-License-Identifier: BSD-3-Clause
2     Copyright(c) 2016 Intel Corporation.
3
4 Tun|Tap Poll Mode Driver
5 ========================
6
7 The ``rte_eth_tap.c`` PMD creates a device using TAP interfaces on the
8 local host. The PMD allows for DPDK and the host to communicate using a raw
9 device interface on the host and in the DPDK application.
10
11 The device created is a TAP device, which sends/receives packet in a raw
12 format with a L2 header. The usage for a TAP PMD is for connectivity to the
13 local host using a TAP interface. When the TAP PMD is initialized it will
14 create a number of tap devices in the host accessed via ``ifconfig -a`` or
15 ``ip`` command. The commands can be used to assign and query the virtual like
16 device.
17
18 These TAP interfaces can be used with Wireshark or tcpdump or Pktgen-DPDK
19 along with being able to be used as a network connection to the DPDK
20 application. The method enable one or more interfaces is to use the
21 ``--vdev=net_tap0`` option on the DPDK application command line. Each
22 ``--vdev=net_tap1`` option given will create an interface named dtap0, dtap1,
23 and so on.
24
25 The interface name can be changed by adding the ``iface=foo0``, for example::
26
27    --vdev=net_tap0,iface=foo0 --vdev=net_tap1,iface=foo1, ...
28
29 Normally the PMD will generate a random MAC address, but when testing or with
30 a static configuration the developer may need a fixed MAC address style.
31 Using the option ``mac=fixed`` you can create a fixed known MAC address::
32
33    --vdev=net_tap0,mac=fixed
34
35 The MAC address will have a fixed value with the last octet incrementing by one
36 for each interface string containing ``mac=fixed``. The MAC address is formatted
37 as 00:'d':'t':'a':'p':[00-FF]. Convert the characters to hex and you get the
38 actual MAC address: ``00:64:74:61:70:[00-FF]``.
39
40    --vdev=net_tap0,mac="00:64:74:61:70:11"
41
42 The MAC address will have a user value passed as string. The MAC address is in
43 format with delimeter ``:``. The string is byte converted to hex and you get
44 the actual MAC address: ``00:64:74:61:70:11``.
45
46 It is possible to specify a remote netdevice to capture packets from by adding
47 ``remote=foo1``, for example::
48
49    --vdev=net_tap,iface=tap0,remote=foo1
50
51 If a ``remote`` is set, the tap MAC address will be set to match the remote one
52 just after netdevice creation. Using TC rules, traffic from the remote netdevice
53 will be redirected to the tap. If the tap is in promiscuous mode, then all
54 packets will be redirected. In allmulti mode, all multicast packets will be
55 redirected.
56
57 Using the remote feature is especially useful for capturing traffic from a
58 netdevice that has no support in the DPDK. It is possible to add explicit
59 rte_flow rules on the tap PMD to capture specific traffic (see next section for
60 examples).
61
62 After the DPDK application is started you can send and receive packets on the
63 interface using the standard rx_burst/tx_burst APIs in DPDK. From the host
64 point of view you can use any host tool like tcpdump, Wireshark, ping, Pktgen
65 and others to communicate with the DPDK application. The DPDK application may
66 not understand network protocols like IPv4/6, UDP or TCP unless the
67 application has been written to understand these protocols.
68
69 If you need the interface as a real network interface meaning running and has
70 a valid IP address then you can do this with the following commands::
71
72    sudo ip link set dtap0 up; sudo ip addr add 192.168.0.250/24 dev dtap0
73    sudo ip link set dtap1 up; sudo ip addr add 192.168.1.250/24 dev dtap1
74
75 Please change the IP addresses as you see fit.
76
77 If routing is enabled on the host you can also communicate with the DPDK App
78 over the internet via a standard socket layer application as long as you
79 account for the protocol handing in the application.
80
81 If you have a Network Stack in your DPDK application or something like it you
82 can utilize that stack to handle the network protocols. Plus you would be able
83 to address the interface using an IP address assigned to the internal
84 interface.
85
86 The TUN PMD allows user to create a TUN device on host. The PMD allows user
87 to transmit and receive packets via DPDK API calls with L3 header and payload.
88 The devices in host can be accessed via ``ifconfig`` or ``ip`` command. TUN
89 interfaces are passed to DPDK ``rte_eal_init`` arguments as ``--vdev=net_tunX``,
90 where X stands for unique id, example::
91
92    --vdev=net_tun0 --vdev=net_tun1,iface=foo1, ...
93
94 Unlike TAP PMD, TUN PMD does not support user arguments as ``MAC`` or ``remote`` user
95 options. Default interface name is ``dtunX``, where X stands for unique id.
96
97 Flow API support
98 ----------------
99
100 The tap PMD supports major flow API pattern items and actions, when running on
101 linux kernels above 4.2 ("Flower" classifier required).
102 The kernel support can be checked with this command::
103
104    zcat /proc/config.gz | ( grep 'CLS_FLOWER=' || echo 'not supported' ) |
105    tee -a /dev/stderr | grep -q '=m' &&
106    lsmod | ( grep cls_flower || echo 'try modprobe cls_flower' )
107
108 Supported items:
109
110 - eth: src and dst (with variable masks), and eth_type (0xffff mask).
111 - vlan: vid, pcp, but not eid. (requires kernel 4.9)
112 - ipv4/6: src and dst (with variable masks), and ip_proto (0xffff mask).
113 - udp/tcp: src and dst port (0xffff) mask.
114
115 Supported actions:
116
117 - DROP
118 - QUEUE
119 - PASSTHRU
120 - RSS (requires kernel 4.9)
121
122 It is generally not possible to provide a "last" item. However, if the "last"
123 item, once masked, is identical to the masked spec, then it is supported.
124
125 Only IPv4/6 and MAC addresses can use a variable mask. All other items need a
126 full mask (exact match).
127
128 As rules are translated to TC, it is possible to show them with something like::
129
130    tc -s filter show dev tap1 parent 1:
131
132 Examples of testpmd flow rules
133 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
134
135 Drop packets for destination IP 192.168.0.1::
136
137    testpmd> flow create 0 priority 1 ingress pattern eth / ipv4 dst is 1.1.1.1 \
138             / end actions drop / end
139
140 Ensure packets from a given MAC address are received on a queue 2::
141
142    testpmd> flow create 0 priority 2 ingress pattern eth src is 06:05:04:03:02:01 \
143             / end actions queue index 2 / end
144
145 Drop UDP packets in vlan 3::
146
147    testpmd> flow create 0 priority 3 ingress pattern eth / vlan vid is 3 / \
148             ipv4 proto is 17 / end actions drop / end
149
150 Distribute IPv4 TCP packets using RSS to a given MAC address over queues 0-3::
151
152    testpmd> flow create 0 priority 4 ingress pattern eth dst is 0a:0b:0c:0d:0e:0f \
153             / ipv4 / tcp / end actions rss queues 0 1 2 3 end / end
154
155 Multi-process sharing
156 ---------------------
157
158 It is possible to attach an existing TAP device in a secondary process,
159 by declaring it as a vdev with the same name as in the primary process,
160 and without any parameter.
161
162 The port attached in a secondary process will give access to the
163 statistics and the queues.
164 Therefore it can be used for monitoring or Rx/Tx processing.
165
166 The IPC synchronization of Rx/Tx queues is currently limited:
167
168   - Maximum 8 queues shared
169   - Synchronized on probing, but not on later port update
170
171 Example
172 -------
173
174 The following is a simple example of using the TAP PMD with the Pktgen
175 packet generator. It requires that the ``socat`` utility is installed on the
176 test system.
177
178 Build DPDK, then pull down Pktgen and build pktgen using the DPDK SDK/Target
179 used to build the dpdk you pulled down.
180
181 Run pktgen from the pktgen directory in a terminal with a commandline like the
182 following::
183
184     sudo ./app/app/x86_64-native-linuxapp-gcc/app/pktgen -l 1-5 -n 4        \
185      --proc-type auto --log-level debug --socket-mem 512,512 --file-prefix pg   \
186      --vdev=net_tap0 --vdev=net_tap1 -b 05:00.0 -b 05:00.1                  \
187      -b 04:00.0 -b 04:00.1 -b 04:00.2 -b 04:00.3                            \
188      -b 81:00.0 -b 81:00.1 -b 81:00.2 -b 81:00.3                            \
189      -b 82:00.0 -b 83:00.0 -- -T -P -m [2:3].0 -m [4:5].1                   \
190      -f themes/black-yellow.theme
191
192 .. Note:
193
194    Change the ``-b`` options to blacklist all of your physical ports. The
195    following command line is all one line.
196
197    Also, ``-f themes/black-yellow.theme`` is optional if the default colors
198    work on your system configuration. See the Pktgen docs for more
199    information.
200
201 Verify with ``ifconfig -a`` command in a different xterm window, should have a
202 ``dtap0`` and ``dtap1`` interfaces created.
203
204 Next set the links for the two interfaces to up via the commands below::
205
206     sudo ip link set dtap0 up; sudo ip addr add 192.168.0.250/24 dev dtap0
207     sudo ip link set dtap1 up; sudo ip addr add 192.168.1.250/24 dev dtap1
208
209 Then use socat to create a loopback for the two interfaces::
210
211     sudo socat interface:dtap0 interface:dtap1
212
213 Then on the Pktgen command line interface you can start sending packets using
214 the commands ``start 0`` and ``start 1`` or you can start both at the same
215 time with ``start all``. The command ``str`` is an alias for ``start all`` and
216 ``stp`` is an alias for ``stop all``.
217
218 While running you should see the 64 byte counters increasing to verify the
219 traffic is being looped back. You can use ``set all size XXX`` to change the
220 size of the packets after you stop the traffic. Use pktgen ``help``
221 command to see a list of all commands. You can also use the ``-f`` option to
222 load commands at startup in command line or Lua script in pktgen.
223
224 RSS specifics
225 -------------
226 Packet distribution in TAP is done by the kernel which has a default
227 distribution. This feature is adding RSS distribution based on eBPF code.
228 The default eBPF code calculates RSS hash based on Toeplitz algorithm for
229 a fixed RSS key. It is calculated on fixed packet offsets. For IPv4 and IPv6 it
230 is calculated over src/dst addresses (8 or 32 bytes for IPv4 or IPv6
231 respectively) and src/dst TCP/UDP ports (4 bytes).
232
233 The RSS algorithm is written in file ``tap_bpf_program.c`` which
234 does not take part in TAP PMD compilation. Instead this file is compiled
235 in advance to eBPF object file. The eBPF object file is then parsed and
236 translated into eBPF byte code in the format of C arrays of eBPF
237 instructions. The C array of eBPF instructions is part of TAP PMD tree and
238 is taking part in TAP PMD compilation. At run time the C arrays are uploaded to
239 the kernel via BPF system calls and the RSS hash is calculated by the
240 kernel.
241
242 It is possible to support different RSS hash algorithms by updating file
243 ``tap_bpf_program.c``  In order to add a new RSS hash algorithm follow these
244 steps:
245
246 1. Write the new RSS implementation in file ``tap_bpf_program.c``
247
248 BPF programs which are uploaded to the kernel correspond to
249 C functions under different ELF sections.
250
251 2. Install ``LLVM`` library and ``clang`` compiler versions 3.7 and above
252
253 3. Compile ``tap_bpf_program.c`` via ``LLVM`` into an object file::
254
255     clang -O2 -emit-llvm -c tap_bpf_program.c -o - | llc -march=bpf \
256     -filetype=obj -o <tap_bpf_program.o>
257
258
259 4. Use a tool that receives two parameters: an eBPF object file and a section
260 name, and prints out the section as a C array of eBPF instructions.
261 Embed the C array in your TAP PMD tree.
262
263 The C arrays are uploaded to the kernel using BPF system calls.
264
265 ``tc`` (traffic control) is a well known user space utility program used to
266 configure the Linux kernel packet scheduler. It is usually packaged as
267 part of the ``iproute2`` package.
268 Since commit 11c39b5e9 ("tc: add eBPF support to f_bpf") ``tc`` can be used
269 to uploads eBPF code to the kernel and can be patched in order to print the
270 C arrays of eBPF instructions just before calling the BPF system call.
271 Please refer to ``iproute2`` package file ``lib/bpf.c`` function
272 ``bpf_prog_load()``.
273
274 An example utility for eBPF instruction generation in the format of C arrays will
275 be added in next releases
276
277 TAP reports on supported RSS functions as part of dev_infos_get callback:
278 ``ETH_RSS_IP``, ``ETH_RSS_UDP`` and ``ETH_RSS_TCP``.
279 **Known limitation:** TAP supports all of the above hash functions together
280 and not in partial combinations.
281
282 Systems supporting flow API
283 ---------------------------
284
285 - "tc flower" classifier requires linux kernel above 4.2
286 - eBPF/RSS requires linux kernel above 4.9
287
288 +--------------------+-----------------------+
289 | RH7.3              | No flow rule support  |
290 +--------------------+-----------------------+
291 | RH7.4              | No RSS action support |
292 +--------------------+-----------------------+
293 | RH7.5              | No RSS action support |
294 +--------------------+-----------------------+
295 | SLES 15,           | No limitation         |
296 | kernel 4.12        |                       |
297 +--------------------+-----------------------+
298 | Azure Ubuntu 16.04,| No limitation         |
299 | kernel 4.13        |                       |
300 +--------------------+-----------------------+
301