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