On Wed, Mar 11, 2026 at 7:53 PM Mark Michelson via dev <
[email protected]> wrote:

> OpenStack Neutron may set specific external_ids on logical switches and
> logical routers in order to propagate those values into the
> corresponding southbound Datapath_Bindings. Specifically, OVN looks for
>
>  * external-ids:neutron:network_name on logical switches, and
>  * external-ids:neutron:router_name on logical routers.
>
> When refactoring datapath syncing in OVN 25.09, we mistakenly started
> reading these values from the wrong column. Specifically, we were
> reading:
>
>  * other_config:neutron:network_name on logical switches, and
>  * options:neutron:router_name on logical routers.
>
> This commit fixes the issue by reading from the external_ids column on
> both logical switches and logical routers.
>
> Fixes: 7bb513bcfda3 ("northd: Refactor datapath syncing.")
> Reported-at: https://issues.redhat.com/browse/FDP-3286
> Signed-off-by: Mark Michelson <[email protected]>
> ---
>  northd/en-datapath-logical-router.c |  2 +-
>  northd/en-datapath-logical-switch.c |  2 +-
>  tests/ovn-northd.at                 | 46 +++++++++++++++++++++++++++++
>  3 files changed, 48 insertions(+), 2 deletions(-)
>
> diff --git a/northd/en-datapath-logical-router.c
> b/northd/en-datapath-logical-router.c
> index ae44ddaf5..34c8b9c5a 100644
> --- a/northd/en-datapath-logical-router.c
> +++ b/northd/en-datapath-logical-router.c
> @@ -43,7 +43,7 @@ gather_external_ids(const struct nbrec_logical_router
> *nbr,
>                      struct smap *external_ids)
>  {
>      smap_add(external_ids, "name", nbr->name);
> -    const char *neutron_router = smap_get(&nbr->options,
> +    const char *neutron_router = smap_get(&nbr->external_ids,
>                                             "neutron:router_name");
>      if (neutron_router && neutron_router[0]) {
>          smap_add(external_ids, "name2", neutron_router);
> diff --git a/northd/en-datapath-logical-switch.c
> b/northd/en-datapath-logical-switch.c
> index afe72003d..ad6d042bc 100644
> --- a/northd/en-datapath-logical-switch.c
> +++ b/northd/en-datapath-logical-switch.c
> @@ -111,7 +111,7 @@ gather_external_ids(const struct nbrec_logical_switch
> *nbs,
>                      struct smap *external_ids)
>  {
>      smap_add(external_ids, "name", nbs->name);
> -    const char *neutron_network = smap_get(&nbs->other_config,
> +    const char *neutron_network = smap_get(&nbs->external_ids,
>                                             "neutron:network_name");
>      if (neutron_network && neutron_network[0]) {
>          smap_add(external_ids, "name2", neutron_network);
> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
> index a8b5436ba..b0fef6d7b 100644
> --- a/tests/ovn-northd.at
> +++ b/tests/ovn-northd.at
> @@ -19939,3 +19939,49 @@ done
>
>  OVN_CLEANUP_NORTHD
>  AT_CLEANUP
> +
> +OVN_FOR_EACH_NORTHD_NO_HV([
> +AT_SETUP([Neutron external-ids])
> +ovn_start
> +
> +# This test ensures that special Neutron external-ids on logical datapaths
> +# are propagated to their southbound Datapath_Bindings.
> +
> +check ovn-nbctl ls-add sw
> +check ovn-nbctl --wait=sb lr-add ro
> +
> +ls_dp_uuid=$(fetch_column Datapath_Binding _uuid type=logical-switch)
> +lr_dp_uuid=$(fetch_column Datapath_Binding _uuid type=logical-router)
> +
> +# We can't use the check_column function since we need to check
> +# an individual external-id value. check_column can only be
> +# used to check the full contents of a column.
> +#
> +# If the external_ids:name2 is not present, then `ovn-sbctl get`
> +# exits with a failure condition.
> +AT_CHECK([ovn-sbctl get Datapath_Binding $ls_dp_uuid external_ids:name2],
> +[1], [ignore], [ignore])
> +AT_CHECK([ovn-sbctl get Datapath_Binding $lr_dp_uuid external_ids:name2],
> +[1], [ignore], [ignore])
> +
> +check ovn-nbctl add Logical_Switch sw external_ids
> \"neutron:network_name\"=the_switch
> +check ovn-nbctl --wait=sb add Logical_Router ro external_ids
> \"neutron:router_name\"=the_router
> +
> +AT_CHECK([ovn-sbctl get Datapath_Binding $ls_dp_uuid external_ids:name2],
> +[0], [the_switch
> +])
> +AT_CHECK([ovn-sbctl get Datapath_Binding $lr_dp_uuid external_ids:name2],
> +[0], [the_router
> +])
> +
> +check ovn-nbctl remove Logical_Switch sw external_ids
> \"neutron:network_name\"
> +check ovn-nbctl --wait=sb remove Logical_Router ro external_ids
> \"neutron:router_name\"
> +
> +AT_CHECK([ovn-sbctl get Datapath_Binding $ls_dp_uuid external_ids:name2],
> +[1], [ignore], [ignore])
> +AT_CHECK([ovn-sbctl get Datapath_Binding $lr_dp_uuid external_ids:name2],
> +[1], [ignore], [ignore])
> +
> +OVN_CLEANUP_NORTHD
> +AT_CLEANUP
> +])
> --
> 2.52.0
>
> _______________________________________________
> dev mailing list
> [email protected]
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
>
Thank you Mark,

I've adjusted the test to include the LSP neutron option, with that applied
to main and backported down to 25.09.

Regards,
Ales
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to