face: enable immediate mode for packet capture on EthernetFace.
Fixes #1511
Change-Id: I6551de8d650c5d14e27713258d958ac3c77a1649
diff --git a/daemon/face/ethernet-face.cpp b/daemon/face/ethernet-face.cpp
index fb278d3..f51a8ae 100644
--- a/daemon/face/ethernet-face.cpp
+++ b/daemon/face/ethernet-face.cpp
@@ -120,6 +120,14 @@
if (!m_pcap)
throw Error("pcap_create(): " + std::string(errbuf));
+#ifdef HAVE_PCAP_SET_IMMEDIATE_MODE
+ // Enable "immediate mode", effectively disabling any read buffering in the kernel.
+ // This corresponds to the BIOCIMMEDIATE ioctl on BSD-like systems (including OS X)
+ // where libpcap uses a BPF device. On Linux this forces libpcap not to use TPACKET_V3,
+ // even if the kernel supports it, thus preventing bug #1511.
+ pcap_set_immediate_mode(m_pcap, 1);
+#endif
+
/// \todo Do not rely on promisc mode, see task #1278
if (!m_destAddress.isBroadcast())
pcap_set_promisc(m_pcap, 1);
diff --git a/daemon/face/ethernet-face.hpp b/daemon/face/ethernet-face.hpp
index 381493c..805c0e0 100644
--- a/daemon/face/ethernet-face.hpp
+++ b/daemon/face/ethernet-face.hpp
@@ -25,6 +25,7 @@
#ifndef NFD_DAEMON_FACE_ETHERNET_FACE_HPP
#define NFD_DAEMON_FACE_ETHERNET_FACE_HPP
+#include "config.hpp"
#include "ethernet.hpp"
#include "face.hpp"
diff --git a/wscript b/wscript
index b3f1480..7fb16ca 100644
--- a/wscript
+++ b/wscript
@@ -59,6 +59,8 @@
'boost', 'dependency-checker', 'websocket',
'doxygen', 'sphinx_build'])
+ conf.find_program('bash', var='BASH')
+
conf.check_cfg(package='libndn-cxx', args=['--cflags', '--libs'],
uselib_store='NDN_CXX', mandatory=True)
@@ -72,7 +74,6 @@
conf.env['WITH_OTHER_TESTS'] = 1
conf.check_boost(lib=boost_libs)
-
if conf.env.BOOST_VERSION_NUMBER < 104800:
Logs.error("Minimum required boost version is 1.48.0")
Logs.error("Please upgrade your distribution or install custom boost libraries" +
@@ -84,15 +85,17 @@
conf.checkDependency(name='librt', lib='rt', mandatory=False)
conf.checkDependency(name='libresolv', lib='resolv', mandatory=False)
+
if not conf.options.without_libpcap:
conf.checkDependency(name='libpcap', lib='pcap', mandatory=True,
errmsg='not found, but required for Ethernet face support. '
'Specify --without-libpcap to disable Ethernet face support.')
+ if conf.env['HAVE_LIBPCAP']:
+ conf.check_cxx(function_name='pcap_set_immediate_mode', header_name='pcap/pcap.h',
+ cxxflags='-Wno-error', use='LIBPCAP', mandatory=False)
conf.load('coverage')
- conf.find_program('bash', var='BASH')
-
conf.define('DEFAULT_CONFIG_FILE', '%s/ndn/nfd.conf' % conf.env['SYSCONFDIR'])
conf.write_config_header('config.hpp')