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

Reply via email to