openflow build environment setup
This commit is contained in:
210
openflow/include/click/dpdkdevice.hh
Normal file
210
openflow/include/click/dpdkdevice.hh
Normal file
@@ -0,0 +1,210 @@
|
||||
#ifndef CLICK_DPDKDEVICE_HH
|
||||
#define CLICK_DPDKDEVICE_HH
|
||||
|
||||
/**
|
||||
* Prevent bug under some configurations
|
||||
* (like travis-ci's one) where these
|
||||
* macros get undefined.
|
||||
*/
|
||||
#ifndef UINT8_MAX
|
||||
#define UINT8_MAX 255
|
||||
#endif
|
||||
#ifndef UINT16_MAX
|
||||
#define UINT16_MAX 65535
|
||||
#endif
|
||||
|
||||
#include <rte_common.h>
|
||||
#include <rte_eal.h>
|
||||
#include <rte_ethdev.h>
|
||||
#include <rte_lcore.h>
|
||||
#include <rte_mbuf.h>
|
||||
#include <rte_mempool.h>
|
||||
#include <rte_pci.h>
|
||||
#include <rte_version.h>
|
||||
|
||||
#include <click/packet.hh>
|
||||
#include <click/error.hh>
|
||||
#include <click/hashtable.hh>
|
||||
#include <click/vector.hh>
|
||||
#include <click/args.hh>
|
||||
#include <click/etheraddress.hh>
|
||||
|
||||
#if RTE_VERSION < RTE_VERSION_NUM(19,8,0,0)
|
||||
#define rte_ipv4_hdr ipv4_hdr
|
||||
#define rte_ether_addr ether_addr
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Unified type for DPDK port IDs.
|
||||
* Until DPDK v17.05 was uint8_t
|
||||
* After DPDK v17.05 has been uint16_t
|
||||
*/
|
||||
#if RTE_VERSION >= RTE_VERSION_NUM(17,05,0,0)
|
||||
typedef uint16_t portid_t;
|
||||
#else
|
||||
typedef uint8_t portid_t;
|
||||
#endif
|
||||
|
||||
CLICK_DECLS
|
||||
class DPDKDeviceArg;
|
||||
|
||||
extern bool dpdk_enabled;
|
||||
|
||||
class DPDKDevice {
|
||||
public:
|
||||
|
||||
portid_t port_id;
|
||||
|
||||
DPDKDevice() CLICK_COLD;
|
||||
DPDKDevice(portid_t port_id) CLICK_COLD;
|
||||
int add_rx_queue(
|
||||
unsigned &queue_id, bool promisc,
|
||||
unsigned n_desc, ErrorHandler *errh
|
||||
) CLICK_COLD;
|
||||
|
||||
int add_tx_queue(
|
||||
unsigned &queue_id, unsigned n_desc,
|
||||
ErrorHandler *errh
|
||||
) CLICK_COLD;
|
||||
|
||||
EtherAddress get_mac();
|
||||
void set_init_mac(EtherAddress mac);
|
||||
void set_init_mtu(uint16_t mtu);
|
||||
|
||||
unsigned int get_nb_txdesc();
|
||||
int nbRXQueues();
|
||||
int nbTXQueues();
|
||||
const char *get_device_driver();
|
||||
|
||||
static unsigned int dev_count() {
|
||||
#if RTE_VERSION >= RTE_VERSION_NUM(18,05,0,0)
|
||||
return rte_eth_dev_count_avail();
|
||||
#else
|
||||
return rte_eth_dev_count();
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct rte_mempool *get_mpool(unsigned int);
|
||||
|
||||
static int get_port_numa_node(portid_t port_id);
|
||||
|
||||
static int initialize(ErrorHandler *errh);
|
||||
|
||||
inline static bool is_dpdk_packet(Packet* p) {
|
||||
return p->buffer_destructor() == DPDKDevice::free_pkt || (p->data_packet() && is_dpdk_packet(p->data_packet()));
|
||||
}
|
||||
|
||||
inline static rte_mbuf* get_pkt(unsigned numa_node);
|
||||
inline static rte_mbuf* get_pkt();
|
||||
static void free_pkt(unsigned char *, size_t, void *pktmbuf);
|
||||
|
||||
static int NB_MBUF;
|
||||
static int MBUF_DATA_SIZE;
|
||||
static int MBUF_SIZE;
|
||||
static int MBUF_CACHE_SIZE;
|
||||
static int RX_PTHRESH;
|
||||
static int RX_HTHRESH;
|
||||
static int RX_WTHRESH;
|
||||
static int TX_PTHRESH;
|
||||
static int TX_HTHRESH;
|
||||
static int TX_WTHRESH;
|
||||
static String MEMPOOL_PREFIX;
|
||||
|
||||
static unsigned DEF_DEV_RXDESC;
|
||||
static unsigned DEF_DEV_TXDESC;
|
||||
|
||||
static unsigned DEF_BURST_SIZE;
|
||||
|
||||
private:
|
||||
|
||||
enum Dir { RX, TX };
|
||||
|
||||
struct DevInfo {
|
||||
inline DevInfo() :
|
||||
rx_queues(0,false), tx_queues(0,false), promisc(false), n_rx_descs(0),
|
||||
n_tx_descs(0), init_mac(), init_mtu(0) {
|
||||
rx_queues.reserve(128);
|
||||
tx_queues.reserve(128);
|
||||
}
|
||||
|
||||
const char* driver;
|
||||
Vector<bool> rx_queues;
|
||||
Vector<bool> tx_queues;
|
||||
bool promisc;
|
||||
unsigned n_rx_descs;
|
||||
unsigned n_tx_descs;
|
||||
EtherAddress init_mac;
|
||||
uint16_t init_mtu;
|
||||
};
|
||||
|
||||
DevInfo info;
|
||||
|
||||
static bool _is_initialized;
|
||||
static HashTable<portid_t, DPDKDevice> _devs;
|
||||
static struct rte_mempool** _pktmbuf_pools;
|
||||
static unsigned _nr_pktmbuf_pools;
|
||||
static bool no_more_buffer_msg_printed;
|
||||
|
||||
int initialize_device(ErrorHandler *errh) CLICK_COLD;
|
||||
int add_queue(Dir dir, unsigned &queue_id, bool promisc,
|
||||
unsigned n_desc, ErrorHandler *errh) CLICK_COLD;
|
||||
|
||||
static bool alloc_pktmbufs() CLICK_COLD;
|
||||
|
||||
static DPDKDevice* get_device(const portid_t &port_id) {
|
||||
return &(_devs.find_insert(port_id, DPDKDevice(port_id)).value());
|
||||
}
|
||||
|
||||
|
||||
#if RTE_VERSION < RTE_VERSION_NUM(18,05,0,0)
|
||||
static int get_port_from_pci(uint32_t domain, uint8_t bus, uint8_t dev_id, uint8_t function) {
|
||||
struct rte_eth_dev_info dev_info;
|
||||
|
||||
uint16_t count = rte_eth_dev_count();
|
||||
for (portid_t port_id = 0 ; port_id < count; ++port_id) {
|
||||
rte_eth_dev_info_get(port_id, &dev_info);
|
||||
struct rte_pci_addr addr = dev_info.pci_dev->addr;
|
||||
if (addr.domain == domain &&
|
||||
addr.bus == bus &&
|
||||
addr.devid == dev_id &&
|
||||
addr.function == function)
|
||||
return port_id;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
friend class DPDKDeviceArg;
|
||||
friend class DPDKInfo;
|
||||
};
|
||||
|
||||
inline rte_mbuf* DPDKDevice::get_pkt(unsigned numa_node) {
|
||||
struct rte_mbuf* mbuf = rte_pktmbuf_alloc(get_mpool(numa_node));
|
||||
if (unlikely(!mbuf)) {
|
||||
if (!DPDKDevice::no_more_buffer_msg_printed)
|
||||
click_chatter("No more DPDK buffer available ! Try using "
|
||||
"DPDKInfo to allocate more.");
|
||||
else
|
||||
DPDKDevice::no_more_buffer_msg_printed = true;
|
||||
}
|
||||
return mbuf;
|
||||
}
|
||||
|
||||
inline rte_mbuf* DPDKDevice::get_pkt() {
|
||||
return get_pkt(rte_socket_id());
|
||||
}
|
||||
|
||||
/** @class DPDKPortArg
|
||||
@brief Parser class for DPDK Port, either an integer or a PCI address. */
|
||||
class DPDKDeviceArg { public:
|
||||
static bool parse(const String &str, DPDKDevice* &result, const ArgContext &args = ArgContext());
|
||||
static String unparse(DPDKDevice* dev) {
|
||||
return String(dev->port_id);
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct DefaultArg<DPDKDevice*> : public DPDKDeviceArg {};
|
||||
|
||||
CLICK_ENDDECLS
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user