f-stack/dpdk/doc/guides/sample_app_ug/flow_classify.rst

243 lines
7.8 KiB
ReStructuredText
Raw Normal View History

2019-06-25 11:12:58 +00:00
.. SPDX-License-Identifier: BSD-3-Clause
Copyright(c) 2017 Intel Corporation.
Flow Classify Sample Application
================================
The Flow Classify sample application is based on the simple *skeleton* example
of a forwarding application.
It is intended as a demonstration of the basic components of a DPDK forwarding
application which uses the Flow Classify library API's.
Please refer to the
:doc:`../prog_guide/flow_classify_lib`
for more information.
Compiling the Application
-------------------------
To compile the sample application see :doc:`compiling`.
The application is located in the ``flow_classify`` sub-directory.
Running the Application
-----------------------
2020-06-18 16:55:50 +00:00
To run the example in a ``linux`` environment:
.. code-block:: console
2021-02-05 08:48:47 +00:00
./<build_dir>/examples/dpdk-flow_classify -c 4 -n 4 -- /
--rule_ipv4="../ipv4_rules_file.txt"
Please refer to the *DPDK Getting Started Guide*, section
:doc:`../linux_gsg/build_sample_apps`
for general information on running applications and the Environment Abstraction
Layer (EAL) options.
Sample ipv4_rules_file.txt
--------------------------
.. code-block:: console
#file format:
#src_ip/masklen dst_ip/masklen src_port : mask dst_port : mask proto/mask priority
#
2.2.2.3/24 2.2.2.7/24 32 : 0xffff 33 : 0xffff 17/0xff 0
9.9.9.3/24 9.9.9.7/24 32 : 0xffff 33 : 0xffff 17/0xff 1
9.9.9.3/24 9.9.9.7/24 32 : 0xffff 33 : 0xffff 6/0xff 2
9.9.8.3/24 9.9.8.7/24 32 : 0xffff 33 : 0xffff 6/0xff 3
6.7.8.9/24 2.3.4.5/24 32 : 0x0000 33 : 0x0000 132/0xff 4
Explanation
-----------
The following sections provide an explanation of the main components of the
code.
All DPDK library functions used in the sample code are prefixed with ``rte_``
and are explained in detail in the *DPDK API Documentation*.
ACL field definitions for the IPv4 5 tuple rule
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The following field definitions are used when creating the ACL table during
2022-09-06 04:00:10 +00:00
initialisation of the ``Flow Classify`` application
2022-09-06 04:00:10 +00:00
.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
:language: c
:start-after: Creation of ACL table during initialization of application. 8<
:end-before: >8 End of creation of ACL table.
The Main Function
~~~~~~~~~~~~~~~~~
The ``main()`` function performs the initialization and calls the execution
threads for each lcore.
The first task is to initialize the Environment Abstraction Layer (EAL).
The ``argc`` and ``argv`` arguments are provided to the ``rte_eal_init()``
function. The value returned is the number of parsed arguments:
2022-09-06 04:00:10 +00:00
.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
:language: c
:start-after: Initialize the Environment Abstraction Layer (EAL). 8<
:end-before: >8 End of initialization of EAL.
:dedent: 1
It then parses the flow_classify application arguments
2022-09-06 04:00:10 +00:00
.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
:language: c
:start-after: Parse application arguments (after the EAL ones). 8<
:end-before: >8 End of parse application arguments.
:dedent: 1
The ``main()`` function also allocates a mempool to hold the mbufs
(Message Buffers) used by the application:
2022-09-06 04:00:10 +00:00
.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
:language: c
:start-after: Creates a new mempool in memory to hold the mbufs. 8<
:end-before: >8 End of creation of new mempool in memory.
:dedent: 1
mbufs are the packet buffer structure used by DPDK. They are explained in
detail in the "Mbuf Library" section of the *DPDK Programmer's Guide*.
The ``main()`` function also initializes all the ports using the user defined
``port_init()`` function which is explained in the next section:
2022-09-06 04:00:10 +00:00
.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
:language: c
:start-after: Initialize all ports. 8<
:end-before: >8 End of initialization of all ports.
:dedent: 1
The ``main()`` function creates the ``flow classifier object`` and adds an ``ACL
table`` to the flow classifier.
2022-09-06 04:00:10 +00:00
.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
:language: c
:start-after: Creation of flow classifier object. 8<
:end-before: >8 End of creation of flow classifier object.
2022-09-06 04:00:10 +00:00
.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
:language: c
:start-after: Memory allocation. 8<
:end-before: >8 End of initialization of table create params.
:dedent: 1
It then reads the ipv4_rules_file.txt file and initialises the parameters for
the ``rte_flow_classify_table_entry_add`` API.
This API adds a rule to the ACL table.
2022-09-06 04:00:10 +00:00
.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
:language: c
:start-after: Read file of IPv4 tuple rules. 8<
:end-before: >8 End of reading file of IPv4 5 tuple rules.
:dedent: 1
Once the initialization is complete, the application is ready to launch a
function on an lcore. In this example ``lcore_main()`` is called on a single
lcore.
.. code-block:: c
lcore_main(cls_app);
The ``lcore_main()`` function is explained below.
The Port Initialization Function
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The main functional part of the port initialization used in the Basic
Forwarding application is shown below:
2022-09-06 04:00:10 +00:00
.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
:language: c
:start-after: Initializing port using global settings. 8<
:end-before: >8 End of initializing a given port.
The Ethernet ports are configured with default settings using the
2022-09-06 04:00:10 +00:00
``rte_eth_dev_configure()`` function.
For this example the ports are set up with 1 RX and 1 TX queue using the
``rte_eth_rx_queue_setup()`` and ``rte_eth_tx_queue_setup()`` functions.
The Ethernet port is then started:
2022-09-06 04:00:10 +00:00
.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
:language: c
:start-after: Start the Ethernet port. 8<
:end-before: >8 End of starting the Ethernet port.
:dedent: 1
Finally the RX port is set in promiscuous mode:
.. code-block:: c
2020-06-18 16:55:50 +00:00
retval = rte_eth_promiscuous_enable(port);
The Add Rules function
~~~~~~~~~~~~~~~~~~~~~~
The ``add_rules`` function reads the ``ipv4_rules_file.txt`` file and calls the
``add_classify_rule`` function which calls the
``rte_flow_classify_table_entry_add`` API.
2022-09-06 04:00:10 +00:00
.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
:language: c
:start-after: Reads file and calls the add_classify_rule function. 8<
:end-before: >8 End of add_rules.
The Lcore Main function
~~~~~~~~~~~~~~~~~~~~~~~
As we saw above the ``main()`` function calls an application function on the
available lcores.
The ``lcore_main`` function calls the ``rte_flow_classifier_query`` API.
For the Basic Forwarding application the ``lcore_main`` function looks like the
following:
2022-09-06 04:00:10 +00:00
.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
:language: c
:start-after: Flow classify data. 8<
:end-before: >8 End of flow classify data.
2022-09-06 04:00:10 +00:00
.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
:language: c
:start-after: Classifying the packets. 8<
:end-before: >8 End of lcore main.
The main work of the application is done within the loop:
2022-09-06 04:00:10 +00:00
.. literalinclude:: ../../../examples/flow_classify/flow_classify.c
:language: c
:start-after: Run until the application is quit or killed. 8<
:end-before: >8 End of main loop.
:dedent: 1
Packets are received in bursts on the RX ports and transmitted in bursts on
the TX ports. The ports are grouped in pairs with a simple mapping scheme
using the an XOR on the port number::
0 -> 1
1 -> 0
2 -> 3
3 -> 2
etc.
The ``rte_eth_tx_burst()`` function frees the memory buffers of packets that
are transmitted. If packets fail to transmit, ``(nb_tx < nb_rx)``, then they
must be freed explicitly using ``rte_pktmbuf_free()``.
The forwarding loop can be interrupted and the application closed using
``Ctrl-C``.