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 <casca...@redhat.com> Signed-off-by: Pravin B Shelar <pshe...@nicira.com> --- 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 a62402c..8650e73 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 0991444..da29ac2 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 583abb5..a6118a8 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 -- 1.8.3.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev