summaryrefslogtreecommitdiff
path: root/isisd/isis_pfpacket.c
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@opensourcerouting.org>2016-11-15 08:26:56 +0900
committerDavid Lamparter <equinox@opensourcerouting.org>2016-11-15 17:51:16 +0900
commit4fa80053a3feee6cce264193f7fa234c880365db (patch)
tree5af083e965b07318e1ff1863a00d76b865bc1d23 /isisd/isis_pfpacket.c
parent095f8fae6476a1a184eafd7ed4c115324b131d99 (diff)
isisd: use BPF on Linux/PF_PACKET
we *really* don't want to receive every single packet (of any protocol type) coming in on an IS-IS enabled interface. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'isisd/isis_pfpacket.c')
-rw-r--r--isisd/isis_pfpacket.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/isisd/isis_pfpacket.c b/isisd/isis_pfpacket.c
index 885ee2c875..6ec7771ec2 100644
--- a/isisd/isis_pfpacket.c
+++ b/isisd/isis_pfpacket.c
@@ -25,6 +25,8 @@
#include <net/ethernet.h> /* the L2 protocols */
#include <netpacket/packet.h>
+#include <linux/filter.h>
+
#include "log.h"
#include "network.h"
#include "stream.h"
@@ -44,6 +46,25 @@
extern struct zebra_privs_t isisd_privs;
+/* tcpdump -i eth0 'isis' -dd */
+static struct sock_filter isisfilter[] = {
+/* NB: we're in SOCK_DGRAM, so src/dst mac + length are stripped off!
+ * (OTOH it's a bit more lower-layer agnostic and might work over GRE?) */
+/* { 0x28, 0, 0, 0x0000000c - 14 }, */
+/* { 0x25, 5, 0, 0x000005dc }, */
+ { 0x28, 0, 0, 0x0000000e - 14 },
+ { 0x15, 0, 3, 0x0000fefe },
+ { 0x30, 0, 0, 0x00000011 - 14 },
+ { 0x15, 0, 1, 0x00000083 },
+ { 0x6, 0, 0, 0x00040000 },
+ { 0x6, 0, 0, 0x00000000 },
+};
+
+static struct sock_fprog bpf = {
+ .len = array_size(isisfilter),
+ .filter = isisfilter,
+};
+
/*
* Table 9 - Architectural constants for use with ISO 8802 subnetworks
* ISO 10589 - 8.4.8
@@ -117,6 +138,12 @@ open_packet_socket (struct isis_circuit *circuit)
return ISIS_WARNING;
}
+ if (setsockopt (fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof (bpf)))
+ {
+ zlog_warn ("open_packet_socket(): SO_ATTACH_FILTER failed: %s",
+ safe_strerror (errno));
+ }
+
/*
* Bind to the physical interface
*/