New upstream version 18.11-rc1
[deb_dpdk.git] / doc / guides / sample_app_ug / kernel_nic_interface.rst
1 ..  SPDX-License-Identifier: BSD-3-Clause
2     Copyright(c) 2010-2014 Intel Corporation.
3
4 Kernel NIC Interface Sample Application
5 =======================================
6
7 The Kernel NIC Interface (KNI) is a DPDK control plane solution that
8 allows userspace applications to exchange packets with the kernel networking stack.
9 To accomplish this, DPDK userspace applications use an IOCTL call
10 to request the creation of a KNI virtual device in the Linux* kernel.
11 The IOCTL call provides interface information and the DPDK's physical address space,
12 which is re-mapped into the kernel address space by the KNI kernel loadable module
13 that saves the information to a virtual device context.
14 The DPDK creates FIFO queues for packet ingress and egress
15 to the kernel module for each device allocated.
16
17 The KNI kernel loadable module is a standard net driver,
18 which upon receiving the IOCTL call access the DPDK's FIFO queue to
19 receive/transmit packets from/to the DPDK userspace application.
20 The FIFO queues contain pointers to data packets in the DPDK. This:
21
22 *   Provides a faster mechanism to interface with the kernel net stack and eliminates system calls
23
24 *   Facilitates the DPDK using standard Linux* userspace net tools (tcpdump, ftp, and so on)
25
26 *   Eliminate the copy_to_user and copy_from_user operations on packets.
27
28 The Kernel NIC Interface sample application is a simple example that demonstrates the use
29 of the DPDK to create a path for packets to go through the Linux* kernel.
30 This is done by creating one or more kernel net devices for each of the DPDK ports.
31 The application allows the use of standard Linux tools (ethtool, ifconfig, tcpdump) with the DPDK ports and
32 also the exchange of packets between the DPDK application and the Linux* kernel.
33
34 The Kernel NIC Interface sample application requires that the
35 KNI kernel module ``rte_kni`` be loaded into the kernel.  See
36 :doc:`../prog_guide/kernel_nic_interface` for more information on loading
37 the ``rte_kni`` kernel module.
38
39 Overview
40 --------
41
42 The Kernel NIC Interface sample application ``kni`` allocates one or more
43 KNI interfaces for each physical NIC port.  For each physical NIC port,
44 ``kni`` uses two DPDK threads in user space; one thread reads from the port and
45 writes to the corresponding KNI interfaces and the other thread reads from
46 the KNI interfaces and writes the data unmodified to the physical NIC port.
47
48 It is recommended to configure one KNI interface for each physical NIC port.
49 The application can be configured with more than one KNI interface for
50 each physical NIC port for performance testing or it can work together with
51 VMDq support in future.
52
53 The packet flow through the Kernel NIC Interface application is as shown
54 in the following figure.
55
56 .. _figure_kernel_nic:
57
58 .. figure:: img/kernel_nic.*
59
60    Kernel NIC Application Packet Flow
61
62 If link monitoring is enabled with the ``-m`` command line flag, one
63 additional pthread is launched which will check the link status of each
64 physical NIC port and will update the carrier status of the corresponding
65 KNI interface(s) to match the physical NIC port's state.  This means that
66 the KNI interface(s) will be disabled automatically when the Ethernet link
67 goes down and enabled when the Ethernet link goes up.
68
69 If link monitoring is enabled, the ``rte_kni`` kernel module should be loaded
70 such that the :ref:`default carrier state <kni_default_carrier_state>` is
71 set to *off*.  This ensures that the KNI interface is only enabled *after*
72 the Ethernet link of the corresponding NIC port has reached the linkup state.
73
74 If link monitoring is not enabled, the ``rte_kni`` kernel module should be
75 loaded with the :ref:`default carrier state <kni_default_carrier_state>`
76 set to *on*.  This sets the carrier state of the KNI interfaces to *on*
77 when the KNI interfaces are enabled without regard to the actual link state
78 of the corresponding NIC port.  This is useful for testing in loopback
79 mode where the NIC port may not be physically connected to anything.
80
81 Compiling the Application
82 -------------------------
83
84 To compile the sample application see :doc:`compiling`.
85
86 The application is located in the ``examples/kni`` sub-directory.
87
88 .. note::
89
90         This application is intended as a linuxapp only.
91
92 Running the kni Example Application
93 -----------------------------------
94
95 The ``kni`` example application requires a number of command line options:
96
97 .. code-block:: console
98
99     kni [EAL options] -- -p PORTMASK --config="(port,lcore_rx,lcore_tx[,lcore_kthread,...])[,(port,lcore_rx,lcore_tx[,lcore_kthread,...])]" [-P] [-m]
100
101 Where:
102
103 *   ``-p PORTMASK``:
104
105     Hexadecimal bitmask of ports to configure.
106
107 *   ``--config="(port,lcore_rx,lcore_tx[,lcore_kthread,...])[,(port,lcore_rx,lcore_tx[,lcore_kthread,...])]"``:
108
109     Determines which lcores the Rx and Tx DPDK tasks, and (optionally)
110     the KNI kernel thread(s) are bound to for each physical port.
111
112 *   ``-P``:
113
114     Optional flag to set all ports to promiscuous mode so that packets are
115     accepted regardless of the packet's Ethernet MAC destination address.
116     Without this option, only packets with the Ethernet MAC destination
117     address set to the Ethernet address of the port are accepted.
118
119 *   ``-m``:
120
121     Optional flag to enable monitoring and updating of the Ethernet
122     carrier state.  With this option set, a thread will be started which
123     will periodically check the Ethernet link status of the physical
124     Ethernet ports and set the carrier state of the corresponding KNI
125     network interface to match it.  This means that the KNI interface will
126     be disabled automatically when the Ethernet link goes down and enabled
127     when the Ethernet link goes up.
128
129 Refer to *DPDK Getting Started Guide* for general information on running
130 applications and the Environment Abstraction Layer (EAL) options.
131
132 The ``-c coremask`` or ``-l corelist`` parameter of the EAL options must
133 include the lcores specified by ``lcore_rx`` and ``lcore_tx`` for each port,
134 but does not need to include lcores specified by ``lcore_kthread`` as those
135 cores are used to pin the kernel threads in the ``rte_kni`` kernel module.
136
137 The ``--config`` parameter must include a set of
138 ``(port,lcore_rx,lcore_tx,[lcore_kthread,...])`` values for each physical
139 port specified in the ``-p PORTMASK`` parameter.
140
141 The optional ``lcore_kthread`` lcore ID parameter in ``--config`` can be
142 specified zero, one or more times for each physical port.
143
144 If no lcore ID is specified for ``lcore_kthread``, one KNI interface will
145 be created for the physical port ``port`` and the KNI kernel thread(s)
146 will have no specific core affinity.
147
148 If one or more lcore IDs are specified for ``lcore_kthread``, a KNI interface
149 will be created for each lcore ID specified, bound to the physical port
150 ``port``.  If the ``rte_kni`` kernel module is loaded in :ref:`multiple
151 kernel thread <kni_kernel_thread_mode>` mode, a kernel thread will be created
152 for each KNI interface and bound to the specified core.  If the ``rte_kni``
153 kernel module is loaded in :ref:`single kernel thread <kni_kernel_thread_mode>`
154 mode, only one kernel thread is started for all KNI interfaces.  The kernel
155 thread will be bound to the first ``lcore_kthread`` lcore ID specified.
156
157 Example Configurations
158 ~~~~~~~~~~~~~~~~~~~~~~~
159
160 The following commands will first load the ``rte_kni`` kernel module in
161 :ref:`multiple kernel thread <kni_kernel_thread_mode>` mode.  The ``kni``
162 application is then started using two ports;  Port 0 uses lcore 4 for the
163 Rx task, lcore 6 for the Tx task, and will create a single KNI interface
164 ``vEth0_0`` with the kernel thread bound to lcore 8.  Port 1 uses lcore
165 5 for the Rx task, lcore 7 for the Tx task, and will create a single KNI
166 interface ``vEth1_0`` with the kernel thread bound to lcore 9.
167
168 .. code-block:: console
169
170     # rmmod rte_kni
171     # insmod kmod/rte_kni.ko kthread_mode=multiple
172     # ./build/kni -l 4-7 -n 4 -- -P -p 0x3 -m --config="(0,4,6,8),(1,5,7,9)"
173
174 The following example is identical, except an additional ``lcore_kthread``
175 core is specified per physical port.  In this case, ``kni`` will create
176 four KNI interfaces: ``vEth0_0``/``vEth0_1`` bound to physical port 0 and
177 ``vEth1_0``/``vEth1_1`` bound to physical port 1.
178
179 The kernel thread for each interface will be bound as follows:
180
181     * ``vEth0_0`` - bound to lcore 8.
182     * ``vEth0_1`` - bound to lcore 10.
183     * ``vEth1_0`` - bound to lcore 9.
184     * ``vEth1_1`` - bound to lcore 11
185
186 .. code-block:: console
187
188     # rmmod rte_kni
189     # insmod kmod/rte_kni.ko kthread_mode=multiple
190     # ./build/kni -l 4-7 -n 4 -- -P -p 0x3 -m --config="(0,4,6,8,10),(1,5,7,9,11)"
191
192 The following example can be used to test the interface between the ``kni``
193 test application and the ``rte_kni`` kernel module.  In this example,
194 the ``rte_kni`` kernel module is loaded in :ref:`single kernel thread
195 mode <kni_kernel_thread_mode>`, :ref:`loopback mode <kni_loopback_mode>`
196 enabled, and the :ref:`default carrier state <kni_default_carrier_state>`
197 is set to *on* so that the corresponding physical NIC port does not have
198 to be connected in order to use the KNI interface.  One KNI interface
199 ``vEth0_0`` is created for port 0 and one KNI interface ``vEth1_0`` is
200 created for port 1.  Since ``rte_kni`` is loaded in "single kernel thread"
201 mode, the one kernel thread is bound to lcore 8.
202
203 Since the physical NIC ports are not being used, link monitoring can be
204 disabled by **not** specifying the ``-m`` flag to ``kni``:
205
206 .. code-block:: console
207
208     # rmmod rte_kni
209     # insmod kmod/rte_kni.ko lo_mode=lo_mode_fifo carrier=on
210     # ./build/kni -l 4-7 -n 4 -- -P -p 0x3 --config="(0,4,6,8),(1,5,7,9)"
211
212 KNI Operations
213 --------------
214
215 Once the ``kni`` application is started, the user can use the normal
216 Linux commands to manage the KNI interfaces as if they were any other
217 Linux network interface.
218
219 Enable KNI interface and assign an IP address:
220
221 .. code-block:: console
222
223     # ifconfig vEth0_0 192.168.0.1
224
225 Show KNI interface configuration and statistics:
226
227 .. code-block:: console
228
229     # ifconfig vEth0_0
230
231 The user can also check and reset the packet statistics inside the ``kni``
232 application by sending the app the USR1 and USR2 signals:
233
234 .. code-block:: console
235
236     # Print statistics
237     # kill -SIGUSR1 `pidof kni`
238
239     # Zero statistics
240     # kill -SIGUSR2 `pidof kni`
241
242 Dump network traffic:
243
244 .. code-block:: console
245
246     # tcpdump -i vEth0_0
247
248 The normal Linux commands can also be used to change the MAC address and
249 MTU size used by the physical NIC which corresponds to the KNI interface.
250 However, if more than one KNI interface is configured for a physical port,
251 these commands will only work on the first KNI interface for that port.
252
253 Change the MAC address:
254
255 .. code-block:: console
256
257     # ifconfig vEth0_0 hw ether 0C:01:02:03:04:08
258
259 Change the MTU size:
260
261 .. code-block:: console
262
263     # ifconfig vEth0_0 mtu 1450
264
265 If DPDK is compiled with ``CONFIG_RTE_KNI_KMOD_ETHTOOL=y`` and an Intel
266 NIC is used, the user can use ``ethtool`` on the KNI interface as if it
267 were a normal Linux kernel interface.
268
269 Displaying the NIC registers:
270
271 .. code-block:: console
272
273     # ethtool -d vEth0_0
274
275 When the ``kni`` application is closed, all the KNI interfaces are deleted
276 from the Linux kernel.
277
278 Explanation
279 -----------
280
281 The following sections provide some explanation of code.
282
283 Initialization
284 ~~~~~~~~~~~~~~
285
286 Setup of mbuf pool, driver and queues is similar to the setup done in the :doc:`l2_forward_real_virtual`..
287 In addition, one or more kernel NIC interfaces are allocated for each
288 of the configured ports according to the command line parameters.
289
290 The code for allocating the kernel NIC interfaces for a specific port is
291 in the function ``kni_alloc``.
292
293 The other step in the initialization process that is unique to this sample application
294 is the association of each port with lcores for RX, TX and kernel threads.
295
296 *   One lcore to read from the port and write to the associated one or more KNI devices
297
298 *   Another lcore to read from one or more KNI devices and write to the port
299
300 *   Other lcores for pinning the kernel threads on one by one
301
302 This is done by using the ``kni_port_params_array[]`` array, which is indexed by the port ID.
303 The code is in the function ``parse_config``.
304
305 Packet Forwarding
306 ~~~~~~~~~~~~~~~~~
307
308 After the initialization steps are completed, the main_loop() function is run on each lcore.
309 This function first checks the lcore_id against the user provided lcore_rx and lcore_tx
310 to see if this lcore is reading from or writing to kernel NIC interfaces.
311
312 For the case that reads from a NIC port and writes to the kernel NIC interfaces (``kni_ingress``),
313 the packet reception is the same as in L2 Forwarding sample application
314 (see :ref:`l2_fwd_app_rx_tx_packets`).
315 The packet transmission is done by sending mbufs into the kernel NIC interfaces by ``rte_kni_tx_burst()``.
316 The KNI library automatically frees the mbufs after the kernel successfully copied the mbufs.
317
318 For the other case that reads from kernel NIC interfaces
319 and writes to a physical NIC port (``kni_egress``),
320 packets are retrieved by reading mbufs from kernel NIC interfaces by ``rte_kni_rx_burst()``.
321 The packet transmission is the same as in the L2 Forwarding sample application
322 (see :ref:`l2_fwd_app_rx_tx_packets`).