xref: /dpdk/doc/guides/sample_app_ug/ip_reassembly.rst (revision 8750576fb2a9a067ffbcce4bab6481f3bfa47097)
15630257fSFerruh Yigit..  SPDX-License-Identifier: BSD-3-Clause
25630257fSFerruh Yigit    Copyright(c) 2010-2014 Intel Corporation.
3d0dff9baSBernard Iremonger
4d0dff9baSBernard IremongerIP Reassembly Sample Application
5d0dff9baSBernard Iremonger================================
6d0dff9baSBernard Iremonger
7e0c7c473SSiobhan ButlerThe L3 Forwarding application is a simple example of packet processing using the DPDK.
8d0dff9baSBernard IremongerThe application performs L3 forwarding with reassembly for fragmented IPv4 and IPv6 packets.
9d0dff9baSBernard Iremonger
10d0dff9baSBernard IremongerOverview
11d0dff9baSBernard Iremonger--------
12d0dff9baSBernard Iremonger
13e0c7c473SSiobhan ButlerThe application demonstrates the use of the DPDK libraries to implement packet forwarding
14d0dff9baSBernard Iremongerwith reassembly for IPv4 and IPv6 fragmented packets.
15513b0723SMauricio Vasquez BThe initialization and run- time paths are very similar to those of the :doc:`l2_forward_real_virtual`.
16d0dff9baSBernard IremongerThe main difference from the L2 Forwarding sample application is that
17d0dff9baSBernard Iremongerit reassembles fragmented IPv4 and IPv6 packets before forwarding.
18d0dff9baSBernard IremongerThe maximum allowed size of reassembled packet is 9.5 KB.
19d0dff9baSBernard Iremonger
20d0dff9baSBernard IremongerThere are two key differences from the L2 Forwarding sample application:
21d0dff9baSBernard Iremonger
22d0dff9baSBernard Iremonger*   The first difference is that the forwarding decision is taken based on information read from the input packet's IP header.
23d0dff9baSBernard Iremonger
24d0dff9baSBernard Iremonger*   The second difference is that the application differentiates between IP and non-IP traffic by means of offload flags.
25d0dff9baSBernard Iremonger
2649cc0a0dSMarko KovacevicThe Longest Prefix Match (LPM for IPv4, LPM6 for IPv6) table is used to store/lookup an outgoing port number,
2749cc0a0dSMarko Kovacevicassociated with that IPv4 address. Any unmatched packets are forwarded to the originating port.
28d0dff9baSBernard Iremonger
29d0dff9baSBernard Iremonger
307cacb056SHerakliusz LipiecCompiling the Application
317cacb056SHerakliusz Lipiec-------------------------
32d0dff9baSBernard Iremonger
33*8750576fSNandini PersadTo compile the sample application, see :doc:`compiling`.
34d0dff9baSBernard Iremonger
357cacb056SHerakliusz LipiecThe application is located in the ``ip_reassembly`` sub-directory.
36d0dff9baSBernard Iremonger
37d0dff9baSBernard Iremonger
38d0dff9baSBernard IremongerRunning the Application
39d0dff9baSBernard Iremonger-----------------------
40d0dff9baSBernard Iremonger
41d0dff9baSBernard IremongerThe application has a number of command line options:
42d0dff9baSBernard Iremonger
43d0dff9baSBernard Iremonger.. code-block:: console
44d0dff9baSBernard Iremonger
45e2a94f9aSCiara Power    ./<build_dir>/examples/dpdk-ip_reassembly [EAL options] -- -p PORTMASK [-q NQ] [--maxflows=FLOWS>] [--flowttl=TTL[(s|ms)]]
46d0dff9baSBernard Iremonger
47d0dff9baSBernard Iremongerwhere:
48d0dff9baSBernard Iremonger
49d0dff9baSBernard Iremonger*   -p PORTMASK: Hexadecimal bitmask of ports to configure
50d0dff9baSBernard Iremonger
51d0dff9baSBernard Iremonger*   -q NQ: Number of RX queues per lcore
52d0dff9baSBernard Iremonger
53d0dff9baSBernard Iremonger*   --maxflows=FLOWS: determines maximum number of active fragmented flows (1-65535). Default value: 4096.
54d0dff9baSBernard Iremonger
55d0dff9baSBernard Iremonger*   --flowttl=TTL[(s|ms)]: determines maximum Time To Live for fragmented packet.
56d0dff9baSBernard Iremonger    If all fragments of the packet wouldn't appear within given time-out,
57fea1d908SJohn McNamara    then they are considered as invalid and will be dropped.
58d0dff9baSBernard Iremonger    Valid range is 1ms - 3600s. Default value: 1s.
59d0dff9baSBernard Iremonger
60*8750576fSNandini PersadTo run the example in a Linux environment with 2 lcores (2,4) over 2 ports(0,2)
61*8750576fSNandini Persadwith 1 Rx queue per lcore:
62d0dff9baSBernard Iremonger
63d0dff9baSBernard Iremonger.. code-block:: console
64d0dff9baSBernard Iremonger
65e2a94f9aSCiara Power    ./<build_dir>/examples/dpdk-ip_reassembly -l 2,4 -n 3 -- -p 5
66d0dff9baSBernard Iremonger    EAL: coremask set to 14
67d0dff9baSBernard Iremonger    EAL: Detected lcore 0 on socket 0
68d0dff9baSBernard Iremonger    EAL: Detected lcore 1 on socket 1
69d0dff9baSBernard Iremonger    EAL: Detected lcore 2 on socket 0
70d0dff9baSBernard Iremonger    EAL: Detected lcore 3 on socket 1
71d0dff9baSBernard Iremonger    EAL: Detected lcore 4 on socket 0
72d0dff9baSBernard Iremonger    ...
73d0dff9baSBernard Iremonger
74d0dff9baSBernard Iremonger    Initializing port 0 on lcore 2... Address:00:1B:21:76:FA:2C, rxq=0 txq=2,0 txq=4,1
75d0dff9baSBernard Iremonger    done: Link Up - speed 10000 Mbps - full-duplex
76d0dff9baSBernard Iremonger    Skipping disabled port 1
77d0dff9baSBernard Iremonger    Initializing port 2 on lcore 4... Address:00:1B:21:5C:FF:54, rxq=0 txq=2,0 txq=4,1
78d0dff9baSBernard Iremonger    done: Link Up - speed 10000 Mbps - full-duplex
79d0dff9baSBernard Iremonger    Skipping disabled port 3IP_FRAG: Socket 0: adding route 100.10.0.0/16 (port 0)
80d0dff9baSBernard Iremonger    IP_RSMBL: Socket 0: adding route 100.20.0.0/16 (port 1)
81d0dff9baSBernard Iremonger    ...
82d0dff9baSBernard Iremonger
83d0dff9baSBernard Iremonger    IP_RSMBL: Socket 0: adding route 0101:0101:0101:0101:0101:0101:0101:0101/48 (port 0)
84d0dff9baSBernard Iremonger    IP_RSMBL: Socket 0: adding route 0201:0101:0101:0101:0101:0101:0101:0101/48 (port 1)
85d0dff9baSBernard Iremonger    ...
86d0dff9baSBernard Iremonger
87d0dff9baSBernard Iremonger    IP_RSMBL: entering main loop on lcore 4
88d0dff9baSBernard Iremonger    IP_RSMBL: -- lcoreid=4 portid=2
89d0dff9baSBernard Iremonger    IP_RSMBL: entering main loop on lcore 2
90d0dff9baSBernard Iremonger    IP_RSMBL: -- lcoreid=2 portid=0
91d0dff9baSBernard Iremonger
92*8750576fSNandini PersadTo run the example in a Linux environment with 1 lcore (4) over 2 ports(0,2)
93*8750576fSNandini Persadwith 2 Rx queues per lcore:
94d0dff9baSBernard Iremonger
95d0dff9baSBernard Iremonger.. code-block:: console
96d0dff9baSBernard Iremonger
97e2a94f9aSCiara Power    ./<build_dir>/examples/dpdk-ip_reassembly -l 4 -n 3 -- -p 5 -q 2
98d0dff9baSBernard Iremonger
99d0dff9baSBernard IremongerTo test the application, flows should be set up in the flow generator that match the values in the
100d0dff9baSBernard Iremongerl3fwd_ipv4_route_array and/or l3fwd_ipv6_route_array table.
101d0dff9baSBernard Iremonger
102d0dff9baSBernard IremongerPlease note that in order to test this application,
103d0dff9baSBernard Iremongerthe traffic generator should be generating valid fragmented IP packets.
104d0dff9baSBernard IremongerFor IPv6, the only supported case is when no other extension headers other than
105*8750576fSNandini Persadthe fragment extension header are present in the packet.
106d0dff9baSBernard Iremonger
107d0dff9baSBernard IremongerThe default l3fwd_ipv4_route_array table is:
108d0dff9baSBernard Iremonger
1099a212dc0SConor Fogarty.. literalinclude:: ../../../examples/ip_reassembly/main.c
1109a212dc0SConor Fogarty    :language: c
1119a212dc0SConor Fogarty    :start-after: Default l3fwd_ipv4_route_array table. 8<
1129a212dc0SConor Fogarty    :end-before: >8 End of default l3fwd_ipv4_route_array table.
113d0dff9baSBernard Iremonger
114d0dff9baSBernard IremongerThe default l3fwd_ipv6_route_array table is:
115d0dff9baSBernard Iremonger
1169a212dc0SConor Fogarty.. literalinclude:: ../../../examples/ip_reassembly/main.c
1179a212dc0SConor Fogarty    :language: c
1189a212dc0SConor Fogarty    :start-after: Default l3fwd_ipv6_route_array table. 8<
1199a212dc0SConor Fogarty    :end-before: >8 End of default l3fwd_ipv6_route_array table.
120d0dff9baSBernard Iremonger
121d0dff9baSBernard IremongerFor example, for the fragmented input IPv4 packet with destination address: 100.10.1.1,
122d0dff9baSBernard Iremongera reassembled IPv4 packet be sent out from port #0 to the destination address 100.10.1.1
123d0dff9baSBernard Iremongeronce all the fragments are collected.
124d0dff9baSBernard Iremonger
125d0dff9baSBernard IremongerExplanation
126d0dff9baSBernard Iremonger-----------
127d0dff9baSBernard Iremonger
128*8750576fSNandini PersadThe following sections provide in-depth explanation of the sample application code.
129*8750576fSNandini PersadAs mentioned in the overview section, the initialization and run-time paths
130*8750576fSNandini Persadare very similar to those of the :doc:`l2_forward_real_virtual`.
131d0dff9baSBernard IremongerThe following sections describe aspects that are specific to the IP reassemble sample application.
132d0dff9baSBernard Iremonger
133d0dff9baSBernard IremongerIPv4 Fragment Table Initialization
134d0dff9baSBernard Iremonger~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
135d0dff9baSBernard Iremonger
136*8750576fSNandini PersadThis application uses the :doc:`../prog_guide/ip_fragment_reassembly_lib` library.
137*8750576fSNandini PersadThe fragment table maintains information about already received fragments of the packet.
138d0dff9baSBernard IremongerEach IP packet is uniquely identified by triple <Source IP address>, <Destination IP address>, <ID>.
139*8750576fSNandini PersadTo avoid lock contention, each Rx queue has its own fragment table.
140*8750576fSNandini PersadThe application cannot handle when different fragments of the same packet
141*8750576fSNandini Persadarrive through different Rx queues.
142*8750576fSNandini PersadEach table entry can hold information about packets
143*8750576fSNandini Persadconsisting of up to ``RTE_LIBRTE_IP_FRAG_MAX_FRAG`` fragments.
144d0dff9baSBernard Iremonger
1459a212dc0SConor Fogarty.. literalinclude:: ../../../examples/ip_reassembly/main.c
1469a212dc0SConor Fogarty    :language: c
1479a212dc0SConor Fogarty    :start-after: Each table entry holds information about packet fragmentation. 8<
1489a212dc0SConor Fogarty    :end-before: >8 End of holding packet fragmentation.
1499a212dc0SConor Fogarty    :dedent: 1
150d0dff9baSBernard Iremonger
151d0dff9baSBernard IremongerMempools Initialization
152d0dff9baSBernard Iremonger~~~~~~~~~~~~~~~~~~~~~~~
153d0dff9baSBernard Iremonger
154d0dff9baSBernard IremongerThe reassembly application demands a lot of mbuf's to be allocated.
155*8750576fSNandini PersadAt any given time, up to (2 \* max_flow_num \* RTE_LIBRTE_IP_FRAG_MAX_FRAG \* <maximum number of mbufs per packet>)
156*8750576fSNandini Persadcan be stored inside the fragment table waiting for remaining fragments.
157*8750576fSNandini PersadTo keep mempool size under reasonable limits
158*8750576fSNandini Persadand to avoid a situation when one Rx queue can starve other queues,
159*8750576fSNandini Persadeach Rx queue uses its own mempool.
160d0dff9baSBernard Iremonger
1619a212dc0SConor Fogarty.. literalinclude:: ../../../examples/ip_reassembly/main.c
1629a212dc0SConor Fogarty    :language: c
1637be78d02SJosh Soref    :start-after: mbufs stored in the fragment table. 8<
1647be78d02SJosh Soref    :end-before: >8 End of mbufs stored in the fragmentation table.
1659a212dc0SConor Fogarty    :dedent: 1
166d0dff9baSBernard Iremonger
167d0dff9baSBernard IremongerPacket Reassembly and Forwarding
168d0dff9baSBernard Iremonger~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
169d0dff9baSBernard Iremonger
170d0dff9baSBernard IremongerFor each input packet, the packet forwarding operation is done by the l3fwd_simple_forward() function.
171*8750576fSNandini PersadIf the packet is an IPv4 or IPv6 fragment, then it calls ``rte_ipv4_reassemble_packet()`` for IPv4 packets,
172*8750576fSNandini Persador ``rte_ipv6_reassemble_packet()`` for IPv6 packets.
173*8750576fSNandini PersadThese functions either return a pointer to a valid mbuf that contains a reassembled packet,
174d0dff9baSBernard Iremongeror NULL (if the packet can't be reassembled for some reason).
175*8750576fSNandini PersadThen, ``l3fwd_simple_forward()`` continues with the code for the packet forwarding decision
176d0dff9baSBernard Iremonger(that is, the identification of the output interface for the packet) and
177d0dff9baSBernard Iremongeractual transmit of the packet.
178d0dff9baSBernard Iremonger
179*8750576fSNandini PersadThe ``rte_ipv4_reassemble_packet()`` or ``rte_ipv6_reassemble_packet()`` are responsible for:
180d0dff9baSBernard Iremonger
181*8750576fSNandini Persad#.  Searching the fragment table for entry with packet's <IP Source Address, IP Destination Address, Packet ID>
182d0dff9baSBernard Iremonger
183d0dff9baSBernard Iremonger#.  If the entry is found, then check if that entry already timed-out.
184d0dff9baSBernard Iremonger    If yes, then free all previously received fragments,
185d0dff9baSBernard Iremonger    and remove information about them from the entry.
186d0dff9baSBernard Iremonger
187d0dff9baSBernard Iremonger#.  If no entry with such key is found, then try to create a new one by one of two ways:
188d0dff9baSBernard Iremonger
189d0dff9baSBernard Iremonger    #.  Use as empty entry
190d0dff9baSBernard Iremonger
191d0dff9baSBernard Iremonger    #.  Delete a timed-out entry, free mbufs associated with it mbufs and store a new entry with specified key in it.
192d0dff9baSBernard Iremonger
193d0dff9baSBernard Iremonger#.  Update the entry with new fragment information and check
194d0dff9baSBernard Iremonger    if a packet can be reassembled (the packet's entry contains all fragments).
195d0dff9baSBernard Iremonger
196d0dff9baSBernard Iremonger    #.  If yes, then, reassemble the packet, mark table's entry as empty and return the reassembled mbuf to the caller.
197d0dff9baSBernard Iremonger
198d0dff9baSBernard Iremonger    #.  If no, then just return a NULL to the caller.
199d0dff9baSBernard Iremonger
200d0dff9baSBernard IremongerIf at any stage of packet processing a reassembly function encounters an error
201d0dff9baSBernard Iremonger(can't insert new entry into the Fragment table, or invalid/timed-out fragment),
202d0dff9baSBernard Iremongerthen it will free all associated with the packet fragments,
203d0dff9baSBernard Iremongermark the table entry as invalid and return NULL to the caller.
204d0dff9baSBernard Iremonger
205d0dff9baSBernard IremongerDebug logging and Statistics Collection
206d0dff9baSBernard Iremonger~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
207d0dff9baSBernard Iremonger
208*8750576fSNandini PersadThe ``RTE_LIBRTE_IP_FRAG_TBL_STAT`` controls statistics collection for the IP fragment table.
209e2a94f9aSCiara PowerThis macro is disabled by default, but it can be enabled by modifying the appropriate line
210e2a94f9aSCiara Powerin ``config/rte_config.h``.
211d0dff9baSBernard IremongerTo make ip_reassembly print the statistics to the standard output,
212d0dff9baSBernard Iremongerthe user must send either an USR1, INT or TERM signal to the process.
213*8750576fSNandini PersadFor all of these signals, the ip_reassembly process prints Fragment table statistics for each Rx queue,
214d0dff9baSBernard Iremongerplus the INT and TERM will cause process termination as usual.
215