face: adjust pcap filter in EthernetTransport to accept only untagged frames
Change-Id: Id14d6e57dc9f7c765f0431335b917c2fe74231c4
Refs: #3348
diff --git a/daemon/face/ethernet-transport.cpp b/daemon/face/ethernet-transport.cpp
index 5318097..aba8b59 100644
--- a/daemon/face/ethernet-transport.cpp
+++ b/daemon/face/ethernet-transport.cpp
@@ -97,11 +97,13 @@
// do this after assigning m_socket because getInterfaceMtu uses it
this->setMtu(getInterfaceMtu());
- char filter[100];
- // std::snprintf not found in some environments
- // http://redmine.named-data.net/issues/2299 for more information
+ char filter[110];
+ // note #1: we cannot use std::snprintf because it's not available
+ // on some platforms (see #2299)
+ // note #2: "not vlan" must appear last in the filter expression, or the
+ // rest of the filter won't work as intended (see pcap-filter(7))
snprintf(filter, sizeof(filter),
- "(ether proto 0x%x) && (ether dst %s) && (not ether src %s)",
+ "(ether proto 0x%x) && (ether dst %s) && (not ether src %s) && (not vlan)",
ethernet::ETHERTYPE_NDN,
m_destAddress.toString().c_str(),
m_srcAddress.toString().c_str());
@@ -338,13 +340,16 @@
const ether_header* eh = reinterpret_cast<const ether_header*>(packet);
const ethernet::Address sourceAddress(eh->ether_shost);
- // assert in case BPF fails to filter unwanted frames
+ // in some cases VLAN-tagged frames may survive the BPF filter,
+ // make sure we do not process those frames (see #3348)
+ if (ntohs(eh->ether_type) != ethernet::ETHERTYPE_NDN)
+ return;
+
+ // check that our BPF filter is working correctly
BOOST_ASSERT_MSG(ethernet::Address(eh->ether_dhost) == m_destAddress,
"Received frame addressed to a different multicast group");
BOOST_ASSERT_MSG(sourceAddress != m_srcAddress,
"Received frame sent by this host");
- BOOST_ASSERT_MSG(ntohs(eh->ether_type) == ethernet::ETHERTYPE_NDN,
- "Received frame with unrecognized ethertype");
packet += ethernet::HDR_LEN;
length -= ethernet::HDR_LEN;