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