@@ -174,7 +174,7 @@ tnl_arp_set(const char name[IFNAMSIZ], ovs_be32 dst,
static int
tnl_arp_snoop(const struct flow *flow, struct flow_wildcards *wc,
- const char name[IFNAMSIZ])
+ const char name[IFNAMSIZ], bool allow_update)
{
/* Snoop normal ARP replies and gratuitous ARP requests/replies only */
if (!is_arp(flow)
@@ -184,13 +184,17 @@ tnl_arp_snoop(const struct flow *flow, struct flow_wildcards *wc,
return EINVAL;
}
- tnl_arp_set(name, FLOW_WC_GET_AND_MASK_WC(flow, wc, nw_src), flow->arp_sha);
+ memset(&wc->masks.nw_src, 0xff, sizeof wc->masks.nw_src);
+
+ if (allow_update) {
+ tnl_arp_set(name, flow->nw_src, flow->arp_sha);
+ }
return 0;
}
static int
tnl_nd_snoop(const struct flow *flow, struct flow_wildcards *wc,
- const char name[IFNAMSIZ])
+ const char name[IFNAMSIZ], bool allow_update)
{
if (!is_nd(flow, wc) || flow->tp_src != htons(ND_NEIGHBOR_ADVERT)) {
return EINVAL;
@@ -209,20 +213,22 @@ tnl_nd_snoop(const struct flow *flow, struct flow_wildcards *wc,
memset(&wc->masks.ipv6_dst, 0xff, sizeof wc->masks.ipv6_dst);
memset(&wc->masks.nd_target, 0xff, sizeof wc->masks.nd_target);
- tnl_neigh_set__(name, &flow->nd_target, flow->arp_tha);
+ if (allow_update) {
+ tnl_neigh_set__(name, &flow->nd_target, flow->arp_tha);
+ }
return 0;
}
int
tnl_neigh_snoop(const struct flow *flow, struct flow_wildcards *wc,
- const char name[IFNAMSIZ])
+ const char name[IFNAMSIZ], bool allow_update)
{
int res;
- res = tnl_arp_snoop(flow, wc, name);
+ res = tnl_arp_snoop(flow, wc, name, allow_update);
if (res != EINVAL) {
return res;
}
- return tnl_nd_snoop(flow, wc, name);
+ return tnl_nd_snoop(flow, wc, name, allow_update);
}
void
@@ -32,7 +32,7 @@
#include "util.h"
int tnl_neigh_snoop(const struct flow *flow, struct flow_wildcards *wc,
- const char dev_name[IFNAMSIZ]);
+ const char dev_name[IFNAMSIZ], bool allow_update);
int tnl_neigh_lookup(const char dev_name[IFNAMSIZ], const struct in6_addr *dst,
struct eth_addr *mac);
void tnl_neigh_cache_init(void);
@@ -4097,7 +4097,8 @@ terminate_native_tunnel(struct xlate_ctx *ctx, struct flow *flow,
(flow->dl_type == htons(ETH_TYPE_ARP) ||
flow->nw_proto == IPPROTO_ICMPV6) &&
is_neighbor_reply_correct(ctx, flow)) {
- tnl_neigh_snoop(flow, wc, ctx->xbridge->name);
+ tnl_neigh_snoop(flow, wc, ctx->xbridge->name,
+ ctx->xin->allow_side_effects);
}
}
This is a minor issue but visible e.g. when you try to flush the neigh cache while the ARP flow is still present in the datapath, triggering the revalidation of the datapath flows which subsequently refreshes/adds the entry in the cache. Signed-off-by: Paolo Valerio <pvalerio@redhat.com> --- v2: - renamed update -> allow_update --- lib/tnl-neigh-cache.c | 20 +++++++++++++------- lib/tnl-neigh-cache.h | 2 +- ofproto/ofproto-dpif-xlate.c | 3 ++- 3 files changed, 16 insertions(+), 9 deletions(-)