fix ethdev port id validation
[dpdk.git] / doc / guides / sample_app_ug / kernel_nic_interface.rst
index 720142f..fc11099 100644 (file)
@@ -1,62 +1,35 @@
-..  BSD LICENSE
-    Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions
-    are met:
-
-    * Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in
-    the documentation and/or other materials provided with the
-    distribution.
-    * Neither the name of Intel Corporation nor the names of its
-    contributors may be used to endorse or promote products derived
-    from this software without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright(c) 2010-2014 Intel Corporation.
 
 Kernel NIC Interface Sample Application
 =======================================
 
-The Kernel NIC Interface (KNI) is an Intel® DPDK control plane solution that
+The Kernel NIC Interface (KNI) is a DPDK control plane solution that
 allows userspace applications to exchange packets with the kernel networking stack.
-To accomplish this, Intel® DPDK userspace applications use an IOCTL call
+To accomplish this, DPDK userspace applications use an IOCTL call
 to request the creation of a KNI virtual device in the Linux* kernel.
-The IOCTL call provides interface information and the Intel® DPDK's physical address space,
+The IOCTL call provides interface information and the DPDK's physical address space,
 which is re-mapped into the kernel address space by the KNI kernel loadable module
 that saves the information to a virtual device context.
-The Intel® DPDK creates FIFO queues for packet ingress and egress
+The DPDK creates FIFO queues for packet ingress and egress
 to the kernel module for each device allocated.
 
 The KNI kernel loadable module is a standard net driver,
-which upon receiving the IOCTL call access the Intel® DPDK's FIFO queue to
-receive/transmit packets from/to the Intel® DPDK userspace application.
-The FIFO queues contain pointers to data packets in the Intel® DPDK. This:
+which upon receiving the IOCTL call access the DPDK's FIFO queue to
+receive/transmit packets from/to the DPDK userspace application.
+The FIFO queues contain pointers to data packets in the DPDK. This:
 
 *   Provides a faster mechanism to interface with the kernel net stack and eliminates system calls
 
-*   Facilitates the Intel® DPDK using standard Linux* userspace net tools (tcpdump, ftp, and so on)
+*   Facilitates the DPDK using standard Linux* userspace net tools (tcpdump, ftp, and so on)
 
 *   Eliminate the copy_to_user and copy_from_user operations on packets.
 
 The Kernel NIC Interface sample application is a simple example that demonstrates the use
-of the Intel® DPDK to create a path for packets to go through the Linux* kernel.
-This is done by creating one or more kernel net devices for each of the Intel® DPDK ports.
-The application allows the use of standard Linux tools (ethtool, ifconfig, tcpdump) with the Intel® DPDK ports and
-also the exchange of packets between the Intel® DPDK application and the Linux* kernel.
+of the DPDK to create a path for packets to go through the Linux* kernel.
+This is done by creating one or more kernel net devices for each of the DPDK ports.
+The application allows the use of standard Linux tools (ethtool, ifconfig, tcpdump) with the DPDK ports and
+also the exchange of packets between the DPDK application and the Linux* kernel.
 
 Overview
 --------
@@ -71,46 +44,27 @@ it is just for performance testing, or it can work together with VMDq support in
 
 The packet flow through the Kernel NIC Interface application is as shown in the following figure.
 
-.. _figure_2:
+.. _figure_kernel_nic:
 
-**Figure 2. Kernel NIC Application Packet Flow**
+.. figure:: img/kernel_nic.*
 
-.. image3_png has been renamed to kernel_nic.png
-
-|kernel_nic|
+   Kernel NIC Application Packet Flow
 
 Compiling the Application
 -------------------------
 
-Compile the application as follows:
-
-#.  Go to the example directory:
-
-    .. code-block:: console
+To compile the sample application see :doc:`compiling`.
 
-        export RTE_SDK=/path/to/rte_sdk cd
-        ${RTE_SDK}/examples/kni
+The application is located in the ``kni`` sub-directory.
 
