Commit bbc1fe55 authored by Tom Barbette's avatar Tom Barbette

Take back changes for the PR for the mainline click for new Netmap integration

It supports zero-copy through buffer swapping with extra buffer allocated on startup. This more or less double the throughput.

The output device also supports a "Full Push" mode, allowing you to build a Click pipeline only with push paths, as the output rings of modern NICs are most of the time enough to absorb transient traffic, allowing to avoid using very slow Queue() elments.

Netmap Buffers are now organized in pool much like click pool through a completed implementation of Luigi Rizzo's NetmapBufQ. A shared Ring allows multiple thread-local NetmapBufQ to exchange batches of buffers.

The amount of extra buffers allocated on startup is set using NetmapInfo, which is now a real element. NetmapBufQ and other methods are moved to a library in lib/netmapdevice.cc

For all those new features, the Netmap integration becomes more different than the other FromDevice/ToDevice methods and this commits moves netmap integration to independent FromNetmapDevice and ToNetmapDevice. This matches the DPDK Integrations. Also, ToNetmapDevice is agnostic, and thereforce could not be kept with ToDevice which is pull-only, or ToDpdkDevice which is push-only.

DPDK fake buffer destructor is removed to use the same empty_destructor than Netmap, which won't be called as it is known to be empty.
parent 33790cbc
Pipeline #47 passed with stage
...@@ -41,12 +41,6 @@ ...@@ -41,12 +41,6 @@
/* Define if you have the <dlfcn.h> header file. */ /* Define if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H #undef HAVE_DLFCN_H
/* Define if a Click user-level driver uses Intel DPDK. */
#undef HAVE_DPDK
/* Define if a Click user-level driver uses Netmap. */
#undef HAVE_NETMAP
/* Define if you have the <nuda.h> header file. */ /* Define if you have the <nuda.h> header file. */
#undef HAVE_NUMA #undef HAVE_NUMA
...@@ -122,18 +116,9 @@ ...@@ -122,18 +116,9 @@
/* Define if you have the <netdb.h> header file. */ /* Define if you have the <netdb.h> header file. */
#undef HAVE_NETDB_H #undef HAVE_NETDB_H
/* Define if you have the <net/netmap.h> header file. */
#undef HAVE_NET_NETMAP_H
/* Define if you use only netmap buffer as data buffer. */
#undef HAVE_NETMAP_PACKET_POOL
/* Define if you have the <netpacket/packet.h> header file. */ /* Define if you have the <netpacket/packet.h> header file. */
#undef HAVE_NETPACKET_PACKET_H #undef HAVE_NETPACKET_PACKET_H
/* Define if Zero-copy is enabled. */
#undef HAVE_ZEROCOPY
/* Define if <new.h> exists and works. */ /* Define if <new.h> exists and works. */
#undef HAVE_NEW_H #undef HAVE_NEW_H
...@@ -229,6 +214,15 @@ ...@@ -229,6 +214,15 @@
/* Define if a Click user-level driver might run multiple threads. */ /* Define if a Click user-level driver might run multiple threads. */
#undef HAVE_USER_MULTITHREAD #undef HAVE_USER_MULTITHREAD
/* Define if Zero-copy is enabled. */
#undef HAVE_ZEROCOPY
/* Define if Netmap support is enabled. */
#undef HAVE_NETMAP
/* Define if you use only netmap buffer as data buffer. */
#undef HAVE_NETMAP_PACKET_POOL
/* Define if a Click user-level driver uses Intel DPDK. */ /* Define if a Click user-level driver uses Intel DPDK. */
#undef HAVE_DPDK #undef HAVE_DPDK
......
...@@ -1501,7 +1501,7 @@ Optional Features: ...@@ -1501,7 +1501,7 @@ Optional Features:
--disable-kqueue do not use kqueue() --disable-kqueue do not use kqueue()
--enable-dpdk use Intel DPDK --enable-dpdk use Intel DPDK
--enable-dpdk-pools Click manages DPDK packet pools --enable-dpdk-pools Click manages DPDK packet pools
--enable-zerocopy use Zero Copy --disable-zerocopy disable Zero Copy
--disable-linuxmodule disable Linux kernel driver --disable-linuxmodule disable Linux kernel driver
--disable-fixincludes do not patch Linux kernel headers for C++ --disable-fixincludes do not patch Linux kernel headers for C++
--enable-multithread support kernel multithreading --enable-multithread support kernel multithreading
...@@ -6564,15 +6564,6 @@ if test "x$enable_dpdk" = "xyes"; then ...@@ -6564,15 +6564,6 @@ if test "x$enable_dpdk" = "xyes"; then
Cannot find \$RTE_SDK/\$RTE_TARGET/include/rte_eal.h for Intel DPDK. Cannot find \$RTE_SDK/\$RTE_TARGET/include/rte_eal.h for Intel DPDK.
Define \$RTE_SDK and \$RTE_TARGET as per Intel DPDK documentation. Define \$RTE_SDK and \$RTE_TARGET as per Intel DPDK documentation.
=========================================" "$LINENO" 5
fi
if test ! -f "$RTE_SDK/$RTE_TARGET/lib/librte_eal.a"; then
as_fn_error $? "
=========================================
Cannot find \$RTE_SDK/\$RTE_TARGET/lib/librte_eal.a for Intel DPDK.
Define \$RTE_SDK and \$RTE_TARGET as per Intel DPDK documentation.
=========================================" "$LINENO" 5 =========================================" "$LINENO" 5
fi fi
rte_ver_major=`grep "#define RTE_VER_MAJOR" "$RTE_SDK/$RTE_TARGET/include/rte_version.h" | head -n 1 | awk '{print $3}'` rte_ver_major=`grep "#define RTE_VER_MAJOR" "$RTE_SDK/$RTE_TARGET/include/rte_version.h" | head -n 1 | awk '{print $3}'`
...@@ -6606,7 +6597,7 @@ fi ...@@ -6606,7 +6597,7 @@ fi
if test "${enable_zerocopy+set}" = set; then : if test "${enable_zerocopy+set}" = set; then :
enableval=$enable_zerocopy; : enableval=$enable_zerocopy; :
else else
enable_zerocopy=no enable_zerocopy=yes
fi fi
if test "x$enable_zerocopy" = xyes; then if test "x$enable_zerocopy" = xyes; then
...@@ -10894,12 +10885,16 @@ $as_echo "$ac_cv_working_net_netmap_h" >&6; } ...@@ -10894,12 +10885,16 @@ $as_echo "$ac_cv_working_net_netmap_h" >&6; }
CPPFLAGS="$saveflags" CPPFLAGS="$saveflags"
if test "$HAVE_NETMAP" = yes -a "$use_netmap" != no; then if test "$HAVE_NETMAP" = yes -a "$use_netmap" != no; then
$as_echo "#define HAVE_NET_NETMAP_H 1" >>confdefs.h $as_echo "#define HAVE_NETMAP 1" >>confdefs.h
EXTRA_DRIVER_OBJS="netmapdevice.o $EXTRA_DRIVER_OBJS"
else
HAVE_NETMAP=no
fi fi
if test "$HAVE_PCAP" != yes -a "$HAVE_NETMAP" != yes -a "$ac_cv_under_linux" != yes; then if test "$HAVE_PCAP" != yes -a "$HAVE_NETMAP" != yes -a "$ac_cv_under_linux" != yes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
========================================= =========================================
......
...@@ -39,12 +39,12 @@ EnsureNetmapBuffer::smaction(Packet* p) { ...@@ -39,12 +39,12 @@ EnsureNetmapBuffer::smaction(Packet* p) {
#if HAVE_NETMAP_PACKET_POOL #if HAVE_NETMAP_PACKET_POOL
WritablePacket* q = WritablePacket::make(p->length()); WritablePacket* q = WritablePacket::make(p->length());
#else #else
unsigned char* buffer = NetmapBufQ::get_local_pool()->extract_p(); unsigned char* buffer = NetmapBufQ::local_pool()->extract_p();
if (!buffer) { if (!buffer) {
p->kill(); p->kill();
return 0; return 0;
} }
WritablePacket* q = WritablePacket::make(buffer,NetmapBufQ::buffer_size(),NetmapBufQ::buffer_destructor,NetmapBufQ::get_local_pool()); WritablePacket* q = WritablePacket::make(buffer,NetmapBufQ::buffer_size(),NetmapBufQ::buffer_destructor,NetmapBufQ::local_pool());
#endif #endif
q->copy(p); q->copy(p);
p->kill(); p->kill();
......
...@@ -57,7 +57,7 @@ CLICK_DECLS ...@@ -57,7 +57,7 @@ CLICK_DECLS
FromDevice::FromDevice() FromDevice::FromDevice()
: :
#if FROMDEVICE_ALLOW_NETMAP || FROMDEVICE_ALLOW_PCAP #if FROMDEVICE_ALLOW_PCAP
_task(this), _task(this),
#endif #endif
#if FROMDEVICE_ALLOW_PCAP #if FROMDEVICE_ALLOW_PCAP
...@@ -65,7 +65,7 @@ FromDevice::FromDevice() ...@@ -65,7 +65,7 @@ FromDevice::FromDevice()
#endif #endif
_datalink(-1), _count(0), _promisc(0), _snaplen(0) _datalink(-1), _count(0), _promisc(0), _snaplen(0)
{ {
#if FROMDEVICE_ALLOW_LINUX || FROMDEVICE_ALLOW_PCAP || FROMDEVICE_ALLOW_NETMAP #if FROMDEVICE_ALLOW_LINUX || FROMDEVICE_ALLOW_PCAP
_fd = -1; _fd = -1;
#endif #endif
} }
...@@ -122,7 +122,7 @@ FromDevice::configure(Vector<String> &conf, ErrorHandler *errh) ...@@ -122,7 +122,7 @@ FromDevice::configure(Vector<String> &conf, ErrorHandler *errh)
// set _method // set _method
if (capture == "") { if (capture == "") {
#if FROMDEVICE_ALLOW_NETMAP || FROMDEVICE_ALLOW_PCAP || FROMDEVICE_ALLOW_LINUX #if FROMDEVICE_ALLOW_PCAP || FROMDEVICE_ALLOW_LINUX
# if FROMDEVICE_ALLOW_PCAP # if FROMDEVICE_ALLOW_PCAP
_method = _bpf_filter ? method_pcap : method_default; _method = _bpf_filter ? method_pcap : method_default;
# else # else
...@@ -139,10 +139,6 @@ FromDevice::configure(Vector<String> &conf, ErrorHandler *errh) ...@@ -139,10 +139,6 @@ FromDevice::configure(Vector<String> &conf, ErrorHandler *errh)
#if FROMDEVICE_ALLOW_PCAP #if FROMDEVICE_ALLOW_PCAP
else if (capture == "PCAP") else if (capture == "PCAP")
_method = method_pcap; _method = method_pcap;
#endif
#if FROMDEVICE_ALLOW_NETMAP
else if (capture == "NETMAP")
_method = method_netmap;
#endif #endif
else else
return errh->error("bad METHOD"); return errh->error("bad METHOD");
...@@ -308,17 +304,6 @@ FromDevice::initialize(ErrorHandler *errh) ...@@ -308,17 +304,6 @@ FromDevice::initialize(ErrorHandler *errh)
if (!_ifname) if (!_ifname)
return errh->error("interface not set"); return errh->error("interface not set");
#if FROMDEVICE_ALLOW_NETMAP
if (_method == method_default || _method == method_netmap) {
_fd = _netmap.open(_ifname, _method == method_netmap, errh);
if (_fd >= 0) {
_datalink = FAKE_DLT_EN10MB;
_method = method_netmap;
_netmap.initialize_rings_rx(_timestamp);
}
}
#endif
#if FROMDEVICE_ALLOW_PCAP #if FROMDEVICE_ALLOW_PCAP
if (_method == method_default || _method == method_pcap) { if (_method == method_default || _method == method_pcap) {
assert(!_pcap); assert(!_pcap);
...@@ -408,11 +393,11 @@ FromDevice::initialize(ErrorHandler *errh) ...@@ -408,11 +393,11 @@ FromDevice::initialize(ErrorHandler *errh)
} }
#endif #endif
#if FROMDEVICE_ALLOW_PCAP || FROMDEVICE_ALLOW_NETMAP #if FROMDEVICE_ALLOW_PCAP
if (_method == method_pcap || _method == method_netmap) if (_method == method_pcap)
ScheduleInfo::initialize_task(this, &_task, false, errh); ScheduleInfo::initialize_task(this, &_task, false, errh);
#endif #endif
#if FROMDEVICE_ALLOW_PCAP || FROMDEVICE_ALLOW_LINUX || FROMDEVICE_ALLOW_NETMAP #if FROMDEVICE_ALLOW_PCAP || FROMDEVICE_ALLOW_LINUX
if (_fd >= 0) if (_fd >= 0)
add_select(_fd, SELECT_READ); add_select(_fd, SELECT_READ);
#endif #endif
...@@ -429,10 +414,6 @@ FromDevice::cleanup(CleanupStage stage) ...@@ -429,10 +414,6 @@ FromDevice::cleanup(CleanupStage stage)
{ {
if (stage >= CLEANUP_INITIALIZED && !_sniffer) if (stage >= CLEANUP_INITIALIZED && !_sniffer)
KernelFilter::device_filter(_ifname, false, ErrorHandler::default_handler()); KernelFilter::device_filter(_ifname, false, ErrorHandler::default_handler());
#if FROMDEVICE_ALLOW_NETMAP
if (_fd >= 0 && _method == method_netmap)
_netmap.close(_fd);
#endif
#if FROMDEVICE_ALLOW_LINUX #if FROMDEVICE_ALLOW_LINUX
if (_fd >= 0 && _method == method_linux) { if (_fd >= 0 && _method == method_linux) {
if (_was_promisc >= 0) if (_was_promisc >= 0)
...@@ -445,12 +426,12 @@ FromDevice::cleanup(CleanupStage stage) ...@@ -445,12 +426,12 @@ FromDevice::cleanup(CleanupStage stage)
pcap_close(_pcap); pcap_close(_pcap);
_pcap = 0; _pcap = 0;
#endif #endif
#if FROMDEVICE_ALLOW_NETMAP || FROMDEVICE_ALLOW_PCAP || FROMDEVICE_ALLOW_LINUX #if FROMDEVICE_ALLOW_PCAP || FROMDEVICE_ALLOW_LINUX
_fd = -1; _fd = -1;
#endif #endif
} }
#if FROMDEVICE_ALLOW_PCAP || FROMDEVICE_ALLOW_NETMAP #if FROMDEVICE_ALLOW_PCAP
void void
FromDevice::emit_packet(WritablePacket *p, int extra_len, const Timestamp &ts) FromDevice::emit_packet(WritablePacket *p, int extra_len, const Timestamp &ts)
{ {
...@@ -474,7 +455,7 @@ FromDevice::emit_packet(WritablePacket *p, int extra_len, const Timestamp &ts) ...@@ -474,7 +455,7 @@ FromDevice::emit_packet(WritablePacket *p, int extra_len, const Timestamp &ts)
} }
#endif #endif
#if FROMDEVICE_ALLOW_PCAP || FROMDEVICE_ALLOW_NETMAP #if FROMDEVICE_ALLOW_PCAP
CLICK_ENDDECLS CLICK_ENDDECLS
extern "C" { extern "C" {
void void
...@@ -501,22 +482,6 @@ CLICK_DECLS ...@@ -501,22 +482,6 @@ CLICK_DECLS
void void
FromDevice::selected(int, int) FromDevice::selected(int, int)
{ {
// netmap and pcap are essentially the same code, different
// dispatch function. This code is also in run_task()
// with fast_reschedule()
#if FROMDEVICE_ALLOW_NETMAP
if (_method == method_netmap) {
// Read and push() at most one burst of packets.
int r = _netmap.dispatch(_burst,
reinterpret_cast<nm_cb_t>(FromDevice_get_packet), (u_char *) this);
if (r > 0) {
_count += r;
_task.reschedule();
} else if (r < 0 && ++_pcap_complaints < 5)
ErrorHandler::default_handler()->error("%p{element}: %s",
this, "nm_dispatch failed");
}
#endif
#if FROMDEVICE_ALLOW_PCAP #if FROMDEVICE_ALLOW_PCAP
if (_method == method_pcap) { if (_method == method_pcap) {
// Read and push() at most one burst of packets. // Read and push() at most one burst of packets.
...@@ -561,29 +526,17 @@ FromDevice::selected(int, int) ...@@ -561,29 +526,17 @@ FromDevice::selected(int, int)
#endif #endif
} }
#if FROMDEVICE_ALLOW_PCAP || FROMDEVICE_ALLOW_NETMAP #if FROMDEVICE_ALLOW_PCAP
bool bool
FromDevice::run_task(Task *) FromDevice::run_task(Task *)
{ {
// Read and push() at most one burst of packets. // Read and push() at most one burst of packets.
int r = 0; int r = 0;
# if FROMDEVICE_ALLOW_NETMAP
if (_method == method_netmap) {
// Read and push() at most one burst of packets.
r = _netmap.dispatch(_burst,
reinterpret_cast<nm_cb_t>(FromDevice_get_packet), (u_char *) this);
if (r < 0 && ++_pcap_complaints < 5)
ErrorHandler::default_handler()->error("%p{element}: %s",
this, "nm_dispatch failed");
}
# endif
# if FROMDEVICE_ALLOW_PCAP
if (_method == method_pcap) { if (_method == method_pcap) {
r = pcap_dispatch(_pcap, _burst, FromDevice_get_packet, (u_char *) this); r = pcap_dispatch(_pcap, _burst, FromDevice_get_packet, (u_char *) this);
if (r < 0 && ++_pcap_complaints < 5) if (r < 0 && ++_pcap_complaints < 5)
ErrorHandler::default_handler()->error("%p{element}: %s", this, pcap_geterr(_pcap)); ErrorHandler::default_handler()->error("%p{element}: %s", this, pcap_geterr(_pcap));
} }
# endif
if (r > 0) { if (r > 0) {
_count += r; _count += r;
_task.fast_reschedule(); _task.fast_reschedule();
...@@ -652,5 +605,5 @@ FromDevice::add_handlers() ...@@ -652,5 +605,5 @@ FromDevice::add_handlers()
} }
CLICK_ENDDECLS CLICK_ENDDECLS
ELEMENT_REQUIRES(userlevel FakePcap KernelFilter NetmapInfo) ELEMENT_REQUIRES(userlevel FakePcap KernelFilter)
EXPORT_ELEMENT(FromDevice) EXPORT_ELEMENT(FromDevice)
...@@ -18,12 +18,7 @@ int pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf); ...@@ -18,12 +18,7 @@ int pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf);
} }
#endif #endif
#if HAVE_NET_NETMAP_H #if FROMDEVICE_ALLOW_PCAP
# define FROMDEVICE_ALLOW_NETMAP 1
# include "elements/userlevel/netmapinfo.hh"
#endif
#if FROMDEVICE_ALLOW_NETMAP || FROMDEVICE_ALLOW_PCAP
# include <click/task.hh> # include <click/task.hh>
extern "C" { extern "C" {
void FromDevice_get_packet(u_char*, const struct pcap_pkthdr*, const u_char*); void FromDevice_get_packet(u_char*, const struct pcap_pkthdr*, const u_char*);
...@@ -182,7 +177,7 @@ class FromDevice : public Element { public: ...@@ -182,7 +177,7 @@ class FromDevice : public Element { public:
void add_handlers() CLICK_COLD; void add_handlers() CLICK_COLD;
inline String ifname() const { return _ifname; } inline String ifname() const { return _ifname; }
#if FROMDEVICE_ALLOW_LINUX || FROMDEVICE_ALLOW_PCAP || FROMDEVICE_ALLOW_NETMAP #if FROMDEVICE_ALLOW_LINUX || FROMDEVICE_ALLOW_PCAP
inline int fd() const { return _fd; } inline int fd() const { return _fd; }
#else #else
inline int fd() const { return -1; } inline int fd() const { return -1; }
...@@ -202,11 +197,7 @@ class FromDevice : public Element { public: ...@@ -202,11 +197,7 @@ class FromDevice : public Element { public:
static int set_promiscuous(int, String, bool); static int set_promiscuous(int, String, bool);
#endif #endif
#if FROMDEVICE_ALLOW_NETMAP #if FROMDEVICE_ALLOW_PCAP
const NetmapInfo *netmap() const { return _method == method_netmap ? &_netmap : 0; }
#endif
#if FROMDEVICE_ALLOW_NETMAP || FROMDEVICE_ALLOW_PCAP
bool run_task(Task *task); bool run_task(Task *task);
#endif #endif
...@@ -214,24 +205,16 @@ class FromDevice : public Element { public: ...@@ -214,24 +205,16 @@ class FromDevice : public Element { public:
private: private:
#if FROMDEVICE_ALLOW_LINUX || FROMDEVICE_ALLOW_PCAP || FROMDEVICE_ALLOW_NETMAP #if FROMDEVICE_ALLOW_LINUX || FROMDEVICE_ALLOW_PCAP
int _fd; int _fd;
#endif #endif
#if FROMDEVICE_ALLOW_NETMAP || FROMDEVICE_ALLOW_PCAP #if FROMDEVICE_ALLOW_PCAP
Task _task; Task _task;
#endif
#if FROMDEVICE_ALLOW_PCAP || FROMDEVICE_ALLOW_NETMAP
void emit_packet(WritablePacket *p, int extra_len, const Timestamp &ts); void emit_packet(WritablePacket *p, int extra_len, const Timestamp &ts);
#endif
#if FROMDEVICE_ALLOW_PCAP
pcap_t *_pcap; pcap_t *_pcap;
int _pcap_complaints; int _pcap_complaints;
#endif #endif
#if FROMDEVICE_ALLOW_NETMAP #if FROMDEVICE_ALLOW_PCAP
NetmapInfo _netmap;
int netmap_dispatch();
#endif
#if FROMDEVICE_ALLOW_PCAP || FROMDEVICE_ALLOW_NETMAP
friend void FromDevice_get_packet(u_char*, const struct pcap_pkthdr*, friend void FromDevice_get_packet(u_char*, const struct pcap_pkthdr*,
const u_char*); const u_char*);
#endif #endif
...@@ -259,7 +242,7 @@ class FromDevice : public Element { public: ...@@ -259,7 +242,7 @@ class FromDevice : public Element { public:
int _snaplen; int _snaplen;
uint16_t _protocol; uint16_t _protocol;
unsigned _headroom; unsigned _headroom;
enum { method_default, method_netmap, method_pcap, method_linux }; enum { method_default, method_pcap, method_linux };
int _method; int _method;
#if FROMDEVICE_ALLOW_PCAP #if FROMDEVICE_ALLOW_PCAP
String _bpf_filter; String _bpf_filter;
......
...@@ -35,6 +35,7 @@ FromNetmapDevice::FromNetmapDevice() : _device(NULL), _promisc(1),_blockant(fals ...@@ -35,6 +35,7 @@ FromNetmapDevice::FromNetmapDevice() : _device(NULL), _promisc(1),_blockant(fals
#if HAVE_BATCH #if HAVE_BATCH
in_batch_mode = BATCH_MODE_YES; in_batch_mode = BATCH_MODE_YES;
#endif #endif
NetmapDevice::global_alloc += 2048;
} }
void * void *
...@@ -210,9 +211,9 @@ FromNetmapDevice::receive_packets(Task* task, int begin, int end, bool fromtask) ...@@ -210,9 +211,9 @@ FromNetmapDevice::receive_packets(Task* task, int begin, int end, bool fromtask)
#if HAVE_ZEROCOPY #if HAVE_ZEROCOPY
if (slot->len > 64 && !(slot->flags & NS_MOREFRAG)) { if (slot->len > 64 && !(slot->flags & NS_MOREFRAG)) {
__builtin_prefetch(data); __builtin_prefetch(data);
p = Packet::make( data, slot->len, NetmapBufQ::buffer_destructor,NetmapBufQ::get_local_pool()); p = Packet::make( data, slot->len, NetmapBufQ::buffer_destructor,NetmapBufQ::local_pool());
if (!p) goto error; if (!p) goto error;
slot->buf_idx = NetmapBufQ::get_local_pool()->extract(); slot->buf_idx = NetmapBufQ::local_pool()->extract();
slot->flags = NS_BUF_CHANGED; slot->flags = NS_BUF_CHANGED;
} else } else
#endif #endif
......
...@@ -18,12 +18,14 @@ CLICK_DECLS ...@@ -18,12 +18,14 @@ CLICK_DECLS
/* /*
* =c * =c
* *
* FromNetmapDevice * FromNetmapDevice(DEVNAME [, QUEUE, NR_QUEUE, [, I<keywords> PROMISC, BURST])
* *
* * =item DEVNAME * =s netdevices
*
* =item DEVNAME
* *
* String. Device number * String. Device number
* * *
* =item PROMISC * =item PROMISC
* *
* Boolean. FromNetmapDevice puts the device in promiscuous mode if PROMISC is * Boolean. FromNetmapDevice puts the device in promiscuous mode if PROMISC is
...@@ -79,7 +81,6 @@ public: ...@@ -79,7 +81,6 @@ public:
int initialize(ErrorHandler*) CLICK_COLD; int initialize(ErrorHandler*) CLICK_COLD;
void cleanup(CleanupStage) CLICK_COLD; void cleanup(CleanupStage) CLICK_COLD;
inline bool receive_packets(Task* task, int begin, int end, bool fromtask); inline bool receive_packets(Task* task, int begin, int end, bool fromtask);
bool run_task(Task *); bool run_task(Task *);
......
// -*- mode: c++; c-basic-offset: 4 -*- // -*- mode: c++; c-basic-offset: 4 -*-
/* /*
* netmapinfo.{cc,hh} -- library for interfacing with netmap * netmapinfo.{cc,hh} -- library for interfacing with netmap
* Eddie Kohler, Luigi Rizzo
* *
* Copyright (c) 2012 Eddie Kohler * Copyright (c) 2015 Tom Barbette
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
...@@ -17,135 +16,28 @@ ...@@ -17,135 +16,28 @@
*/ */
#include <click/config.h> #include <click/config.h>
#include <click/glue.hh> #include <click/args.hh>
#if HAVE_NET_NETMAP_H #include <click/error.hh>
#define NETMAP_WITH_LIBS
#include "netmapinfo.hh" #include "netmapinfo.hh"
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <click/sync.hh>
#include <unistd.h>
#include <fcntl.h>
CLICK_DECLS
/*
* keep a list of netmap ports so matching the name we
* can recycle the regions
*/
static Spinlock netmap_memory_lock;
//static struct NetmapInfo *netmap_ports;
int CLICK_DECLS
NetmapInfo::open(const String &ifname,
bool always_error, ErrorHandler *errh)
{
click_chatter("%s ifname %s\n", __FUNCTION__, ifname.c_str());
ErrorHandler *initial_errh = always_error ? errh : ErrorHandler::silent_handler();
netmap_memory_lock.acquire(); int NetmapInfo::configure(Vector<String> &conf, ErrorHandler *errh) {
// for the time being, just a new block if (instance) {
do { return errh->error("You cannot place multiple instances of NetmapInfo !");
desc = nm_open(ifname.c_str(), NULL, 0, NULL);
if (desc == NULL) {
initial_errh->error("nm_open(%s): %s", ifname.c_str(), strerror(errno));
break;
} }
click_chatter("%s %s memsize %d mem %p buf_start %p buf_end %p", instance = this;
__FUNCTION__, desc->req.nr_name, if (Args(conf, this, errh)
desc->memsize, desc->mem, desc->buf_start, desc->buf_end); .read_p("EXTRA_BUFFER", NetmapDevice::global_alloc)
bufq.init(desc->buf_start, desc->buf_end, .complete() < 0)
desc->some_ring->nr_buf_size); return -1;
/* eventually try to match the region */
destructor_arg = this;
click_chatter("private mapping for %s\n", ifname.c_str());
} while (0);
netmap_memory_lock.release();
return desc ? desc->fd : -1;
}
void return 0;
NetmapInfo::initialize_rings_rx(int timestamp)
{