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