1 .. SPDX-License-Identifier: BSD-3-Clause
2 Copyright(c) 2010-2015 Intel Corporation.
9 The DPDK Kernel NIC Interface (KNI) allows userspace applications access to the Linux* control plane.
11 The benefits of using the DPDK KNI are:
13 * Faster than existing Linux TUN/TAP interfaces
14 (by eliminating system calls and copy_to_user()/copy_from_user() operations.
16 * Allows management of DPDK ports using standard Linux net tools such as ethtool, ifconfig and tcpdump.
18 * Allows an interface with the kernel network stack.
20 The components of an application using the DPDK Kernel NIC Interface are shown in :numref:`figure_kernel_nic_intf`.
22 .. _figure_kernel_nic_intf:
24 .. figure:: img/kernel_nic_intf.*
26 Components of a DPDK KNI Application
29 The DPDK KNI Kernel Module
30 --------------------------
32 The KNI kernel loadable module ``rte_kni`` provides the kernel interface
33 for DPDK applications.
35 When the ``rte_kni`` module is loaded, it will create a device ``/dev/kni``
36 that is used by the DPDK KNI API functions to control and communicate with
39 The ``rte_kni`` kernel module contains several optional parameters which
40 can be specified when the module is loaded to control its behavior:
42 .. code-block:: console
46 parm: lo_mode: KNI loopback mode (default=lo_mode_none):
47 lo_mode_none Kernel loopback disabled
48 lo_mode_fifo Enable kernel loopback with fifo
49 lo_mode_fifo_skb Enable kernel loopback with fifo and skb buffer
51 parm: kthread_mode: Kernel thread mode (default=single):
52 single Single kernel thread mode enabled.
53 multiple Multiple kernel thread mode enabled.
55 parm: carrier: Default carrier state for KNI interface (default=off):
56 off Interfaces will be created with carrier state set to off.
57 on Interfaces will be created with carrier state set to on.
60 Loading the ``rte_kni`` kernel module without any optional parameters is
61 the typical way a DPDK application gets packets into and out of the kernel
62 network stack. Without any parameters, only one kernel thread is created
63 for all KNI devices for packet receiving in kernel side, loopback mode is
64 disabled, and the default carrier state of KNI interfaces is set to *off*.
66 .. code-block:: console
68 # insmod kmod/rte_kni.ko
70 .. _kni_loopback_mode:
75 For testing, the ``rte_kni`` kernel module can be loaded in loopback mode
76 by specifying the ``lo_mode`` parameter:
78 .. code-block:: console
80 # insmod kmod/rte_kni.ko lo_mode=lo_mode_fifo
82 The ``lo_mode_fifo`` loopback option will loop back ring enqueue/dequeue
83 operations in kernel space.
85 .. code-block:: console
87 # insmod kmod/rte_kni.ko lo_mode=lo_mode_fifo_skb
89 The ``lo_mode_fifo_skb`` loopback option will loop back ring enqueue/dequeue
90 operations and sk buffer copies in kernel space.
92 If the ``lo_mode`` parameter is not specified, loopback mode is disabled.
94 .. _kni_kernel_thread_mode:
99 To provide flexibility of performance, the ``rte_kni`` KNI kernel module
100 can be loaded with the ``kthread_mode`` parameter. The ``rte_kni`` kernel
101 module supports two options: "single kernel thread" mode and "multiple
104 Single kernel thread mode is enabled as follows:
106 .. code-block:: console
108 # insmod kmod/rte_kni.ko kthread_mode=single
110 This mode will create only one kernel thread for all KNI interfaces to
111 receive data on the kernel side. By default, this kernel thread is not
112 bound to any particular core, but the user can set the core affinity for
113 this kernel thread by setting the ``core_id`` and ``force_bind`` parameters
114 in ``struct rte_kni_conf`` when the first KNI interface is created:
116 For optimum performance, the kernel thread should be bound to a core in
117 on the same socket as the DPDK lcores used in the application.
119 The KNI kernel module can also be configured to start a separate kernel
120 thread for each KNI interface created by the DPDK application. Multiple
121 kernel thread mode is enabled as follows:
123 .. code-block:: console
125 # insmod kmod/rte_kni.ko kthread_mode=multiple
127 This mode will create a separate kernel thread for each KNI interface to
128 receive data on the kernel side. The core affinity of each ``kni_thread``
129 kernel thread can be specified by setting the ``core_id`` and ``force_bind``
130 parameters in ``struct rte_kni_conf`` when each KNI interface is created.
132 Multiple kernel thread mode can provide scalable higher performance if
133 sufficient unused cores are available on the host system.
135 If the ``kthread_mode`` parameter is not specified, the "single kernel
136 thread" mode is used.
138 .. _kni_default_carrier_state:
140 Default Carrier State
141 ~~~~~~~~~~~~~~~~~~~~~
143 The default carrier state of KNI interfaces created by the ``rte_kni``
144 kernel module is controlled via the ``carrier`` option when the module
147 If ``carrier=off`` is specified, the kernel module will leave the carrier
148 state of the interface *down* when the interface is management enabled.
149 The DPDK application can set the carrier state of the KNI interface using the
150 ``rte_kni_update_link()`` function. This is useful for DPDK applications
151 which require that the carrier state of the KNI interface reflect the
152 actual link state of the corresponding physical NIC port.
154 If ``carrier=on`` is specified, the kernel module will automatically set
155 the carrier state of the interface to *up* when the interface is management
156 enabled. This is useful for DPDK applications which use the KNI interface as
157 a purely virtual interface that does not correspond to any physical hardware
158 and do not wish to explicitly set the carrier state of the interface with
159 ``rte_kni_update_link()``. It is also useful for testing in loopback mode
160 where the NIC port may not be physically connected to anything.
162 To set the default carrier state to *on*:
164 .. code-block:: console
166 # insmod kmod/rte_kni.ko carrier=on
168 To set the default carrier state to *off*:
170 .. code-block:: console
172 # insmod kmod/rte_kni.ko carrier=off
174 If the ``carrier`` parameter is not specified, the default carrier state
175 of KNI interfaces will be set to *off*.
177 KNI Creation and Deletion
178 -------------------------
180 Before any KNI interfaces can be created, the ``rte_kni`` kernel module must
181 be loaded into the kernel and configured withe ``rte_kni_init()`` function.
183 The KNI interfaces are created by a DPDK application dynamically via the
184 ``rte_kni_alloc()`` function.
186 The ``struct rte_kni_conf`` structure contains fields which allow the
187 user to specify the interface name, set the MTU size, set an explicit or
188 random MAC address and control the affinity of the kernel Rx thread(s)
189 (both single and multi-threaded modes).
190 By default the KNI sample example gets the MTU from the matching device,
191 and in case of KNI PMD it is derived from mbuf buffer length.
193 The ``struct rte_kni_ops`` structure contains pointers to functions to
194 handle requests from the ``rte_kni`` kernel module. These functions
195 allow DPDK applications to perform actions when the KNI interfaces are
196 manipulated by control commands or functions external to the application.
198 For example, the DPDK application may wish to enabled/disable a physical
199 NIC port when a user enabled/disables a KNI interface with ``ip link set
200 [up|down] dev <ifaceX>``. The DPDK application can register a callback for
201 ``config_network_if`` which will be called when the interface management
204 There are currently four callbacks for which the user can register
205 application functions:
207 ``config_network_if``:
209 Called when the management state of the KNI interface changes.
210 For example, when the user runs ``ip link set [up|down] dev <ifaceX>``.
214 Called when the user changes the MTU size of the KNI
215 interface. For example, when the user runs ``ip link set mtu <size>
218 ``config_mac_address``:
220 Called when the user changes the MAC address of the KNI interface.
221 For example, when the user runs ``ip link set address <MAC>
222 dev <ifaceX>``. If the user sets this callback function to NULL,
223 but sets the ``port_id`` field to a value other than -1, a default
224 callback handler in the rte_kni library ``kni_config_mac_address()``
225 will be called which calls ``rte_eth_dev_default_mac_addr_set()``
226 on the specified ``port_id``.
228 ``config_promiscusity``:
230 Called when the user changes the promiscuity state of the KNI
231 interface. For example, when the user runs ``ip link set promisc
232 [on|off] dev <ifaceX>``. If the user sets this callback function to
233 NULL, but sets the ``port_id`` field to a value other than -1, a default
234 callback handler in the rte_kni library ``kni_config_promiscusity()``
235 will be called which calls ``rte_eth_promiscuous_<enable|disable>()``
236 on the specified ``port_id``.
238 In order to run these callbacks, the application must periodically call
239 the ``rte_kni_handle_request()`` function. Any user callback function
240 registered will be called directly from ``rte_kni_handle_request()`` so
241 care must be taken to prevent deadlock and to not block any DPDK fastpath
242 tasks. Typically DPDK applications which use these callbacks will need
243 to create a separate thread or secondary process to periodically call
244 ``rte_kni_handle_request()``.
246 The KNI interfaces can be deleted by a DPDK application with
247 ``rte_kni_release()``. All KNI interfaces not explicitly deleted will be
248 deleted when the the ``/dev/kni`` device is closed, either explicitly with
249 ``rte_kni_close()`` or when the DPDK application is closed.
254 To minimize the amount of DPDK code running in kernel space, the mbuf mempool is managed in userspace only.
255 The kernel module will be aware of mbufs,
256 but all mbuf allocation and free operations will be handled by the DPDK application only.
258 :numref:`figure_pkt_flow_kni` shows a typical scenario with packets sent in both directions.
260 .. _figure_pkt_flow_kni:
262 .. figure:: img/pkt_flow_kni.*
264 Packet Flow via mbufs in the DPDK KNI
270 On the DPDK RX side, the mbuf is allocated by the PMD in the RX thread context.
271 This thread will enqueue the mbuf in the rx_q FIFO,
272 and the next pointers in mbuf-chain will convert to physical address.
273 The KNI thread will poll all KNI active devices for the rx_q.
274 If an mbuf is dequeued, it will be converted to a sk_buff and sent to the net stack via netif_rx().
275 The dequeued mbuf must be freed, so the same pointer is sent back in the free_q FIFO,
276 and next pointers must convert back to virtual address if exists before put in the free_q FIFO.
278 The RX thread, in the same main loop, polls this FIFO and frees the mbuf after dequeuing it.
279 The address conversion of the next pointer is to prevent the chained mbuf
280 in different hugepage segments from causing kernel crash.
285 For packet egress the DPDK application must first enqueue several mbufs to create an mbuf cache on the kernel side.
287 The packet is received from the Linux net stack, by calling the kni_net_tx() callback.
288 The mbuf is dequeued (without waiting due the cache) and filled with data from sk_buff.
289 The sk_buff is then freed and the mbuf sent in the tx_q FIFO.
291 The DPDK TX thread dequeues the mbuf and sends it to the PMD via ``rte_eth_tx_burst()``.
292 It then puts the mbuf back in the cache.
297 Ethtool is a Linux-specific tool with corresponding support in the kernel.
298 The current version of kni provides minimal ethtool functionality
299 including querying version and link state. It does not support link
300 control, statistics, or dumping device registers.