1..  SPDX-License-Identifier: BSD-3-Clause
2    Copyright(c) 2017 Intel Corporation.
3
4Flow Classify Sample Application
5================================
6
7The Flow Classify sample application is based on the simple *skeleton* example
8of a forwarding application.
9
10It is intended as a demonstration of the basic components of a DPDK forwarding
11application which uses the Flow Classify library API's.
12
13Please refer to the
14:doc:`../prog_guide/flow_classify_lib`
15for more information.
16
17Compiling the Application
18-------------------------
19
20To compile the sample application see :doc:`compiling`.
21
22The application is located in the ``flow_classify`` sub-directory.
23
24Running the Application
25-----------------------
26
27To run the example in a ``linux`` environment:
28
29.. code-block:: console
30
31    ./<build_dir>/examples/dpdk-flow_classify -c 4 -n 4 -- /
32    --rule_ipv4="../ipv4_rules_file.txt"
33
34Please refer to the *DPDK Getting Started Guide*, section
35:doc:`../linux_gsg/build_sample_apps`
36for general information on running applications and the Environment Abstraction
37Layer (EAL) options.
38
39
40Sample ipv4_rules_file.txt
41--------------------------
42
43.. code-block:: console
44
45    #file format:
46    #src_ip/masklen dst_ip/masklen src_port : mask dst_port : mask proto/mask priority
47    #
48    2.2.2.3/24 2.2.2.7/24 32 : 0xffff 33 : 0xffff 17/0xff 0
49    9.9.9.3/24 9.9.9.7/24 32 : 0xffff 33 : 0xffff 17/0xff 1
50    9.9.9.3/24 9.9.9.7/24 32 : 0xffff 33 : 0xffff 6/0xff 2
51    9.9.8.3/24 9.9.8.7/24 32 : 0xffff 33 : 0xffff 6/0xff 3
52    6.7.8.9/24 2.3.4.5/24 32 : 0x0000 33 : 0x0000 132/0xff 4
53
54Explanation
55-----------
56
57The following sections provide an explanation of the main components of the
58code.
59
60All DPDK library functions used in the sample code are prefixed with ``rte_``
61and are explained in detail in the *DPDK API Documentation*.
62
63ACL field definitions for the IPv4 5 tuple rule
64~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
65
66The following field definitions are used when creating the ACL table during
67initialisation of the ``Flow Classify`` application
68
69.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
70    :language: c
71    :start-after: Creation of ACL table during initialization of application. 8<
72    :end-before: >8 End of creation of ACL table.
73
74The Main Function
75~~~~~~~~~~~~~~~~~
76
77The ``main()`` function performs the initialization and calls the execution
78threads for each lcore.
79
80The first task is to initialize the Environment Abstraction Layer (EAL).
81The ``argc`` and ``argv`` arguments are provided to the ``rte_eal_init()``
82function. The value returned is the number of parsed arguments:
83
84.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
85    :language: c
86    :start-after: Initialize the Environment Abstraction Layer (EAL). 8<
87    :end-before: >8 End of initialization of EAL.
88    :dedent: 1
89
90It then parses the flow_classify application arguments
91
92.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
93    :language: c
94    :start-after: Parse application arguments (after the EAL ones). 8<
95    :end-before: >8 End of parse application arguments.
96    :dedent: 1
97
98The ``main()`` function also allocates a mempool to hold the mbufs
99(Message Buffers) used by the application:
100
101.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
102    :language: c
103    :start-after: Creates a new mempool in memory to hold the mbufs. 8<
104    :end-before: >8 End of creation of new mempool in memory.
105    :dedent: 1
106
107mbufs are the packet buffer structure used by DPDK. They are explained in
108detail in the "Mbuf Library" section of the *DPDK Programmer's Guide*.
109
110The ``main()`` function also initializes all the ports using the user defined
111``port_init()`` function which is explained in the next section:
112
113.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
114    :language: c
115    :start-after: Initialize all ports. 8<
116    :end-before: >8 End of initialization of all ports.
117    :dedent: 1
118
119The ``main()`` function creates the ``flow classifier object`` and adds an ``ACL
120table`` to the flow classifier.
121
122.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
123    :language: c
124    :start-after: Creation of flow classifier object. 8<
125    :end-before: >8 End of creation of flow classifier object.
126
127.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
128    :language: c
129    :start-after: Memory allocation. 8<
130    :end-before: >8 End of initialization of table create params.
131    :dedent: 1
132
133It then reads the ipv4_rules_file.txt file and initialises the parameters for
134the ``rte_flow_classify_table_entry_add`` API.
135This API adds a rule to the ACL table.
136
137.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
138    :language: c
139    :start-after: Read file of IPv4 tuple rules. 8<
140    :end-before: >8 End of reading file of IPv4 5 tuple rules.
141    :dedent: 1
142
143Once the initialization is complete, the application is ready to launch a
144function on an lcore. In this example ``lcore_main()`` is called on a single
145lcore.
146
147.. code-block:: c
148
149    lcore_main(cls_app);
150
151The ``lcore_main()`` function is explained below.
152
153The Port Initialization  Function
154~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
155
156The main functional part of the port initialization used in the Basic
157Forwarding application is shown below:
158
159.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
160    :language: c
161    :start-after: Initializing port using global settings. 8<
162    :end-before: >8 End of initializing a given port.
163
164The Ethernet ports are configured with default settings using the
165``rte_eth_dev_configure()`` function and the ``port_conf_default`` struct.
166
167.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
168    :language: c
169    :start-after: Ethernet ports configured with default settings using struct. 8<
170    :end-before: >8 End of configuration of Ethernet ports.
171
172For this example the ports are set up with 1 RX and 1 TX queue using the
173``rte_eth_rx_queue_setup()`` and ``rte_eth_tx_queue_setup()`` functions.
174
175The Ethernet port is then started:
176
177.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
178    :language: c
179    :start-after: Start the Ethernet port. 8<
180    :end-before: >8 End of starting the Ethernet port.
181    :dedent: 1
182
183
184Finally the RX port is set in promiscuous mode:
185
186.. code-block:: c
187
188    retval = rte_eth_promiscuous_enable(port);
189
190The Add Rules function
191~~~~~~~~~~~~~~~~~~~~~~
192
193The ``add_rules`` function reads the ``ipv4_rules_file.txt`` file and calls the
194``add_classify_rule`` function which calls the
195``rte_flow_classify_table_entry_add`` API.
196
197.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
198    :language: c
199    :start-after: Reads file and calls the add_classify_rule function. 8<
200    :end-before: >8 End of add_rules.
201
202
203The Lcore Main function
204~~~~~~~~~~~~~~~~~~~~~~~
205
206As we saw above the ``main()`` function calls an application function on the
207available lcores.
208The ``lcore_main`` function calls the ``rte_flow_classifier_query`` API.
209For the Basic Forwarding application the ``lcore_main`` function looks like the
210following:
211
212.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
213    :language: c
214    :start-after: Flow classify data. 8<
215    :end-before: >8 End of flow classify data.
216
217.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
218    :language: c
219    :start-after: Classifying the packets. 8<
220    :end-before: >8 End of lcore main.
221
222The main work of the application is done within the loop:
223
224.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
225    :language: c
226    :start-after: Run until the application is quit or killed. 8<
227    :end-before: >8 End of main loop.
228    :dedent: 1
229
230Packets are received in bursts on the RX ports and transmitted in bursts on
231the TX ports. The ports are grouped in pairs with a simple mapping scheme
232using the an XOR on the port number::
233
234    0 -> 1
235    1 -> 0
236
237    2 -> 3
238    3 -> 2
239
240    etc.
241
242The ``rte_eth_tx_burst()`` function frees the memory buffers of packets that
243are transmitted. If packets fail to transmit, ``(nb_tx < nb_rx)``, then they
244must be freed explicitly using ``rte_pktmbuf_free()``.
245
246The forwarding loop can be interrupted and the application closed using
247``Ctrl-C``.
248