15129044dSC.J. Collier..  BSD LICENSE
25129044dSC.J. Collier    Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
35129044dSC.J. Collier    All rights reserved.
45129044dSC.J. Collier
55129044dSC.J. Collier    Redistribution and use in source and binary forms, with or without
65129044dSC.J. Collier    modification, are permitted provided that the following conditions
75129044dSC.J. Collier    are met:
85129044dSC.J. Collier
95129044dSC.J. Collier    * Redistributions of source code must retain the above copyright
105129044dSC.J. Collier    notice, this list of conditions and the following disclaimer.
115129044dSC.J. Collier    * Redistributions in binary form must reproduce the above copyright
125129044dSC.J. Collier    notice, this list of conditions and the following disclaimer in
135129044dSC.J. Collier    the documentation and/or other materials provided with the
145129044dSC.J. Collier    distribution.
155129044dSC.J. Collier    * Neither the name of Intel Corporation nor the names of its
165129044dSC.J. Collier    contributors may be used to endorse or promote products derived
175129044dSC.J. Collier    from this software without specific prior written permission.
185129044dSC.J. Collier
195129044dSC.J. Collier    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
205129044dSC.J. Collier    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
215129044dSC.J. Collier    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
225129044dSC.J. Collier    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
235129044dSC.J. Collier    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
245129044dSC.J. Collier    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
255129044dSC.J. Collier    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
265129044dSC.J. Collier    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
275129044dSC.J. Collier    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
285129044dSC.J. Collier    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
295129044dSC.J. Collier    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
305129044dSC.J. Collier
315129044dSC.J. CollierLibpcap and Ring Based Poll Mode Drivers
325129044dSC.J. Collier========================================
335129044dSC.J. Collier
345129044dSC.J. CollierIn addition to Poll Mode Drivers (PMDs) for physical and virtual hardware,
355129044dSC.J. Collierthe DPDK also includes two pure-software PMDs. These two drivers are:
365129044dSC.J. Collier
375129044dSC.J. Collier*   A libpcap -based PMD (librte_pmd_pcap) that reads and writes packets using libpcap,
385129044dSC.J. Collier    - both from files on disk, as well as from physical NIC devices using standard Linux kernel drivers.
395129044dSC.J. Collier
405129044dSC.J. Collier*   A ring-based PMD (librte_pmd_ring) that allows a set of software FIFOs (that is, rte_ring)
415129044dSC.J. Collier    to be accessed using the PMD APIs, as though they were physical NICs.
425129044dSC.J. Collier
435129044dSC.J. Collier.. note::
445129044dSC.J. Collier
455129044dSC.J. Collier    The libpcap -based PMD is disabled by default in the build configuration files,
465129044dSC.J. Collier    owing to an external dependency on the libpcap development files which must be installed on the board.
475129044dSC.J. Collier    Once the libpcap development files are installed,
485129044dSC.J. Collier    the library can be enabled by setting CONFIG_RTE_LIBRTE_PMD_PCAP=y and recompiling the DPDK.
495129044dSC.J. Collier
505129044dSC.J. CollierUsing the Drivers from the EAL Command Line
515129044dSC.J. Collier-------------------------------------------
525129044dSC.J. Collier
535129044dSC.J. CollierFor ease of use, the DPDK EAL also has been extended to allow pseudo-Ethernet devices,
545129044dSC.J. Collierusing one or more of these drivers,
555129044dSC.J. Collierto be created at application startup time during EAL initialization.
565129044dSC.J. Collier
575129044dSC.J. CollierTo do so, the --vdev= parameter must be passed to the EAL.
585129044dSC.J. CollierThis takes take options to allow ring and pcap-based Ethernet to be allocated and used transparently by the application.
595129044dSC.J. CollierThis can be used, for example, for testing on a virtual machine where there are no Ethernet ports.
605129044dSC.J. Collier
615129044dSC.J. CollierLibpcap-based PMD
625129044dSC.J. Collier~~~~~~~~~~~~~~~~~
635129044dSC.J. Collier
645129044dSC.J. CollierPcap-based devices can be created using the virtual device --vdev option.
653d9b7210SChristian EhrhardtThe device name must start with the net_pcap prefix followed by numbers or letters.
665129044dSC.J. CollierThe name is unique for each device. Each device can have multiple stream options and multiple devices can be used.
675129044dSC.J. CollierMultiple device definitions can be arranged using multiple --vdev.
685129044dSC.J. CollierDevice name and stream options must be separated by commas as shown below:
695129044dSC.J. Collier
705129044dSC.J. Collier.. code-block:: console
715129044dSC.J. Collier
723d9b7210SChristian Ehrhardt   $RTE_TARGET/app/testpmd -c f -n 4 \
733d9b7210SChristian Ehrhardt       --vdev 'net_pcap0,stream_opt0=..,stream_opt1=..' \
743d9b7210SChristian Ehrhardt       --vdev='net_pcap1,stream_opt0=..'
755129044dSC.J. Collier
765129044dSC.J. CollierDevice Streams
775129044dSC.J. Collier^^^^^^^^^^^^^^
785129044dSC.J. Collier
795129044dSC.J. CollierMultiple ways of stream definitions can be assessed and combined as long as the following two rules are respected:
805129044dSC.J. Collier
815129044dSC.J. Collier*   A device is provided with two different streams - reception and transmission.
825129044dSC.J. Collier
835129044dSC.J. Collier*   A device is provided with one network interface name used for reading and writing packets.
845129044dSC.J. Collier
855129044dSC.J. CollierThe different stream types are:
865129044dSC.J. Collier
875129044dSC.J. Collier*   rx_pcap: Defines a reception stream based on a pcap file.
885129044dSC.J. Collier    The driver reads each packet within the given pcap file as if it was receiving it from the wire.
895129044dSC.J. Collier    The value is a path to a valid pcap file.
905129044dSC.J. Collier
915129044dSC.J. Collier        rx_pcap=/path/to/file.pcap
925129044dSC.J. Collier
935129044dSC.J. Collier*   tx_pcap: Defines a transmission stream based on a pcap file.
945129044dSC.J. Collier    The driver writes each received packet to the given pcap file.
955129044dSC.J. Collier    The value is a path to a pcap file.
965129044dSC.J. Collier    The file is overwritten if it already exists and it is created if it does not.
975129044dSC.J. Collier
985129044dSC.J. Collier        tx_pcap=/path/to/file.pcap
995129044dSC.J. Collier
1005129044dSC.J. Collier*   rx_iface: Defines a reception stream based on a network interface name.
1015129044dSC.J. Collier    The driver reads packets coming from the given interface using the Linux kernel driver for that interface.
1025129044dSC.J. Collier    The value is an interface name.
1035129044dSC.J. Collier
1045129044dSC.J. Collier        rx_iface=eth0
1055129044dSC.J. Collier
1065129044dSC.J. Collier*   tx_iface: Defines a transmission stream based on a network interface name.
1075129044dSC.J. Collier    The driver sends packets to the given interface using the Linux kernel driver for that interface.
1085129044dSC.J. Collier    The value is an interface name.
1095129044dSC.J. Collier
1105129044dSC.J. Collier        tx_iface=eth0
1115129044dSC.J. Collier
1125129044dSC.J. Collier*   iface: Defines a device mapping a network interface.
1135129044dSC.J. Collier    The driver both reads and writes packets from and to the given interface.
1145129044dSC.J. Collier    The value is an interface name.
1155129044dSC.J. Collier
1165129044dSC.J. Collier        iface=eth0
1175129044dSC.J. Collier
1185129044dSC.J. CollierExamples of Usage
1195129044dSC.J. Collier^^^^^^^^^^^^^^^^^
1205129044dSC.J. Collier
1215129044dSC.J. CollierRead packets from one pcap file and write them to another:
1225129044dSC.J. Collier
1235129044dSC.J. Collier.. code-block:: console
1245129044dSC.J. Collier
1253d9b7210SChristian Ehrhardt    $RTE_TARGET/app/testpmd -c '0xf' -n 4 \
1263d9b7210SChristian Ehrhardt        --vdev 'net_pcap0,rx_pcap=file_rx.pcap,tx_pcap=file_tx.pcap' \
1273d9b7210SChristian Ehrhardt        -- --port-topology=chained
1285129044dSC.J. Collier
1295129044dSC.J. CollierRead packets from a network interface and write them to a pcap file:
1305129044dSC.J. Collier
1315129044dSC.J. Collier.. code-block:: console
1325129044dSC.J. Collier
1333d9b7210SChristian Ehrhardt    $RTE_TARGET/app/testpmd -c '0xf' -n 4 \
1343d9b7210SChristian Ehrhardt        --vdev 'net_pcap0,rx_iface=eth0,tx_pcap=file_tx.pcap' \
1353d9b7210SChristian Ehrhardt        -- --port-topology=chained
1365129044dSC.J. Collier
1375129044dSC.J. CollierRead packets from a pcap file and write them to a network interface:
1385129044dSC.J. Collier
1395129044dSC.J. Collier.. code-block:: console
1405129044dSC.J. Collier
1413d9b7210SChristian Ehrhardt    $RTE_TARGET/app/testpmd -c '0xf' -n 4 \
1423d9b7210SChristian Ehrhardt        --vdev 'net_pcap0,rx_pcap=file_rx.pcap,tx_iface=eth1' \
1433d9b7210SChristian Ehrhardt        -- --port-topology=chained
1445129044dSC.J. Collier
1455129044dSC.J. CollierForward packets through two network interfaces:
1465129044dSC.J. Collier
1475129044dSC.J. Collier.. code-block:: console
1485129044dSC.J. Collier
1493d9b7210SChristian Ehrhardt    $RTE_TARGET/app/testpmd -c '0xf' -n 4 \
1503d9b7210SChristian Ehrhardt        --vdev 'net_pcap0,iface=eth0' --vdev='net_pcap1;iface=eth1'
1515129044dSC.J. Collier
1525129044dSC.J. CollierUsing libpcap-based PMD with the testpmd Application
1535129044dSC.J. Collier^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1545129044dSC.J. Collier
1555129044dSC.J. CollierOne of the first things that testpmd does before starting to forward packets is to flush the RX streams
1565129044dSC.J. Collierby reading the first 512 packets on every RX stream and discarding them.
1575129044dSC.J. CollierWhen using a libpcap-based PMD this behavior can be turned off using the following command line option:
1585129044dSC.J. Collier
1595129044dSC.J. Collier.. code-block:: console
1605129044dSC.J. Collier
1615129044dSC.J. Collier    --no-flush-rx
1625129044dSC.J. Collier
1635129044dSC.J. CollierIt is also available in the runtime command line:
1645129044dSC.J. Collier
1655129044dSC.J. Collier.. code-block:: console
1665129044dSC.J. Collier
1675129044dSC.J. Collier    set flush_rx on/off
1685129044dSC.J. Collier
1695129044dSC.J. CollierIt is useful for the case where the rx_pcap is being used and no packets are meant to be discarded.
1705129044dSC.J. CollierOtherwise, the first 512 packets from the input pcap file will be discarded by the RX flushing operation.
1715129044dSC.J. Collier
1725129044dSC.J. Collier.. code-block:: console
1735129044dSC.J. Collier
1743d9b7210SChristian Ehrhardt    $RTE_TARGET/app/testpmd -c '0xf' -n 4 \
1753d9b7210SChristian Ehrhardt        --vdev 'net_pcap0,rx_pcap=file_rx.pcap,tx_pcap=file_tx.pcap' \
1763d9b7210SChristian Ehrhardt        -- --port-topology=chained --no-flush-rx
1775129044dSC.J. Collier
1785129044dSC.J. Collier
1795129044dSC.J. CollierRings-based PMD
1805129044dSC.J. Collier~~~~~~~~~~~~~~~
1815129044dSC.J. Collier
1825129044dSC.J. CollierTo run a DPDK application on a machine without any Ethernet devices, a pair of ring-based rte_ethdevs can be used as below.
1833d9b7210SChristian EhrhardtThe device names passed to the --vdev option must start with net_ring and take no additional parameters.
1845129044dSC.J. CollierMultiple devices may be specified, separated by commas.
1855129044dSC.J. Collier
1865129044dSC.J. Collier.. code-block:: console
1875129044dSC.J. Collier
1883d9b7210SChristian Ehrhardt    ./testpmd -c E -n 4 --vdev=net_ring0 --vdev=net_ring1 -- -i
1895129044dSC.J. Collier    EAL: Detected lcore 1 as core 1 on socket 0
1905129044dSC.J. Collier    ...
1915129044dSC.J. Collier
1925129044dSC.J. Collier    Interactive-mode selected
1935129044dSC.J. Collier    Configuring Port 0 (socket 0)
1945129044dSC.J. Collier    Configuring Port 1 (socket 0)
1955129044dSC.J. Collier    Checking link statuses...
1965129044dSC.J. Collier    Port 0 Link Up - speed 10000 Mbps - full-duplex
1975129044dSC.J. Collier    Port 1 Link Up - speed 10000 Mbps - full-duplex
1985129044dSC.J. Collier    Done
1995129044dSC.J. Collier
2005129044dSC.J. Collier    testpmd> start tx_first
2015129044dSC.J. Collier    io packet forwarding - CRC stripping disabled - packets/burst=16
2025129044dSC.J. Collier    nb forwarding cores=1 - nb forwarding ports=2
2035129044dSC.J. Collier    RX queues=1 - RX desc=128 - RX free threshold=0
2045129044dSC.J. Collier    RX threshold registers: pthresh=8 hthresh=8 wthresh=4
2055129044dSC.J. Collier    TX queues=1 - TX desc=512 - TX free threshold=0
2065129044dSC.J. Collier    TX threshold registers: pthresh=36 hthresh=0 wthresh=0
2075129044dSC.J. Collier    TX RS bit threshold=0 - TXQ flags=0x0
2085129044dSC.J. Collier
2095129044dSC.J. Collier    testpmd> stop
2105129044dSC.J. Collier    Telling cores to stop...
2115129044dSC.J. Collier    Waiting for lcores to finish...
2125129044dSC.J. Collier
2135129044dSC.J. Collier.. image:: img/forward_stats.*
2145129044dSC.J. Collier
2155129044dSC.J. Collier.. code-block:: console
2165129044dSC.J. Collier
2175129044dSC.J. Collier    +++++++++++++++ Accumulated forward statistics for allports++++++++++
2185129044dSC.J. Collier    RX-packets: 462384736  RX-dropped: 0 RX-total: 462384736
2195129044dSC.J. Collier    TX-packets: 462384768  TX-dropped: 0 TX-total: 462384768
2205129044dSC.J. Collier    +++++++++++++++++++++++++++++++++++++++++++++++++++++
2215129044dSC.J. Collier
2225129044dSC.J. Collier    Done.
2235129044dSC.J. Collier
2245129044dSC.J. Collier
2255129044dSC.J. CollierUsing the Poll Mode Driver from an Application
2265129044dSC.J. Collier~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2275129044dSC.J. Collier
2285129044dSC.J. CollierBoth drivers can provide similar APIs to allow the user to create a PMD, that is,
2295129044dSC.J. Collierrte_ethdev structure, instances at run-time in the end-application,
2305129044dSC.J. Collierfor example, using rte_eth_from_rings() or rte_eth_from_pcaps() APIs.
2315129044dSC.J. CollierFor the rings-based PMD, this functionality could be used, for example,
2325129044dSC.J. Collierto allow data exchange between cores using rings to be done in exactly the
2335129044dSC.J. Colliersame way as sending or receiving packets from an Ethernet device.
2345129044dSC.J. CollierFor the libpcap-based PMD, it allows an application to open one or more pcap files
2355129044dSC.J. Collierand use these as a source of packet input to the application.
2365129044dSC.J. Collier
2375129044dSC.J. CollierUsage Examples
2385129044dSC.J. Collier^^^^^^^^^^^^^^
2395129044dSC.J. Collier
2405129044dSC.J. CollierTo create two pseudo-Ethernet ports where all traffic sent to a port is looped back
2415129044dSC.J. Collierfor reception on the same port (error handling omitted for clarity):
2425129044dSC.J. Collier
2435129044dSC.J. Collier.. code-block:: c
2445129044dSC.J. Collier
2455129044dSC.J. Collier    #define RING_SIZE 256
2465129044dSC.J. Collier    #define NUM_RINGS 2
2475129044dSC.J. Collier    #define SOCKET0 0
2485129044dSC.J. Collier
2495129044dSC.J. Collier    struct rte_ring *ring[NUM_RINGS];
2505129044dSC.J. Collier    int port0, port1;
2515129044dSC.J. Collier
2525129044dSC.J. Collier    ring[0] = rte_ring_create("R0", RING_SIZE, SOCKET0, RING_F_SP_ENQ|RING_F_SC_DEQ);
2535129044dSC.J. Collier    ring[1] = rte_ring_create("R1", RING_SIZE, SOCKET0, RING_F_SP_ENQ|RING_F_SC_DEQ);
2545129044dSC.J. Collier
2555129044dSC.J. Collier    /* create two ethdev's */
2565129044dSC.J. Collier
2573d9b7210SChristian Ehrhardt    port0 = rte_eth_from_rings("net_ring0", ring, NUM_RINGS, ring, NUM_RINGS, SOCKET0);
2583d9b7210SChristian Ehrhardt    port1 = rte_eth_from_rings("net_ring1", ring, NUM_RINGS, ring, NUM_RINGS, SOCKET0);
2595129044dSC.J. Collier
2605129044dSC.J. Collier
2615129044dSC.J. CollierTo create two pseudo-Ethernet ports where the traffic is switched between them,
2625129044dSC.J. Collierthat is, traffic sent to port 0 is read back from port 1 and vice-versa,
2635129044dSC.J. Collierthe final two lines could be changed as below:
2645129044dSC.J. Collier
2655129044dSC.J. Collier.. code-block:: c
2665129044dSC.J. Collier
2673d9b7210SChristian Ehrhardt    port0 = rte_eth_from_rings("net_ring0", &ring[0], 1, &ring[1], 1, SOCKET0);
2683d9b7210SChristian Ehrhardt    port1 = rte_eth_from_rings("net_ring1", &ring[1], 1, &ring[0], 1, SOCKET0);
2695129044dSC.J. Collier
2705129044dSC.J. CollierThis type of configuration could be useful in a pipeline model, for example,
2715129044dSC.J. Collierwhere one may want to have inter-core communication using pseudo Ethernet devices rather than raw rings,
2725129044dSC.J. Collierfor reasons of API consistency.
2735129044dSC.J. Collier
2745129044dSC.J. CollierEnqueuing and dequeuing items from an rte_ring using the rings-based PMD may be slower than using the native rings API.
2755129044dSC.J. CollierThis is because DPDK Ethernet drivers make use of function pointers to call the appropriate enqueue or dequeue functions,
2765129044dSC.J. Collierwhile the rte_ring specific functions are direct function calls in the code and are often inlined by the compiler.
2775129044dSC.J. Collier
2785129044dSC.J. Collier   Once an ethdev has been created, for either a ring or a pcap-based PMD,
2795129044dSC.J. Collier   it should be configured and started in the same way as a regular Ethernet device, that is,
2805129044dSC.J. Collier   by calling rte_eth_dev_configure() to set the number of receive and transmit queues,
2815129044dSC.J. Collier   then calling rte_eth_rx_queue_setup() / tx_queue_setup() for each of those queues and
2825129044dSC.J. Collier   finally calling rte_eth_dev_start() to allow transmission and reception of packets to begin.
283