15630257fSFerruh Yigit.. SPDX-License-Identifier: BSD-3-Clause 25630257fSFerruh Yigit Copyright(c) 2010-2014 Intel Corporation. 3d0dff9baSBernard Iremonger 4d0dff9baSBernard IremongerKernel NIC Interface Sample Application 5d0dff9baSBernard Iremonger======================================= 6d0dff9baSBernard Iremonger 7e0c7c473SSiobhan ButlerThe Kernel NIC Interface (KNI) is a DPDK control plane solution that 8d0dff9baSBernard Iremongerallows userspace applications to exchange packets with the kernel networking stack. 9e0c7c473SSiobhan ButlerTo accomplish this, DPDK userspace applications use an IOCTL call 10d0dff9baSBernard Iremongerto request the creation of a KNI virtual device in the Linux* kernel. 11e0c7c473SSiobhan ButlerThe IOCTL call provides interface information and the DPDK's physical address space, 12d0dff9baSBernard Iremongerwhich is re-mapped into the kernel address space by the KNI kernel loadable module 13d0dff9baSBernard Iremongerthat saves the information to a virtual device context. 14e0c7c473SSiobhan ButlerThe DPDK creates FIFO queues for packet ingress and egress 15d0dff9baSBernard Iremongerto the kernel module for each device allocated. 16d0dff9baSBernard Iremonger 17d0dff9baSBernard IremongerThe KNI kernel loadable module is a standard net driver, 18e0c7c473SSiobhan Butlerwhich upon receiving the IOCTL call access the DPDK's FIFO queue to 19e0c7c473SSiobhan Butlerreceive/transmit packets from/to the DPDK userspace application. 20e0c7c473SSiobhan ButlerThe FIFO queues contain pointers to data packets in the DPDK. This: 21d0dff9baSBernard Iremonger 22d0dff9baSBernard Iremonger* Provides a faster mechanism to interface with the kernel net stack and eliminates system calls 23d0dff9baSBernard Iremonger 2489247e1aSStephen Hemminger* Facilitates the DPDK using standard Linux* userspace net tools (tshark, rsync, and so on) 25d0dff9baSBernard Iremonger 26d0dff9baSBernard Iremonger* Eliminate the copy_to_user and copy_from_user operations on packets. 27d0dff9baSBernard Iremonger 28d0dff9baSBernard IremongerThe Kernel NIC Interface sample application is a simple example that demonstrates the use 29e0c7c473SSiobhan Butlerof the DPDK to create a path for packets to go through the Linux* kernel. 30e0c7c473SSiobhan ButlerThis is done by creating one or more kernel net devices for each of the DPDK ports. 3189247e1aSStephen HemmingerThe application allows the use of standard Linux tools (ethtool, iproute, tshark) with the DPDK ports and 32e0c7c473SSiobhan Butleralso the exchange of packets between the DPDK application and the Linux* kernel. 33d0dff9baSBernard Iremonger 34724beb91SDan GoraThe Kernel NIC Interface sample application requires that the 35724beb91SDan GoraKNI kernel module ``rte_kni`` be loaded into the kernel. See 36724beb91SDan Gora:doc:`../prog_guide/kernel_nic_interface` for more information on loading 37724beb91SDan Gorathe ``rte_kni`` kernel module. 38724beb91SDan Gora 39d0dff9baSBernard IremongerOverview 40d0dff9baSBernard Iremonger-------- 41d0dff9baSBernard Iremonger 42724beb91SDan GoraThe Kernel NIC Interface sample application ``kni`` allocates one or more 43724beb91SDan GoraKNI interfaces for each physical NIC port. For each physical NIC port, 44724beb91SDan Gora``kni`` uses two DPDK threads in user space; one thread reads from the port and 45724beb91SDan Gorawrites to the corresponding KNI interfaces and the other thread reads from 46724beb91SDan Gorathe KNI interfaces and writes the data unmodified to the physical NIC port. 47d0dff9baSBernard Iremonger 48724beb91SDan GoraIt is recommended to configure one KNI interface for each physical NIC port. 49724beb91SDan GoraThe application can be configured with more than one KNI interface for 50724beb91SDan Goraeach physical NIC port for performance testing or it can work together with 51724beb91SDan GoraVMDq support in future. 52724beb91SDan Gora 53724beb91SDan GoraThe packet flow through the Kernel NIC Interface application is as shown 54724beb91SDan Gorain the following figure. 55d0dff9baSBernard Iremonger 564a22e6eeSJohn McNamara.. _figure_kernel_nic: 57d0dff9baSBernard Iremonger 584a22e6eeSJohn McNamara.. figure:: img/kernel_nic.* 59d0dff9baSBernard Iremonger 604a22e6eeSJohn McNamara Kernel NIC Application Packet Flow 61d0dff9baSBernard Iremonger 62724beb91SDan GoraIf link monitoring is enabled with the ``-m`` command line flag, one 63724beb91SDan Goraadditional pthread is launched which will check the link status of each 64724beb91SDan Goraphysical NIC port and will update the carrier status of the corresponding 65724beb91SDan GoraKNI interface(s) to match the physical NIC port's state. This means that 66724beb91SDan Gorathe KNI interface(s) will be disabled automatically when the Ethernet link 67724beb91SDan Goragoes down and enabled when the Ethernet link goes up. 68724beb91SDan Gora 69724beb91SDan GoraIf link monitoring is enabled, the ``rte_kni`` kernel module should be loaded 70724beb91SDan Gorasuch that the :ref:`default carrier state <kni_default_carrier_state>` is 71724beb91SDan Goraset to *off*. This ensures that the KNI interface is only enabled *after* 72724beb91SDan Gorathe Ethernet link of the corresponding NIC port has reached the linkup state. 73724beb91SDan Gora 74724beb91SDan GoraIf link monitoring is not enabled, the ``rte_kni`` kernel module should be 75724beb91SDan Goraloaded with the :ref:`default carrier state <kni_default_carrier_state>` 76724beb91SDan Goraset to *on*. This sets the carrier state of the KNI interfaces to *on* 77724beb91SDan Gorawhen the KNI interfaces are enabled without regard to the actual link state 78724beb91SDan Goraof the corresponding NIC port. This is useful for testing in loopback 79724beb91SDan Goramode where the NIC port may not be physically connected to anything. 80724beb91SDan Gora 81d0dff9baSBernard IremongerCompiling the Application 82d0dff9baSBernard Iremonger------------------------- 83d0dff9baSBernard Iremonger 847cacb056SHerakliusz LipiecTo compile the sample application see :doc:`compiling`. 85d0dff9baSBernard Iremonger 86724beb91SDan GoraThe application is located in the ``examples/kni`` sub-directory. 87d0dff9baSBernard Iremonger 88d0dff9baSBernard Iremonger.. note:: 89d0dff9baSBernard Iremonger 90218c4e68SBruce Richardson This application is intended as a linux only. 91d0dff9baSBernard Iremonger 92724beb91SDan GoraRunning the kni Example Application 93724beb91SDan Gora----------------------------------- 94d0dff9baSBernard Iremonger 95724beb91SDan GoraThe ``kni`` example application requires a number of command line options: 96d0dff9baSBernard Iremonger 97d0dff9baSBernard Iremonger.. code-block:: console 98d0dff9baSBernard Iremonger 99*e2a94f9aSCiara Power dpdk-kni [EAL options] -- -p PORTMASK --config="(port,lcore_rx,lcore_tx[,lcore_kthread,...])[,(port,lcore_rx,lcore_tx[,lcore_kthread,...])]" [-P] [-m] 100d0dff9baSBernard Iremonger 101d0dff9baSBernard IremongerWhere: 102d0dff9baSBernard Iremonger 103724beb91SDan Gora* ``-p PORTMASK``: 104d0dff9baSBernard Iremonger 105724beb91SDan Gora Hexadecimal bitmask of ports to configure. 106d0dff9baSBernard Iremonger 107724beb91SDan Gora* ``--config="(port,lcore_rx,lcore_tx[,lcore_kthread,...])[,(port,lcore_rx,lcore_tx[,lcore_kthread,...])]"``: 108d0dff9baSBernard Iremonger 109724beb91SDan Gora Determines which lcores the Rx and Tx DPDK tasks, and (optionally) 110724beb91SDan Gora the KNI kernel thread(s) are bound to for each physical port. 111d0dff9baSBernard Iremonger 112724beb91SDan Gora* ``-P``: 113d0dff9baSBernard Iremonger 114724beb91SDan Gora Optional flag to set all ports to promiscuous mode so that packets are 115724beb91SDan Gora accepted regardless of the packet's Ethernet MAC destination address. 116724beb91SDan Gora Without this option, only packets with the Ethernet MAC destination 117724beb91SDan Gora address set to the Ethernet address of the port are accepted. 118d0dff9baSBernard Iremonger 119724beb91SDan Gora* ``-m``: 120724beb91SDan Gora 121724beb91SDan Gora Optional flag to enable monitoring and updating of the Ethernet 122724beb91SDan Gora carrier state. With this option set, a thread will be started which 123724beb91SDan Gora will periodically check the Ethernet link status of the physical 124724beb91SDan Gora Ethernet ports and set the carrier state of the corresponding KNI 125724beb91SDan Gora network interface to match it. This means that the KNI interface will 126724beb91SDan Gora be disabled automatically when the Ethernet link goes down and enabled 127724beb91SDan Gora when the Ethernet link goes up. 128724beb91SDan Gora 129724beb91SDan GoraRefer to *DPDK Getting Started Guide* for general information on running 130724beb91SDan Goraapplications and the Environment Abstraction Layer (EAL) options. 131724beb91SDan Gora 132724beb91SDan GoraThe ``-c coremask`` or ``-l corelist`` parameter of the EAL options must 133724beb91SDan Gorainclude the lcores specified by ``lcore_rx`` and ``lcore_tx`` for each port, 134724beb91SDan Gorabut does not need to include lcores specified by ``lcore_kthread`` as those 135724beb91SDan Goracores are used to pin the kernel threads in the ``rte_kni`` kernel module. 136724beb91SDan Gora 137724beb91SDan GoraThe ``--config`` parameter must include a set of 138724beb91SDan Gora``(port,lcore_rx,lcore_tx,[lcore_kthread,...])`` values for each physical 139724beb91SDan Goraport specified in the ``-p PORTMASK`` parameter. 140724beb91SDan Gora 141724beb91SDan GoraThe optional ``lcore_kthread`` lcore ID parameter in ``--config`` can be 142724beb91SDan Goraspecified zero, one or more times for each physical port. 143724beb91SDan Gora 144724beb91SDan GoraIf no lcore ID is specified for ``lcore_kthread``, one KNI interface will 145724beb91SDan Gorabe created for the physical port ``port`` and the KNI kernel thread(s) 146724beb91SDan Gorawill have no specific core affinity. 147724beb91SDan Gora 148724beb91SDan GoraIf one or more lcore IDs are specified for ``lcore_kthread``, a KNI interface 149724beb91SDan Gorawill be created for each lcore ID specified, bound to the physical port 150724beb91SDan Gora``port``. If the ``rte_kni`` kernel module is loaded in :ref:`multiple 151724beb91SDan Gorakernel thread <kni_kernel_thread_mode>` mode, a kernel thread will be created 152724beb91SDan Gorafor each KNI interface and bound to the specified core. If the ``rte_kni`` 153724beb91SDan Gorakernel module is loaded in :ref:`single kernel thread <kni_kernel_thread_mode>` 154724beb91SDan Goramode, only one kernel thread is started for all KNI interfaces. The kernel 155724beb91SDan Gorathread will be bound to the first ``lcore_kthread`` lcore ID specified. 156724beb91SDan Gora 157724beb91SDan GoraExample Configurations 158724beb91SDan Gora~~~~~~~~~~~~~~~~~~~~~~~ 159724beb91SDan Gora 160724beb91SDan GoraThe following commands will first load the ``rte_kni`` kernel module in 161724beb91SDan Gora:ref:`multiple kernel thread <kni_kernel_thread_mode>` mode. The ``kni`` 162724beb91SDan Goraapplication is then started using two ports; Port 0 uses lcore 4 for the 163724beb91SDan GoraRx task, lcore 6 for the Tx task, and will create a single KNI interface 164724beb91SDan Gora``vEth0_0`` with the kernel thread bound to lcore 8. Port 1 uses lcore 165724beb91SDan Gora5 for the Rx task, lcore 7 for the Tx task, and will create a single KNI 166724beb91SDan Gorainterface ``vEth1_0`` with the kernel thread bound to lcore 9. 167d0dff9baSBernard Iremonger 168d0dff9baSBernard Iremonger.. code-block:: console 169d0dff9baSBernard Iremonger 170724beb91SDan Gora # rmmod rte_kni 171*e2a94f9aSCiara Power # insmod <build_dir>/kernel/linux/kni/rte_kni.ko kthread_mode=multiple 172*e2a94f9aSCiara Power # ./<build-dir>/examples/dpdk-kni -l 4-7 -n 4 -- -P -p 0x3 -m --config="(0,4,6,8),(1,5,7,9)" 173724beb91SDan Gora 174724beb91SDan GoraThe following example is identical, except an additional ``lcore_kthread`` 175724beb91SDan Goracore is specified per physical port. In this case, ``kni`` will create 176724beb91SDan Gorafour KNI interfaces: ``vEth0_0``/``vEth0_1`` bound to physical port 0 and 177724beb91SDan Gora``vEth1_0``/``vEth1_1`` bound to physical port 1. 178724beb91SDan Gora 179724beb91SDan GoraThe kernel thread for each interface will be bound as follows: 180724beb91SDan Gora 181724beb91SDan Gora * ``vEth0_0`` - bound to lcore 8. 182724beb91SDan Gora * ``vEth0_1`` - bound to lcore 10. 183724beb91SDan Gora * ``vEth1_0`` - bound to lcore 9. 184724beb91SDan Gora * ``vEth1_1`` - bound to lcore 11 185724beb91SDan Gora 186724beb91SDan Gora.. code-block:: console 187724beb91SDan Gora 188724beb91SDan Gora # rmmod rte_kni 189*e2a94f9aSCiara Power # insmod <build_dir>/kernel/linux/kni/rte_kni.ko kthread_mode=multiple 190*e2a94f9aSCiara Power # ./<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)" 191724beb91SDan Gora 192724beb91SDan GoraThe following example can be used to test the interface between the ``kni`` 193724beb91SDan Goratest application and the ``rte_kni`` kernel module. In this example, 194724beb91SDan Gorathe ``rte_kni`` kernel module is loaded in :ref:`single kernel thread 195724beb91SDan Goramode <kni_kernel_thread_mode>`, :ref:`loopback mode <kni_loopback_mode>` 196724beb91SDan Goraenabled, and the :ref:`default carrier state <kni_default_carrier_state>` 197724beb91SDan Gorais set to *on* so that the corresponding physical NIC port does not have 198724beb91SDan Gorato be connected in order to use the KNI interface. One KNI interface 199724beb91SDan Gora``vEth0_0`` is created for port 0 and one KNI interface ``vEth1_0`` is 200724beb91SDan Goracreated for port 1. Since ``rte_kni`` is loaded in "single kernel thread" 201724beb91SDan Goramode, the one kernel thread is bound to lcore 8. 202724beb91SDan Gora 203724beb91SDan GoraSince the physical NIC ports are not being used, link monitoring can be 204724beb91SDan Goradisabled by **not** specifying the ``-m`` flag to ``kni``: 205724beb91SDan Gora 206724beb91SDan Gora.. code-block:: console 207724beb91SDan Gora 208724beb91SDan Gora # rmmod rte_kni 209*e2a94f9aSCiara Power # insmod <build_dir>/kernel/linux/kni/rte_kni.ko lo_mode=lo_mode_fifo carrier=on 210*e2a94f9aSCiara Power # ./<build-dir>/examples/dpdk-kni -l 4-7 -n 4 -- -P -p 0x3 --config="(0,4,6,8),(1,5,7,9)" 211d0dff9baSBernard Iremonger 212d0dff9baSBernard IremongerKNI Operations 213d0dff9baSBernard Iremonger-------------- 214d0dff9baSBernard Iremonger 215724beb91SDan GoraOnce the ``kni`` application is started, the user can use the normal 216724beb91SDan GoraLinux commands to manage the KNI interfaces as if they were any other 217724beb91SDan GoraLinux network interface. 218d0dff9baSBernard Iremonger 219724beb91SDan GoraEnable KNI interface and assign an IP address: 220d0dff9baSBernard Iremonger 221d0dff9baSBernard Iremonger.. code-block:: console 222d0dff9baSBernard Iremonger 22389247e1aSStephen Hemminger # ip addr add dev vEth0_0 192.168.0.1 224d0dff9baSBernard Iremonger 225724beb91SDan GoraShow KNI interface configuration and statistics: 226d0dff9baSBernard Iremonger 227d0dff9baSBernard Iremonger.. code-block:: console 228d0dff9baSBernard Iremonger 22989247e1aSStephen Hemminger # ip -s -d addr show vEth0_0 230d0dff9baSBernard Iremonger 231724beb91SDan GoraThe user can also check and reset the packet statistics inside the ``kni`` 232724beb91SDan Goraapplication by sending the app the USR1 and USR2 signals: 233724beb91SDan Gora 234724beb91SDan Gora.. code-block:: console 235724beb91SDan Gora 236724beb91SDan Gora # Print statistics 23789247e1aSStephen Hemminger # pkill -USR1 kni 238724beb91SDan Gora 239724beb91SDan Gora # Zero statistics 24089247e1aSStephen Hemminger # pkill -USR2 kni 241724beb91SDan Gora 242724beb91SDan GoraDump network traffic: 243d0dff9baSBernard Iremonger 244d0dff9baSBernard Iremonger.. code-block:: console 245d0dff9baSBernard Iremonger 24689247e1aSStephen Hemminger # tshark -n -i vEth0_0 247d0dff9baSBernard Iremonger 248724beb91SDan GoraThe normal Linux commands can also be used to change the MAC address and 249724beb91SDan GoraMTU size used by the physical NIC which corresponds to the KNI interface. 250724beb91SDan GoraHowever, if more than one KNI interface is configured for a physical port, 251724beb91SDan Gorathese commands will only work on the first KNI interface for that port. 252724beb91SDan Gora 2531cfe212eSHemant AgrawalChange the MAC address: 2541cfe212eSHemant Agrawal 2551cfe212eSHemant Agrawal.. code-block:: console 2561cfe212eSHemant Agrawal 25789247e1aSStephen Hemminger # ip link set dev vEth0_0 lladdr 0C:01:02:03:04:08 2581cfe212eSHemant Agrawal 259724beb91SDan GoraChange the MTU size: 260724beb91SDan Gora 261724beb91SDan Gora.. code-block:: console 262724beb91SDan Gora 26389247e1aSStephen Hemminger # ip link set dev vEth0_0 mtu 1450 26489247e1aSStephen Hemminger 26589247e1aSStephen HemmingerLimited ethtool support: 26689247e1aSStephen Hemminger 26789247e1aSStephen Hemminger.. code-block:: console 26889247e1aSStephen Hemminger 26989247e1aSStephen Hemminger # ethtool -i vEth0_0 270724beb91SDan Gora 271724beb91SDan GoraWhen the ``kni`` application is closed, all the KNI interfaces are deleted 272724beb91SDan Gorafrom the Linux kernel. 273d0dff9baSBernard Iremonger 274d0dff9baSBernard IremongerExplanation 275d0dff9baSBernard Iremonger----------- 276d0dff9baSBernard Iremonger 277d0dff9baSBernard IremongerThe following sections provide some explanation of code. 278d0dff9baSBernard Iremonger 279d0dff9baSBernard IremongerInitialization 280d0dff9baSBernard Iremonger~~~~~~~~~~~~~~ 281d0dff9baSBernard Iremonger 282513b0723SMauricio Vasquez BSetup of mbuf pool, driver and queues is similar to the setup done in the :doc:`l2_forward_real_virtual`.. 283d0dff9baSBernard IremongerIn addition, one or more kernel NIC interfaces are allocated for each 284d0dff9baSBernard Iremongerof the configured ports according to the command line parameters. 285d0dff9baSBernard Iremonger 28605096a8bSThomas MonjalonThe code for allocating the kernel NIC interfaces for a specific port is 28705096a8bSThomas Monjalonin the function ``kni_alloc``. 288d0dff9baSBernard Iremonger 289d0dff9baSBernard IremongerThe other step in the initialization process that is unique to this sample application 290d0dff9baSBernard Iremongeris the association of each port with lcores for RX, TX and kernel threads. 291d0dff9baSBernard Iremonger 292d0dff9baSBernard Iremonger* One lcore to read from the port and write to the associated one or more KNI devices 293d0dff9baSBernard Iremonger 294d0dff9baSBernard Iremonger* Another lcore to read from one or more KNI devices and write to the port 295d0dff9baSBernard Iremonger 296d0dff9baSBernard Iremonger* Other lcores for pinning the kernel threads on one by one 297d0dff9baSBernard Iremonger 29805096a8bSThomas MonjalonThis is done by using the ``kni_port_params_array[]`` array, which is indexed by the port ID. 29905096a8bSThomas MonjalonThe code is in the function ``parse_config``. 300d0dff9baSBernard Iremonger 301d0dff9baSBernard IremongerPacket Forwarding 302d0dff9baSBernard Iremonger~~~~~~~~~~~~~~~~~ 303d0dff9baSBernard Iremonger 304d0dff9baSBernard IremongerAfter the initialization steps are completed, the main_loop() function is run on each lcore. 305d0dff9baSBernard IremongerThis function first checks the lcore_id against the user provided lcore_rx and lcore_tx 306d0dff9baSBernard Iremongerto see if this lcore is reading from or writing to kernel NIC interfaces. 307d0dff9baSBernard Iremonger 30805096a8bSThomas MonjalonFor the case that reads from a NIC port and writes to the kernel NIC interfaces (``kni_ingress``), 309d0dff9baSBernard Iremongerthe packet reception is the same as in L2 Forwarding sample application 310513b0723SMauricio Vasquez B(see :ref:`l2_fwd_app_rx_tx_packets`). 311724beb91SDan GoraThe packet transmission is done by sending mbufs into the kernel NIC interfaces by ``rte_kni_tx_burst()``. 312d0dff9baSBernard IremongerThe KNI library automatically frees the mbufs after the kernel successfully copied the mbufs. 313d0dff9baSBernard Iremonger 31405096a8bSThomas MonjalonFor the other case that reads from kernel NIC interfaces 31505096a8bSThomas Monjalonand writes to a physical NIC port (``kni_egress``), 31605096a8bSThomas Monjalonpackets are retrieved by reading mbufs from kernel NIC interfaces by ``rte_kni_rx_burst()``. 317d0dff9baSBernard IremongerThe packet transmission is the same as in the L2 Forwarding sample application 318513b0723SMauricio Vasquez B(see :ref:`l2_fwd_app_rx_tx_packets`). 319