-
Notifications
You must be signed in to change notification settings - Fork 721
Sockets dimensioned by Num queues #2000
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from 4 commits
9d030cd
09f8145
7fc2796
79b06f5
b565c74
943f7bd
739fd67
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,11 +5,16 @@ | |
#include "Device.h" | ||
#include <utility> | ||
#include <functional> | ||
#include <array> | ||
|
||
/// @namespace pcpp | ||
/// @ | ||
namespace pcpp | ||
{ | ||
|
||
// used to dimension sockets | ||
#define PCPP_MAXIMUM_NUMBER_QUEUES 8 | ||
|
||
/// @class XdpDevice | ||
/// A class wrapping the main functionality of using AF_XDP (XSK) sockets | ||
/// which are optimized for high performance packet processing. | ||
|
@@ -19,13 +24,6 @@ namespace pcpp | |
class XdpDevice : public IDevice | ||
{ | ||
public: | ||
/// @typedef OnPacketsArrive | ||
/// The callback that is called whenever packets are received on the socket | ||
/// @param[in] packets An array of the raw packets received | ||
/// @param[in] packetCount The number of packets received | ||
/// @param[in] device The XdpDevice packets are received from (represents the AF_XDP socket) | ||
/// @param[in] userCookie A pointer to an object set by the user when receivePackets() started | ||
typedef void (*OnPacketsArrive)(RawPacket packets[], uint32_t packetCount, XdpDevice* device, void* userCookie); | ||
|
||
/// @struct XdpDeviceConfiguration | ||
/// A struct containing the configuration parameters available for opening an XDP device | ||
|
@@ -47,6 +45,10 @@ namespace pcpp | |
/// AF_XDP operation mode | ||
AttachMode attachMode; | ||
|
||
/// number of queues. Should be less than or equal to the number of hardware queues supported by the device | ||
// the queue ids are inferred as consecutive starting at zero | ||
uint32_t numQueues; | ||
|
||
/// UMEM is a region of virtual contiguous memory, divided into equal-sized frames. | ||
/// This parameter determines the number of frames that will be allocated as pert of the UMEM. | ||
uint16_t umemNumFrames; | ||
|
@@ -89,7 +91,7 @@ namespace pcpp | |
explicit XdpDeviceConfiguration(AttachMode attachMode = AutoMode, uint16_t umemNumFrames = 0, | ||
uint16_t umemFrameSize = 0, uint32_t fillRingSize = 0, | ||
uint32_t completionRingSize = 0, uint32_t rxSize = 0, uint32_t txSize = 0, | ||
uint16_t rxTxBatchSize = 0) | ||
uint16_t rxTxBatchSize = 0, uint32_t numQueues = 0) | ||
{ | ||
this->attachMode = attachMode; | ||
this->umemNumFrames = umemNumFrames; | ||
|
@@ -99,6 +101,7 @@ namespace pcpp | |
this->rxSize = rxSize; | ||
this->txSize = txSize; | ||
this->rxTxBatchSize = rxTxBatchSize; | ||
this->numQueues = numQueues; | ||
} | ||
}; | ||
|
||
|
@@ -184,58 +187,12 @@ namespace pcpp | |
return m_DeviceOpened; | ||
} | ||
|
||
/// Start receiving packets. In order to use this method the device should be open. Note that this method is | ||
/// blocking and will return if: | ||
/// - stopReceivePackets() was called from within the user callback | ||
/// - timeoutMS passed without receiving any packets | ||
/// - Some error occurred (an error log will be printed) | ||
/// @param[in] onPacketsArrive A callback to be called when packets are received | ||
/// @param[in] onPacketsArriveUserCookie The callback is invoked with this cookie as a parameter. It can be used | ||
/// to pass information from the user application to the callback | ||
/// @param[in] timeoutMS Timeout in milliseconds to stop if no packets are received. The default value is 5000 | ||
/// ms | ||
/// @return True if stopped receiving packets because stopReceivePackets() was called or because timeoutMS | ||
/// passed, or false if an error occurred. | ||
bool receivePackets(OnPacketsArrive onPacketsArrive, void* onPacketsArriveUserCookie, int timeoutMS = 5000); | ||
|
||
/// Stop receiving packets. Call this method from within the callback passed to receivePackets() whenever you | ||
/// want to stop receiving packets. | ||
void stopReceivePackets(); | ||
|
||
/// Send a vector of packet pointers. | ||
/// @param[in] packets A vector of packet pointers to send | ||
/// @param[in] waitForTxCompletion Wait for confirmation from the kernel that packets were sent. If set to true | ||
/// this method will wait until the number of packets in the completion ring is equal or greater to the number | ||
/// of packets that were sent. The default value is false | ||
/// @param[in] waitForTxCompletionTimeoutMS If waitForTxCompletion is set to true, poll the completion ring with | ||
/// this timeout. The default value is 5000 ms | ||
/// @return True if all packets were sent, or if waitForTxCompletion is true - all sent packets were confirmed. | ||
/// Returns false if an error occurred or if poll timed out. | ||
bool sendPackets(const RawPacketVector& packets, bool waitForTxCompletion = false, | ||
int waitForTxCompletionTimeoutMS = 5000); | ||
|
||
/// Send an array of packets. | ||
/// @param[in] packets An array of raw packets to send | ||
/// @param[in] packetCount The length of the packet array | ||
/// @param[in] waitForTxCompletion Wait for confirmation from the kernel that packets were sent. If set to true | ||
/// this method will wait until the number of packets in the completion ring is equal or greater to the number | ||
/// of packets sent. The default value is false | ||
/// @param[in] waitForTxCompletionTimeoutMS If waitForTxCompletion is set to true, poll the completion ring with | ||
/// this timeout. The default value is 5000 ms | ||
/// @return True if all packets were sent, or if waitForTxCompletion is true - all sent packets were confirmed. | ||
/// Returns false if an error occurred or if poll timed out. | ||
bool sendPackets(RawPacket packets[], size_t packetCount, bool waitForTxCompletion = false, | ||
int waitForTxCompletionTimeoutMS = 5000); | ||
|
||
/// @return A pointer to the current device configuration. If the device is not open this method returns nullptr | ||
XdpDeviceConfiguration* getConfig() const | ||
{ | ||
return m_Config; | ||
} | ||
|
||
/// @return Current device statistics | ||
XdpDeviceStats getStatistics(); | ||
Comment on lines
238
to
239
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto, API compat. |
||
|
||
private: | ||
class XdpUmem | ||
{ | ||
|
@@ -290,25 +247,132 @@ namespace pcpp | |
uint64_t txCompletedPackets; | ||
}; | ||
|
||
|
||
|
||
|
||
public: | ||
|
||
class XdpSocket | ||
{ | ||
public: | ||
XdpSocket(XdpDevice *device, uint32_t qid); | ||
|
||
~XdpSocket(); | ||
|
||
const XdpDevice *getDevice() { return m_Device; } | ||
|
||
/// @typedef OnPacketsArrive | ||
/// The callback that is called whenever packets are received on the socket | ||
/// @param[in] packets An array of the raw packets received | ||
/// @param[in] packetCount The number of packets received | ||
/// @param[in] device The XdpDevice packets are received from (represents the AF_XDP socket) | ||
/// @param[in] userCookie A pointer to an object set by the user when receivePackets() started | ||
typedef void (*OnPacketsArrive)(RawPacket packets[], uint32_t packetCount, XdpSocket* socket, void* userCookie); | ||
|
||
|
||
|
||
/// Start receiving packets. In order to use this method the device should be open. Note that this method is | ||
/// blocking and will return if: | ||
/// - stopReceivePackets() was called from within the user callback | ||
/// - timeoutMS passed without receiving any packets | ||
/// - Some error occurred (an error log will be printed) | ||
/// @param[in] onPacketsArrive A callback to be called when packets are received | ||
/// @param[in] onPacketsArriveUserCookie The callback is invoked with this cookie as a parameter. It can be used | ||
/// to pass information from the user application to the callback | ||
/// @param[in] timeoutMS Timeout in milliseconds to stop if no packets are received. The default value is 5000 | ||
/// ms | ||
/// @return True if stopped receiving packets because stopReceivePackets() was called or because timeoutMS | ||
/// passed, or false if an error occurred. | ||
bool receivePackets(OnPacketsArrive onPacketsArrive, void* onPacketsArriveUserCookie, int timeoutMS = 5000); | ||
|
||
/// Stop receiving packets. Call this method from within the callback passed to receivePackets() whenever you | ||
/// want to stop receiving packets. | ||
void stopReceivePackets(); | ||
|
||
/// Send a vector of packet pointers. | ||
/// @param[in] packets A vector of packet pointers to send | ||
/// @param[in] waitForTxCompletion Wait for confirmation from the kernel that packets were sent. If set to true | ||
/// this method will wait until the number of packets in the completion ring is equal or greater to the number | ||
/// of packets that were sent. The default value is false | ||
/// @param[in] waitForTxCompletionTimeoutMS If waitForTxCompletion is set to true, poll the completion ring with | ||
/// this timeout. The default value is 5000 ms | ||
/// @return True if all packets were sent, or if waitForTxCompletion is true - all sent packets were confirmed. | ||
/// Returns false if an error occurred or if poll timed out. | ||
bool sendPackets(const RawPacketVector& packets, bool waitForTxCompletion = false, | ||
int waitForTxCompletionTimeoutMS = 5000); | ||
|
||
/// Send an array of packets. | ||
/// @param[in] packets An array of raw packets to send | ||
/// @param[in] packetCount The length of the packet array | ||
/// @param[in] waitForTxCompletion Wait for confirmation from the kernel that packets were sent. If set to true | ||
/// this method will wait until the number of packets in the completion ring is equal or greater to the number | ||
/// of packets sent. The default value is false | ||
/// @param[in] waitForTxCompletionTimeoutMS If waitForTxCompletion is set to true, poll the completion ring with | ||
/// this timeout. The default value is 5000 ms | ||
/// @return True if all packets were sent, or if waitForTxCompletion is true - all sent packets were confirmed. | ||
/// Returns false if an error occurred or if poll timed out. | ||
bool sendPackets(RawPacket packets[], size_t packetCount, bool waitForTxCompletion = false, | ||
int waitForTxCompletionTimeoutMS = 5000); | ||
|
||
/// @return Current device statistics | ||
XdpDeviceStats getStatistics(); | ||
|
||
bool configure(); | ||
|
||
|
||
private: | ||
|
||
void initialize() | ||
{ | ||
m_Device = nullptr; | ||
m_Queueid = 0; | ||
|
||
m_ReceivingPackets = false; | ||
m_Umem = nullptr; | ||
m_SocketInfo = nullptr; | ||
memset(&m_Stats, 0, sizeof(XdpDeviceStats)); | ||
memset(&m_PrevStats, 0, sizeof(XdpPrevDeviceStats)); | ||
} | ||
Dimi1010 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
// point to the device that has this socket | ||
XdpDevice *m_Device; | ||
uint32_t m_Queueid; | ||
|
||
bool m_ReceivingPackets = false; | ||
XdpUmem* m_Umem = nullptr; | ||
void* m_SocketInfo = nullptr; | ||
XdpDeviceStats m_Stats; | ||
XdpPrevDeviceStats m_PrevStats; | ||
|
||
bool sendPackets(const std::function<RawPacket(uint32_t)>& getPacketAt, | ||
const std::function<uint32_t()>& getPacketCount, bool waitForTxCompletion = false, | ||
int waitForTxCompletionTimeoutMS = 5000); | ||
bool populateFillRing(uint32_t count, uint32_t rxId = 0); | ||
bool populateFillRing(const std::vector<uint64_t>& addresses, uint32_t rxId); | ||
uint32_t checkCompletionRing(); | ||
bool initUmem(); | ||
bool getSocketStats(); | ||
}; | ||
|
||
const std::string& getInterfaceName() const { return m_InterfaceName; } | ||
XdpSocket *getSocket(uint32_t queueid) | ||
{ | ||
if(queueid < m_NumQueues) | ||
{ | ||
return m_Socket[queueid]; | ||
} | ||
|
||
return nullptr; | ||
} | ||
|
||
private: | ||
|
||
bool m_DeviceOpened = false; | ||
|
||
std::string m_InterfaceName; | ||
XdpDeviceConfiguration* m_Config; | ||
bool m_ReceivingPackets; | ||
XdpUmem* m_Umem; | ||
void* m_SocketInfo; | ||
XdpDeviceStats m_Stats; | ||
XdpPrevDeviceStats m_PrevStats; | ||
|
||
bool sendPackets(const std::function<RawPacket(uint32_t)>& getPacketAt, | ||
const std::function<uint32_t()>& getPacketCount, bool waitForTxCompletion = false, | ||
int waitForTxCompletionTimeoutMS = 5000); | ||
bool populateFillRing(uint32_t count, uint32_t rxId = 0); | ||
bool populateFillRing(const std::vector<uint64_t>& addresses, uint32_t rxId); | ||
uint32_t checkCompletionRing(); | ||
bool configureSocket(); | ||
bool initUmem(); | ||
uint32_t m_NumQueues; // number of queues | ||
std::array<XdpSocket*, PCPP_MAXIMUM_NUMBER_QUEUES> m_Socket; | ||
|
||
|
||
bool initConfig(); | ||
bool getSocketStats(); | ||
|
||
}; | ||
} // namespace pcpp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we keep this API, but forward to
XdpSocket m_Sockets[0]
if called to keep the existing compatibility?They can still fail if the device is not opened and there are no sockets.