sipcap/netmap/extra/bro-netmap.diff

96 lines
2.5 KiB
Diff
Raw Normal View History

diff --git a/src/PktSrc.cc b/src/PktSrc.cc
index 9d6bce6..e8f59dd 100644
--- a/src/PktSrc.cc
+++ b/src/PktSrc.cc
@@ -11,6 +11,26 @@
#include "Net.h"
#include "Sessions.h"
+#define HAVE_NETMAP
+
+#ifdef HAVE_NETMAP
+
+// Compile in netmap support. If the interface name starts with
+// "netmap:" or "vale" we use a netmap fd instead of pcap, and bind
+// one or all rings depending on NETMAP_RING_ID environment variable.
+//
+// For a test run you can use the vale switch,
+// pkt-gen -i vale1:b -f tx -R ..rate_in_pps
+// and launch bro like this
+/*
+
+BROPATH=`./bro-path-dev` ./src/bro -i vale1:a -b -e 'global l=0; event p(){local s=net_stats(); local c=s$pkts_recvd;print c-l;l=c; schedule 1 sec {p()};} event bro_init(){event p();}'
+
+ */
+#define NETMAP_WITH_LIBS
+#include <net/netmap_user.h>
+
+#endif /* HAVE_NETMAP */
// ### This needs auto-confing.
#ifdef HAVE_PCAP_INT_H
@@ -75,7 +95,14 @@ int PktSrc::ExtractNextPacket()
return 0;
}
+#ifdef HAVE_NETMAP
+ // in netmap mode call netmap equivalent of pcap_next()
+ if (IS_NETMAP_DESC(pd))
+ data = last_data = nm_nextpkt((struct nm_desc *)pd,
+ (struct nm_pkthdr *)&hdr);
+ else
+#endif /* HAVE_NETMAP */
data = last_data = pcap_next(pd, &hdr);
if ( data && (hdr.len == 0 || hdr.caplen == 0) )
{
@@ -407,6 +435,11 @@ void PktSrc::Close()
{
if ( pd )
{
+#ifdef HAVE_NETMAP
+ if (IS_NETMAP_DESC(pd))
+ nm_close((struct nm_desc *)pd);
+ else
+#endif /* HAVE_NETMAP */
pcap_close(pd);
pd = 0;
closed = true;
@@ -443,6 +476,14 @@ void PktSrc::Statistics(Stats* s)
else
{
struct pcap_stat pstat;
+#ifdef HAVE_NETMAP
+ if (IS_NETMAP_DESC(pd))
+ {
+ s->dropped = stats.dropped;
+ s->link = stats.received;
+ }
+ else
+#endif /* HAVE_NETMAP */
if ( pcap_stats(pd, &pstat) < 0 )
{
reporter->Error("problem getting packet filter statistics: %s",
@@ -482,6 +523,21 @@ PktInterfaceSrc::PktInterfaceSrc(const char* arg_interface, const char* filter,
interface = copy_string(arg_interface);
+#ifdef HAVE_NETMAP
+ pd = (pcap_t *)nm_open(interface, getenv("NETMAP_RING_ID"), 0, 0);
+ // netmap interfaces are named netmap:* or vale*
+ // If pd == 0 && errno == 0 "interface" is not a valid
+ // netmap interface name, so we fall through to pcap
+ if (pd || errno > 0)
+ {
+ if (pd)
+ selectable_fd = NETMAP_FD(pd);
+ else
+ closed = true;
+ return;
+ }
+#endif /* HAVE_NETMAP */
+
// Determine network and netmask.
uint32 net;
if ( pcap_lookupnet(interface, &net, &netmask, tmp_errbuf) < 0 )