PcapPlusPlus
|
#include <DpdkDevice.h>
Classes | |
struct | DpdkDeviceConfiguration |
struct | DpdkDeviceStats |
struct | LinkStatus |
struct | RxTxStats |
Public Types | |
enum | DpdkRssHashFunction { RSS_IPV4 = 0x1, RSS_FRAG_IPV4 = 0x2, RSS_NONFRAG_IPV4_TCP = 0x4, RSS_NONFRAG_IPV4_UDP = 0x8, RSS_NONFRAG_IPV4_SCTP = 0x10, RSS_NONFRAG_IPV4_OTHER = 0x20, RSS_IPV6 = 0x40, RSS_FRAG_IPV6 = 0x80, RSS_NONFRAG_IPV6_TCP = 0x100, RSS_NONFRAG_IPV6_UDP = 0x200, RSS_NONFRAG_IPV6_SCTP = 0x400, RSS_NONFRAG_IPV6_OTHER = 0x800, RSS_L2_PAYLOAD = 0x1000, RSS_IPV6_EX = 0x2000, RSS_IPV6_TCP_EX = 0x4000, RSS_IPV6_UDP_EX = 0x8000, RSS_PORT = 0x10000, RSS_VXLAN = 0x20000, RSS_GENEVE = 0x40000, RSS_NVGRE = 0x80000 } |
Public Member Functions | |
int | getDeviceId () |
std::string | getDeviceName () |
MacAddress | getMacAddress () |
std::string | getPMDName () |
DpdkPMDType | getPMDType () |
PciAddress | getPciAddress () |
uint16_t | getMtu () |
bool | setMtu (uint16_t newMtu) |
bool | isVirtual () |
void | getLinkStatus (LinkStatus &linkStatus) |
uint32_t | getCurrentCoreId () |
uint16_t | getNumOfOpenedRxQueues () |
uint16_t | getNumOfOpenedTxQueues () |
uint16_t | getTotalNumOfRxQueues () |
uint16_t | getTotalNumOfTxQueues () |
uint16_t | receivePackets (MBufRawPacketVector &rawPacketsArr, uint16_t rxQueueId) |
uint16_t | receivePackets (MBufRawPacket **rawPacketsArr, uint16_t rawPacketArrLength, uint16_t rxQueueId) |
uint16_t | receivePackets (Packet **packetsArr, uint16_t packetsArrLength, uint16_t rxQueueId) |
uint16_t | sendPackets (MBufRawPacket **rawPacketsArr, uint16_t arrLength, uint16_t txQueueId=0, bool useTxBuffer=false) |
uint16_t | sendPackets (Packet **packetsArr, uint16_t arrLength, uint16_t txQueueId=0, bool useTxBuffer=false) |
uint16_t | sendPackets (MBufRawPacketVector &rawPacketsVec, uint16_t txQueueId=0, bool useTxBuffer=false) |
uint16_t | sendPackets (RawPacketVector &rawPacketsVec, uint16_t txQueueId=0, bool useTxBuffer=false) |
bool | sendPacket (RawPacket &rawPacket, uint16_t txQueueId=0, bool useTxBuffer=false) |
bool | sendPacket (MBufRawPacket &rawPacket, uint16_t txQueueId=0, bool useTxBuffer=false) |
bool | sendPacket (Packet &packet, uint16_t txQueueId=0, bool useTxBuffer=false) |
bool | setFilter (GeneralFilter &filter) |
bool | setFilter (std::string filterAsString) |
bool | openMultiQueues (uint16_t numOfRxQueuesToOpen, uint16_t numOfTxQueuesToOpen, const DpdkDeviceConfiguration &config=DpdkDeviceConfiguration()) |
bool | startCaptureSingleThread (OnDpdkPacketsArriveCallback onPacketsArrive, void *onPacketsArriveUserCookie) |
bool | startCaptureMultiThreads (OnDpdkPacketsArriveCallback onPacketsArrive, void *onPacketsArriveUserCookie, CoreMask coreMask) |
void | stopCapture () |
int | getAmountOfFreeMbufs () |
int | getAmountOfMbufsInUse () |
bool | open () |
void | close () |
void | getStatistics (pcap_stat &stats) |
void | getStatistics (DpdkDeviceStats &stats) |
void | clearStatistics () |
uint16_t | flushTxBuffer (bool flushOnlyIfTimeoutExpired=false, uint16_t txQueueId=0) |
bool | isDeviceSupportRssHashFunction (DpdkRssHashFunction rssHF) |
bool | isDeviceSupportRssHashFunction (uint64_t rssHFMask) |
uint64_t | getSupportedRssHashFunctions () |
Public Member Functions inherited from pcpp::IPcapDevice | |
bool | isOpened () |
bool | setFilter (GeneralFilter &filter) |
void | clearFilter () |
Additional Inherited Members | |
Static Public Member Functions inherited from pcpp::IPcapDevice | |
static bool | verifyFilter (std::string filterAsString) |
static bool | matchPakcetWithFilter (std::string filterAsString, RawPacket *rawPacket) |
Encapsulates a DPDK port and enables receiving and sending packets using DPDK as well as getting interface info & status, packet statistics, etc. This class has no public c'tor as it's constructed by DpdkDeviceList during initialization.
RX/TX queues: modern NICs provide hardware load-balancing for packets. This means that each packet received by the NIC is hashed by one or more parameter (IP address, port, etc.) and goes into one of several RX queues provided by the NIC. This enables applications to work in a multi-core environment where each core can read packets from different RX queue(s). Same goes for TX queues: it's possible to write packets to different TX queues and the NIC is taking care of sending them to the network. Different NICs provide different number of RX and TX queues. DPDK supports this capability and enables the user to open the DPDK port (DpdkDevice) with a single or multiple RX and TX queues. When receiving packets the user can decide from which RX queue to read from, and when transmitting packets the user can decide to which TX queue to send them to. RX/TX queues are configured when opening the DpdkDevice (see openMultiQueues())
Capturing packets: there are two ways to capture packets using DpdkDevice:
Sending packets: DpdkDevice has various methods for sending packets. They enable sending raw packets, parsed packets, etc. for all opened TX queues. Also, DPDK provides an option to buffer TX packets and send them only when reaching a certain threshold (you can read more about it here: http://dpdk.org/doc/api/rte__ethdev_8h.html#a0e941a74ae1b1b886764bc282458d946). DpdkDevice supports that option as well. See DpdkDevice::sendPackets()
Get interface info: DpdkDevice provides all kind of information on the interface/device such as MAC address, MTU, link status, PCI address, PMD (poll-mode-driver) used for this port, etc. In addition it provides RX/TX statistics when receiving or sending packets
Known limitations:
An enum describing all RSS (Receive Side Scaling) hash functions supported in DPDK. Notice not all PMDs support all types of hash functions
void pcpp::DpdkDevice::clearStatistics | ( | ) |
Clear device statistics
|
virtual |
Close the DpdkDevice. When device is closed it's not possible work with it
Implements pcpp::IPcapDevice.
uint16_t pcpp::DpdkDevice::flushTxBuffer | ( | bool | flushOnlyIfTimeoutExpired = false , |
uint16_t | txQueueId = 0 |
||
) |
DPDK supports an option to buffer TX packets and send them only when reaching a certain threshold. This method enables the user to flush a TX buffer for certain TX queue and send the packets stored in it (you can read about it here: http://dpdk.org/doc/api/rte__ethdev_8h.html#a0e941a74ae1b1b886764bc282458d946). It has the option to flush only when timeout that was set in DpdkDeviceConfiguration::flushTxBufferTimeout expired or flush immediately regardless of the timeout. The usage of this method can be in the main loop where you can call this method once every a couple of iterations to make sure TX buffers are flushed
[in] | flushOnlyIfTimeoutExpired | When set to true, flush will happen only if the timeout defined in DpdkDeviceConfiguration::flushTxBufferTimeout expired. If set to false flush will happen immediately. Default value is false |
[in] | txQueueId | The TX queue ID to flush its buffer. Default is 0 |
int pcpp::DpdkDevice::getAmountOfFreeMbufs | ( | ) |
int pcpp::DpdkDevice::getAmountOfMbufsInUse | ( | ) |
uint32_t pcpp::DpdkDevice::getCurrentCoreId | ( | ) |
|
inline |
|
inline |
void pcpp::DpdkDevice::getLinkStatus | ( | LinkStatus & | linkStatus | ) |
Get the link status (link up/down, link speed and link duplex)
[out] | linkStatus | A reference to object the result shall be written to |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
virtual |
Implements pcpp::IPcapDevice.
void pcpp::DpdkDevice::getStatistics | ( | DpdkDeviceStats & | stats | ) |
Retrieve RX/TX statistics from device
[out] | stats | A reference to a DpdkDeviceStats object where stats will be written into |
uint64_t pcpp::DpdkDevice::getSupportedRssHashFunctions | ( | ) |
|
inline |
|
inline |
bool pcpp::DpdkDevice::isDeviceSupportRssHashFunction | ( | DpdkRssHashFunction | rssHF | ) |
Check whether a specific RSS hash function is supported by this device (PMD)
[in] | rssHF | RSS hash function to check |
bool pcpp::DpdkDevice::isDeviceSupportRssHashFunction | ( | uint64_t | rssHFMask | ) |
Check whether a mask of RSS hash functions is supported by this device (PMD)
[in] | rssHFMask | RSS hash functions mask to check. This mask should be built from values in DpdkRssHashFunction enum |
bool pcpp::DpdkDevice::isVirtual | ( | ) |
|
inlinevirtual |
Overridden method from IPcapDevice. It calls openMultiQueues() with 1 RX queue and 1 TX queue. Notice opening the device only makes it ready to use, it doesn't start packet capturing. The device is opened in promiscuous mode
Implements pcpp::IPcapDevice.
bool pcpp::DpdkDevice::openMultiQueues | ( | uint16_t | numOfRxQueuesToOpen, |
uint16_t | numOfTxQueuesToOpen, | ||
const DpdkDeviceConfiguration & | config = DpdkDeviceConfiguration() |
||
) |
Open the DPDK device. Notice opening the device only makes it ready to use, it doesn't start packet capturing. This method initializes RX and TX queues, configures the DPDK port and starts it. Call close() to close the device. The device is opened in promiscuous mode
[in] | numOfRxQueuesToOpen | Number of RX queues to setup. This number must be smaller or equal to the return value of getTotalNumOfRxQueues() |
[in] | numOfTxQueuesToOpen | Number of TX queues to setup. This number must be smaller or equal to the return value of getTotalNumOfTxQueues() |
[in] | config | Optional parameter for defining special port configuration parameters such as number of receive/transmit descriptors. If not set the default parameters will be set (see DpdkDeviceConfiguration) |
uint16_t pcpp::DpdkDevice::receivePackets | ( | MBufRawPacketVector & | rawPacketsArr, |
uint16_t | rxQueueId | ||
) |
Receive raw packets from the network
[out] | rawPacketsArr | A vector where all received packets will be written into |
[in] | rxQueueId | The RX queue to receive packets from |
uint16_t pcpp::DpdkDevice::receivePackets | ( | MBufRawPacket ** | rawPacketsArr, |
uint16_t | rawPacketArrLength, | ||
uint16_t | rxQueueId | ||
) |
Receive raw packets from the network. Please notice that in terms of performance, this is the best method to use for receiving packets because out of all receivePackets overloads this method requires the least overhead and is almost as efficient as receiving packets directly through DPDK. So if performance is a critical factor in your application, please use this method
[out] | rawPacketsArr | A pointer to an array of MBufRawPacket pointers where all received packets will be written into. The array is expected to be allocated by the user and its length should be provided in rawPacketArrLength. Number of packets received will be returned. Notice it's the user responsibility to free the array and its content when done using it |
[out] | rawPacketArrLength | The length of MBufRawPacket pointers array |
[in] | rxQueueId | The RX queue to receive packets from |
uint16_t pcpp::DpdkDevice::receivePackets | ( | Packet ** | packetsArr, |
uint16_t | packetsArrLength, | ||
uint16_t | rxQueueId | ||
) |
Receive parsed packets from the network
[out] | packetsArr | A pointer to an allocated array of Packet pointers where all received packets will be written into. The array is expected to be allocated by the user and its length should be provided in packetsArrLength. Number of packets received will be returned. Notice it's the user responsibility to free the array and its content when done using it |
[out] | packetsArrLength | The length of Packet pointers array |
[in] | rxQueueId | The RX queue to receive packets from |
bool pcpp::DpdkDevice::sendPacket | ( | RawPacket & | rawPacket, |
uint16_t | txQueueId = 0 , |
||
bool | useTxBuffer = false |
||
) |
Send a raw packet to the network. Please notice that if the raw packet isn't of type MBufRawPacket, a new temp MBufRawPacket will be created and the data will be copied to it. This is necessary to allocate an mbuf which will store the data to be sent. If performance is a critical factor please make sure you send a raw packet of type MBufRawPacket. Please also notice that the mbuf used or allocated in this method isn't freed by this method, it will be transparently freed by DPDK
[in] | rawPacket | The raw packet to send |
[in] | txQueueId | An optional parameter which indicates to which TX queue the packet will be sent to. The default is TX queue 0 |
[in] | useTxBuffer | A flag which indicates whether to use TX buffer mechanism or not. To read more about DPDK's TX buffer mechanism please refer to DpdkDevice class description. Default value is false (don't use this mechanism) |
bool pcpp::DpdkDevice::sendPacket | ( | MBufRawPacket & | rawPacket, |
uint16_t | txQueueId = 0 , |
||
bool | useTxBuffer = false |
||
) |
Send a MBufRawPacket to the network. Please notice that the mbuf used in this method isn't freed by this method, it will be transparently freed by DPDK
[in] | rawPacket | The MBufRawPacket to send |
[in] | txQueueId | An optional parameter which indicates to which TX queue the packet will be sent to. The default is TX queue 0 |
[in] | useTxBuffer | A flag which indicates whether to use TX buffer mechanism or not. To read more about DPDK's TX buffer mechanism please refer to DpdkDevice class description. Default value is false (don't use this mechanism) |
bool pcpp::DpdkDevice::sendPacket | ( | Packet & | packet, |
uint16_t | txQueueId = 0 , |
||
bool | useTxBuffer = false |
||
) |
Send a parsed packet to the network. Please notice that the mbuf used or allocated in this method isn't freed by this method, it will be transparently freed by DPDK
[in] | packet | The parsed packet to send. Please notice that if the packet contains a raw packet which isn't of type MBufRawPacket, a new temp MBufRawPacket will be created and the data will be copied to it. This is necessary to allocate an mbuf which will store the data to be sent. If performance is a critical factor please make sure you send a parsed packet that contains a raw packet of type MBufRawPacket |
[in] | txQueueId | An optional parameter which indicates to which TX queue the packet will be sent on. The default is TX queue 0 |
[in] | useTxBuffer | A flag which indicates whether to use TX buffer mechanism or not. To read more about DPDK's TX buffer mechanism please refer to DpdkDevice class description. Default value is false (don't use this mechanism) |
uint16_t pcpp::DpdkDevice::sendPackets | ( | MBufRawPacket ** | rawPacketsArr, |
uint16_t | arrLength, | ||
uint16_t | txQueueId = 0 , |
||
bool | useTxBuffer = false |
||
) |
Send an array of MBufRawPacket to the network. Please notice the following:
[in] | rawPacketsArr | A pointer to an array of MBufRawPacket |
[in] | arrLength | The length of the array |
[in] | txQueueId | An optional parameter which indicates to which TX queue the packets will be sent to. The default is TX queue 0 |
[in] | useTxBuffer | A flag which indicates whether to use TX buffer mechanism or not. To read more about DPDK's TX buffer mechanism please refer to DpdkDevice class description. Default value is false (don't use this mechanism) |
uint16_t pcpp::DpdkDevice::sendPackets | ( | Packet ** | packetsArr, |
uint16_t | arrLength, | ||
uint16_t | txQueueId = 0 , |
||
bool | useTxBuffer = false |
||
) |
Send an array of parsed packets to the network. Please notice the following:
[in] | packetsArr | A pointer to an array of parsed packet pointers |
[in] | arrLength | The length of the array |
[in] | txQueueId | An optional parameter which indicates to which TX queue the packets will be sent to. The default is TX queue 0 |
[in] | useTxBuffer | A flag which indicates whether to use TX buffer mechanism or not. To read more about DPDK's TX buffer mechanism please refer to DpdkDevice class description. Default value is false (don't use this mechanism) |
uint16_t pcpp::DpdkDevice::sendPackets | ( | MBufRawPacketVector & | rawPacketsVec, |
uint16_t | txQueueId = 0 , |
||
bool | useTxBuffer = false |
||
) |
Send a vector of MBufRawPacket pointers to the network. Please notice the following:
[in] | rawPacketsVec | The vector of raw packet |
[in] | txQueueId | An optional parameter which indicates to which TX queue the packets will be sent to. The default is TX queue 0 |
[in] | useTxBuffer | A flag which indicates whether to use TX buffer mechanism or not. To read more about DPDK's TX buffer mechanism please refer to DpdkDevice class description. Default value is false (don't use this mechanism) |
uint16_t pcpp::DpdkDevice::sendPackets | ( | RawPacketVector & | rawPacketsVec, |
uint16_t | txQueueId = 0 , |
||
bool | useTxBuffer = false |
||
) |
Send a vector of RawPacket pointers to the network. Please notice the following:
[in] | rawPacketsVec | The vector of raw packet |
[in] | txQueueId | An optional parameter which indicates to which TX queue the packets will be sent to. The default is TX queue 0 |
[in] | useTxBuffer | A flag which indicates whether to use TX buffer mechanism or not. To read more about DPDK's TX buffer mechanism please refer to DpdkDevice class description. Default value is false (don't use this mechanism) |
bool pcpp::DpdkDevice::setFilter | ( | GeneralFilter & | filter | ) |
Overridden method from IPcapDevice. BPF filters are currently not implemented for DpdkDevice
|
virtual |
Overridden method from IPcapDevice. BPF filters are currently not implemented for DpdkDevice
Reimplemented from pcpp::IPcapDevice.
bool pcpp::DpdkDevice::setMtu | ( | uint16_t | newMtu | ) |
Set a new maximum transmission unit (MTU) for this device
[in] | newMtu | The new MTU in bytes |
bool pcpp::DpdkDevice::startCaptureMultiThreads | ( | OnDpdkPacketsArriveCallback | onPacketsArrive, |
void * | onPacketsArriveUserCookie, | ||
CoreMask | coreMask | ||
) |
This method does exactly what startCaptureSingleThread() does, but with more than one RX queue / capturing thread. It's called with a core mask as a parameter and creates a packet capture thread on every core. Each capturing thread is assigned with a specific RX queue. This method assumes all cores in the core-mask are available and there are enough opened RX queues to match for each thread. If these assumptions are not true an error is returned. After invoking all threads, all of them run in an endless loop and try to capture packets from their designated RX queues. Each time a burst of packets is captured the callback is invoked with the user cookie and the thread ID that captured the packets
[in] | onPacketsArrive | The user callback which will be invoked each time a burst of packets is captured by the device |
[in] | onPacketsArriveUserCookie | The user callback is invoked with this cookie as a parameter. It can be used to pass information from the user application to the callback |
coreMask | The core-mask for creating the cpature threads |
bool pcpp::DpdkDevice::startCaptureSingleThread | ( | OnDpdkPacketsArriveCallback | onPacketsArrive, |
void * | onPacketsArriveUserCookie | ||
) |
There are two ways to capture packets using DpdkDevice: one of them is using worker threads (see DpdkDeviceList::startDpdkWorkerThreads() ) and the other way is setting a callback which is invoked each time a burst of packets is captured. This method implements the second way. After invoking this method the DpdkDevice enters capture mode and starts capturing packets. This method assumes there is only 1 RX queue opened for this device, otherwise an error is returned. It then allocates a core and creates 1 thread that runs in an endless loop and tries to capture packets using DPDK. Each time a burst of packets is captured the user callback is invoked with the user cookie as a parameter. This loop continues until stopCapture() is called. Notice: since the callback is invoked for every packet burst using this method can be slower than using worker threads. On the other hand, it's a simpler way comparing to worker threads
[in] | onPacketsArrive | The user callback which will be invoked each time a packet burst is captured by the device |
[in] | onPacketsArriveUserCookie | The user callback is invoked with this cookie as a parameter. It can be used to pass information from the user application to the callback |
void pcpp::DpdkDevice::stopCapture | ( | ) |
If device is in capture mode started by invoking startCaptureSingleThread() or startCaptureMultiThreads(), this method will stop all capturing threads and set the device to non-capturing mode