14#include "ns3/net-device-queue-interface.h" 
   15#include "ns3/simulator.h" 
   16#include "ns3/uinteger.h" 
   20#include <rte_common.h> 
   21#include <rte_cycles.h> 
   23#include <rte_ethdev.h> 
   24#include <rte_malloc.h> 
   26#include <rte_mempool.h> 
   30#include <sys/signal.h> 
   46        TypeId(
"ns3::DpdkNetDevice")
 
   48            .SetGroupName(
"FdNetDevice")
 
   50            .AddAttribute(
"TxTimeout",
 
   51                          "The time to wait before transmitting burst from Tx buffer.",
 
   55            .AddAttribute(
"MaxRxBurst",
 
   60            .AddAttribute(
"MaxTxBurst",
 
   65            .AddAttribute(
"MempoolCacheSize",
 
   66                          "Size of mempool cache.",
 
   70            .AddAttribute(
"NbRxDesc",
 
   71                          "Number of Rx descriptors.",
 
   75            .AddAttribute(
"NbTxDesc",
 
   76                          "Number of Tx descriptors.",
 
 
   95    rte_eal_wait_lcore(1);
 
 
  113#define CHECK_INTERVAL 100  
  114#define MAX_CHECK_TIME 90   
  116    uint8_t printFlag = 0;
 
  117    struct rte_eth_link link;
 
  121        uint8_t allPortsUp = 1;
 
  131        memset(&link, 0, 
sizeof(link));
 
  136            if (!link.link_status)
 
  144        if (link.link_status == ETH_LINK_DOWN)
 
 
  173    if (signum == SIGINT || signum == SIGTERM)
 
  175        NS_LOG_INFO(
"Signal " << signum << 
" received, preparing to exit...");
 
 
  193    for (uint16_t i = 0; i < 
m_rxBuffer->length; i++)
 
  195        struct rte_mbuf* pkt = 
nullptr;
 
  203        uint8_t* buf = rte_pktmbuf_mtod(pkt, uint8_t*);
 
  204        size_t length = pkt->data_len;
 
 
  216    lcoreId = rte_lcore_id();
 
 
  244    command.append(
"dpdk-devbind.py --force ");
 
  245    command.append(
"--bind=");
 
  246    command.append(dpdkDriver);
 
  250    if (system(command.c_str()))
 
  252        rte_exit(EXIT_FAILURE, 
"Execution failed - bye\n");
 
  259    int ret = rte_eal_init(argc, argv);
 
  262        rte_exit(EXIT_FAILURE, 
"Invalid EAL arguments\n");
 
  269    unsigned nbPorts = rte_eth_dev_count_avail();
 
  272        rte_exit(EXIT_FAILURE, 
"No Ethernet ports - bye\n");
 
  278        rte_exit(EXIT_FAILURE, 
"Cannot get port id - bye\n");
 
  282    unsigned int nbLcores = 2;
 
  289    m_mempool = rte_pktmbuf_pool_create(
"mbuf_pool",
 
  293                                        RTE_MBUF_DEFAULT_BUF_SIZE,
 
  298        rte_exit(EXIT_FAILURE, 
"Cannot init mbuf pool\n");
 
  302    static struct rte_eth_conf portConf = {};
 
  303    portConf.rxmode = {};
 
  304    portConf.rxmode.split_hdr_size = 0;
 
  305    portConf.txmode = {};
 
  306    portConf.txmode.mq_mode = ETH_MQ_TX_NONE;
 
  308    struct rte_eth_rxconf reqConf;
 
  309    struct rte_eth_txconf txqConf;
 
  310    struct rte_eth_conf localPortConf = portConf;
 
  311    struct rte_eth_dev_info devInfo;
 
  314    rte_eth_dev_info_get(
m_portId, &devInfo);
 
  315    if (devInfo.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
 
  317        localPortConf.txmode.offloads |= DEV_TX_OFFLOAD_MBUF_FAST_FREE;
 
  319    ret = rte_eth_dev_configure(
m_portId, 1, 1, &localPortConf);
 
  322        rte_exit(EXIT_FAILURE, 
"Cannot configure device: err=%d, port=%u\n", ret, 
m_portId);
 
  328        rte_exit(EXIT_FAILURE,
 
  329                 "Cannot adjust number of descriptors: err=%d, port=%u\n",
 
  336    reqConf = devInfo.default_rxconf;
 
  337    reqConf.offloads = localPortConf.rxmode.offloads;
 
  338    ret = rte_eth_rx_queue_setup(
m_portId,
 
  346        rte_exit(EXIT_FAILURE, 
"rte_eth_rx_queue_setup:err=%d, port=%u\n", ret, 
m_portId);
 
  351    txqConf = devInfo.default_txconf;
 
  352    txqConf.offloads = localPortConf.txmode.offloads;
 
  357        rte_exit(EXIT_FAILURE, 
"rte_eth_tx_queue_setup:err=%d, port=%u\n", ret, 
m_portId);
 
  361    m_txBuffer = (rte_eth_dev_tx_buffer*)rte_zmalloc_socket(
"tx_buffer",
 
  366    m_rxBuffer = (rte_eth_dev_tx_buffer*)rte_zmalloc_socket(
"rx_buffer",
 
  372        rte_exit(EXIT_FAILURE, 
"Cannot allocate buffer for rx/tx on port %u\n", 
m_portId);
 
  382        rte_exit(EXIT_FAILURE, 
"rte_eth_dev_start:err=%d, port=%u\n", ret, 
m_portId);
 
  385    rte_eth_promiscuous_enable(
m_portId);
 
  390    rte_eal_mp_remote_launch(
LaunchCore, 
this, CALL_MASTER);
 
 
  396    struct rte_mbuf* pkt = rte_pktmbuf_alloc(
m_mempool);
 
  401    uint8_t* buf = rte_pktmbuf_mtod(pkt, uint8_t*);
 
 
  408    struct rte_mbuf* pkt;
 
  414    pkt = (
struct rte_mbuf*)RTE_PTR_SUB(buf, 
sizeof(
struct rte_mbuf) + RTE_PKTMBUF_HEADROOM);
 
  416    rte_pktmbuf_free(pkt);
 
 
  422    struct rte_mbuf** pkt = 
new struct rte_mbuf*[1];
 
  431    pkt[0] = (
struct rte_mbuf*)RTE_PTR_SUB(buffer, 
sizeof(
struct rte_mbuf) + RTE_PKTMBUF_HEADROOM);
 
  433    pkt[0]->pkt_len = length;
 
  434    pkt[0]->data_len = length;
 
 
a NetDevice to read/write network traffic from/into a Dpdk enabled port.
static int LaunchCore(void *arg)
A function to handle rx & tx operations.
uint32_t m_maxRxPktBurst
Size of Rx burst.
void InitDpdk(int argc, char **argv, std::string dpdkDriver)
Initialize Dpdk.
void SetDeviceName(std::string deviceName)
Set device name.
void HandleTx()
Transmit packets in burst from the tx_buffer to the nic.
static void SignalHandler(int signum)
A signal handler for SIGINT and SIGTERM signals.
void FreeBuffer(uint8_t *buf) override
Free the given packet buffer.
struct rte_eth_dev_tx_buffer * m_txBuffer
Buffer to handle burst transmission.
struct rte_eth_dev_tx_buffer * m_rxBuffer
Buffer to handle burst reception.
uint32_t m_maxTxPktBurst
Size of Tx burst.
static TypeId GetTypeId()
Get the type ID.
EventId m_txEvent
Event for stale packet transmission.
ssize_t Write(uint8_t *buffer, size_t length) override
Write packet data to device.
std::string m_deviceName
The device name;.
~DpdkNetDevice() override
Destructor for the DpdkNetDevice.
static volatile bool m_forceQuit
Condition variable for Dpdk to stop.
bool IsLinkUp() const override
Check the status of the link.
uint16_t m_nbTxDesc
Number of Tx descriptors.
uint16_t m_nbRxDesc
Number of Rx descriptors.
uint8_t * AllocateBuffer(size_t len) override
Allocate packet buffer.
struct rte_mempool * m_mempool
Packet memory pool.
void CheckAllPortsLinkStatus()
Check the link status of all ports in up to 9s and print them finally.
uint16_t m_portId
The port number of the device to be used.
void DoFinishStoppingDevice() override
Complete additional actions, if any, to tear down the device.
DpdkNetDevice()
Constructor for the DpdkNetDevice.
void HandleRx()
Receive packets in burst from the nic to the rx_buffer.
Time m_txTimeout
The time to wait before transmitting burst from Tx buffer.
uint32_t m_mempoolCacheSize
Mempool cache size.
a NetDevice to read/write network traffic from/into a file descriptor.
std::mutex m_pendingReadMutex
Mutex to increase pending read counter.
std::queue< std::pair< uint8_t *, ssize_t > > m_pendingQueue
Number of packets that were received and scheduled for read but not yet read.
Callback< bool, Ptr< NetDevice >, Ptr< const Packet >, uint16_t, const Address & > ReceiveCallback
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
AttributeValue implementation for Time.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Hold an unsigned integer type.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Ptr< const AttributeChecker > MakeUintegerChecker()
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Every class exported by the ns3 library is enclosed in the ns3 namespace.