diff options
author | Pravin B Shelar <pshelar@ovn.org> | 2016-03-24 09:30:57 -0700 |
---|---|---|
committer | Pravin B Shelar <pshelar@ovn.org> | 2016-03-24 09:30:57 -0700 |
commit | b23ddcc57d419849219c3a5aedc25f39d3818ad7 (patch) | |
tree | 5b338af3da5e9ad30a80137d08a700db0e1ef8c0 /lib | |
parent | a8704b502785a9661721f041b2ee168d7a4eb460 (diff) | |
download | openvswitch-b23ddcc57d419849219c3a5aedc25f39d3818ad7.tar.gz |
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 <cascardo@redhat.com>
Signed-off-by: Pravin B Shelar <pshelar@ovn.org>
Acked-by: Thadeu Lima de Souza Cascardo <cascardo@redhat.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/tnl-neigh-cache.c | 13 |
1 files changed, 12 insertions, 1 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); |