1.. SPDX-License-Identifier: BSD-3-Clause 2 Copyright(c) 2015 Intel Corporation. 3 4Basic Forwarding Sample Application 5=================================== 6 7The Basic Forwarding sample application is a simple *skeleton* example of a 8forwarding application. 9 10It is intended as a demonstration of the basic components of a DPDK forwarding 11application. For more detailed implementations see the L2 and L3 forwarding 12sample applications. 13 14Compiling the Application 15------------------------- 16 17To compile the sample application see :doc:`compiling`. 18 19The application is located in the ``skeleton`` sub-directory. 20 21Running the Application 22----------------------- 23 24To run the example in a ``linux`` environment: 25 26.. code-block:: console 27 28 ./<build_dir>/examples/dpdk-skeleton -l 1 -n 4 29 30Refer to *DPDK Getting Started Guide* for general information on running 31applications and the Environment Abstraction Layer (EAL) options. 32 33 34Explanation 35----------- 36 37The following sections provide an explanation of the main components of the 38code. 39 40All DPDK library functions used in the sample code are prefixed with ``rte_`` 41and are explained in detail in the *DPDK API Documentation*. 42 43 44The Main Function 45~~~~~~~~~~~~~~~~~ 46 47The ``main()`` function performs the initialization and calls the execution 48threads for each lcore. 49 50The first task is to initialize the Environment Abstraction Layer (EAL). The 51``argc`` and ``argv`` arguments are provided to the ``rte_eal_init()`` 52function. The value returned is the number of parsed arguments: 53 54.. literalinclude:: ../../../examples/skeleton/basicfwd.c 55 :language: c 56 :start-after: Initializion the Environment Abstraction Layer (EAL). 8< 57 :end-before: >8 End of initializion the Environment Abstraction Layer (EAL). 58 :dedent: 1 59 60 61The ``main()`` also allocates a mempool to hold the mbufs (Message Buffers) 62used by the application: 63 64.. literalinclude:: ../../../examples/skeleton/basicfwd.c 65 :language: c 66 :start-after: Allocates mempool to hold the mbufs. 8< 67 :end-before: >8 End of allocating mempool to hold mbuf. 68 :dedent: 1 69 70Mbufs are the packet buffer structure used by DPDK. They are explained in 71detail in the "Mbuf Library" section of the *DPDK Programmer's Guide*. 72 73The ``main()`` function also initializes all the ports using the user defined 74``port_init()`` function which is explained in the next section: 75 76.. literalinclude:: ../../../examples/skeleton/basicfwd.c 77 :language: c 78 :start-after: Initializing all ports. 8< 79 :end-before: >8 End of initializing all ports. 80 :dedent: 1 81 82Once the initialization is complete, the application is ready to launch a 83function on an lcore. In this example ``lcore_main()`` is called on a single 84lcore. 85 86 87.. literalinclude:: ../../../examples/skeleton/basicfwd.c 88 :language: c 89 :start-after: Called on single lcore. 8< 90 :end-before: >8 End of called on single lcore. 91 :dedent: 1 92 93The ``lcore_main()`` function is explained below. 94 95 96 97The Port Initialization Function 98~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 99 100The main functional part of the port initialization used in the Basic 101Forwarding application is shown below: 102 103.. literalinclude:: ../../../examples/skeleton/basicfwd.c 104 :language: c 105 :start-after: Main functional part of port initialization. 8< 106 :end-before: >8 End of main functional part of port initialization. 107 108The Ethernet ports are configured with default settings using the 109``rte_eth_dev_configure()`` function. 110 111For this example the ports are set up with 1 RX and 1 TX queue using the 112``rte_eth_rx_queue_setup()`` and ``rte_eth_tx_queue_setup()`` functions. 113 114The Ethernet port is then started: 115 116.. literalinclude:: ../../../examples/skeleton/basicfwd.c 117 :language: c 118 :start-after: Starting Ethernet port. 8< 119 :end-before: >8 End of starting of ethernet port. 120 :dedent: 1 121 122 123Finally the RX port is set in promiscuous mode: 124 125.. literalinclude:: ../../../examples/skeleton/basicfwd.c 126 :language: c 127 :start-after: Enable RX in promiscuous mode for the Ethernet device. 128 :end-before: End of setting RX port in promiscuous mode. 129 :dedent: 1 130 131 132The Lcores Main 133~~~~~~~~~~~~~~~ 134 135As we saw above the ``main()`` function calls an application function on the 136available lcores. For the Basic Forwarding application the lcore function 137looks like the following: 138 139.. literalinclude:: ../../../examples/skeleton/basicfwd.c 140 :language: c 141 :start-after: Basic forwarding application lcore. 8< 142 :end-before: >8 End Basic forwarding application lcore. 143 144The main work of the application is done within the loop: 145 146.. literalinclude:: ../../../examples/skeleton/basicfwd.c 147 :language: c 148 :start-after: Main work of application loop. 8< 149 :end-before: >8 End of loop. 150 :dedent: 1 151 152Packets are received in bursts on the RX ports and transmitted in bursts on 153the TX ports. The ports are grouped in pairs with a simple mapping scheme 154using the an XOR on the port number:: 155 156 0 -> 1 157 1 -> 0 158 159 2 -> 3 160 3 -> 2 161 162 etc. 163 164The ``rte_eth_tx_burst()`` function frees the memory buffers of packets that 165are transmitted. If packets fail to transmit, ``(nb_tx < nb_rx)``, then they 166must be freed explicitly using ``rte_pktmbuf_free()``. 167 168The forwarding loop can be interrupted and the application closed using 169``Ctrl-C``. 170