examples/l3fwd: merge l3fwd-acl example
l3fwd-acl contains duplicate functions to l3fwd. For this reason we merge l3fwd-acl code into l3fwd with '--lookup acl' cmdline option to run ACL. Signed-off-by: Sean Morrissey <sean.morrissey@intel.com> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
This commit is contained in:
parent
3cc977704b
commit
6de0ea50e9
@ -1524,8 +1524,6 @@ F: lib/acl/
|
||||
F: doc/guides/prog_guide/packet_classif_access_ctrl.rst
|
||||
F: app/test-acl/
|
||||
F: app/test/test_acl.*
|
||||
F: examples/l3fwd-acl/
|
||||
F: doc/guides/sample_app_ug/l3_forward_access_ctrl.rst
|
||||
|
||||
EFD
|
||||
M: Byron Marohn <byron.marohn@intel.com>
|
||||
|
@ -190,6 +190,11 @@ New Features
|
||||
This is a fall-back implementation for platforms that
|
||||
don't support vector operations.
|
||||
|
||||
* **Merged l3fwd-acl into l3fwd example.**
|
||||
|
||||
Merged l3fwd-acl code into l3fwd as l3fwd-acl contains duplicate
|
||||
and common functions to l3fwd.
|
||||
|
||||
|
||||
Removed Items
|
||||
-------------
|
||||
|
@ -31,7 +31,6 @@ Sample Applications User Guides
|
||||
l3_forward
|
||||
l3_forward_graph
|
||||
l3_forward_power_man
|
||||
l3_forward_access_ctrl
|
||||
link_status_intr
|
||||
server_node_efd
|
||||
service_cores
|
||||
|
@ -11,7 +11,7 @@ The application performs L3 forwarding.
|
||||
Overview
|
||||
--------
|
||||
|
||||
The application demonstrates the use of the hash, LPM and FIB libraries in DPDK
|
||||
The application demonstrates the use of the hash, LPM, FIB and ACL libraries in DPDK
|
||||
to implement packet forwarding using poll or event mode PMDs for packet I/O.
|
||||
The initialization and run-time paths are very similar to those of the
|
||||
:doc:`l2_forward_real_virtual` and :doc:`l2_forward_event`.
|
||||
@ -22,7 +22,7 @@ decision is made based on information read from the input packet.
|
||||
Eventdev can optionally use S/W or H/W (if supported by platform) scheduler
|
||||
implementation for packet I/O based on run time parameters.
|
||||
|
||||
The lookup method is hash-based, LPM-based or FIB-based
|
||||
The lookup method is hash-based, LPM-based, FIB-based or ACL-based
|
||||
and is selected at run time.
|
||||
When the selected lookup method is hash-based,
|
||||
a hash object is used to emulate the flow classification stage.
|
||||
@ -44,7 +44,19 @@ returned by the LPM or FIB lookup.
|
||||
The set of LPM and FIB rules used by the application is statically configured
|
||||
and loaded into the LPM or FIB object at initialization time.
|
||||
|
||||
In the sample application, hash-based and FIB-based forwarding supports
|
||||
For ACL, the ACL library is used to perform both ACL and route entry lookup.
|
||||
When packets are received from a port,
|
||||
the application extracts the necessary information
|
||||
from the TCP/IP header of the received packet
|
||||
and performs a lookup in the rule database to figure out
|
||||
whether the packets should be dropped (in the ACL range)
|
||||
or forwarded to desired ports.
|
||||
For ACL, the application implements packet classification
|
||||
for the IPv4/IPv6 5-tuple syntax specifically.
|
||||
The 5-tuple syntax consists of a source IP address, a destination IP address,
|
||||
a source port, a destination port and a protocol identifier.
|
||||
|
||||
In the sample application, hash-based, FIB-based and ACL-based forwarding supports
|
||||
both IPv4 and IPv6.
|
||||
LPM-based forwarding supports IPv4 only.
|
||||
During the initialization phase route rules for IPv4 and IPv6 are read from rule files.
|
||||
@ -97,7 +109,8 @@ Where,
|
||||
Accepted options:
|
||||
``em`` (Exact Match),
|
||||
``lpm`` (Longest Prefix Match),
|
||||
``fib`` (Forwarding Information Base).
|
||||
``fib`` (Forwarding Information Base),
|
||||
``acl`` (Access Control List).
|
||||
Default is ``lpm``.
|
||||
|
||||
* ``--config (port,queue,lcore)[,(port,queue,lcore)]:`` Determines which queues from which ports are mapped to which cores.
|
||||
@ -128,6 +141,9 @@ Where,
|
||||
|
||||
* ``--event-vector-tmo:`` Optional, Max timeout to form vector in nanoseconds if event vectorization is enabled.
|
||||
|
||||
* ``--alg=<val>:`` optional, ACL classify method to use, one of:
|
||||
``scalar|sse|avx2|neon|altivec|avx512x16|avx512x32``
|
||||
|
||||
* ``-E:`` Optional, enable exact match,
|
||||
legacy flag, please use ``--lookup=em`` instead.
|
||||
|
||||
@ -248,6 +264,8 @@ To read data from the specified file successfully, the application assumes the f
|
||||
|
||||
* Comment line, which starts with a leading character '#'
|
||||
|
||||
* ACL rule line, which starts with a leading character ‘@’
|
||||
|
||||
* Empty line, which consists of a space, form-feed ('\f'), newline ('\n'),
|
||||
carriage return ('\r'), horizontal tab ('\t'), or vertical tab ('\v').
|
||||
|
||||
@ -264,13 +282,30 @@ R<destination_ip>/<ip_mask_length><output_port_number>
|
||||
|
||||
R<destination_ip><source_ip><destination_port><source_port><protocol><output_port_number>
|
||||
|
||||
* A typical IPv4 ACL rule line should have a format as shown below:
|
||||
|
||||
.. _figure_ipv4_acl_rule:
|
||||
|
||||
.. figure:: img/ipv4_acl_rule.*
|
||||
|
||||
A typical IPv4 ACL rule
|
||||
|
||||
IPv4 addresses are specified in CIDR format as specified in RFC 4632.
|
||||
For LPM/FIB they consist of the dot notation for the address and a prefix length separated by '/'.
|
||||
For LPM/FIB/ACL they consist of the dot notation for the address
|
||||
and a prefix length separated by '/'.
|
||||
For example, 192.168.0.34/32, where the address is 192.168.0.34 and the prefix length is 32.
|
||||
For EM they consist of just the dot notation for the address and no prefix length.
|
||||
For example, 192.168.0.34, where the Address is 192.168.0.34.
|
||||
EM also includes ports which are specified as a single number which represents a single port.
|
||||
|
||||
The application parses the rules from the file,
|
||||
it ignores empty and comment lines,
|
||||
and parses and validates the rules it reads.
|
||||
If errors are detected, the application exits
|
||||
with messages to identify the errors encountered.
|
||||
The ACL rules save the index to the specific rules in the userdata field,
|
||||
while route rules save the forwarding port number.
|
||||
|
||||
Hash Initialization
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -334,6 +369,35 @@ the full setup function including the IPv6 setup can be seen in the app code.
|
||||
:start-after: Function to setup fib. 8<
|
||||
:end-before: >8 End of setup fib.
|
||||
|
||||
ACL Initialization
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For each supported ACL rule format (IPv4 5-tuple, IPv6 6-tuple),
|
||||
the application creates a separate context handler
|
||||
from the ACL library for each CPU socket on the board
|
||||
and adds parsed rules into that context.
|
||||
|
||||
Note, that for each supported rule type,
|
||||
the application needs to calculate the expected offset of the fields
|
||||
from the start of the packet.
|
||||
That's why only packets with fixed IPv4/ IPv6 header are supported.
|
||||
That allows to perform ACL classify straight over incoming packet buffer -
|
||||
no extra protocol field retrieval need to be performed.
|
||||
|
||||
Subsequently, the application checks whether NUMA is enabled.
|
||||
If it is, the application records the socket IDs of the CPU cores involved in the task.
|
||||
|
||||
Finally, the application creates contexts handler from the ACL library,
|
||||
adds rules parsed from the file into the database and build an ACL trie.
|
||||
It is important to note that the application creates an independent copy
|
||||
of each database for each socket CPU involved in the task
|
||||
to reduce the time for remote memory access.
|
||||
|
||||
.. literalinclude:: ../../../examples/l3fwd/l3fwd_acl.c
|
||||
:language: c
|
||||
:start-after: Setup ACL context. 8<
|
||||
:end-before: >8 End of ACL context setup.
|
||||
|
||||
Packet Forwarding for Hash-based Lookups
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -1,340 +0,0 @@
|
||||
.. SPDX-License-Identifier: BSD-3-Clause
|
||||
Copyright(c) 2010-2014 Intel Corporation.
|
||||
|
||||
L3 Forwarding with Access Control Sample Application
|
||||
====================================================
|
||||
|
||||
The L3 Forwarding with Access Control application is a simple example of packet processing using the DPDK.
|
||||
The application performs a security check on received packets.
|
||||
Packets that are in the Access Control List (ACL), which is loaded during initialization, are dropped.
|
||||
Others are forwarded to the correct port.
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
The application demonstrates the use of the ACL library in the DPDK to implement access control
|
||||
and packet L3 forwarding.
|
||||
The application loads two types of rules at initialization:
|
||||
|
||||
* Route information rules, which are used for L3 forwarding
|
||||
|
||||
* Access Control List (ACL) rules that block packets with a specific characteristic
|
||||
|
||||
When packets are received from a port,
|
||||
the application extracts the necessary information from the TCP/IP header of the received packet and
|
||||
performs a lookup in the rule database to figure out whether the packets should be dropped (in the ACL range)
|
||||
or forwarded to desired ports.
|
||||
The initialization and run-time paths are similar to those of the :doc:`l3_forward`.
|
||||
However, there are significant differences in the two applications.
|
||||
For example, the original L3 forwarding application uses either LPM or
|
||||
an exact match algorithm to perform forwarding port lookup,
|
||||
while this application uses the ACL library to perform both ACL and route entry lookup.
|
||||
The following sections provide more detail.
|
||||
|
||||
Classification for both IPv4 and IPv6 packets is supported in this application.
|
||||
The application also assumes that all the packets it processes are TCP/UDP packets and
|
||||
always extracts source/destination port information from the packets.
|
||||
|
||||
Tuple Packet Syntax
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The application implements packet classification for the IPv4/IPv6 5-tuple syntax specifically.
|
||||
The 5-tuple syntax consist of a source IP address, a destination IP address,
|
||||
a source port, a destination port and a protocol identifier.
|
||||
The fields in the 5-tuple syntax have the following formats:
|
||||
|
||||
* **Source IP address and destination IP address**
|
||||
: Each is either a 32-bit field (for IPv4), or a set of 4 32-bit fields (for IPv6) represented by a value and a mask length.
|
||||
For example, an IPv4 range of 192.168.1.0 to 192.168.1.255 could be represented by a value = [192, 168, 1, 0] and a mask length = 24.
|
||||
|
||||
* **Source port and destination port**
|
||||
: Each is a 16-bit field, represented by a lower start and a higher end.
|
||||
For example, a range of ports 0 to 8192 could be represented by lower = 0 and higher = 8192.
|
||||
|
||||
* **Protocol identifier**
|
||||
: An 8-bit field, represented by a value and a mask, that covers a range of values.
|
||||
To verify that a value is in the range, use the following expression: "(VAL & mask) == value"
|
||||
|
||||
The trick in how to represent a range with a mask and value is as follows.
|
||||
A range can be enumerated in binary numbers with some bits that are never changed and some bits that are dynamically changed.
|
||||
Set those bits that dynamically changed in mask and value with 0.
|
||||
Set those bits that never changed in the mask with 1, in value with number expected.
|
||||
For example, a range of 6 to 7 is enumerated as 0b110 and 0b111.
|
||||
Bit 1-7 are bits never changed and bit 0 is the bit dynamically changed.
|
||||
Therefore, set bit 0 in mask and value with 0, set bits 1-7 in mask with 1, and bits 1-7 in value with number 0b11.
|
||||
So, mask is 0xfe, value is 0x6.
|
||||
|
||||
.. note::
|
||||
|
||||
The library assumes that each field in the rule is in LSB or Little Endian order when creating the database.
|
||||
It internally converts them to MSB or Big Endian order.
|
||||
When performing a lookup, the library assumes the input is in MSB or Big Endian order.
|
||||
|
||||
Access Rule Syntax
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In this sample application, each rule is a combination of the following:
|
||||
|
||||
* 5-tuple field: This field has a format described in Section.
|
||||
|
||||
* priority field: A weight to measure the priority of the rules.
|
||||
The rule with the higher priority will ALWAYS be returned if the specific input has multiple matches in the rule database.
|
||||
Rules with lower priority will NEVER be returned in any cases.
|
||||
|
||||
* userdata field: A user-defined field that could be any value.
|
||||
It can be the forwarding port number if the rule is a route table entry or it can be a pointer to a mapping address
|
||||
if the rule is used for address mapping in the NAT application.
|
||||
The key point is that it is a useful reserved field for user convenience.
|
||||
|
||||
ACL and Route Rules
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The application needs to acquire ACL and route rules before it runs.
|
||||
Route rules are mandatory, while ACL rules are optional.
|
||||
To simplify the complexity of the priority field for each rule, all ACL and route entries are assumed to be in the same file.
|
||||
To read data from the specified file successfully, the application assumes the following:
|
||||
|
||||
* Each rule occupies a single line.
|
||||
|
||||
* Only the following four rule line types are valid in this application:
|
||||
|
||||
* ACL rule line, which starts with a leading character '@'
|
||||
|
||||
* Route rule line, which starts with a leading character 'R'
|
||||
|
||||
* Comment line, which starts with a leading character '#'
|
||||
|
||||
* Empty line, which consists of a space, form-feed ('\f'), newline ('\n'),
|
||||
carriage return ('\r'), horizontal tab ('\t'), or vertical tab ('\v').
|
||||
|
||||
Other lines types are considered invalid.
|
||||
|
||||
* Rules are organized in descending order of priority,
|
||||
which means rules at the head of the file always have a higher priority than those further down in the file.
|
||||
|
||||
* A typical IPv4 ACL rule line should have a format as shown below:
|
||||
|
||||
|
||||
.. _figure_ipv4_acl_rule:
|
||||
|
||||
.. figure:: img/ipv4_acl_rule.*
|
||||
|
||||
A typical IPv4 ACL rule
|
||||
|
||||
|
||||
IPv4 addresses are specified in CIDR format as specified in RFC 4632.
|
||||
They consist of the dot notation for the address and a prefix length separated by '/'.
|
||||
For example, 192.168.0.34/32, where the address is 192.168.0.34 and the prefix length is 32.
|
||||
|
||||
Ports are specified as a range of 16-bit numbers in the format MIN:MAX,
|
||||
where MIN and MAX are the inclusive minimum and maximum values of the range.
|
||||
The range 0:65535 represents all possible ports in a range.
|
||||
When MIN and MAX are the same value, a single port is represented, for example, 20:20.
|
||||
|
||||
The protocol identifier is an 8-bit value and a mask separated by '/'.
|
||||
For example: 6/0xfe matches protocol values 6 and 7.
|
||||
|
||||
* Route rules start with a leading character 'R' and have the same format as ACL rules except an extra field at the tail
|
||||
that indicates the forwarding port number.
|
||||
|
||||
Rules File Example
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. _figure_example_rules:
|
||||
|
||||
.. figure:: img/example_rules.*
|
||||
|
||||
Rules example
|
||||
|
||||
|
||||
Each rule is explained as follows:
|
||||
|
||||
* Rule 1 (the first line) tells the application to drop those packets with source IP address = [1.2.3.*],
|
||||
destination IP address = [192.168.0.36], protocol = [6]/[7]
|
||||
|
||||
* Rule 2 (the second line) is similar to Rule 1, except the source IP address is ignored.
|
||||
It tells the application to forward packets with destination IP address = [192.168.0.36],
|
||||
protocol = [6]/[7], destined to port 1.
|
||||
|
||||
* Rule 3 (the third line) tells the application to forward all packets to port 0.
|
||||
This is something like a default route entry.
|
||||
|
||||
As described earlier, the application assume rules are listed in descending order of priority,
|
||||
therefore Rule 1 has the highest priority, then Rule 2, and finally,
|
||||
Rule 3 has the lowest priority.
|
||||
|
||||
Consider the arrival of the following three packets:
|
||||
|
||||
* Packet 1 has source IP address = [1.2.3.4], destination IP address = [192.168.0.36], and protocol = [6]
|
||||
|
||||
* Packet 2 has source IP address = [1.2.4.4], destination IP address = [192.168.0.36], and protocol = [6]
|
||||
|
||||
* Packet 3 has source IP address = [1.2.3.4], destination IP address = [192.168.0.36], and protocol = [8]
|
||||
|
||||
Observe that:
|
||||
|
||||
* Packet 1 matches all of the rules
|
||||
|
||||
* Packet 2 matches Rule 2 and Rule 3
|
||||
|
||||
* Packet 3 only matches Rule 3
|
||||
|
||||
For priority reasons, Packet 1 matches Rule 1 and is dropped.
|
||||
Packet 2 matches Rule 2 and is forwarded to port 1.
|
||||
Packet 3 matches Rule 3 and is forwarded to port 0.
|
||||
|
||||
For more details on the rule file format,
|
||||
please refer to rule_ipv4.db and rule_ipv6.db files (inside dpdk/examples/l3fwd-acl/).
|
||||
|
||||
Application Phases
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Once the application starts, it transitions through three phases:
|
||||
|
||||
* **Initialization Phase**
|
||||
- Perform the following tasks:
|
||||
|
||||
* Parse command parameters. Check the validity of rule file(s) name(s), number of logical cores, receive and transmit queues.
|
||||
Bind ports, queues and logical cores. Check ACL search options, and so on.
|
||||
|
||||
* Call Environmental Abstraction Layer (EAL) and Poll Mode Driver (PMD) functions to initialize the environment and detect possible NICs.
|
||||
The EAL creates several threads and sets affinity to a specific hardware thread CPU based on the configuration specified
|
||||
by the command line arguments.
|
||||
|
||||
* Read the rule files and format the rules into the representation that the ACL library can recognize.
|
||||
Call the ACL library function to add the rules into the database and compile them as a trie of pattern sets.
|
||||
Note that application maintains a separate AC contexts for IPv4 and IPv6 rules.
|
||||
|
||||
* **Runtime Phase**
|
||||
- Process the incoming packets from a port. Packets are processed in three steps:
|
||||
|
||||
* Retrieval: Gets a packet from the receive queue. Each logical core may process several queues for different ports.
|
||||
This depends on the configuration specified by command line arguments.
|
||||
|
||||
* Lookup: Checks that the packet type is supported (IPv4/IPv6) and performs a 5-tuple lookup over corresponding AC context.
|
||||
If an ACL rule is matched, the packets will be dropped and return back to step 1.
|
||||
If a route rule is matched, it indicates the packet is not in the ACL list and should be forwarded.
|
||||
If there is no matches for the packet, then the packet is dropped.
|
||||
|
||||
* Forwarding: Forwards the packet to the corresponding port.
|
||||
|
||||
* **Final Phase** - Perform the following tasks:
|
||||
|
||||
Calls the EAL, PMD and ACL library to free resource, then quits.
|
||||
|
||||
Compiling the Application
|
||||
-------------------------
|
||||
|
||||
To compile the sample application see :doc:`compiling`.
|
||||
|
||||
The application is located in the ``l3fwd-acl`` sub-directory.
|
||||
|
||||
Running the Application
|
||||
-----------------------
|
||||
|
||||
The application has a number of command line options:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
./<build_dir>/examples/dpdk-l3fwd-acl [EAL options] -- -p PORTMASK [-P] --config(port,queue,lcore)[,(port,queue,lcore)] --rule_ipv4 FILENAME --rule_ipv6 FILENAME [--alg=<val>] [--max-pkt-len PKTLEN] [--no-numa] [--eth-dest=X,MM:MM:MM:MM:MM:MM]
|
||||
|
||||
|
||||
where,
|
||||
|
||||
* -p PORTMASK: Hexadecimal bitmask of ports to configure
|
||||
|
||||
* -P: Sets all ports to promiscuous mode so that packets are accepted regardless of the packet's Ethernet MAC destination address.
|
||||
Without this option, only packets with the Ethernet MAC destination address set to the Ethernet address of the port are accepted.
|
||||
|
||||
* --config (port,queue,lcore)[,(port,queue,lcore)]: determines which queues from which ports are mapped to which cores
|
||||
|
||||
* --rule_ipv4 FILENAME: Specifies the IPv4 ACL and route rules file
|
||||
|
||||
* --rule_ipv6 FILENAME: Specifies the IPv6 ACL and route rules file
|
||||
|
||||
* --alg=<val>: optional, ACL classify method to use, one of:
|
||||
``scalar|sse|avx2|neon|altivec|avx512x16|avx512x32``
|
||||
|
||||
* --max-pkt-len: optional, maximum packet length in decimal (64-9600)
|
||||
|
||||
* --no-numa: optional, disables numa awareness
|
||||
|
||||
* --eth-dest=X,MM:MM:MM:MM:MM:MM: optional, ethernet destination for port X
|
||||
|
||||
For example, consider a dual processor socket platform with 8 physical cores, where cores 0-7 and 16-23 appear on socket 0,
|
||||
while cores 8-15 and 24-31 appear on socket 1.
|
||||
|
||||
To enable L3 forwarding between two ports, assuming that both ports are in the same socket, using two cores, cores 1 and 2,
|
||||
(which are in the same socket too), use the following command:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
./<build_dir>/examples/dpdk-l3fwd-acl -l 1,2 -n 4 -- -p 0x3 --config="(0,0,1),(1,0,2)" --rule_ipv4="rule_ipv4.db" --rule_ipv6="rule_ipv6.db" --alg=scalar
|
||||
|
||||
In this command:
|
||||
|
||||
* The -l option enables cores 1, 2
|
||||
|
||||
* The -p option enables ports 0 and 1
|
||||
|
||||
* The --config option enables one queue on each port and maps each (port,queue) pair to a specific core.
|
||||
The following table shows the mapping in this example:
|
||||
|
||||
+----------+------------+-----------+-------------------------------------+
|
||||
| **Port** | **Queue** | **lcore** | **Description** |
|
||||
| | | | |
|
||||
+==========+============+===========+=====================================+
|
||||
| 0 | 0 | 1 | Map queue 0 from port 0 to lcore 1. |
|
||||
| | | | |
|
||||
+----------+------------+-----------+-------------------------------------+
|
||||
| 1 | 0 | 2 | Map queue 0 from port 1 to lcore 2. |
|
||||
| | | | |
|
||||
+----------+------------+-----------+-------------------------------------+
|
||||
|
||||
* The --rule_ipv4 option specifies the reading of IPv4 rules sets from the rule_ipv4.db file.
|
||||
|
||||
* The --rule_ipv6 option specifies the reading of IPv6 rules sets from the rule_ipv6.db file.
|
||||
|
||||
* The --alg=scalar option specifies the performing of rule lookup with a scalar function.
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
The following sections provide some explanation of the sample application code.
|
||||
The aspects of port, device and CPU configuration are similar to those of the :doc:`l3_forward`.
|
||||
The following sections describe aspects that are specific to L3 forwarding with access control.
|
||||
|
||||
Parse Rules from File
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
As described earlier, both ACL and route rules are assumed to be saved in the same file.
|
||||
The application parses the rules from the file and adds them to the database by calling the ACL library function.
|
||||
It ignores empty and comment lines, and parses and validates the rules it reads.
|
||||
If errors are detected, the application exits with messages to identify the errors encountered.
|
||||
|
||||
The application needs to consider the userdata and priority fields.
|
||||
The ACL rules save the index to the specific rules in the userdata field,
|
||||
while route rules save the forwarding port number.
|
||||
In order to differentiate the two types of rules, ACL rules add a signature in the userdata field.
|
||||
As for the priority field, the application assumes rules are organized in descending order of priority.
|
||||
Therefore, the code only decreases the priority number with each rule it parses.
|
||||
|
||||
Setting Up the ACL Context
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For each supported AC rule format (IPv4 5-tuple, IPv6 6-tuple) application creates a separate context handler
|
||||
from the ACL library for each CPU socket on the board and adds parsed rules into that context.
|
||||
|
||||
Note, that for each supported rule type,
|
||||
application needs to calculate the expected offset of the fields from the start of the packet.
|
||||
That's why only packets with fixed IPv4/ IPv6 header are supported.
|
||||
That allows to perform ACL classify straight over incoming packet buffer -
|
||||
no extra protocol field retrieval need to be performed.
|
||||
|
||||
Subsequently, the application checks whether NUMA is enabled.
|
||||
If it is, the application records the socket IDs of the CPU cores involved in the task.
|
||||
|
||||
Finally, the application creates contexts handler from the ACL library,
|
||||
adds rules parsed from the file into the database and build an ACL trie.
|
||||
It is important to note that the application creates an independent copy of each database for each socket CPU
|
||||
involved in the task to reduce the time for remote memory access.
|
@ -1,51 +0,0 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# Copyright(c) 2010-2014 Intel Corporation
|
||||
|
||||
# binary name
|
||||
APP = l3fwd-acl
|
||||
|
||||
# all source are stored in SRCS-y
|
||||
SRCS-y := main.c
|
||||
|
||||
PKGCONF ?= pkg-config
|
||||
|
||||
# Build using pkg-config variables if possible
|
||||
ifneq ($(shell $(PKGCONF) --exists libdpdk && echo 0),0)
|
||||
$(error "no installation of DPDK found")
|
||||
endif
|
||||
|
||||
all: shared
|
||||
.PHONY: shared static
|
||||
shared: build/$(APP)-shared
|
||||
ln -sf $(APP)-shared build/$(APP)
|
||||
static: build/$(APP)-static
|
||||
ln -sf $(APP)-static build/$(APP)
|
||||
|
||||
PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null)
|
||||
CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk)
|
||||
LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk)
|
||||
LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk)
|
||||
|
||||
ifeq ($(MAKECMDGOALS),static)
|
||||
# check for broken pkg-config
|
||||
ifeq ($(shell echo $(LDFLAGS_STATIC) | grep 'whole-archive.*l:lib.*no-whole-archive'),)
|
||||
$(warning "pkg-config output list does not contain drivers between 'whole-archive'/'no-whole-archive' flags.")
|
||||
$(error "Cannot generate statically-linked binaries with this version of pkg-config")
|
||||
endif
|
||||
endif
|
||||
|
||||
CFLAGS += -DALLOW_EXPERIMENTAL_API
|
||||
|
||||
build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
|
||||
$(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
|
||||
|
||||
build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
|
||||
$(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
|
||||
|
||||
build:
|
||||
@mkdir -p $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
|
||||
test -d build && rmdir -p build || true
|
File diff suppressed because it is too large
Load Diff
@ -1,13 +0,0 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# Copyright(c) 2017 Intel Corporation
|
||||
|
||||
# meson file, for building this example as part of a main DPDK build.
|
||||
#
|
||||
# To build this example as a standalone application with an already-installed
|
||||
# DPDK instance, use 'make'
|
||||
|
||||
allow_experimental_apis = true
|
||||
deps += ['acl', 'lpm', 'hash']
|
||||
sources = files(
|
||||
'main.c',
|
||||
)
|
@ -5,7 +5,7 @@
|
||||
APP = l3fwd
|
||||
|
||||
# all source are stored in SRCS-y
|
||||
SRCS-y := main.c l3fwd_lpm.c l3fwd_fib.c l3fwd_em.c l3fwd_event.c
|
||||
SRCS-y := main.c l3fwd_acl.c l3fwd_lpm.c l3fwd_fib.c l3fwd_em.c l3fwd_event.c
|
||||
SRCS-y += l3fwd_event_generic.c l3fwd_event_internal_port.c
|
||||
|
||||
PKGCONF ?= pkg-config
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <rte_ethdev.h>
|
||||
#include <rte_vect.h>
|
||||
#include <rte_acl.h>
|
||||
|
||||
#define DO_RFC_1812_CHECKS
|
||||
|
||||
@ -61,6 +62,12 @@
|
||||
struct parm_cfg {
|
||||
const char *rule_ipv4_name;
|
||||
const char *rule_ipv6_name;
|
||||
enum rte_acl_classify_alg alg;
|
||||
};
|
||||
|
||||
struct acl_algorithms {
|
||||
const char *name;
|
||||
enum rte_acl_classify_alg alg;
|
||||
};
|
||||
|
||||
struct mbuf_table {
|
||||
@ -107,6 +114,8 @@ extern struct lcore_conf lcore_conf[RTE_MAX_LCORE];
|
||||
|
||||
extern struct parm_cfg parm_config;
|
||||
|
||||
extern struct acl_algorithms acl_alg[];
|
||||
|
||||
/* Send burst of packets on an output interface */
|
||||
static inline int
|
||||
send_burst(struct lcore_conf *qconf, uint16_t n, uint16_t port)
|
||||
@ -190,10 +199,19 @@ is_valid_ipv4_pkt(struct rte_ipv4_hdr *pkt, uint32_t link_len)
|
||||
}
|
||||
#endif /* DO_RFC_1812_CHECKS */
|
||||
|
||||
enum rte_acl_classify_alg
|
||||
parse_acl_alg(const char *alg);
|
||||
|
||||
int
|
||||
usage_acl_alg(char *buf, size_t sz);
|
||||
|
||||
int
|
||||
init_mem(uint16_t portid, unsigned int nb_mbuf);
|
||||
|
||||
/* Function pointers for LPM, EM or FIB functionality. */
|
||||
/* Function pointers for ACL, LPM, EM or FIB functionality. */
|
||||
void
|
||||
setup_acl(const int socketid);
|
||||
|
||||
void
|
||||
setup_lpm(const int socketid);
|
||||
|
||||
@ -217,6 +235,9 @@ uint16_t
|
||||
lpm_cb_parse_ptype(uint16_t port, uint16_t queue, struct rte_mbuf *pkts[],
|
||||
uint16_t nb_pkts, uint16_t max_pkts, void *user_param);
|
||||
|
||||
int
|
||||
acl_main_loop(__rte_unused void *dummy);
|
||||
|
||||
int
|
||||
em_main_loop(__rte_unused void *dummy);
|
||||
|
||||
@ -278,7 +299,13 @@ int
|
||||
fib_event_main_loop_tx_q_burst_vector(__rte_unused void *dummy);
|
||||
|
||||
|
||||
/* Return ipv4/ipv6 fwd lookup struct for LPM, EM or FIB. */
|
||||
/* Return ipv4/ipv6 fwd lookup struct for ACL, LPM, EM or FIB. */
|
||||
void *
|
||||
acl_get_ipv4_l3fwd_lookup_struct(const int socketid);
|
||||
|
||||
void *
|
||||
acl_get_ipv6_l3fwd_lookup_struct(const int socketid);
|
||||
|
||||
void *
|
||||
em_get_ipv4_l3fwd_lookup_struct(const int socketid);
|
||||
|
||||
|
1112
examples/l3fwd/l3fwd_acl.c
Normal file
1112
examples/l3fwd/l3fwd_acl.c
Normal file
File diff suppressed because it is too large
Load Diff
57
examples/l3fwd/l3fwd_acl.h
Normal file
57
examples/l3fwd/l3fwd_acl.h
Normal file
@ -0,0 +1,57 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
* Copyright(c) 2022 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef L3FWD_ACL_H
|
||||
#define L3FWD_ACL_H
|
||||
|
||||
#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
|
||||
#define L3FWDACL_DEBUG
|
||||
#endif
|
||||
|
||||
#define MAX_ACL_RULE_NUM 100000
|
||||
#define DEFAULT_MAX_CATEGORIES 1
|
||||
#define L3FWD_ACL_IPV4_NAME "l3fwd-acl-ipv4"
|
||||
#define L3FWD_ACL_IPV6_NAME "l3fwd-acl-ipv6"
|
||||
|
||||
#define ACL_DENY_SIGNATURE 0xf0000000
|
||||
#define RTE_LOGTYPE_L3FWDACL RTE_LOGTYPE_USER3
|
||||
#define acl_log(format, ...) RTE_LOG(ERR, L3FWDACL, format, ##__VA_ARGS__)
|
||||
#define uint32_t_to_char(ip, a, b, c, d) do {\
|
||||
*a = (unsigned char)(ip >> 24 & 0xff);\
|
||||
*b = (unsigned char)(ip >> 16 & 0xff);\
|
||||
*c = (unsigned char)(ip >> 8 & 0xff);\
|
||||
*d = (unsigned char)(ip & 0xff);\
|
||||
} while (0)
|
||||
#define OFF_ETHHEAD (sizeof(struct rte_ether_hdr))
|
||||
#define OFF_IPV42PROTO (offsetof(struct rte_ipv4_hdr, next_proto_id))
|
||||
#define OFF_IPV62PROTO (offsetof(struct rte_ipv6_hdr, proto))
|
||||
#define MBUF_IPV4_2PROTO(m) \
|
||||
rte_pktmbuf_mtod_offset((m), uint8_t *, OFF_ETHHEAD + OFF_IPV42PROTO)
|
||||
#define MBUF_IPV6_2PROTO(m) \
|
||||
rte_pktmbuf_mtod_offset((m), uint8_t *, OFF_ETHHEAD + OFF_IPV62PROTO)
|
||||
|
||||
/*
|
||||
* ACL rules should have higher priorities than route ones to ensure ACL rule
|
||||
* always be found when input packets have multi-matches in the database.
|
||||
* A exception case is performance measure, which can define route rules with
|
||||
* higher priority and route rules will always be returned in each lookup.
|
||||
* Reserve range from ACL_RULE_PRIORITY_MAX + 1 to
|
||||
* RTE_ACL_MAX_PRIORITY for route entries in performance measure
|
||||
*/
|
||||
#define ACL_RULE_PRIORITY_MAX 0x10000000
|
||||
|
||||
/*
|
||||
* Forward port info save in ACL lib starts from 1
|
||||
* since ACL assume 0 is invalid.
|
||||
* So, need add 1 when saving and minus 1 when forwarding packets.
|
||||
*/
|
||||
#define FWD_PORT_SHIFT 1
|
||||
|
||||
void
|
||||
print_one_ipv4_rule(struct acl4_rule *rule, int extra);
|
||||
|
||||
void
|
||||
print_one_ipv6_rule(struct acl6_rule *rule, int extra);
|
||||
|
||||
#endif /* L3FWD_ACL_H */
|
112
examples/l3fwd/l3fwd_acl_scalar.h
Normal file
112
examples/l3fwd/l3fwd_acl_scalar.h
Normal file
@ -0,0 +1,112 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
* Copyright(c) 2022 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef L3FWD_ACL_SCALAR_H
|
||||
#define L3FWD_ACL_SCALAR_H
|
||||
|
||||
#include "l3fwd.h"
|
||||
#include "l3fwd_common.h"
|
||||
|
||||
static inline void
|
||||
l3fwd_acl_prepare_one_packet(struct rte_mbuf **pkts_in, struct acl_search_t *acl,
|
||||
int index)
|
||||
{
|
||||
struct rte_mbuf *pkt = pkts_in[index];
|
||||
|
||||
if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type)) {
|
||||
/* Fill acl structure */
|
||||
acl->data_ipv4[acl->num_ipv4] = MBUF_IPV4_2PROTO(pkt);
|
||||
acl->m_ipv4[(acl->num_ipv4)++] = pkt;
|
||||
|
||||
} else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) {
|
||||
/* Fill acl structure */
|
||||
acl->data_ipv6[acl->num_ipv6] = MBUF_IPV6_2PROTO(pkt);
|
||||
acl->m_ipv6[(acl->num_ipv6)++] = pkt;
|
||||
} else {
|
||||
/* Unknown type, drop the packet */
|
||||
rte_pktmbuf_free(pkt);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
l3fwd_acl_prepare_acl_parameter(struct rte_mbuf **pkts_in, struct acl_search_t *acl,
|
||||
int nb_rx)
|
||||
{
|
||||
int i;
|
||||
|
||||
acl->num_ipv4 = 0;
|
||||
acl->num_ipv6 = 0;
|
||||
|
||||
/* Prefetch first packets */
|
||||
for (i = 0; i < PREFETCH_OFFSET && i < nb_rx; i++) {
|
||||
rte_prefetch0(rte_pktmbuf_mtod(
|
||||
pkts_in[i], void *));
|
||||
}
|
||||
|
||||
for (i = 0; i < (nb_rx - PREFETCH_OFFSET); i++) {
|
||||
rte_prefetch0(rte_pktmbuf_mtod(pkts_in[
|
||||
i + PREFETCH_OFFSET], void *));
|
||||
l3fwd_acl_prepare_one_packet(pkts_in, acl, i);
|
||||
}
|
||||
|
||||
/* Process left packets */
|
||||
for (; i < nb_rx; i++)
|
||||
l3fwd_acl_prepare_one_packet(pkts_in, acl, i);
|
||||
}
|
||||
|
||||
static inline void
|
||||
send_packets_single(struct lcore_conf *qconf, struct rte_mbuf *pkts[], uint16_t hops[],
|
||||
uint32_t nb_tx)
|
||||
{
|
||||
uint32_t j;
|
||||
struct rte_ether_hdr *eth_hdr;
|
||||
|
||||
for (j = 0; j < nb_tx; j++) {
|
||||
/* Run rfc1812 if packet is ipv4 and checks enabled. */
|
||||
rfc1812_process((struct rte_ipv4_hdr *)(rte_pktmbuf_mtod(
|
||||
pkts[j], struct rte_ether_hdr *) + 1),
|
||||
&hops[j], pkts[j]->packet_type);
|
||||
|
||||
/* Set MAC addresses. */
|
||||
eth_hdr = rte_pktmbuf_mtod(pkts[j], struct rte_ether_hdr *);
|
||||
*(uint64_t *)ð_hdr->dst_addr = dest_eth_addr[hops[j]];
|
||||
rte_ether_addr_copy(&ports_eth_addr[hops[j]],
|
||||
ð_hdr->src_addr);
|
||||
}
|
||||
|
||||
for (j = 0; j != nb_tx; j++) {
|
||||
if (hops[j] != BAD_PORT)
|
||||
send_single_packet(qconf, pkts[j], hops[j]);
|
||||
else
|
||||
rte_pktmbuf_free(pkts[j]);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
l3fwd_acl_send_packets(struct lcore_conf *qconf, struct rte_mbuf *pkts[], uint32_t res[],
|
||||
uint32_t nb_tx)
|
||||
{
|
||||
uint32_t i;
|
||||
uint16_t dst_port[nb_tx];
|
||||
|
||||
for (i = 0; i != nb_tx; i++) {
|
||||
if (likely((res[i] & ACL_DENY_SIGNATURE) == 0 && res[i] != 0)) {
|
||||
dst_port[i] = res[i] - FWD_PORT_SHIFT;
|
||||
} else {
|
||||
dst_port[i] = BAD_PORT;
|
||||
#ifdef L3FWDACL_DEBUG
|
||||
if ((res & ACL_DENY_SIGNATURE) != 0) {
|
||||
if (RTE_ETH_IS_IPV4_HDR(pkts[i]->packet_type))
|
||||
dump_acl4_rule(pkts[i], res[i]);
|
||||
else if (RTE_ETH_IS_IPV6_HDR(pkt[i]->packet_type))
|
||||
dump_acl6_rule(pkt[i], res[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
send_packets_single(qconf, pkts, dst_port, nb_tx);
|
||||
}
|
||||
|
||||
#endif /* L3FWD_ACL_SCALAR_H */
|
@ -5,6 +5,7 @@
|
||||
/* Log file related character defs. */
|
||||
#define COMMENT_LEAD_CHAR ('#')
|
||||
#define ROUTE_LEAD_CHAR ('R')
|
||||
#define ACL_LEAD_CHAR ('@')
|
||||
|
||||
#define IPV6_ADDR_LEN 16
|
||||
#define IPV6_ADDR_U16 (IPV6_ADDR_LEN / sizeof(uint16_t))
|
||||
@ -96,11 +97,26 @@ read_config_files_lpm(void);
|
||||
void
|
||||
read_config_files_em(void);
|
||||
|
||||
void
|
||||
read_config_files_acl(void);
|
||||
|
||||
void
|
||||
em_free_routes(void);
|
||||
|
||||
void
|
||||
lpm_free_routes(void);
|
||||
|
||||
void
|
||||
acl_free_routes(void);
|
||||
|
||||
void
|
||||
l3fwd_set_alg(const char *optarg);
|
||||
|
||||
void
|
||||
l3fwd_set_rule_ipv6_name(const char *optarg);
|
||||
|
||||
void
|
||||
l3fwd_set_rule_ipv4_name(const char *optarg);
|
||||
|
||||
int
|
||||
is_bypass_line(const char *buff);
|
||||
|
@ -59,17 +59,17 @@ uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT;
|
||||
/**< Ports set in promiscuous mode off by default. */
|
||||
static int promiscuous_on;
|
||||
|
||||
/* Select Longest-Prefix, Exact match or Forwarding Information Base. */
|
||||
/* Select Longest-Prefix, Exact match, Forwarding Information Base or Access Control. */
|
||||
enum L3FWD_LOOKUP_MODE {
|
||||
L3FWD_LOOKUP_DEFAULT,
|
||||
L3FWD_LOOKUP_LPM,
|
||||
L3FWD_LOOKUP_EM,
|
||||
L3FWD_LOOKUP_FIB
|
||||
L3FWD_LOOKUP_FIB,
|
||||
L3FWD_LOOKUP_ACL
|
||||
};
|
||||
static enum L3FWD_LOOKUP_MODE lookup_mode;
|
||||
|
||||
/* Global variables. */
|
||||
|
||||
static int numa_on = 1; /**< NUMA is enabled by default. */
|
||||
static int parse_ptype; /**< Parse packet type using rx callback, and */
|
||||
/**< disabled by default */
|
||||
@ -187,6 +187,17 @@ static struct l3fwd_lkp_mode l3fwd_fib_lkp = {
|
||||
.free_routes = lpm_free_routes,
|
||||
};
|
||||
|
||||
static struct l3fwd_lkp_mode l3fwd_acl_lkp = {
|
||||
.read_config_files = read_config_files_acl,
|
||||
.setup = setup_acl,
|
||||
.check_ptype = em_check_ptype,
|
||||
.cb_parse_ptype = em_cb_parse_ptype,
|
||||
.main_loop = acl_main_loop,
|
||||
.get_ipv4_lookup_struct = acl_get_ipv4_l3fwd_lookup_struct,
|
||||
.get_ipv6_lookup_struct = acl_get_ipv6_l3fwd_lookup_struct,
|
||||
.free_routes = acl_free_routes,
|
||||
};
|
||||
|
||||
/*
|
||||
* 198.18.0.0/16 are set aside for RFC2544 benchmarking (RFC5735).
|
||||
* 198.18.{0-15}.0/24 = Port {0-15}
|
||||
@ -236,18 +247,24 @@ const struct ipv6_l3fwd_route ipv6_l3fwd_route_array[] = {
|
||||
/*
|
||||
* API's called during initialization to setup ACL/EM/LPM rules.
|
||||
*/
|
||||
static void
|
||||
void
|
||||
l3fwd_set_rule_ipv4_name(const char *optarg)
|
||||
{
|
||||
parm_config.rule_ipv4_name = optarg;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
l3fwd_set_rule_ipv6_name(const char *optarg)
|
||||
{
|
||||
parm_config.rule_ipv6_name = optarg;
|
||||
}
|
||||
|
||||
void
|
||||
l3fwd_set_alg(const char *optarg)
|
||||
{
|
||||
parm_config.alg = parse_acl_alg(optarg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup lookup methods for forwarding.
|
||||
* Currently exact-match, longest-prefix-match and forwarding information
|
||||
@ -262,6 +279,9 @@ setup_l3fwd_lookup_tables(void)
|
||||
/* Setup FIB lookup functions. */
|
||||
else if (lookup_mode == L3FWD_LOOKUP_FIB)
|
||||
l3fwd_lkp = l3fwd_fib_lkp;
|
||||
/* Setup ACL lookup functions. */
|
||||
else if (lookup_mode == L3FWD_LOOKUP_ACL)
|
||||
l3fwd_lkp = l3fwd_acl_lkp;
|
||||
/* Setup LPM lookup functions. */
|
||||
else
|
||||
l3fwd_lkp = l3fwd_lpm_lkp;
|
||||
@ -361,6 +381,9 @@ init_lcore_rx_queues(void)
|
||||
static void
|
||||
print_usage(const char *prgname)
|
||||
{
|
||||
char alg[PATH_MAX];
|
||||
|
||||
usage_acl_alg(alg, sizeof(alg));
|
||||
fprintf(stderr, "%s [EAL options] --"
|
||||
" -p PORTMASK"
|
||||
" --rule_ipv4=FILE"
|
||||
@ -387,7 +410,8 @@ print_usage(const char *prgname)
|
||||
" -P : Enable promiscuous mode\n"
|
||||
" --lookup: Select the lookup method\n"
|
||||
" Default: lpm\n"
|
||||
" Accepted: em (Exact Match), lpm (Longest Prefix Match), fib (Forwarding Information Base)\n"
|
||||
" Accepted: em (Exact Match), lpm (Longest Prefix Match), fib (Forwarding Information Base),\n"
|
||||
" acl (Access Control List)\n"
|
||||
" --config (port,queue,lcore): Rx queue configuration\n"
|
||||
" --rx-queue-size NPKTS: Rx queue size in decimal\n"
|
||||
" Default: %d\n"
|
||||
@ -416,8 +440,13 @@ print_usage(const char *prgname)
|
||||
" -L : Enable longest prefix match, legacy flag please use --lookup=lpm instead\n"
|
||||
" --rule_ipv4=FILE: Specify the ipv4 rules entries file.\n"
|
||||
" Each rule occupies one line.\n"
|
||||
" --rule_ipv6=FILE: Specify the ipv6 rules entries file.\n\n",
|
||||
prgname, RTE_TEST_RX_DESC_DEFAULT, RTE_TEST_TX_DESC_DEFAULT);
|
||||
" 2 kinds of rules are supported.\n"
|
||||
" One is ACL entry at while line leads with character '%c',\n"
|
||||
" another is route entry at while line leads with character '%c'.\n"
|
||||
" --rule_ipv6=FILE: Specify the ipv6 rules entries file.\n"
|
||||
" --alg: ACL classify method to use, one of: %s.\n\n",
|
||||
prgname, RTE_TEST_RX_DESC_DEFAULT, RTE_TEST_TX_DESC_DEFAULT,
|
||||
ACL_LEAD_CHAR, ROUTE_LEAD_CHAR, alg);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -632,8 +661,10 @@ parse_lookup(const char *optarg)
|
||||
lookup_mode = L3FWD_LOOKUP_LPM;
|
||||
else if (!strcmp(optarg, "fib"))
|
||||
lookup_mode = L3FWD_LOOKUP_FIB;
|
||||
else if (!strcmp(optarg, "acl"))
|
||||
lookup_mode = L3FWD_LOOKUP_ACL;
|
||||
else {
|
||||
fprintf(stderr, "Invalid lookup option! Accepted options: em, lpm, fib\n");
|
||||
fprintf(stderr, "Invalid lookup option! Accepted options: acl, em, lpm, fib\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
@ -667,6 +698,7 @@ static const char short_options[] =
|
||||
#define CMD_LINE_OPT_VECTOR_TMO_NS "event-vector-tmo"
|
||||
#define CMD_LINE_OPT_RULE_IPV4 "rule_ipv4"
|
||||
#define CMD_LINE_OPT_RULE_IPV6 "rule_ipv6"
|
||||
#define CMD_LINE_OPT_ALG "alg"
|
||||
|
||||
enum {
|
||||
/* long options mapped to a short option */
|
||||
@ -685,6 +717,7 @@ enum {
|
||||
CMD_LINE_OPT_PARSE_PTYPE_NUM,
|
||||
CMD_LINE_OPT_RULE_IPV4_NUM,
|
||||
CMD_LINE_OPT_RULE_IPV6_NUM,
|
||||
CMD_LINE_OPT_ALG_NUM,
|
||||
CMD_LINE_OPT_PARSE_PER_PORT_POOL,
|
||||
CMD_LINE_OPT_MODE_NUM,
|
||||
CMD_LINE_OPT_EVENTQ_SYNC_NUM,
|
||||
@ -716,6 +749,7 @@ static const struct option lgopts[] = {
|
||||
{CMD_LINE_OPT_VECTOR_TMO_NS, 1, 0, CMD_LINE_OPT_VECTOR_TMO_NS_NUM},
|
||||
{CMD_LINE_OPT_RULE_IPV4, 1, 0, CMD_LINE_OPT_RULE_IPV4_NUM},
|
||||
{CMD_LINE_OPT_RULE_IPV6, 1, 0, CMD_LINE_OPT_RULE_IPV6_NUM},
|
||||
{CMD_LINE_OPT_ALG, 1, 0, CMD_LINE_OPT_ALG_NUM},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
@ -884,6 +918,9 @@ parse_args(int argc, char **argv)
|
||||
case CMD_LINE_OPT_RULE_IPV6_NUM:
|
||||
l3fwd_set_rule_ipv6_name(optarg);
|
||||
break;
|
||||
case CMD_LINE_OPT_ALG_NUM:
|
||||
l3fwd_set_alg(optarg);
|
||||
break;
|
||||
default:
|
||||
print_usage(prgname);
|
||||
return -1;
|
||||
@ -923,7 +960,7 @@ parse_args(int argc, char **argv)
|
||||
* as default match.
|
||||
*/
|
||||
if (lookup_mode == L3FWD_LOOKUP_DEFAULT) {
|
||||
fprintf(stderr, "Neither LPM, EM, or FIB selected, defaulting to LPM\n");
|
||||
fprintf(stderr, "Neither ACL, LPM, EM, or FIB selected, defaulting to LPM\n");
|
||||
lookup_mode = L3FWD_LOOKUP_LPM;
|
||||
}
|
||||
|
||||
@ -937,6 +974,12 @@ parse_args(int argc, char **argv)
|
||||
hash_entry_number = HASH_ENTRY_NUMBER_DEFAULT;
|
||||
}
|
||||
|
||||
/* For ACL, update port config rss hash filter */
|
||||
if (lookup_mode == L3FWD_LOOKUP_ACL) {
|
||||
port_conf.rx_adv_conf.rss_conf.rss_hf |=
|
||||
RTE_ETH_RSS_UDP | RTE_ETH_RSS_TCP | RTE_ETH_RSS_SCTP;
|
||||
}
|
||||
|
||||
if (optind >= 0)
|
||||
argv[optind-1] = prgname;
|
||||
|
||||
@ -992,7 +1035,7 @@ init_mem(uint16_t portid, unsigned int nb_mbuf)
|
||||
printf("Allocated mbuf pool on socket %d\n",
|
||||
socketid);
|
||||
|
||||
/* Setup LPM, EM(f.e Hash) or FIB. But, only once per
|
||||
/* Setup ACL, LPM, EM(f.e Hash) or FIB. But, only once per
|
||||
* available socket.
|
||||
*/
|
||||
if (!lkp_per_socket[socketid]) {
|
||||
|
@ -7,8 +7,9 @@
|
||||
# DPDK instance, use 'make'
|
||||
|
||||
allow_experimental_apis = true
|
||||
deps += ['hash', 'lpm', 'fib', 'eventdev']
|
||||
deps += ['acl', 'hash', 'lpm', 'fib', 'eventdev']
|
||||
sources = files(
|
||||
'l3fwd_acl.c',
|
||||
'l3fwd_em.c',
|
||||
'l3fwd_event.c',
|
||||
'l3fwd_event_internal_port.c',
|
||||
|
@ -32,7 +32,6 @@ all_examples = [
|
||||
'l2fwd-jobstats',
|
||||
'l2fwd-keepalive',
|
||||
'l3fwd',
|
||||
'l3fwd-acl',
|
||||
'l3fwd-graph',
|
||||
'l3fwd-power',
|
||||
'link_status_interrupt',
|
||||
|
Loading…
Reference in New Issue
Block a user