-#.  Set the target (a default target is used if not specified)
-
-    .. note::
+.. note::
 
         This application is intended as a linuxapp only.
 
-    .. code-block:: console
-
-        export RTE_TARGET=x86_64-native-linuxapp-gcc
-
-#.  Build the application:
-
-    .. code-block:: console
-
-        make
-
 Loading the Kernel Module
 -------------------------
 
-Loading the KNI kernel module without any parameter is the typical way an Intel® DPDK application
+Loading the KNI kernel module without any parameter is the typical way a DPDK application
 gets packets into and out of the kernel net stack.
 This way, only one kernel thread is created for all KNI devices for packet receiving in kernel side:
 
@@ -132,7 +86,7 @@ For optimum performance,
 the lcore in the mask must be selected to be on the same socket as the lcores used in the KNI application.
 
 To provide flexibility of performance, the kernel module of the KNI,
-located in the kmod sub-directory of the Intel® DPDK target directory,
+located in the kmod sub-directory of the DPDK target directory,
 can be loaded with parameter of kthread_mode as follows:
 
 *   #insmod rte_kni.ko kthread_mode=single
@@ -149,7 +103,7 @@ can be loaded with parameter of kthread_mode as follows:
     Multiple kernel thread mode can provide scalable higher performance.
 
 To measure the throughput in a loopback mode, the kernel module of the KNI,
-located in the kmod sub-directory of the Intel® DPDK target directory,
+located in the kmod sub-directory of the DPDK target directory,
 can be loaded with parameters as follows:
 
 *   #insmod rte_kni.ko lo_mode=lo_mode_fifo
@@ -179,9 +133,9 @@ Where:
 *   --config="(port,lcore_rx, lcore_tx[,lcore_kthread, ...]) [, port,lcore_rx, lcore_tx[,lcore_kthread, ...]]":
     Determines which lcores of RX, TX, kernel thread are mapped to which ports.
 
-Refer to *Intel® DPDK Getting Started Guide* for general information on running applications and the Environment Abstraction Layer (EAL) options.
+Refer to *DPDK Getting Started Guide* for general information on running applications and the Environment Abstraction Layer (EAL) options.
 
-The -c coremask parameter of the EAL options should include the lcores indicated by the lcore_rx and lcore_tx,
+The -c coremask or -l corelist parameter of the EAL options should include the lcores indicated by the lcore_rx and lcore_tx,
 but does not need to include lcores indicated by lcore_kthread as they are used to pin the kernel thread on.
 The -p PORTMASK parameter should include the ports indicated by the port in --config, neither more nor less.
 
@@ -200,7 +154,7 @@ and one lcore of kernel thread for each port:
 
 .. code-block:: console
 
-    ./build/kni -c 0xf0 -n 4 -- -P -p 0x3 -config="(0,4,6,8),(1,5,7,9)"
+    ./build/kni -l 4-7 -n 4 -- -P -p 0x3 --config="(0,4,6,8),(1,5,7,9)"
 
 KNI Operations
 --------------
@@ -228,7 +182,13 @@ Dumping the network traffic:
 
     #tcpdump -i vEth0_0
 
-When the Intel® DPDK userspace application is closed, all the KNI devices are deleted from Linux*.
+Change the MAC address:
+
+.. code-block:: console
+
+    #ifconfig vEth0_0 hw ether 0C:01:02:03:04:08
+
+When the DPDK userspace application is closed, all the KNI devices are deleted from Linux*.
 
 Explanation
 -----------
@@ -238,26 +198,16 @@ The following sections provide some explanation of code.
 Initialization
 ~~~~~~~~~~~~~~
 
-Setup of mbuf pool, driver and queues is similar to the setup done in the L2 Forwarding sample application
-(see Chapter 9 "L2 Forwarding Sample Application (in Real and Virtualized Environments" for details).
+Setup of mbuf pool, driver and queues is similar to the setup done in the :doc:`l2_forward_real_virtual`..
 In addition, one or more kernel NIC interfaces are allocated for each
 of the configured ports according to the command line parameters.
 
