1.. SPDX-License-Identifier: BSD-3-Clause 2 Copyright(c) 2010-2015 Intel Corporation. 3 4.. _kni: 5 6Kernel NIC Interface 7==================== 8 9The DPDK Kernel NIC Interface (KNI) allows userspace applications access to the Linux* control plane. 10 11The benefits of using the DPDK KNI are: 12 13* Faster than existing Linux TUN/TAP interfaces 14 (by eliminating system calls and copy_to_user()/copy_from_user() operations. 15 16* Allows management of DPDK ports using standard Linux net tools such as ethtool, ifconfig and tcpdump. 17 18* Allows an interface with the kernel network stack. 19 20The components of an application using the DPDK Kernel NIC Interface are shown in :numref:`figure_kernel_nic_intf`. 21 22.. _figure_kernel_nic_intf: 23 24.. figure:: img/kernel_nic_intf.* 25 26 Components of a DPDK KNI Application 27 28 29The DPDK KNI Kernel Module 30-------------------------- 31 32The KNI kernel loadable module ``rte_kni`` provides the kernel interface 33for DPDK applications. 34 35When the ``rte_kni`` module is loaded, it will create a device ``/dev/kni`` 36that is used by the DPDK KNI API functions to control and communicate with 37the kernel module. 38 39The ``rte_kni`` kernel module contains several optional parameters which 40can be specified when the module is loaded to control its behavior: 41 42.. code-block:: console 43 44 # modinfo rte_kni.ko 45 <snip> 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 50 (charp) 51 parm: kthread_mode: Kernel thread mode (default=single): 52 single Single kernel thread mode enabled. 53 multiple Multiple kernel thread mode enabled. 54 (charp) 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. 58 (charp) 59 parm: enable_bifurcated: Enable request processing support for 60 bifurcated drivers, which means releasing rtnl_lock before calling 61 userspace callback and supporting async requests (default=off): 62 on Enable request processing support for bifurcated drivers. 63 (charp) 64 65 66Loading the ``rte_kni`` kernel module without any optional parameters is 67the typical way a DPDK application gets packets into and out of the kernel 68network stack. Without any parameters, only one kernel thread is created 69for all KNI devices for packet receiving in kernel side, loopback mode is 70disabled, and the default carrier state of KNI interfaces is set to *off*. 71 72.. code-block:: console 73 74 # insmod <build_dir>/kernel/linux/kni/rte_kni.ko 75 76.. _kni_loopback_mode: 77 78Loopback Mode 79~~~~~~~~~~~~~ 80 81For testing, the ``rte_kni`` kernel module can be loaded in loopback mode 82by specifying the ``lo_mode`` parameter: 83 84.. code-block:: console 85 86 # insmod <build_dir>/kernel/linux/kni/rte_kni.ko lo_mode=lo_mode_fifo 87 88The ``lo_mode_fifo`` loopback option will loop back ring enqueue/dequeue 89operations in kernel space. 90 91.. code-block:: console 92 93 # insmod <build_dir>/kernel/linux/kni/rte_kni.ko lo_mode=lo_mode_fifo_skb 94 95The ``lo_mode_fifo_skb`` loopback option will loop back ring enqueue/dequeue 96operations and sk buffer copies in kernel space. 97 98If the ``lo_mode`` parameter is not specified, loopback mode is disabled. 99 100.. _kni_kernel_thread_mode: 101 102Kernel Thread Mode 103~~~~~~~~~~~~~~~~~~ 104 105To provide flexibility of performance, the ``rte_kni`` KNI kernel module 106can be loaded with the ``kthread_mode`` parameter. The ``rte_kni`` kernel 107module supports two options: "single kernel thread" mode and "multiple 108kernel thread" mode. 109 110Single kernel thread mode is enabled as follows: 111 112.. code-block:: console 113 114 # insmod <build_dir>/kernel/linux/kni/rte_kni.ko kthread_mode=single 115 116This mode will create only one kernel thread for all KNI interfaces to 117receive data on the kernel side. By default, this kernel thread is not 118bound to any particular core, but the user can set the core affinity for 119this kernel thread by setting the ``core_id`` and ``force_bind`` parameters 120in ``struct rte_kni_conf`` when the first KNI interface is created: 121 122For optimum performance, the kernel thread should be bound to a core in 123on the same socket as the DPDK lcores used in the application. 124 125The KNI kernel module can also be configured to start a separate kernel 126thread for each KNI interface created by the DPDK application. Multiple 127kernel thread mode is enabled as follows: 128 129.. code-block:: console 130 131 # insmod <build_dir>/kernel/linux/kni/rte_kni.ko kthread_mode=multiple 132 133This mode will create a separate kernel thread for each KNI interface to 134receive data on the kernel side. The core affinity of each ``kni_thread`` 135kernel thread can be specified by setting the ``core_id`` and ``force_bind`` 136parameters in ``struct rte_kni_conf`` when each KNI interface is created. 137 138Multiple kernel thread mode can provide scalable higher performance if 139sufficient unused cores are available on the host system. 140 141If the ``kthread_mode`` parameter is not specified, the "single kernel 142thread" mode is used. 143 144.. _kni_default_carrier_state: 145 146Default Carrier State 147~~~~~~~~~~~~~~~~~~~~~ 148 149The default carrier state of KNI interfaces created by the ``rte_kni`` 150kernel module is controlled via the ``carrier`` option when the module 151is loaded. 152 153If ``carrier=off`` is specified, the kernel module will leave the carrier 154state of the interface *down* when the interface is management enabled. 155The DPDK application can set the carrier state of the KNI interface using the 156``rte_kni_update_link()`` function. This is useful for DPDK applications 157which require that the carrier state of the KNI interface reflect the 158actual link state of the corresponding physical NIC port. 159 160If ``carrier=on`` is specified, the kernel module will automatically set 161the carrier state of the interface to *up* when the interface is management 162enabled. This is useful for DPDK applications which use the KNI interface as 163a purely virtual interface that does not correspond to any physical hardware 164and do not wish to explicitly set the carrier state of the interface with 165``rte_kni_update_link()``. It is also useful for testing in loopback mode 166where the NIC port may not be physically connected to anything. 167 168To set the default carrier state to *on*: 169 170.. code-block:: console 171 172 # insmod <build_dir>/kernel/linux/kni/rte_kni.ko carrier=on 173 174To set the default carrier state to *off*: 175 176.. code-block:: console 177 178 # insmod <build_dir>/kernel/linux/kni/rte_kni.ko carrier=off 179 180If the ``carrier`` parameter is not specified, the default carrier state 181of KNI interfaces will be set to *off*. 182 183.. _kni_bifurcated_device_support: 184 185Bifurcated Device Support 186~~~~~~~~~~~~~~~~~~~~~~~~~ 187 188User callbacks are executed while kernel module holds the ``rtnl`` lock, this 189causes a deadlock when callbacks run control commands on another Linux kernel 190network interface. 191 192Bifurcated devices has kernel network driver part and to prevent deadlock for 193them ``enable_bifurcated`` is used. 194 195To enable bifurcated device support: 196 197.. code-block:: console 198 199 # insmod <build_dir>/kernel/linux/kni/rte_kni.ko enable_bifurcated=on 200 201Enabling bifurcated device support releases ``rtnl`` lock before calling 202callback and locks it back after callback. Also enables asynchronous request to 203support callbacks that requires rtnl lock to work (interface down). 204 205KNI Creation and Deletion 206------------------------- 207 208Before any KNI interfaces can be created, the ``rte_kni`` kernel module must 209be loaded into the kernel and configured with the ``rte_kni_init()`` function. 210 211The KNI interfaces are created by a DPDK application dynamically via the 212``rte_kni_alloc()`` function. 213 214The ``struct rte_kni_conf`` structure contains fields which allow the 215user to specify the interface name, set the MTU size, set an explicit or 216random MAC address and control the affinity of the kernel Rx thread(s) 217(both single and multi-threaded modes). 218By default the KNI sample example gets the MTU from the matching device, 219and in case of KNI PMD it is derived from mbuf buffer length. 220 221The ``struct rte_kni_ops`` structure contains pointers to functions to 222handle requests from the ``rte_kni`` kernel module. These functions 223allow DPDK applications to perform actions when the KNI interfaces are 224manipulated by control commands or functions external to the application. 225 226For example, the DPDK application may wish to enabled/disable a physical 227NIC port when a user enabled/disables a KNI interface with ``ip link set 228[up|down] dev <ifaceX>``. The DPDK application can register a callback for 229``config_network_if`` which will be called when the interface management 230state changes. 231 232There are currently four callbacks for which the user can register 233application functions: 234 235``config_network_if``: 236 237 Called when the management state of the KNI interface changes. 238 For example, when the user runs ``ip link set [up|down] dev <ifaceX>``. 239 240``change_mtu``: 241 242 Called when the user changes the MTU size of the KNI 243 interface. For example, when the user runs ``ip link set mtu <size> 244 dev <ifaceX>``. 245 246``config_mac_address``: 247 248 Called when the user changes the MAC address of the KNI interface. 249 For example, when the user runs ``ip link set address <MAC> 250 dev <ifaceX>``. If the user sets this callback function to NULL, 251 but sets the ``port_id`` field to a value other than -1, a default 252 callback handler in the rte_kni library ``kni_config_mac_address()`` 253 will be called which calls ``rte_eth_dev_default_mac_addr_set()`` 254 on the specified ``port_id``. 255 256``config_promiscusity``: 257 258 Called when the user changes the promiscuity state of the KNI 259 interface. For example, when the user runs ``ip link set promisc 260 [on|off] dev <ifaceX>``. If the user sets this callback function to 261 NULL, but sets the ``port_id`` field to a value other than -1, a default 262 callback handler in the rte_kni library ``kni_config_promiscusity()`` 263 will be called which calls ``rte_eth_promiscuous_<enable|disable>()`` 264 on the specified ``port_id``. 265 266``config_allmulticast``: 267 268 Called when the user changes the allmulticast state of the KNI interface. 269 For example, when the user runs ``ifconfig <ifaceX> [-]allmulti``. If the 270 user sets this callback function to NULL, but sets the ``port_id`` field to 271 a value other than -1, a default callback handler in the rte_kni library 272 ``kni_config_allmulticast()`` will be called which calls 273 ``rte_eth_allmulticast_<enable|disable>()`` on the specified ``port_id``. 274 275In order to run these callbacks, the application must periodically call 276the ``rte_kni_handle_request()`` function. Any user callback function 277registered will be called directly from ``rte_kni_handle_request()`` so 278care must be taken to prevent deadlock and to not block any DPDK fastpath 279tasks. Typically DPDK applications which use these callbacks will need 280to create a separate thread or secondary process to periodically call 281``rte_kni_handle_request()``. 282 283The KNI interfaces can be deleted by a DPDK application with 284``rte_kni_release()``. All KNI interfaces not explicitly deleted will be 285deleted when the ``/dev/kni`` device is closed, either explicitly with 286``rte_kni_close()`` or when the DPDK application is closed. 287 288DPDK mbuf Flow 289-------------- 290 291To minimize the amount of DPDK code running in kernel space, the mbuf mempool is managed in userspace only. 292The kernel module will be aware of mbufs, 293but all mbuf allocation and free operations will be handled by the DPDK application only. 294 295:numref:`figure_pkt_flow_kni` shows a typical scenario with packets sent in both directions. 296 297.. _figure_pkt_flow_kni: 298 299.. figure:: img/pkt_flow_kni.* 300 301 Packet Flow via mbufs in the DPDK KNI 302 303 304Use Case: Ingress 305----------------- 306 307On the DPDK RX side, the mbuf is allocated by the PMD in the RX thread context. 308This thread will enqueue the mbuf in the rx_q FIFO, 309and the next pointers in mbuf-chain will convert to physical address. 310The KNI thread will poll all KNI active devices for the rx_q. 311If an mbuf is dequeued, it will be converted to a sk_buff and sent to the net stack via netif_rx(). 312The dequeued mbuf must be freed, so the same pointer is sent back in the free_q FIFO, 313and next pointers must convert back to virtual address if exists before put in the free_q FIFO. 314 315The RX thread, in the same main loop, polls this FIFO and frees the mbuf after dequeuing it. 316The address conversion of the next pointer is to prevent the chained mbuf 317in different hugepage segments from causing kernel crash. 318 319Use Case: Egress 320---------------- 321 322For packet egress the DPDK application must first enqueue several mbufs to create an mbuf cache on the kernel side. 323 324The packet is received from the Linux net stack, by calling the kni_net_tx() callback. 325The mbuf is dequeued (without waiting due the cache) and filled with data from sk_buff. 326The sk_buff is then freed and the mbuf sent in the tx_q FIFO. 327 328The DPDK TX thread dequeues the mbuf and sends it to the PMD via ``rte_eth_tx_burst()``. 329It then puts the mbuf back in the cache. 330 331IOVA = VA: Support 332------------------ 333 334KNI operates in IOVA_VA scheme when 335 336- LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) and 337- EAL option `iova-mode=va` is passed or bus IOVA scheme in the DPDK is selected 338 as RTE_IOVA_VA. 339 340Due to IOVA to KVA address translations, based on the KNI use case there 341can be a performance impact. For mitigation, forcing IOVA to PA via EAL 342"--iova-mode=pa" option can be used, IOVA_DC bus iommu scheme can also 343result in IOVA as PA. 344 345Ethtool 346------- 347 348Ethtool is a Linux-specific tool with corresponding support in the kernel. 349The current version of kni provides minimal ethtool functionality 350including querying version and link state. It does not support link 351control, statistics, or dumping device registers. 352