1.. SPDX-License-Identifier: BSD-3-Clause 2 Copyright(c) 2010-2015 Intel Corporation. 3 4Libpcap and Ring Based Poll Mode Drivers 5======================================== 6 7In addition to Poll Mode Drivers (PMDs) for physical and virtual hardware, 8the DPDK also includes pure-software PMDs, two of these drivers are: 9 10* A libpcap -based PMD (librte_pmd_pcap) that reads and writes packets using libpcap, 11 - both from files on disk, as well as from physical NIC devices using standard Linux kernel drivers. 12 13* A ring-based PMD (librte_pmd_ring) that allows a set of software FIFOs (that is, rte_ring) 14 to be accessed using the PMD APIs, as though they were physical NICs. 15 16.. note:: 17 18 The libpcap -based PMD is disabled by default in the build configuration files, 19 owing to an external dependency on the libpcap development files which must be installed on the board. 20 Once the libpcap development files are installed, 21 the library can be enabled by setting CONFIG_RTE_LIBRTE_PMD_PCAP=y and recompiling the DPDK. 22 23Using the Drivers from the EAL Command Line 24------------------------------------------- 25 26For ease of use, the DPDK EAL also has been extended to allow pseudo-Ethernet devices, 27using one or more of these drivers, 28to be created at application startup time during EAL initialization. 29 30To do so, the --vdev= parameter must be passed to the EAL. 31This takes take options to allow ring and pcap-based Ethernet to be allocated and used transparently by the application. 32This can be used, for example, for testing on a virtual machine where there are no Ethernet ports. 33 34Libpcap-based PMD 35~~~~~~~~~~~~~~~~~ 36 37Pcap-based devices can be created using the virtual device --vdev option. 38The device name must start with the net_pcap prefix followed by numbers or letters. 39The name is unique for each device. Each device can have multiple stream options and multiple devices can be used. 40Multiple device definitions can be arranged using multiple --vdev. 41Device name and stream options must be separated by commas as shown below: 42 43.. code-block:: console 44 45 $RTE_TARGET/app/testpmd -l 0-3 -n 4 \ 46 --vdev 'net_pcap0,stream_opt0=..,stream_opt1=..' \ 47 --vdev='net_pcap1,stream_opt0=..' 48 49Device Streams 50^^^^^^^^^^^^^^ 51 52Multiple ways of stream definitions can be assessed and combined as long as the following two rules are respected: 53 54* A device is provided with two different streams - reception and transmission. 55 56* A device is provided with one network interface name used for reading and writing packets. 57 58The different stream types are: 59 60* rx_pcap: Defines a reception stream based on a pcap file. 61 The driver reads each packet within the given pcap file as if it was receiving it from the wire. 62 The value is a path to a valid pcap file. 63 64 rx_pcap=/path/to/file.pcap 65 66* tx_pcap: Defines a transmission stream based on a pcap file. 67 The driver writes each received packet to the given pcap file. 68 The value is a path to a pcap file. 69 The file is overwritten if it already exists and it is created if it does not. 70 71 tx_pcap=/path/to/file.pcap 72 73* rx_iface: Defines a reception stream based on a network interface name. 74 The driver reads packets from the given interface using the Linux kernel driver for that interface. 75 The driver captures both the incoming and outgoing packets on that interface. 76 The value is an interface name. 77 78 rx_iface=eth0 79 80* rx_iface_in: Defines a reception stream based on a network interface name. 81 The driver reads packets from the given interface using the Linux kernel driver for that interface. 82 The driver captures only the incoming packets on that interface. 83 The value is an interface name. 84 85 rx_iface_in=eth0 86 87* tx_iface: Defines a transmission stream based on a network interface name. 88 The driver sends packets to the given interface using the Linux kernel driver for that interface. 89 The value is an interface name. 90 91 tx_iface=eth0 92 93* iface: Defines a device mapping a network interface. 94 The driver both reads and writes packets from and to the given interface. 95 The value is an interface name. 96 97 iface=eth0 98 99Runtime Config Options 100^^^^^^^^^^^^^^^^^^^^^^ 101 102- Use PCAP interface physical MAC 103 104 In case ``iface=`` configuration is set, user may want to use the selected interface's physical MAC 105 address. This can be done with a ``devarg`` ``phy_mac``, for example:: 106 107 --vdev 'net_pcap0,iface=eth0,phy_mac=1' 108 109- Use the RX PCAP file to infinitely receive packets 110 111 In case ``rx_pcap=`` configuration is set, user may want to use the selected PCAP file for rudimental 112 performance testing. This can be done with a ``devarg`` ``infinite_rx``, for example:: 113 114 --vdev 'net_pcap0,rx_pcap=file_rx.pcap,infinite_rx=1' 115 116 When this mode is used, it is recommended to drop all packets on transmit by not providing a tx_pcap or tx_iface. 117 118 This option is device wide, so all queues on a device will either have this enabled or disabled. 119 This option should only be provided once per device. 120 121- Drop all packets on transmit 122 123 The user may want to drop all packets on tx for a device. This can be done by not providing a tx_pcap or tx_iface, for example:: 124 125 --vdev 'net_pcap0,rx_pcap=file_rx.pcap' 126 127 In this case, one tx drop queue is created for each rxq on that device. 128 129 - Receive no packets on Rx 130 131 The user may want to run without receiving any packets on Rx. This can be done by not providing a rx_pcap or rx_iface, for example:: 132 133 --vdev 'net_pcap0,tx_pcap=file_tx.pcap' 134 135In this case, one dummy rx queue is created for each tx queue argument passed 136 137Examples of Usage 138^^^^^^^^^^^^^^^^^ 139 140Read packets from one pcap file and write them to another: 141 142.. code-block:: console 143 144 $RTE_TARGET/app/testpmd -l 0-3 -n 4 \ 145 --vdev 'net_pcap0,rx_pcap=file_rx.pcap,tx_pcap=file_tx.pcap' \ 146 -- --port-topology=chained 147 148Read packets from a network interface and write them to a pcap file: 149 150.. code-block:: console 151 152 $RTE_TARGET/app/testpmd -l 0-3 -n 4 \ 153 --vdev 'net_pcap0,rx_iface=eth0,tx_pcap=file_tx.pcap' \ 154 -- --port-topology=chained 155 156Read packets from a pcap file and write them to a network interface: 157 158.. code-block:: console 159 160 $RTE_TARGET/app/testpmd -l 0-3 -n 4 \ 161 --vdev 'net_pcap0,rx_pcap=file_rx.pcap,tx_iface=eth1' \ 162 -- --port-topology=chained 163 164Forward packets through two network interfaces: 165 166.. code-block:: console 167 168 $RTE_TARGET/app/testpmd -l 0-3 -n 4 \ 169 --vdev 'net_pcap0,iface=eth0' --vdev='net_pcap1;iface=eth1' 170 171Enable 2 tx queues on a network interface: 172 173.. code-block:: console 174 175 $RTE_TARGET/app/testpmd -l 0-3 -n 4 \ 176 --vdev 'net_pcap0,rx_iface=eth1,tx_iface=eth1,tx_iface=eth1' \ 177 -- --txq 2 178 179Read only incoming packets from a network interface and write them back to the same network interface: 180 181.. code-block:: console 182 183 $RTE_TARGET/app/testpmd -l 0-3 -n 4 \ 184 --vdev 'net_pcap0,rx_iface_in=eth1,tx_iface=eth1' 185 186Using libpcap-based PMD with the testpmd Application 187^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 188 189One of the first things that testpmd does before starting to forward packets is to flush the RX streams 190by reading the first 512 packets on every RX stream and discarding them. 191When using a libpcap-based PMD this behavior can be turned off using the following command line option: 192 193.. code-block:: console 194 195 --no-flush-rx 196 197It is also available in the runtime command line: 198 199.. code-block:: console 200 201 set flush_rx on/off 202 203It is useful for the case where the rx_pcap is being used and no packets are meant to be discarded. 204Otherwise, the first 512 packets from the input pcap file will be discarded by the RX flushing operation. 205 206.. code-block:: console 207 208 $RTE_TARGET/app/testpmd -l 0-3 -n 4 \ 209 --vdev 'net_pcap0,rx_pcap=file_rx.pcap,tx_pcap=file_tx.pcap' \ 210 -- --port-topology=chained --no-flush-rx 211 212.. note:: 213 214 The network interface provided to the PMD should be up. The PMD will return 215 an error if interface is down, and the PMD itself won't change the status 216 of the external network interface. 217 218 219Rings-based PMD 220~~~~~~~~~~~~~~~ 221 222To run a DPDK application on a machine without any Ethernet devices, a pair of ring-based rte_ethdevs can be used as below. 223The device names passed to the --vdev option must start with net_ring and take no additional parameters. 224Multiple devices may be specified, separated by commas. 225 226.. code-block:: console 227 228 ./testpmd -l 1-3 -n 4 --vdev=net_ring0 --vdev=net_ring1 -- -i 229 EAL: Detected lcore 1 as core 1 on socket 0 230 ... 231 232 Interactive-mode selected 233 Configuring Port 0 (socket 0) 234 Configuring Port 1 (socket 0) 235 Checking link statuses... 236 Port 0 Link Up - speed 10000 Mbps - full-duplex 237 Port 1 Link Up - speed 10000 Mbps - full-duplex 238 Done 239 240 testpmd> start tx_first 241 io packet forwarding - CRC stripping disabled - packets/burst=16 242 nb forwarding cores=1 - nb forwarding ports=2 243 RX queues=1 - RX desc=128 - RX free threshold=0 244 RX threshold registers: pthresh=8 hthresh=8 wthresh=4 245 TX queues=1 - TX desc=512 - TX free threshold=0 246 TX threshold registers: pthresh=36 hthresh=0 wthresh=0 247 TX RS bit threshold=0 - TXQ flags=0x0 248 249 testpmd> stop 250 Telling cores to stop... 251 Waiting for lcores to finish... 252 253.. image:: img/forward_stats.* 254 255.. code-block:: console 256 257 +++++++++++++++ Accumulated forward statistics for allports++++++++++ 258 RX-packets: 462384736 RX-dropped: 0 RX-total: 462384736 259 TX-packets: 462384768 TX-dropped: 0 TX-total: 462384768 260 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 261 262 Done. 263 264 265Using the Poll Mode Driver from an Application 266~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 267 268Both drivers can provide similar APIs to allow the user to create a PMD, that is, 269rte_ethdev structure, instances at run-time in the end-application, 270for example, using rte_eth_from_rings() or rte_eth_from_pcaps() APIs. 271For the rings-based PMD, this functionality could be used, for example, 272to allow data exchange between cores using rings to be done in exactly the 273same way as sending or receiving packets from an Ethernet device. 274For the libpcap-based PMD, it allows an application to open one or more pcap files 275and use these as a source of packet input to the application. 276 277Usage Examples 278^^^^^^^^^^^^^^ 279 280To create two pseudo-Ethernet ports where all traffic sent to a port is looped back 281for reception on the same port (error handling omitted for clarity): 282 283.. code-block:: c 284 285 #define RING_SIZE 256 286 #define NUM_RINGS 2 287 #define SOCKET0 0 288 289 struct rte_ring *ring[NUM_RINGS]; 290 int port0, port1; 291 292 ring[0] = rte_ring_create("R0", RING_SIZE, SOCKET0, RING_F_SP_ENQ|RING_F_SC_DEQ); 293 ring[1] = rte_ring_create("R1", RING_SIZE, SOCKET0, RING_F_SP_ENQ|RING_F_SC_DEQ); 294 295 /* create two ethdev's */ 296 297 port0 = rte_eth_from_rings("net_ring0", ring, NUM_RINGS, ring, NUM_RINGS, SOCKET0); 298 port1 = rte_eth_from_rings("net_ring1", ring, NUM_RINGS, ring, NUM_RINGS, SOCKET0); 299 300 301To create two pseudo-Ethernet ports where the traffic is switched between them, 302that is, traffic sent to port 0 is read back from port 1 and vice-versa, 303the final two lines could be changed as below: 304 305.. code-block:: c 306 307 port0 = rte_eth_from_rings("net_ring0", &ring[0], 1, &ring[1], 1, SOCKET0); 308 port1 = rte_eth_from_rings("net_ring1", &ring[1], 1, &ring[0], 1, SOCKET0); 309 310This type of configuration could be useful in a pipeline model, for example, 311where one may want to have inter-core communication using pseudo Ethernet devices rather than raw rings, 312for reasons of API consistency. 313 314Enqueuing and dequeuing items from an rte_ring using the rings-based PMD may be slower than using the native rings API. 315This is because DPDK Ethernet drivers make use of function pointers to call the appropriate enqueue or dequeue functions, 316while the rte_ring specific functions are direct function calls in the code and are often inlined by the compiler. 317 318 Once an ethdev has been created, for either a ring or a pcap-based PMD, 319 it should be configured and started in the same way as a regular Ethernet device, that is, 320 by calling rte_eth_dev_configure() to set the number of receive and transmit queues, 321 then calling rte_eth_rx_queue_setup() / tx_queue_setup() for each of those queues and 322 finally calling rte_eth_dev_start() to allow transmission and reception of packets to begin. 323