From b23ddcc57d419849219c3a5aedc25f39d3818ad7 Mon Sep 17 00:00:00 2001 From: Pravin B Shelar Date: Thu, 24 Mar 2016 09:30:57 -0700 Subject: [PATCH] tnl-neigh-cache: tighten arp and nd snooping. Currently arp and nd snooping is pretty loose. That causes unnecessary entries in neighbour cache. Following patch adds required checks. Thanks Cascardo for detailed comment msg. CC: Thadeu Lima de Souza Cascardo Signed-off-by: Pravin B Shelar Acked-by: Thadeu Lima de Souza Cascardo --- lib/tnl-neigh-cache.c | 13 ++++++++++++- tests/ofproto-dpif.at | 2 +- tests/tunnel-push-pop.at | 4 ++-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/tnl-neigh-cache.c b/lib/tnl-neigh-cache.c index a62402c57..8650e73e7 100644 --- a/lib/tnl-neigh-cache.c +++ b/lib/tnl-neigh-cache.c @@ -147,7 +147,9 @@ static int tnl_arp_snoop(const struct flow *flow, struct flow_wildcards *wc, const char name[IFNAMSIZ]) { - if (flow->dl_type != htons(ETH_TYPE_ARP)) { + if (flow->dl_type != htons(ETH_TYPE_ARP) || + flow->nw_proto != ARP_OP_REPLY || + eth_addr_is_zero(flow->arp_sha)) { return EINVAL; } @@ -170,6 +172,15 @@ tnl_nd_snoop(const struct flow *flow, struct flow_wildcards *wc, flow->tp_src != htons(ND_NEIGHBOR_ADVERT)) { return EINVAL; } + /* - RFC4861 says Neighbor Advertisements sent in response to unicast Neighbor + * Solicitations SHOULD include the Target link-layer address. However, Linux + * doesn't. So, the response to Solicitations sent by OVS will include the + * TLL address and other Advertisements not including it can be ignored. + * - OVS flow extract can set this field to zero in case of packet parsing errors. + * For details refer miniflow_extract()*/ + if (eth_addr_is_zero(flow->arp_tha)) { + return EINVAL; + } memset(&wc->masks.ipv6_src, 0xff, sizeof wc->masks.ipv6_src); memset(&wc->masks.ipv6_dst, 0xff, sizeof wc->masks.ipv6_dst); diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index 09914447b..da29ac2f2 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -5483,7 +5483,7 @@ AT_CHECK([ovs-appctl ovs/route/add 1.1.2.92/24 br0], [0], [OK AT_CHECK([ovs-ofctl add-flow br0 action=normal]) dnl Prime ARP Cache for 1.1.2.92 -AT_CHECK([ovs-appctl netdev-dummy/receive br0 'recirc_id(0),in_port(100),eth(src=f8:bc:12:44:34:b6,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=1.1.2.92,tip=1.1.2.88,op=1,sha=f8:bc:12:44:34:b6,tha=00:00:00:00:00:00)']) +AT_CHECK([ovs-appctl netdev-dummy/receive br0 'recirc_id(0),in_port(100),eth(src=f8:bc:12:44:34:b6,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=1.1.2.92,tip=1.1.2.88,op=2,sha=f8:bc:12:44:34:b6,tha=00:00:00:00:00:00)']) dnl configure sflow on int-br only ovs-vsctl \ diff --git a/tests/tunnel-push-pop.at b/tests/tunnel-push-pop.at index 583abb555..a6118a895 100644 --- a/tests/tunnel-push-pop.at +++ b/tests/tunnel-push-pop.at @@ -37,8 +37,8 @@ AT_CHECK([ovs-appctl ovs/route/add 1.1.2.92/24 br0], [0], [OK AT_CHECK([ovs-ofctl add-flow br0 action=normal]) dnl Check ARP Snoop -AT_CHECK([ovs-appctl netdev-dummy/receive br0 'recirc_id(0),in_port(100),eth(src=f8:bc:12:44:34:b6,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=1.1.2.92,tip=1.1.2.88,op=1,sha=f8:bc:12:44:34:b6,tha=00:00:00:00:00:00)']) -AT_CHECK([ovs-appctl netdev-dummy/receive br0 'recirc_id(0),in_port(100),eth(src=f8:bc:12:44:34:b7,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=1.1.2.93,tip=1.1.2.88,op=1,sha=f8:bc:12:44:34:b7,tha=00:00:00:00:00:00)']) +AT_CHECK([ovs-appctl netdev-dummy/receive br0 'recirc_id(0),in_port(100),eth(src=f8:bc:12:44:34:b6,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=1.1.2.92,tip=1.1.2.88,op=2,sha=f8:bc:12:44:34:b6,tha=00:00:00:00:00:00)']) +AT_CHECK([ovs-appctl netdev-dummy/receive br0 'recirc_id(0),in_port(100),eth(src=f8:bc:12:44:34:b7,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=1.1.2.93,tip=1.1.2.88,op=2,sha=f8:bc:12:44:34:b7,tha=00:00:00:00:00:00)']) AT_CHECK([ovs-appctl tnl/neigh/show], [0], [dnl IP MAC Bridge