15630257fSFerruh Yigit.. SPDX-License-Identifier: BSD-3-Clause 25630257fSFerruh Yigit Copyright(c) 2010-2014 Intel Corporation. 3d0dff9baSBernard Iremonger 4d0dff9baSBernard IremongerL3 Forwarding Sample Application 5d0dff9baSBernard Iremonger================================ 6d0dff9baSBernard Iremonger 7*8750576fSNandini PersadThe L3 forwarding application is an example of packet processing 8*8750576fSNandini Persadusing DPDK to demonstrate the usage of poll and event mode packet I/O mechanism. 9d0dff9baSBernard Iremonger 10d0dff9baSBernard IremongerOverview 11d0dff9baSBernard Iremonger-------- 12d0dff9baSBernard Iremonger 136de0ea50SSean MorrisseyThe application demonstrates the use of the hash, LPM, FIB and ACL libraries in DPDK 1455499896SPavan Nikhileshto implement packet forwarding using poll or event mode PMDs for packet I/O. 1555499896SPavan NikhileshThe initialization and run-time paths are very similar to those of the 1655499896SPavan Nikhilesh:doc:`l2_forward_real_virtual` and :doc:`l2_forward_event`. 17*8750576fSNandini PersadThe main difference from the L2 forwarding sample application 18*8750576fSNandini Persadis that optionally the packet can be Rx/Tx from/to eventdev instead of to port directly. 19*8750576fSNandini PersadThe forwarding decision is made based on information read from the input packet. 2055499896SPavan Nikhilesh 2155499896SPavan NikhileshEventdev can optionally use S/W or H/W (if supported by platform) scheduler 2255499896SPavan Nikhileshimplementation for packet I/O based on run time parameters. 23d0dff9baSBernard Iremonger 246de0ea50SSean MorrisseyThe lookup method is hash-based, LPM-based, FIB-based or ACL-based 256a094e32SConor Walshand is selected at run time. 266a094e32SConor WalshWhen the selected lookup method is hash-based, 27d0dff9baSBernard Iremongera hash object is used to emulate the flow classification stage. 28d0dff9baSBernard IremongerThe hash object is used in correlation with a flow table to map each input packet to its flow at runtime. 29d0dff9baSBernard Iremonger 30d0dff9baSBernard IremongerThe hash lookup key is represented by a DiffServ 5-tuple composed of the following fields read from the input packet: 31d0dff9baSBernard IremongerSource IP Address, Destination IP Address, Protocol, Source Port and Destination Port. 32d0dff9baSBernard IremongerThe ID of the output interface for the input packet is read from the identified flow table entry. 33d0dff9baSBernard IremongerThe set of flows used by the application is statically configured and loaded into the hash at initialization time. 346a094e32SConor WalshWhen the selected lookup method is LPM or FIB based, 356a094e32SConor Walshan LPM or FIB object is used to emulate the forwarding stage for IPv4 packets. 366a094e32SConor WalshThe LPM or FIB object is used as the routing table 376a094e32SConor Walshto identify the next hop for each input packet at runtime. 38d0dff9baSBernard Iremonger 396a094e32SConor WalshThe LPM and FIB lookup keys are represented by the destination IP address field 406a094e32SConor Walshread from the input packet. 416a094e32SConor WalshThe ID of the output interface for the input packet is the next hop 426a094e32SConor Walshreturned by the LPM or FIB lookup. 436a094e32SConor WalshThe set of LPM and FIB rules used by the application is statically configured 446a094e32SConor Walshand loaded into the LPM or FIB object at initialization time. 45d0dff9baSBernard Iremonger 466de0ea50SSean MorrisseyFor ACL, the ACL library is used to perform both ACL and route entry lookup. 476de0ea50SSean MorrisseyWhen packets are received from a port, 486de0ea50SSean Morrisseythe application extracts the necessary information 496de0ea50SSean Morrisseyfrom the TCP/IP header of the received packet 506de0ea50SSean Morrisseyand performs a lookup in the rule database to figure out 516de0ea50SSean Morrisseywhether the packets should be dropped (in the ACL range) 526de0ea50SSean Morrisseyor forwarded to desired ports. 536de0ea50SSean MorrisseyFor ACL, the application implements packet classification 546de0ea50SSean Morrisseyfor the IPv4/IPv6 5-tuple syntax specifically. 556de0ea50SSean MorrisseyThe 5-tuple syntax consists of a source IP address, a destination IP address, 566de0ea50SSean Morrisseya source port, a destination port and a protocol identifier. 576de0ea50SSean Morrissey 582bf48044SKamalakshitha AligeriIn the sample application, hash-based, LPM-based, FIB-based and ACL-based forwarding supports 596a094e32SConor Walshboth IPv4 and IPv6. 60*8750576fSNandini PersadDuring the initialization, phase route rules for IPv4 and IPv6 are read from rule files. 61d0dff9baSBernard Iremonger 62d0dff9baSBernard IremongerCompiling the Application 63d0dff9baSBernard Iremonger------------------------- 64d0dff9baSBernard Iremonger 65*8750576fSNandini PersadTo compile the sample application, see :doc:`compiling`. 66d0dff9baSBernard Iremonger 677cacb056SHerakliusz LipiecThe application is located in the ``l3fwd`` sub-directory. 68d0dff9baSBernard Iremonger 69d0dff9baSBernard IremongerRunning the Application 70d0dff9baSBernard Iremonger----------------------- 71d0dff9baSBernard Iremonger 7254659744SBeilei XingThe application has a number of command line options:: 73d0dff9baSBernard Iremonger 74e2a94f9aSCiara Power ./dpdk-l3fwd [EAL options] -- -p PORTMASK 75e7e6dd64SSean Morrissey --rule_ipv4=FILE 76e7e6dd64SSean Morrissey --rule_ipv6=FILE 7754659744SBeilei Xing [-P] 789510dd1fSConor Walsh [--lookup LOOKUP_METHOD] 7954659744SBeilei Xing --config(port,queue,lcore)[,(port,queue,lcore)] 8054659744SBeilei Xing [--eth-dest=X,MM:MM:MM:MM:MM:MM] 811bb4a528SFerruh Yigit [--max-pkt-len PKTLEN] 8254659744SBeilei Xing [--no-numa] 8354659744SBeilei Xing [--hash-entry-num] 8454659744SBeilei Xing [--ipv6] 8554659744SBeilei Xing [--parse-ptype] 86f0a26885SShreyansh Jain [--per-port-pool] 8755499896SPavan Nikhilesh [--mode] 8855499896SPavan Nikhilesh [--eventq-sched] 8955499896SPavan Nikhilesh [--event-eth-rxqs] 90e8adca19SShijith Thotton [--event-vector [--event-vector-size SIZE] [--event-vector-tmo NS]] 919510dd1fSConor Walsh [-E] 929510dd1fSConor Walsh [-L] 93d0dff9baSBernard Iremonger 9454659744SBeilei XingWhere, 95d0dff9baSBernard Iremonger 9654659744SBeilei Xing* ``-p PORTMASK:`` Hexadecimal bitmask of ports to configure 97d0dff9baSBernard Iremonger 98e7e6dd64SSean Morrissey* ``--rule_ipv4=FILE:`` specify the ipv4 rules entries file. 99e7e6dd64SSean Morrissey Each rule occupies one line. 100e7e6dd64SSean Morrissey 101e7e6dd64SSean Morrissey* ``--rule_ipv6=FILE:`` specify the ipv6 rules entries file. 102e7e6dd64SSean Morrissey 10354659744SBeilei Xing* ``-P:`` Optional, sets all ports to promiscuous mode so that packets are accepted regardless of the packet's Ethernet MAC destination address. 104d0dff9baSBernard Iremonger Without this option, only packets with the Ethernet MAC destination address set to the Ethernet address of the port are accepted. 105d0dff9baSBernard Iremonger 1069510dd1fSConor Walsh* ``--lookup:`` Optional, select the lookup method. 1079510dd1fSConor Walsh Accepted options: 1089510dd1fSConor Walsh ``em`` (Exact Match), 1099510dd1fSConor Walsh ``lpm`` (Longest Prefix Match), 1106de0ea50SSean Morrissey ``fib`` (Forwarding Information Base), 1116de0ea50SSean Morrissey ``acl`` (Access Control List). 1129510dd1fSConor Walsh Default is ``lpm``. 113d0dff9baSBernard Iremonger 11454659744SBeilei Xing* ``--config (port,queue,lcore)[,(port,queue,lcore)]:`` Determines which queues from which ports are mapped to which cores. 115d0dff9baSBernard Iremonger 11654659744SBeilei Xing* ``--eth-dest=X,MM:MM:MM:MM:MM:MM:`` Optional, ethernet destination for port X. 117d0dff9baSBernard Iremonger 1181bb4a528SFerruh Yigit* ``--max-pkt-len:`` Optional, maximum packet length in decimal (64-9600). 119d0dff9baSBernard Iremonger 12054659744SBeilei Xing* ``--no-numa:`` Optional, disables numa awareness. 12154659744SBeilei Xing 12254659744SBeilei Xing* ``--hash-entry-num:`` Optional, specifies the hash entry number in hexadecimal to be setup. 12354659744SBeilei Xing 12454659744SBeilei Xing* ``--ipv6:`` Optional, set if running ipv6 packets. 12554659744SBeilei Xing 12654659744SBeilei Xing* ``--parse-ptype:`` Optional, set to use software to analyze packet type. Without this option, hardware will check the packet type. 12771a7e242SJianfeng Tan 128f0a26885SShreyansh Jain* ``--per-port-pool:`` Optional, set to use independent buffer pools per port. Without this option, single buffer pool is used for all ports. 129f0a26885SShreyansh Jain 13055499896SPavan Nikhilesh* ``--mode:`` Optional, Packet transfer mode for I/O, poll or eventdev. 13155499896SPavan Nikhilesh 13255499896SPavan Nikhilesh* ``--eventq-sched:`` Optional, Event queue synchronization method, Ordered, Atomic or Parallel. Only valid if --mode=eventdev. 13355499896SPavan Nikhilesh 13455499896SPavan Nikhilesh* ``--event-eth-rxqs:`` Optional, Number of ethernet RX queues per device. Only valid if --mode=eventdev. 13555499896SPavan Nikhilesh 136e8adca19SShijith Thotton* ``--event-vector:`` Optional, Enable event vectorization. Only valid if --mode=eventdev. 137e8adca19SShijith Thotton 138e8adca19SShijith Thotton* ``--event-vector-size:`` Optional, Max vector size if event vectorization is enabled. 139e8adca19SShijith Thotton 140e8adca19SShijith Thotton* ``--event-vector-tmo:`` Optional, Max timeout to form vector in nanoseconds if event vectorization is enabled. 141e8adca19SShijith Thotton 1426de0ea50SSean Morrissey* ``--alg=<val>:`` optional, ACL classify method to use, one of: 1436de0ea50SSean Morrissey ``scalar|sse|avx2|neon|altivec|avx512x16|avx512x32`` 1446de0ea50SSean Morrissey 1459510dd1fSConor Walsh* ``-E:`` Optional, enable exact match, 1469510dd1fSConor Walsh legacy flag, please use ``--lookup=em`` instead. 1479510dd1fSConor Walsh 1489510dd1fSConor Walsh* ``-L:`` Optional, enable longest prefix match, 1499510dd1fSConor Walsh legacy flag, please use ``--lookup=lpm`` instead. 1509510dd1fSConor Walsh 15155499896SPavan Nikhilesh 152e0ef2aecSPablo de LaraFor example, consider a dual processor socket platform with 8 physical cores, where cores 0-7 and 16-23 appear on socket 0, 153e0ef2aecSPablo de Larawhile cores 8-15 and 24-31 appear on socket 1. 154d0dff9baSBernard Iremonger 155e0ef2aecSPablo de LaraTo enable L3 forwarding between two ports, assuming that both ports are in the same socket, using two cores, cores 1 and 2, 156e0ef2aecSPablo de Lara(which are in the same socket too), use the following command: 157d0dff9baSBernard Iremonger 158d0dff9baSBernard Iremonger.. code-block:: console 159d0dff9baSBernard Iremonger 160e7e6dd64SSean Morrissey ./<build_dir>/examples/dpdk-l3fwd -l 1,2 -n 4 -- -p 0x3 --config="(0,0,1),(1,0,2)" --rule_ipv4="rule_ipv4.cfg" --rule_ipv6="rule_ipv6.cfg" 161d0dff9baSBernard Iremonger 162d0dff9baSBernard IremongerIn this command: 163d0dff9baSBernard Iremonger 164e0ef2aecSPablo de Lara* The -l option enables cores 1, 2 165d0dff9baSBernard Iremonger 166d0dff9baSBernard Iremonger* The -p option enables ports 0 and 1 167d0dff9baSBernard Iremonger 168e0ef2aecSPablo de Lara* The --config option enables one queue on each port and maps each (port,queue) pair to a specific core. 169d0dff9baSBernard Iremonger The following table shows the mapping in this example: 170d0dff9baSBernard Iremonger 171d0dff9baSBernard Iremonger+----------+-----------+-----------+-------------------------------------+ 172d0dff9baSBernard Iremonger| **Port** | **Queue** | **lcore** | **Description** | 173d0dff9baSBernard Iremonger| | | | | 174d0dff9baSBernard Iremonger+----------+-----------+-----------+-------------------------------------+ 175e0ef2aecSPablo de Lara| 0 | 0 | 1 | Map queue 0 from port 0 to lcore 1. | 176d0dff9baSBernard Iremonger| | | | | 177d0dff9baSBernard Iremonger+----------+-----------+-----------+-------------------------------------+ 178e0ef2aecSPablo de Lara| 1 | 0 | 2 | Map queue 0 from port 1 to lcore 2. | 179d0dff9baSBernard Iremonger| | | | | 180d0dff9baSBernard Iremonger+----------+-----------+-----------+-------------------------------------+ 181d0dff9baSBernard Iremonger 182e7e6dd64SSean Morrissey* The -rule_ipv4 option specifies the reading of IPv4 rules sets from the rule_ipv4.cfg file 183e7e6dd64SSean Morrissey 184e7e6dd64SSean Morrissey* The -rule_ipv6 option specifies the reading of IPv6 rules sets from the rule_ipv6.cfg file. 185e7e6dd64SSean Morrissey 186*8750576fSNandini PersadTo use eventdev mode with sync method **ordered** on the above environment, 187*8750576fSNandini Persadthe following is the sample command: 18855499896SPavan Nikhilesh 18955499896SPavan Nikhilesh.. code-block:: console 19055499896SPavan Nikhilesh 191e7e6dd64SSean Morrissey ./<build_dir>/examples/dpdk-l3fwd -l 0-3 -n 4 -a <event device> -- -p 0x3 --eventq-sched=ordered --rule_ipv4="rule_ipv4.cfg" --rule_ipv6="rule_ipv6.cfg" 19255499896SPavan Nikhilesh 19355499896SPavan Nikhileshor 19455499896SPavan Nikhilesh 19555499896SPavan Nikhilesh.. code-block:: console 19655499896SPavan Nikhilesh 197db27370bSStephen Hemminger ./<build_dir>/examples/dpdk-l3fwd -l 0-3 -n 4 -a <event device> \ 198e7e6dd64SSean Morrissey -- -p 0x03 --mode=eventdev --eventq-sched=ordered --rule_ipv4="rule_ipv4.cfg" --rule_ipv6="rule_ipv6.cfg" 19955499896SPavan Nikhilesh 20055499896SPavan NikhileshIn this command: 20155499896SPavan Nikhilesh 202db27370bSStephen Hemminger* -a option allows the event device supported by platform. 203db27370bSStephen Hemminger The syntax used to indicate this device may vary based on platform. 20455499896SPavan Nikhilesh 20555499896SPavan Nikhilesh* The --mode option defines PMD to be used for packet I/O. 20655499896SPavan Nikhilesh 20755499896SPavan Nikhilesh* The --eventq-sched option enables synchronization menthod of event queue so that packets will be scheduled accordingly. 20855499896SPavan Nikhilesh 20955499896SPavan NikhileshIf application uses S/W scheduler, it uses following DPDK services: 21055499896SPavan Nikhilesh 21155499896SPavan Nikhilesh* Software scheduler 21255499896SPavan Nikhilesh* Rx adapter service function 21355499896SPavan Nikhilesh* Tx adapter service function 21455499896SPavan Nikhilesh 215*8750576fSNandini PersadThe application needs service cores to run the above mentioned services. Service cores 21655499896SPavan Nikhileshmust be provided as EAL parameters along with the --vdev=event_sw0 to enable S/W 217*8750576fSNandini Persadscheduler. The following is the sample command: 21855499896SPavan Nikhilesh 21955499896SPavan Nikhilesh.. code-block:: console 22055499896SPavan Nikhilesh 221e7e6dd64SSean Morrissey ./<build_dir>/examples/dpdk-l3fwd -l 0-7 -s 0xf0000 -n 4 --vdev event_sw0 -- -p 0x3 --mode=eventdev --eventq-sched=ordered --rule_ipv4="rule_ipv4.cfg" --rule_ipv6="rule_ipv6.cfg" 22255499896SPavan Nikhilesh 22355499896SPavan NikhileshIn case of eventdev mode, *--config* option is not used for ethernet port 224*8750576fSNandini Persadconfiguration. Instead, each ethernet port will be configured with this 22555499896SPavan Nikhileshsetup: 22655499896SPavan Nikhilesh 22755499896SPavan Nikhilesh* Single Rx/Tx queue 22855499896SPavan Nikhilesh 22955499896SPavan Nikhilesh* Each Rx queue will be connected to event queue via Rx adapter. 23055499896SPavan Nikhilesh 23155499896SPavan Nikhilesh* Each Tx queue will be connected via Tx adapter. 23255499896SPavan Nikhilesh 233e0c7c473SSiobhan ButlerRefer to the *DPDK Getting Started Guide* for general information on running applications and 234d0dff9baSBernard Iremongerthe Environment Abstraction Layer (EAL) options. 235d0dff9baSBernard Iremonger 236513b0723SMauricio Vasquez B.. _l3_fwd_explanation: 237513b0723SMauricio Vasquez B 238d0dff9baSBernard IremongerExplanation 239d0dff9baSBernard Iremonger----------- 240d0dff9baSBernard Iremonger 241*8750576fSNandini PersadThe following sections provide explanation of the sample application code. As mentioned in the overview section, 24255499896SPavan Nikhileshthe initialization and run-time paths are very similar to those of the :doc:`l2_forward_real_virtual` and :doc:`l2_forward_event`. 243d0dff9baSBernard IremongerThe following sections describe aspects that are specific to the L3 Forwarding sample application. 244d0dff9baSBernard Iremonger 245e7e6dd64SSean MorrisseyParse Rules from File 246e7e6dd64SSean Morrissey~~~~~~~~~~~~~~~~~~~~~ 247e7e6dd64SSean Morrissey 248e7e6dd64SSean MorrisseyThe application parses the rules from the file and adds them to the appropriate route table by calling the appropriate function. 249e7e6dd64SSean MorrisseyIt ignores empty and comment lines, and parses and validates the rules it reads. 250e7e6dd64SSean MorrisseyIf errors are detected, the application exits with messages to identify the errors encountered. 251e7e6dd64SSean Morrissey 252e7e6dd64SSean MorrisseyThe format of the route rules differs based on which lookup method is being used. 253e7e6dd64SSean MorrisseyTherefore, the code only decreases the priority number with each rule it parses. 254e7e6dd64SSean MorrisseyRoute rules are mandatory. 255e7e6dd64SSean MorrisseyTo read data from the specified file successfully, the application assumes the following: 256e7e6dd64SSean Morrissey 257e7e6dd64SSean Morrissey* Each rule occupies a single line. 258e7e6dd64SSean Morrissey 259e7e6dd64SSean Morrissey* Only the following four rule line types are valid in this application: 260e7e6dd64SSean Morrissey 261e7e6dd64SSean Morrissey* Route rule line, which starts with a leading character 'R' 262e7e6dd64SSean Morrissey 263e7e6dd64SSean Morrissey* Comment line, which starts with a leading character '#' 264e7e6dd64SSean Morrissey 2656de0ea50SSean Morrissey* ACL rule line, which starts with a leading character ‘@’ 2666de0ea50SSean Morrissey 267e7e6dd64SSean Morrissey* Empty line, which consists of a space, form-feed ('\f'), newline ('\n'), 268e7e6dd64SSean Morrissey carriage return ('\r'), horizontal tab ('\t'), or vertical tab ('\v'). 269e7e6dd64SSean Morrissey 270e7e6dd64SSean MorrisseyOther lines types are considered invalid. 271e7e6dd64SSean Morrissey 272e7e6dd64SSean Morrissey* Rules are organized in descending order of priority, 273e7e6dd64SSean Morrissey which means rules at the head of the file always have a higher priority than those further down in the file. 274e7e6dd64SSean Morrissey 275e7e6dd64SSean Morrissey* A typical IPv4 LPM/FIB rule line should have a format as shown below: 276e7e6dd64SSean Morrissey 277e7e6dd64SSean MorrisseyR<destination_ip>/<ip_mask_length><output_port_number> 278e7e6dd64SSean Morrissey 279e7e6dd64SSean Morrissey* A typical IPv4 EM rule line should have a format as shown below: 280e7e6dd64SSean Morrissey 281e7e6dd64SSean MorrisseyR<destination_ip><source_ip><destination_port><source_port><protocol><output_port_number> 282e7e6dd64SSean Morrissey 2836de0ea50SSean Morrissey* A typical IPv4 ACL rule line should have a format as shown below: 2846de0ea50SSean Morrissey 2856de0ea50SSean Morrissey.. _figure_ipv4_acl_rule: 2866de0ea50SSean Morrissey 2876de0ea50SSean Morrissey.. figure:: img/ipv4_acl_rule.* 2886de0ea50SSean Morrissey 2896de0ea50SSean Morrissey A typical IPv4 ACL rule 2906de0ea50SSean Morrissey 291e7e6dd64SSean MorrisseyIPv4 addresses are specified in CIDR format as specified in RFC 4632. 2926de0ea50SSean MorrisseyFor LPM/FIB/ACL they consist of the dot notation for the address 2936de0ea50SSean Morrisseyand a prefix length separated by '/'. 294e7e6dd64SSean MorrisseyFor example, 192.168.0.34/32, where the address is 192.168.0.34 and the prefix length is 32. 295*8750576fSNandini PersadFor EM, they consist of just the dot notation for the address and no prefix length. 296e7e6dd64SSean MorrisseyFor example, 192.168.0.34, where the Address is 192.168.0.34. 297e7e6dd64SSean MorrisseyEM also includes ports which are specified as a single number which represents a single port. 298e7e6dd64SSean Morrissey 2996de0ea50SSean MorrisseyThe application parses the rules from the file, 300*8750576fSNandini Persadit ignores empty and comment lines 3016de0ea50SSean Morrisseyand parses and validates the rules it reads. 3026de0ea50SSean MorrisseyIf errors are detected, the application exits 3036de0ea50SSean Morrisseywith messages to identify the errors encountered. 3046de0ea50SSean MorrisseyThe ACL rules save the index to the specific rules in the userdata field, 3056de0ea50SSean Morrisseywhile route rules save the forwarding port number. 3066de0ea50SSean Morrissey 307d0dff9baSBernard IremongerHash Initialization 308d0dff9baSBernard Iremonger~~~~~~~~~~~~~~~~~~~ 309d0dff9baSBernard Iremonger 310d0dff9baSBernard IremongerThe hash object is created and loaded with the pre-configured entries read from a global array, 311d0dff9baSBernard Iremongerand then generate the expected 5-tuple as key to keep consistence with those of real flow 312d0dff9baSBernard Iremongerfor the convenience to execute hash performance test on 4M/8M/16M flows. 313d0dff9baSBernard Iremonger 314d0dff9baSBernard Iremonger.. note:: 315d0dff9baSBernard Iremonger 316d0dff9baSBernard Iremonger The Hash initialization will setup both ipv4 and ipv6 hash table, 317d0dff9baSBernard Iremonger and populate the either table depending on the value of variable ipv6. 318d0dff9baSBernard Iremonger 319d0dff9baSBernard Iremonger.. note:: 320d0dff9baSBernard Iremonger 321d0dff9baSBernard Iremonger Value of global variable ipv6 can be specified with --ipv6 in the command line. 322d0dff9baSBernard Iremonger Value of global variable hash_entry_number, 323d0dff9baSBernard Iremonger which is used to specify the total hash entry number for all used ports in hash performance test, 324d0dff9baSBernard Iremonger can be specified with --hash-entry-num VALUE in command line, being its default value 4. 325d0dff9baSBernard Iremonger 326d0dff9baSBernard Iremonger.. code-block:: c 327d0dff9baSBernard Iremonger 328d0dff9baSBernard Iremonger #if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH) 329d0dff9baSBernard Iremonger 330d0dff9baSBernard Iremonger static void 331d0dff9baSBernard Iremonger setup_hash(int socketid) 332d0dff9baSBernard Iremonger { 333d0dff9baSBernard Iremonger // ... 334d0dff9baSBernard Iremonger 335d0dff9baSBernard Iremonger if (ipv6 == 0) { 336d0dff9baSBernard Iremonger /* populate the ipv4 hash */ 337e7e6dd64SSean Morrissey populate_ipv4_flow_into_table( 338e7e6dd64SSean Morrissey ipv4_l3fwd_em_lookup_struct[socketid]); 339d0dff9baSBernard Iremonger } else { 340d0dff9baSBernard Iremonger /* populate the ipv6 hash */ 341e7e6dd64SSean Morrissey populate_ipv6_flow_into_table( 342e7e6dd64SSean Morrissey ipv6_l3fwd_em_lookup_struct[socketid]); 343d0dff9baSBernard Iremonger } 344d0dff9baSBernard Iremonger } 345d0dff9baSBernard Iremonger #endif 346d0dff9baSBernard Iremonger 347d0dff9baSBernard IremongerLPM Initialization 348d0dff9baSBernard Iremonger~~~~~~~~~~~~~~~~~~ 349d0dff9baSBernard Iremonger 350d0dff9baSBernard IremongerThe LPM object is created and loaded with the pre-configured entries read from a global array. 351d0dff9baSBernard Iremonger 3529a212dc0SConor Fogarty.. literalinclude:: ../../../examples/l3fwd/l3fwd_em.c 3539a212dc0SConor Fogarty :language: c 3549a212dc0SConor Fogarty :start-after: Initialize exact match (hash) parameters. 8< 3559a212dc0SConor Fogarty :end-before: >8 End of initialization of hash parameters. 356d0dff9baSBernard Iremonger 3576a094e32SConor WalshFIB Initialization 3586a094e32SConor Walsh~~~~~~~~~~~~~~~~~~ 3596a094e32SConor Walsh 3606a094e32SConor WalshThe FIB object is created and loaded with the pre-configured entries 3616a094e32SConor Walshread from a global array. 3626a094e32SConor WalshThe abridged code snippet below shows the FIB initialization for IPv4, 3636a094e32SConor Walshthe full setup function including the IPv6 setup can be seen in the app code. 3646a094e32SConor Walsh 3656a094e32SConor Walsh.. literalinclude:: ../../../examples/l3fwd/l3fwd_fib.c 3666a094e32SConor Walsh :language: c 3679a212dc0SConor Fogarty :start-after: Function to setup fib. 8< 3689a212dc0SConor Fogarty :end-before: >8 End of setup fib. 3696a094e32SConor Walsh 3706de0ea50SSean MorrisseyACL Initialization 3716de0ea50SSean Morrissey~~~~~~~~~~~~~~~~~~ 3726de0ea50SSean Morrissey 3736de0ea50SSean MorrisseyFor each supported ACL rule format (IPv4 5-tuple, IPv6 6-tuple), 3746de0ea50SSean Morrisseythe application creates a separate context handler 3756de0ea50SSean Morrisseyfrom the ACL library for each CPU socket on the board 3766de0ea50SSean Morrisseyand adds parsed rules into that context. 3776de0ea50SSean Morrissey 3786de0ea50SSean MorrisseyNote, that for each supported rule type, 3796de0ea50SSean Morrisseythe application needs to calculate the expected offset of the fields 3806de0ea50SSean Morrisseyfrom the start of the packet. 3816de0ea50SSean MorrisseyThat's why only packets with fixed IPv4/ IPv6 header are supported. 3826de0ea50SSean MorrisseyThat allows to perform ACL classify straight over incoming packet buffer - 3836de0ea50SSean Morrisseyno extra protocol field retrieval need to be performed. 3846de0ea50SSean Morrissey 3856de0ea50SSean MorrisseySubsequently, the application checks whether NUMA is enabled. 3866de0ea50SSean MorrisseyIf it is, the application records the socket IDs of the CPU cores involved in the task. 3876de0ea50SSean Morrissey 3886de0ea50SSean MorrisseyFinally, the application creates contexts handler from the ACL library, 3896de0ea50SSean Morrisseyadds rules parsed from the file into the database and build an ACL trie. 3906de0ea50SSean MorrisseyIt is important to note that the application creates an independent copy 3916de0ea50SSean Morrisseyof each database for each socket CPU involved in the task 3926de0ea50SSean Morrisseyto reduce the time for remote memory access. 3936de0ea50SSean Morrissey 3946de0ea50SSean Morrissey.. literalinclude:: ../../../examples/l3fwd/l3fwd_acl.c 3956de0ea50SSean Morrissey :language: c 3966de0ea50SSean Morrissey :start-after: Setup ACL context. 8< 3976de0ea50SSean Morrissey :end-before: >8 End of ACL context setup. 3986de0ea50SSean Morrissey 399d0dff9baSBernard IremongerPacket Forwarding for Hash-based Lookups 400d0dff9baSBernard Iremonger~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 401d0dff9baSBernard Iremonger 402d0dff9baSBernard IremongerFor each input packet, the packet forwarding operation is done by the l3fwd_simple_forward() 403d0dff9baSBernard Iremongeror simple_ipv4_fwd_4pkts() function for IPv4 packets or the simple_ipv6_fwd_4pkts() function for IPv6 packets. 404d0dff9baSBernard IremongerThe l3fwd_simple_forward() function provides the basic functionality for both IPv4 and IPv6 packet forwarding 405d0dff9baSBernard Iremongerfor any number of burst packets received, 406d0dff9baSBernard Iremongerand the packet forwarding decision (that is, the identification of the output interface for the packet) 407d0dff9baSBernard Iremongerfor hash-based lookups is done by the get_ipv4_dst_port() or get_ipv6_dst_port() function. 408d0dff9baSBernard IremongerThe get_ipv4_dst_port() function is shown below: 409d0dff9baSBernard Iremonger 4109a212dc0SConor Fogarty.. literalinclude:: ../../../examples/l3fwd/l3fwd_em.c 4119a212dc0SConor Fogarty :language: c 4129a212dc0SConor Fogarty :start-after: Performing hash-based lookups. 8< 4139a212dc0SConor Fogarty :end-before: >8 End of performing hash-based lookups. 414d0dff9baSBernard Iremonger 415d0dff9baSBernard IremongerThe get_ipv6_dst_port() function is similar to the get_ipv4_dst_port() function. 416d0dff9baSBernard Iremonger 417d0dff9baSBernard IremongerThe simple_ipv4_fwd_4pkts() and simple_ipv6_fwd_4pkts() function are optimized for continuous 4 valid ipv4 and ipv6 packets, 418d0dff9baSBernard Iremongerthey leverage the multiple buffer optimization to boost the performance of forwarding packets with the exact match on hash table. 419d0dff9baSBernard IremongerThe key code snippet of simple_ipv4_fwd_4pkts() is shown below: 420d0dff9baSBernard Iremonger 421d0dff9baSBernard Iremonger.. code-block:: c 422d0dff9baSBernard Iremonger 423d0dff9baSBernard Iremonger static inline void 424c6d6982dSZhiyong Yang simple_ipv4_fwd_4pkts(struct rte_mbuf* m[4], uint16_t portid, struct lcore_conf *qconf) 425d0dff9baSBernard Iremonger { 426d0dff9baSBernard Iremonger // ... 427d0dff9baSBernard Iremonger 428a7c528e5SOlivier Matz data[0] = _mm_loadu_si128(( m128i*)(rte_pktmbuf_mtod(m[0], unsigned char *) + sizeof(struct rte_ether_hdr) + offsetof(struct rte_ipv4_hdr, time_to_live))); 429a7c528e5SOlivier Matz data[1] = _mm_loadu_si128(( m128i*)(rte_pktmbuf_mtod(m[1], unsigned char *) + sizeof(struct rte_ether_hdr) + offsetof(struct rte_ipv4_hdr, time_to_live))); 430a7c528e5SOlivier Matz data[2] = _mm_loadu_si128(( m128i*)(rte_pktmbuf_mtod(m[2], unsigned char *) + sizeof(struct rte_ether_hdr) + offsetof(struct rte_ipv4_hdr, time_to_live))); 431a7c528e5SOlivier Matz data[3] = _mm_loadu_si128(( m128i*)(rte_pktmbuf_mtod(m[3], unsigned char *) + sizeof(struct rte_ether_hdr) + offsetof(struct rte_ipv4_hdr, time_to_live))); 432d0dff9baSBernard Iremonger 433d0dff9baSBernard Iremonger key[0].xmm = _mm_and_si128(data[0], mask0); 434d0dff9baSBernard Iremonger key[1].xmm = _mm_and_si128(data[1], mask0); 435d0dff9baSBernard Iremonger key[2].xmm = _mm_and_si128(data[2], mask0); 436d0dff9baSBernard Iremonger key[3].xmm = _mm_and_si128(data[3], mask0); 437d0dff9baSBernard Iremonger 438d0dff9baSBernard Iremonger const void *key_array[4] = {&key[0], &key[1], &key[2],&key[3]}; 439d0dff9baSBernard Iremonger 440656ecbe9SThomas Monjalon rte_hash_lookup_bulk(qconf->ipv4_lookup_struct, &key_array[0], 4, ret); 441d0dff9baSBernard Iremonger 442d0dff9baSBernard Iremonger dst_port[0] = (ret[0] < 0)? portid:ipv4_l3fwd_out_if[ret[0]]; 443d0dff9baSBernard Iremonger dst_port[1] = (ret[1] < 0)? portid:ipv4_l3fwd_out_if[ret[1]]; 444d0dff9baSBernard Iremonger dst_port[2] = (ret[2] < 0)? portid:ipv4_l3fwd_out_if[ret[2]]; 445d0dff9baSBernard Iremonger dst_port[3] = (ret[3] < 0)? portid:ipv4_l3fwd_out_if[ret[3]]; 446d0dff9baSBernard Iremonger 447d0dff9baSBernard Iremonger // ... 448d0dff9baSBernard Iremonger } 449d0dff9baSBernard Iremonger 450d0dff9baSBernard IremongerThe simple_ipv6_fwd_4pkts() function is similar to the simple_ipv4_fwd_4pkts() function. 451d0dff9baSBernard Iremonger 45271a7e242SJianfeng TanKnown issue: IP packets with extensions or IP packets which are not TCP/UDP cannot work well at this mode. 45371a7e242SJianfeng Tan 454d0dff9baSBernard IremongerPacket Forwarding for LPM-based Lookups 455d0dff9baSBernard Iremonger~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 456d0dff9baSBernard Iremonger 457d0dff9baSBernard IremongerFor each input packet, the packet forwarding operation is done by the l3fwd_simple_forward() function, 458d0dff9baSBernard Iremongerbut the packet forwarding decision (that is, the identification of the output interface for the packet) 459d0dff9baSBernard Iremongerfor LPM-based lookups is done by the get_ipv4_dst_port() function below: 460d0dff9baSBernard Iremonger 4619a212dc0SConor Fogarty.. literalinclude:: ../../../examples/l3fwd/l3fwd_lpm.c 4629a212dc0SConor Fogarty :language: c 4639a212dc0SConor Fogarty :start-after: Performing LPM-based lookups. 8< 4649a212dc0SConor Fogarty :end-before: >8 End of performing LPM-based lookups. 46555499896SPavan Nikhilesh 4666a094e32SConor WalshPacket Forwarding for FIB-based Lookups 4676a094e32SConor Walsh~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4686a094e32SConor Walsh 4696a094e32SConor WalshThe FIB library was designed to process multiple packets at once, 4706a094e32SConor Walshit does not have separate functions for single and bulk lookups. 4716a094e32SConor Walsh``rte_fib_lookup_bulk`` is used for IPv4 lookups 4726a094e32SConor Walshand ``rte_fib6_lookup_bulk`` for IPv6. 4736a094e32SConor WalshVarious examples of these functions being used 4746a094e32SConor Walshcan be found in the sample app code. 4756a094e32SConor Walsh 47655499896SPavan NikhileshEventdev Driver Initialization 47755499896SPavan Nikhilesh~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 478*8750576fSNandini Persad 479*8750576fSNandini PersadEventdev driver initialization is the same as L2 forwarding eventdev application. 48055499896SPavan NikhileshRefer :doc:`l2_forward_event` for more details. 481