]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
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 | ||
f67539c2 | 24 | * Facilitates the DPDK using standard Linux* userspace net tools (tshark, rsync, and so on) |
11fdf7f2 TL |
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. | |
f67539c2 | 31 | The application allows the use of standard Linux tools (ethtool, iproute, tshark) with the DPDK ports and |
11fdf7f2 TL |
32 | also the exchange of packets between the DPDK application and the Linux* kernel. |
33 | ||
9f95a23c TL |
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 | ||
11fdf7f2 TL |
39 | Overview |
40 | -------- | |
41 | ||
9f95a23c TL |
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. | |
11fdf7f2 | 52 | |
9f95a23c TL |
53 | The packet flow through the Kernel NIC Interface application is as shown |
54 | in the following figure. | |
11fdf7f2 TL |
55 | |
56 | .. _figure_kernel_nic: | |
57 | ||
58 | .. figure:: img/kernel_nic.* | |
59 | ||
60 | Kernel NIC Application Packet Flow | |
61 | ||
9f95a23c TL |
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 | ||
11fdf7f2 TL |
81 | Compiling the Application |
82 | ------------------------- | |
83 | ||
84 | To compile the sample application see :doc:`compiling`. | |
85 | ||
9f95a23c | 86 | The application is located in the ``examples/kni`` sub-directory. |
11fdf7f2 TL |
87 | |
88 | .. note:: | |
89 | ||
9f95a23c | 90 | This application is intended as a linux only. |
11fdf7f2 | 91 | |
9f95a23c TL |
92 | Running the kni Example Application |
93 | ----------------------------------- | |
11fdf7f2 | 94 | |
9f95a23c | 95 | The ``kni`` example application requires a number of command line options: |
11fdf7f2 TL |
96 | |
97 | .. code-block:: console | |
98 | ||
9f95a23c | 99 | kni [EAL options] -- -p PORTMASK --config="(port,lcore_rx,lcore_tx[,lcore_kthread,...])[,(port,lcore_rx,lcore_tx[,lcore_kthread,...])]" [-P] [-m] |
11fdf7f2 | 100 | |
9f95a23c | 101 | Where: |
11fdf7f2 | 102 | |
9f95a23c | 103 | * ``-p PORTMASK``: |
11fdf7f2 | 104 | |
9f95a23c | 105 | Hexadecimal bitmask of ports to configure. |
11fdf7f2 | 106 | |
9f95a23c | 107 | * ``--config="(port,lcore_rx,lcore_tx[,lcore_kthread,...])[,(port,lcore_rx,lcore_tx[,lcore_kthread,...])]"``: |
11fdf7f2 | 108 | |
9f95a23c TL |
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. | |
11fdf7f2 | 111 | |
9f95a23c | 112 | * ``-P``: |
11fdf7f2 | 113 | |
9f95a23c TL |
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. | |
11fdf7f2 | 118 | |
9f95a23c | 119 | * ``-m``: |
11fdf7f2 | 120 | |
9f95a23c TL |
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. | |
11fdf7f2 | 128 | |
9f95a23c TL |
129 | Refer to *DPDK Getting Started Guide* for general information on running |
130 | applications and the Environment Abstraction Layer (EAL) options. | |
11fdf7f2 | 131 | |
9f95a23c TL |
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. | |
11fdf7f2 | 136 | |
9f95a23c TL |
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. | |
11fdf7f2 | 140 | |
9f95a23c TL |
141 | The optional ``lcore_kthread`` lcore ID parameter in ``--config`` can be |
142 | specified zero, one or more times for each physical port. | |
11fdf7f2 | 143 | |
9f95a23c TL |
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. | |
11fdf7f2 | 147 | |
9f95a23c TL |
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. | |
11fdf7f2 | 156 | |
9f95a23c TL |
157 | Example Configurations |
158 | ~~~~~~~~~~~~~~~~~~~~~~~ | |
11fdf7f2 | 159 | |
9f95a23c TL |
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. | |
11fdf7f2 TL |
167 | |
168 | .. code-block:: console | |
169 | ||
9f95a23c TL |
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)" | |
11fdf7f2 | 173 | |
9f95a23c TL |
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. | |
11fdf7f2 | 178 | |
9f95a23c | 179 | The kernel thread for each interface will be bound as follows: |
11fdf7f2 | 180 | |
9f95a23c TL |
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 | |
11fdf7f2 | 185 | |
9f95a23c | 186 | .. code-block:: console |
11fdf7f2 | 187 | |
9f95a23c TL |
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)" | |
11fdf7f2 | 191 | |
9f95a23c TL |
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. | |
11fdf7f2 | 202 | |
9f95a23c TL |
203 | Since the physical NIC ports are not being used, link monitoring can be |
204 | disabled by **not** specifying the ``-m`` flag to ``kni``: | |
11fdf7f2 TL |
205 | |
206 | .. code-block:: console | |
207 | ||
9f95a23c TL |
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)" | |
11fdf7f2 TL |
211 | |
212 | KNI Operations | |
213 | -------------- | |
214 | ||
9f95a23c TL |
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. | |
11fdf7f2 | 218 | |
9f95a23c | 219 | Enable KNI interface and assign an IP address: |
11fdf7f2 TL |
220 | |
221 | .. code-block:: console | |
222 | ||
f67539c2 | 223 | # ip addr add dev vEth0_0 192.168.0.1 |
11fdf7f2 | 224 | |
9f95a23c | 225 | Show KNI interface configuration and statistics: |
11fdf7f2 TL |
226 | |
227 | .. code-block:: console | |
228 | ||
f67539c2 | 229 | # ip -s -d addr show vEth0_0 |
9f95a23c TL |
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 | |
f67539c2 | 237 | # pkill -USR1 kni |
9f95a23c TL |
238 | |
239 | # Zero statistics | |
f67539c2 | 240 | # pkill -USR2 kni |
11fdf7f2 | 241 | |
9f95a23c | 242 | Dump network traffic: |
11fdf7f2 TL |
243 | |
244 | .. code-block:: console | |
245 | ||
f67539c2 | 246 | # tshark -n -i vEth0_0 |
9f95a23c TL |
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. | |
11fdf7f2 TL |
252 | |
253 | Change the MAC address: | |
254 | ||
255 | .. code-block:: console | |
256 | ||
f67539c2 | 257 | # ip link set dev vEth0_0 lladdr 0C:01:02:03:04:08 |
9f95a23c TL |
258 | |
259 | Change the MTU size: | |
260 | ||
261 | .. code-block:: console | |
262 | ||
f67539c2 | 263 | # ip link set dev vEth0_0 mtu 1450 |
9f95a23c | 264 | |
f67539c2 | 265 | Limited ethtool support: |
9f95a23c TL |
266 | |
267 | .. code-block:: console | |
268 | ||
f67539c2 | 269 | # ethtool -i vEth0_0 |
11fdf7f2 | 270 | |
9f95a23c TL |
271 | When the ``kni`` application is closed, all the KNI interfaces are deleted |
272 | from the Linux kernel. | |
11fdf7f2 TL |
273 | |
274 | Explanation | |
275 | ----------- | |
276 | ||
277 | The following sections provide some explanation of code. | |
278 | ||
279 | Initialization | |
280 | ~~~~~~~~~~~~~~ | |
281 | ||
282 | Setup of mbuf pool, driver and queues is similar to the setup done in the :doc:`l2_forward_real_virtual`.. | |
283 | In addition, one or more kernel NIC interfaces are allocated for each | |
284 | of the configured ports according to the command line parameters. | |
285 | ||
286 | The code for allocating the kernel NIC interfaces for a specific port is | |
287 | in the function ``kni_alloc``. | |
288 | ||
289 | The other step in the initialization process that is unique to this sample application | |
290 | is the association of each port with lcores for RX, TX and kernel threads. | |
291 | ||
292 | * One lcore to read from the port and write to the associated one or more KNI devices | |
293 | ||
294 | * Another lcore to read from one or more KNI devices and write to the port | |
295 | ||
296 | * Other lcores for pinning the kernel threads on one by one | |
297 | ||
298 | This is done by using the ``kni_port_params_array[]`` array, which is indexed by the port ID. | |
299 | The code is in the function ``parse_config``. | |
300 | ||
301 | Packet Forwarding | |
302 | ~~~~~~~~~~~~~~~~~ | |
303 | ||
304 | After the initialization steps are completed, the main_loop() function is run on each lcore. | |
305 | This function first checks the lcore_id against the user provided lcore_rx and lcore_tx | |
306 | to see if this lcore is reading from or writing to kernel NIC interfaces. | |
307 | ||
308 | For the case that reads from a NIC port and writes to the kernel NIC interfaces (``kni_ingress``), | |
309 | the packet reception is the same as in L2 Forwarding sample application | |
310 | (see :ref:`l2_fwd_app_rx_tx_packets`). | |
9f95a23c | 311 | The packet transmission is done by sending mbufs into the kernel NIC interfaces by ``rte_kni_tx_burst()``. |
11fdf7f2 TL |
312 | The KNI library automatically frees the mbufs after the kernel successfully copied the mbufs. |
313 | ||
314 | For the other case that reads from kernel NIC interfaces | |
315 | and writes to a physical NIC port (``kni_egress``), | |
316 | packets are retrieved by reading mbufs from kernel NIC interfaces by ``rte_kni_rx_burst()``. | |
317 | The packet transmission is the same as in the L2 Forwarding sample application | |
318 | (see :ref:`l2_fwd_app_rx_tx_packets`). |