xref: /dpdk/doc/guides/sample_app_ug/ipv4_multicast.rst (revision 8750576fb2a9a067ffbcce4bab6481f3bfa47097)
15630257fSFerruh Yigit..  SPDX-License-Identifier: BSD-3-Clause
25630257fSFerruh Yigit    Copyright(c) 2010-2014 Intel Corporation.
3d0dff9baSBernard Iremonger
4d0dff9baSBernard IremongerIPv4 Multicast Sample Application
5d0dff9baSBernard Iremonger=================================
6d0dff9baSBernard Iremonger
7d0dff9baSBernard IremongerThe IPv4 Multicast application is a simple example of packet processing
8e0c7c473SSiobhan Butlerusing the Data Plane Development Kit (DPDK).
9d0dff9baSBernard IremongerThe application performs L3 multicasting.
10d0dff9baSBernard Iremonger
11d0dff9baSBernard IremongerOverview
12d0dff9baSBernard Iremonger--------
13d0dff9baSBernard Iremonger
14d0dff9baSBernard IremongerThe application demonstrates the use of zero-copy buffers for packet forwarding.
15513b0723SMauricio Vasquez BThe initialization and run-time paths are very similar to those of the :doc:`l2_forward_real_virtual`.
16d0dff9baSBernard IremongerThis guide highlights the differences between the two applications.
17d0dff9baSBernard IremongerThere are two key differences from the L2 Forwarding sample application:
18d0dff9baSBernard Iremonger
19d0dff9baSBernard Iremonger*   The IPv4 Multicast sample application makes use of indirect buffers.
20d0dff9baSBernard Iremonger
21d0dff9baSBernard Iremonger*   The forwarding decision is taken based on information read from the input packet's IPv4 header.
22d0dff9baSBernard Iremonger
23d0dff9baSBernard IremongerThe lookup method is the Four-byte Key (FBK) hash-based method.
24*8750576fSNandini PersadThe lookup table is composed of pairs of destination IPv4 addresses (the FBK)
25d0dff9baSBernard Iremongerand a port mask associated with that IPv4 address.
26854c0b1fSHuzaifa RahmanBy default, the following IP addresses and their respective port masks are added:
27854c0b1fSHuzaifa Rahman
28854c0b1fSHuzaifa Rahman.. literalinclude:: ../../../examples/ipv4_multicast/main.c
29854c0b1fSHuzaifa Rahman   :language: c
30854c0b1fSHuzaifa Rahman   :start-after: mcast_group_table
31854c0b1fSHuzaifa Rahman   :end-before: };
32d0dff9baSBernard Iremonger
337c8f4eedSHemant Agrawal.. note::
347c8f4eedSHemant Agrawal
357c8f4eedSHemant Agrawal    The max port mask supported in the given hash table is 0xf, so only first
367c8f4eedSHemant Agrawal    four ports can be supported.
377c8f4eedSHemant Agrawal    If using non-consecutive ports, use the destination IPv4 address accordingly.
387c8f4eedSHemant Agrawal
39d0dff9baSBernard IremongerFor convenience and simplicity, this sample application does not take IANA-assigned multicast addresses into account,
40d0dff9baSBernard Iremongerbut instead equates the last four bytes of the multicast group (that is, the last four bytes of the destination IP address)
41*8750576fSNandini Persadwith the mask of ports to multicast packets.
42*8750576fSNandini Persad
43d0dff9baSBernard IremongerAlso, the application does not consider the Ethernet addresses;
44d0dff9baSBernard Iremongerit looks only at the IPv4 destination address for any given packet.
45d0dff9baSBernard Iremonger
467cacb056SHerakliusz LipiecCompiling the Application
477cacb056SHerakliusz Lipiec-------------------------
48d0dff9baSBernard Iremonger
49*8750576fSNandini PersadTo compile the sample application, see :doc:`compiling`.
50d0dff9baSBernard Iremonger
517cacb056SHerakliusz LipiecThe application is located in the ``ipv4_multicast`` sub-directory.
52d0dff9baSBernard Iremonger
53d0dff9baSBernard IremongerRunning the Application
54d0dff9baSBernard Iremonger-----------------------
55d0dff9baSBernard Iremonger
56d0dff9baSBernard IremongerThe application has a number of command line options:
57d0dff9baSBernard Iremonger
58d0dff9baSBernard Iremonger.. code-block:: console
59d0dff9baSBernard Iremonger
60e2a94f9aSCiara Power    ./<build_dir>/examples/dpdk-ipv4_multicast [EAL options] -- -p PORTMASK [-q NQ]
61d0dff9baSBernard Iremonger
62d0dff9baSBernard Iremongerwhere,
63d0dff9baSBernard Iremonger
64d0dff9baSBernard Iremonger*   -p PORTMASK: Hexadecimal bitmask of ports to configure
65d0dff9baSBernard Iremonger
66d0dff9baSBernard Iremonger*   -q NQ: determines the number of queues per lcore
67d0dff9baSBernard Iremonger
68d0dff9baSBernard Iremonger.. note::
69d0dff9baSBernard Iremonger
70d0dff9baSBernard Iremonger    Unlike the basic L2/L3 Forwarding sample applications,
71d0dff9baSBernard Iremonger    NUMA support is not provided in the IPv4 Multicast sample application.
72d0dff9baSBernard Iremonger
73d0dff9baSBernard IremongerTypically, to run the IPv4 Multicast sample application, issue the following command (as root):
74d0dff9baSBernard Iremonger
75d0dff9baSBernard Iremonger.. code-block:: console
76d0dff9baSBernard Iremonger
77e2a94f9aSCiara Power    ./<build_dir>/examples/dpdk-ipv4_multicast -l 0-3 -n 3 -- -p 0x3 -q 1
78d0dff9baSBernard Iremonger
79d0dff9baSBernard IremongerIn this command:
80d0dff9baSBernard Iremonger
81da8e7a30SRami Rosen*   The -l option enables cores 0, 1, 2 and 3
82d0dff9baSBernard Iremonger
83d0dff9baSBernard Iremonger*   The -n option specifies 3 memory channels
84d0dff9baSBernard Iremonger
85d0dff9baSBernard Iremonger*   The -p option enables ports 0 and 1
86d0dff9baSBernard Iremonger
87d0dff9baSBernard Iremonger*   The -q option assigns 1 queue to each lcore
88d0dff9baSBernard Iremonger
89e0c7c473SSiobhan ButlerRefer to the *DPDK Getting Started Guide* for general information on running applications
90d0dff9baSBernard Iremongerand the Environment Abstraction Layer (EAL) options.
91d0dff9baSBernard Iremonger
92d0dff9baSBernard IremongerExplanation
93d0dff9baSBernard Iremonger-----------
94d0dff9baSBernard Iremonger
95d0dff9baSBernard IremongerThe following sections provide some explanation of the code.
96d0dff9baSBernard IremongerAs mentioned in the overview section,
97513b0723SMauricio Vasquez Bthe initialization and run-time paths are very similar to those of the :doc:`l2_forward_real_virtual`.
98d0dff9baSBernard IremongerThe following sections describe aspects that are specific to the IPv4 Multicast sample application.
99d0dff9baSBernard Iremonger
100d0dff9baSBernard IremongerMemory Pool Initialization
101d0dff9baSBernard Iremonger~~~~~~~~~~~~~~~~~~~~~~~~~~
102d0dff9baSBernard Iremonger
103d0dff9baSBernard IremongerThe IPv4 Multicast sample application uses three memory pools.
104d0dff9baSBernard IremongerTwo of the pools are for indirect buffers used for packet duplication purposes.
105d0dff9baSBernard IremongerMemory pools for indirect buffers are initialized differently from the memory pool for direct buffers:
106d0dff9baSBernard Iremonger
1079a212dc0SConor Fogarty.. literalinclude:: ../../../examples/ipv4_multicast/main.c
1089a212dc0SConor Fogarty    :language: c
1099a212dc0SConor Fogarty    :start-after: Create the mbuf pools. 8<
1109a212dc0SConor Fogarty    :end-before: >8 End of create mbuf pools.
1119a212dc0SConor Fogarty    :dedent: 1
112d0dff9baSBernard Iremonger
113*8750576fSNandini PersadThe reason for this is that indirect buffers are not supposed to hold any packet data and
114*8750576fSNandini Persadtherefore can be initialized with the lower amount of reserved memory for each buffer.
115d0dff9baSBernard Iremonger
116d0dff9baSBernard IremongerHash Initialization
117d0dff9baSBernard Iremonger~~~~~~~~~~~~~~~~~~~
118d0dff9baSBernard Iremonger
119d0dff9baSBernard IremongerThe hash object is created and loaded with the pre-configured entries read from a global array:
120d0dff9baSBernard Iremonger
1219a212dc0SConor Fogarty.. literalinclude:: ../../../examples/ipv4_multicast/main.c
1229a212dc0SConor Fogarty    :language: c
1239a212dc0SConor Fogarty    :start-after: Hash object is created and loaded. 8<
1249a212dc0SConor Fogarty    :end-before: >8 End of hash object is created and loaded.
125d0dff9baSBernard Iremonger
126d0dff9baSBernard IremongerForwarding
127d0dff9baSBernard Iremonger~~~~~~~~~~
128d0dff9baSBernard Iremonger
129*8750576fSNandini PersadAll forwarding is done inside the ``mcast_forward()`` function.
130d0dff9baSBernard IremongerFirstly, the Ethernet* header is removed from the packet and the IPv4 address is extracted from the IPv4 header:
131d0dff9baSBernard Iremonger
1329a212dc0SConor Fogarty.. literalinclude:: ../../../examples/ipv4_multicast/main.c
1339a212dc0SConor Fogarty    :language: c
1349a212dc0SConor Fogarty    :start-after: Remove the Ethernet header from the input packet. 8<
1359a212dc0SConor Fogarty    :end-before: >8 End of removing the Ethernet header from the input packet.
1369a212dc0SConor Fogarty    :dedent: 1
137d0dff9baSBernard Iremonger
138d0dff9baSBernard IremongerThen, the packet is checked to see if it has a multicast destination address and
139d0dff9baSBernard Iremongerif the routing table has any ports assigned to the destination address:
140d0dff9baSBernard Iremonger
1419a212dc0SConor Fogarty.. literalinclude:: ../../../examples/ipv4_multicast/main.c
1429a212dc0SConor Fogarty    :language: c
1439a212dc0SConor Fogarty    :start-after: Check valid multicast address. 8<
1449a212dc0SConor Fogarty    :end-before: >8 End of valid multicast address check.
1459a212dc0SConor Fogarty    :dedent: 1
146d0dff9baSBernard Iremonger
147*8750576fSNandini PersadNext, the number of ports in the destination portmask
148*8750576fSNandini Persadis calculated with the help of the ``bitcnt()`` function:
149d0dff9baSBernard Iremonger
1509a212dc0SConor Fogarty.. literalinclude:: ../../../examples/ipv4_multicast/main.c
1519a212dc0SConor Fogarty    :language: c
1529a212dc0SConor Fogarty    :start-after: Get number of bits set. 8<
1539a212dc0SConor Fogarty    :end-before: >8 End of getting number of bits set.
154d0dff9baSBernard Iremonger
155d0dff9baSBernard IremongerThis is done to determine which forwarding algorithm to use.
156d0dff9baSBernard IremongerThis is explained in more detail in the next section.
157d0dff9baSBernard Iremonger
158d0dff9baSBernard IremongerThereafter, a destination Ethernet address is constructed:
159d0dff9baSBernard Iremonger
1609a212dc0SConor Fogarty.. literalinclude:: ../../../examples/ipv4_multicast/main.c
1619a212dc0SConor Fogarty    :language: c
1629a212dc0SConor Fogarty    :start-after: Construct destination ethernet address. 8<
1639a212dc0SConor Fogarty    :end-before: >8 End of constructing destination ethernet address.
1649a212dc0SConor Fogarty    :dedent: 1
165d0dff9baSBernard Iremonger
166d0dff9baSBernard IremongerSince Ethernet addresses are also part of the multicast process, each outgoing packet carries the same destination Ethernet address.
167fea1d908SJohn McNamaraThe destination Ethernet address is constructed from the lower 23 bits of the multicast group OR-ed
168d0dff9baSBernard Iremongerwith the Ethernet address 01:00:5e:00:00:00, as per RFC 1112:
169d0dff9baSBernard Iremonger
1709a212dc0SConor Fogarty.. literalinclude:: ../../../examples/ipv4_multicast/main.c
1719a212dc0SConor Fogarty    :language: c
1729a212dc0SConor Fogarty    :start-after: Construct Ethernet multicast address from IPv4 multicast Address. 8<
1739a212dc0SConor Fogarty    :end-before: >8 End of Construction of multicast address from IPv4 multicast address.
174d0dff9baSBernard Iremonger
175*8750576fSNandini PersadPackets are then dispatched to the destination ports according to the portmask associated with a multicast group:
176d0dff9baSBernard Iremonger
1779a212dc0SConor Fogarty.. literalinclude:: ../../../examples/ipv4_multicast/main.c
1789a212dc0SConor Fogarty    :language: c
1799a212dc0SConor Fogarty    :start-after: Packets dispatched to destination ports. 8<
1809a212dc0SConor Fogarty    :end-before: >8 End of packets dispatched to destination ports.
1819a212dc0SConor Fogarty    :dedent: 1
182d0dff9baSBernard Iremonger
183*8750576fSNandini PersadThe actual packet transmission is done in the ``mcast_send_pkt()`` function:
184d0dff9baSBernard Iremonger
1859a212dc0SConor Fogarty.. literalinclude:: ../../../examples/ipv4_multicast/main.c
1869a212dc0SConor Fogarty    :language: c
1879a212dc0SConor Fogarty    :start-after: Write new Ethernet header to outgoing packets. 8<
1889a212dc0SConor Fogarty    :end-before: >8 End of writing new Ethernet headers.
189d0dff9baSBernard Iremonger
190d0dff9baSBernard IremongerBuffer Cloning
191d0dff9baSBernard Iremonger~~~~~~~~~~~~~~
192d0dff9baSBernard Iremonger
193*8750576fSNandini PersadThis is the most important part of the application
194*8750576fSNandini Persadsince it demonstrates the use of zero-copy buffer cloning.
195*8750576fSNandini PersadThere are two approaches for creating the outgoing packet.
196*8750576fSNandini PersadAlthough both are based on the data zero-copy idea,
197*8750576fSNandini Persadthere are some differences in the details.
198d0dff9baSBernard Iremonger
199*8750576fSNandini PersadThe first approach creates a clone of the input packet. For example,
200d0dff9baSBernard Iremongerwalk though all segments of the input packet and for each of segment,
201d0dff9baSBernard Iremongercreate a new buffer and attach that new buffer to the segment
202*8750576fSNandini Persad(refer to ``rte_pktmbuf_clone()`` in the mbuf library for more details).
203d0dff9baSBernard IremongerA new buffer is then allocated for the packet header and is prepended to the cloned buffer.
204d0dff9baSBernard Iremonger
205*8750576fSNandini PersadThe second approach does not make a clone.
206*8750576fSNandini PersadIt simply increments the reference counter for all input packet segments,
207d0dff9baSBernard Iremongerallocates a new buffer for the packet header and prepends it to the input packet.
208d0dff9baSBernard Iremonger
209d0dff9baSBernard IremongerBasically, the first approach reuses only the input packet's data, but creates its own copy of packet's metadata.
210d0dff9baSBernard IremongerThe second approach reuses both input packet's data and metadata.
211d0dff9baSBernard Iremonger
212*8750576fSNandini PersadThe advantage of the first approach is that each outgoing packet has its own copy of the metadata,
213d0dff9baSBernard Iremongerso we can safely modify the data pointer of the input packet.
214d0dff9baSBernard IremongerThat allows us to skip creation if the output packet is for the last destination port
215*8750576fSNandini Persadand, instead, modify the input packet's header in place.
216*8750576fSNandini PersadFor example, for N destination ports, we need to invoke ``mcast_out_pkt()`` (N-1) times.
217d0dff9baSBernard Iremonger
218*8750576fSNandini PersadThe advantage of the second approach is that there is less work to be done for each outgoing packet.
219*8750576fSNandini PersadThe "clone" operation is skipped completely.
220d0dff9baSBernard IremongerHowever, there is a price to pay.
221*8750576fSNandini PersadThe input packet's metadata must remain intact. For N destination ports,
222*8750576fSNandini Persadwe need to invoke ``mcast_out_pkt()`` (N) times.
223d0dff9baSBernard Iremonger
224d0dff9baSBernard IremongerTherefore, for a small number of outgoing ports (and segments in the input packet),
225*8750576fSNandini Persadthe first approach is faster.
226d0dff9baSBernard IremongerAs the number of outgoing ports (and/or input segments) grows, the second approach becomes more preferable.
227d0dff9baSBernard Iremonger
228d0dff9baSBernard IremongerDepending on the number of segments or the number of ports in the outgoing portmask,
229d0dff9baSBernard Iremongereither the first (with cloning) or the second (without cloning) approach is taken:
230d0dff9baSBernard Iremonger
2319a212dc0SConor Fogarty.. literalinclude:: ../../../examples/ipv4_multicast/main.c
2329a212dc0SConor Fogarty    :language: c
2339a212dc0SConor Fogarty    :start-after: Should we use rte_pktmbuf_clone() or not. 8<
2349a212dc0SConor Fogarty    :end-before: >8 End of using rte_pktmbuf_clone().
2359a212dc0SConor Fogarty    :dedent: 1
236d0dff9baSBernard Iremonger
237*8750576fSNandini PersadIt is the ``mcast_out_pkt()`` function that performs the packet duplication
238*8750576fSNandini Persad(either with or without actually cloning the buffers):
239d0dff9baSBernard Iremonger
2409a212dc0SConor Fogarty.. literalinclude:: ../../../examples/ipv4_multicast/main.c
2419a212dc0SConor Fogarty    :language: c
2429a212dc0SConor Fogarty    :start-after: mcast_out_pkt 8<
2439a212dc0SConor Fogarty    :end-before: >8 End of mcast_out_kt.
244