xref: /dpdk/doc/guides/sample_app_ug/skeleton.rst (revision daa02b5cddbb8e11b31d41e2bf7bb1ae64dcae2f)
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