When two switch ports are configured with the same requested-tnl-key, only one port gets the requested key while the other gets a random one. If the port whose request was satisfied is deleted, the remaining port's tunnel key was not updated until a full recompute.
Fix this by tracking in the datapath whether any port had a requested-tnl-key conflict. When a port is deleted from such a datapath, fall back to recompute so the tunnel key is properly reassigned. The change is a bit aggressive and will trigger recomputes every time a port is deleted from such a switch but we're in a situation in which the configuration is incorrect so it's probably acceptable and definitely better than the old behavior of just remaining in an inconsistent state until a recompute happens (potentially for ever). Reported-at: https://redhat.atlassian.net/browse/FDP-3560 Assisted-by: Claude, with model: claude-opus-4-6 Signed-off-by: Dumitru Ceara <[email protected]> --- northd/northd.c | 9 +++++++++ northd/northd.h | 3 +++ tests/ovn-northd.at | 25 +++++++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/northd/northd.c b/northd/northd.c index ac23614172..b7239f4e20 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -4279,6 +4279,7 @@ ovn_port_assign_requested_tnl_id(struct ovn_port *op) "%"PRIu32" as another LSP or LRP", op->nbsp ? "switch" : "router", op_get_name(op), tunnel_key); + op->od->port_key_conflict = true; return false; } } @@ -4985,6 +4986,14 @@ ls_handle_lsp_changes(struct ovsdb_idl_txn *ovnsb_idl_txn, * impacted by this deletion. Fallback to recompute. */ goto fail; } + if (od->port_key_conflict && + smap_get_int(&op->nbsp->options, "requested-tnl-key", 0)) { + /* Some port in this datapath had a requested-tnl-key + * that couldn't be satisfied due to a conflict. Now + * that a port is being deleted the conflict may be + * resolved; fall back to recompute. */ + goto fail; + } add_op_to_northd_tracked_ports(&trk_lsps->deleted, op); hmap_remove(&nd->ls_ports, &op->key_node); hmap_remove(&od->ports, &op->dp_node); diff --git a/northd/northd.h b/northd/northd.h index 884edc22d9..1395190064 100644 --- a/northd/northd.h +++ b/northd/northd.h @@ -417,6 +417,9 @@ struct ovn_datapath { struct hmap port_tnlids; uint32_t port_key_hint; + bool port_key_conflict; /* True if a port's requested-tnl-key could + * not be assigned due to a conflict. */ + bool has_unknown; bool has_vtep_lports; bool has_arp_proxy_port; diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index 3e7a6f7f80..6230fd039a 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -3049,6 +3049,31 @@ AT_CHECK([test $lsp02 = 3 && test $ls1 = 123]) OVN_CLEANUP_NORTHD AT_CLEANUP ]) + +OVN_FOR_EACH_NORTHD_NO_HV([ +AT_SETUP([port requested-tnl-key -- conflict resolved on deletion]) +AT_KEYWORDS([requested tnl tunnel key keys]) +ovn_start + +AS_BOX([Create two ports with the same requested-tnl-key]) +check ovn-nbctl --wait=sb ls-add ls \ + -- lsp-add ls lsp1 \ + -- set logical_switch_port lsp1 options:requested-tnl-key=1 \ + -- lsp-add ls lsp2 \ + -- set logical_switch_port lsp2 options:requested-tnl-key=1 + +AS_BOX([Delete the port that got key 1]) +lsp=$(fetch_column port_binding logical_port tunnel_key=1) +check test -n "$lsp" +check ovn-nbctl --wait=sb lsp-del $lsp + +AS_BOX([Remaining port should now have tunnel_key=1]) +check_column 1 Port_Binding tunnel_key + +OVN_CLEANUP_NORTHD +AT_CLEANUP +]) + OVN_FOR_EACH_NORTHD_NO_HV([ AT_SETUP([check VXLAN mode disabling]) ovn_start -- 2.53.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
