summaryrefslogtreecommitdiff
path: root/ofproto
diff options
context:
space:
mode:
authorPaolo Valerio <pvalerio@redhat.com>2021-11-27 00:13:04 +0100
committerIlya Maximets <i.maximets@ovn.org>2021-12-17 20:32:13 +0100
commitec2aa2ab4689d156a5397e3379b8c9f7521473d4 (patch)
tree0a37ac0637110d44c6fcf15e0b52d6d42ee56a4b /ofproto
parentb723b93200c329b5f49014bd63ce7f4dd1215d61 (diff)
downloadopenvswitch-ec2aa2ab4689d156a5397e3379b8c9f7521473d4.tar.gz
ofproto-dpif-xlate: Snoop ingress packets and update neigh cache if needed.
In case of native tunnel with bfd enabled, if the MAC address of the remote end's interface changes (e.g. because it got rebooted, and the MAC address is allocated dynamically), the BFD session will never be re-established. This happens because the local tunnel neigh entry doesn't get updated, and the local end keeps sending BFD packets with the old destination MAC address. This was not an issue until b23ddcc57d41 ("tnl-neigh-cache: tighten arp and nd snooping.") because ARP requests were snooped as well avoiding the problem. Fix this by snooping the incoming packets in the slow path, and updating the neigh cache accordingly. Fixes: b23ddcc57d41 ("tnl-neigh-cache: tighten arp and nd snooping.") Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2002430 Signed-off-by: Paolo Valerio <pvalerio@redhat.com> Acked-by: Gaetan Rivet <grive@u256.net> Acked-by: Flavio Leitner <fbl@sysclose.org> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Diffstat (limited to 'ofproto')
-rw-r--r--ofproto/ofproto-dpif-xlate.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 248aacd6a..cafcd014a 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -4121,6 +4121,19 @@ terminate_native_tunnel(struct xlate_ctx *ctx, const struct xport *xport,
is_neighbor_reply_correct(ctx, flow)) {
tnl_neigh_snoop(flow, wc, ctx->xbridge->name,
ctx->xin->allow_side_effects);
+ } else if (*tnl_port != ODPP_NONE &&
+ ctx->xin->allow_side_effects &&
+ dl_type_is_ip_any(flow->dl_type)) {
+ struct eth_addr mac = flow->dl_src;
+ struct in6_addr s_ip6;
+
+ if (flow->dl_type == htons(ETH_TYPE_IP)) {
+ in6_addr_set_mapped_ipv4(&s_ip6, flow->nw_src);
+ } else {
+ s_ip6 = flow->ipv6_src;
+ }
+
+ tnl_neigh_set(ctx->xbridge->name, &s_ip6, mac);
}
}