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