-The code for creating the kernel NIC interface for a specific port is as follows:
-
-.. code-block:: c
-
-    kni = rte_kni_create(port, MAX_PACKET_SZ, pktmbuf_pool, &kni_ops);
-    if (kni == NULL)
-        rte_exit(EXIT_FAILURE, "Fail to create kni dev "
-           "for port: %d\n", port);
-
 The code for allocating the kernel NIC interfaces for a specific port is as follows:
 
 .. code-block:: c
 
     static int
-    kni_alloc(uint8_t port_id)
+    kni_alloc(uint16_t port_id)
     {
         uint8_t i;
         struct rte_kni *kni;
@@ -275,11 +225,11 @@ The code for allocating the kernel NIC interfaces for a specific port is as foll
 
             memset(&conf, 0, sizeof(conf));
             if (params[port_id]->nb_lcore_k) {
-                rte_snprintf(conf.name, RTE_KNI_NAMESIZE, "vEth%u_%u", port_id, i);
+                snprintf(conf.name, RTE_KNI_NAMESIZE, "vEth%u_%u", port_id, i);
                 conf.core_id = params[port_id]->lcore_k[i];
                 conf.force_bind = 1;
             } else
-                rte_snprintf(conf.name, RTE_KNI_NAMESIZE, "vEth%u", port_id);
+                snprintf(conf.name, RTE_KNI_NAMESIZE, "vEth%u", port_id);
                 conf.group_id = (uint16_t)port_id;
                 conf.mbuf_size = MAX_PACKET_SZ;
 
@@ -298,11 +248,15 @@ The code for allocating the kernel NIC interfaces for a specific port is as foll
                     conf.addr = dev_info.pci_dev->addr;
                     conf.id = dev_info.pci_dev->id;
 
+                    /* Get the interface default mac address */
+                    rte_eth_macaddr_get(port_id, (struct ether_addr *)&conf.mac_addr);
+
                     memset(&ops, 0, sizeof(ops));
 
                     ops.port_id = port_id;
                     ops.change_mtu = kni_change_mtu;
                     ops.config_network_if = kni_config_network_interface;
+                    ops.config_mac_address = kni_config_mac_address;
 
                     kni = rte_kni_alloc(pktmbuf_pool, &conf, &ops);
                 } else
@@ -346,7 +300,7 @@ The code is as follows:
         int i, j, nb_token;
         char *str_fld[_NUM_FLD];
         unsigned long int_fld[_NUM_FLD];
-        uint8_t port_id, nb_kni_port_params = 0;
+        uint16_t port_id, nb_kni_port_params = 0;
 
         memset(&kni_port_params_array, 0, sizeof(kni_port_params_array));
 
@@ -362,7 +316,7 @@ The code is as follows:
                 goto fail;
             }
 
-            rte_snprintf(s, sizeof(s), "%.*s", size, p);
+            snprintf(s, sizeof(s), "%.*s", size, p);
             nb_token = rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',');
 
             if (nb_token <= FLD_LCORE_TX) {
@@ -392,7 +346,7 @@ The code is as follows:
                 goto fail;
             }
 
-            kni_port_params_array[port_id] = (struct kni_port_params*)rte_zmalloc("KNI_port_params", sizeof(struct kni_port_params), CACHE_LINE_SIZE);
+            kni_port_params_array[port_id] = (struct kni_port_params*)rte_zmalloc("KNI_port_params", sizeof(struct kni_port_params), RTE_CACHE_LINE_SIZE);
             kni_port_params_array[port_id]->port_id = port_id;
             kni_port_params_array[port_id]->lcore_rx = (uint8_t)int_fld[i++];
             kni_port_params_array[port_id]->lcore_tx = (uint8_t)int_fld[i++];
