On Fri, Mar 27, 2026 at 9:53 PM Dumitru Ceara via dev <
[email protected]> wrote:

> 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
>
>
Looks good to me, thanks.

Acked-by: Ales Musil <[email protected]>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to