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