@@ -435,7 +389,7 @@ to see if this lcore is reading from or writing to kernel NIC interfaces.
 
 For the case that reads from a NIC port and writes to the kernel NIC interfaces,
 the packet reception is the same as in L2 Forwarding sample application
-(see Section 9.4.6 "Receive, Process  and Transmit Packets").
+(see :ref:`l2_fwd_app_rx_tx_packets`).
 The packet transmission is done by sending mbufs into the kernel NIC interfaces by rte_kni_tx_burst().
 The KNI library automatically frees the mbufs after the kernel successfully copied the mbufs.
 
@@ -482,7 +436,7 @@ The KNI library automatically frees the mbufs after the kernel successfully copi
 For the other case that reads from kernel NIC interfaces and writes to a physical NIC port, packets are retrieved by reading
 mbufs from kernel NIC interfaces by `rte_kni_rx_burst()`.
 The packet transmission is the same as in the L2 Forwarding sample application
-(see Section 9.4.6 "Receive, Process and Transmit Packet's").
+(see :ref:`l2_fwd_app_rx_tx_packets`).
 
 .. code-block:: c
 
@@ -531,28 +485,32 @@ Callbacks for Kernel Requests
 
 To execute specific PMD operations in user space requested by some Linux* commands,
 callbacks must be implemented and filled in the struct rte_kni_ops structure.
-Currently, setting a new MTU and configuring the network interface (up/ down) are supported.
+Currently, setting a new MTU, change in MAC address, configuring promiscusous mode and
+configuring the network interface(up/down) re supported.
+Default implementation for following is available in rte_kni library.
+Application may choose to not implement following callbacks:
+
+- ``config_mac_address``
+- ``config_promiscusity``
+
 
 .. code-block:: c
 
     static struct rte_kni_ops kni_ops = {
         .change_mtu = kni_change_mtu,
         .config_network_if = kni_config_network_interface,
+        .config_mac_address = kni_config_mac_address,
+        .config_promiscusity = kni_config_promiscusity,
     };
 
     /* Callback for request of changing MTU */
 
     static int
-    kni_change_mtu(uint8_t port_id, unsigned new_mtu)
+    kni_change_mtu(uint16_t port_id, unsigned new_mtu)
     {
         int ret;
         struct rte_eth_conf conf;
 
-        if (port_id >= rte_eth_dev_count()) {
-            RTE_LOG(ERR, APP, "Invalid port id %d\n", port_id);
-            return -EINVAL;
-        }
-
         RTE_LOG(INFO, APP, "Change MTU of port %d to %u\n", port_id, new_mtu);
 
         /* Stop specific port */
@@ -592,15 +550,10 @@ Currently, setting a new MTU and configuring the network interface (up/ down) ar
     /* Callback for request of configuring network interface up/down */
 
     static int
-    kni_config_network_interface(uint8_t port_id, uint8_t if_up)
+    kni_config_network_interface(uint16_t port_id, uint8_t if_up)
     {
         int ret = 0;
 
-        if (port_id >= rte_eth_dev_count() || port_id >= RTE_MAX_ETHPORTS) {
-            RTE_LOG(ERR, APP, "Invalid port id %d\n", port_id);
-            return -EINVAL;
-        }
-
         RTE_LOG(INFO, APP, "Configure network interface of %d %s\n",
 
         port_id, if_up ? "up" : "down");
@@ -617,4 +570,18 @@ Currently, setting a new MTU and configuring the network interface (up/ down) ar
         return ret;
     }
 
-.. |kernel_nic| image:: img/kernel_nic.png
+    /* Callback for request of configuring device mac address */
+
+    static int
+    kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
+    {
+        .....
+    }
+
+    /* Callback for request of configuring promiscuous mode */
+
+    static int
+    kni_config_promiscusity(uint16_t port_id, uint8_t to_on)
+    {
+        .....
+    }