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