Hi Ales,

Thanks for the fix!

On 8/29/25 4:06 PM, Ales Musil wrote:
> Unfortunately the previous fix wasn't enough, when we call
> "sbrec_static_mac_binding_table_get_for_uuid()" it will still return
> row even if was marked as deleted in the current transaction. This

That's a bit unfortunate in my opinion.  It makes it harder to use
get_for_uuid() in the context of incremental processing.  Ilya, should
we consider changing the semantics of *_table_get_for_uuid()?

> would cause the Static MAC binding to be removed in one txn and added
> in other one, causing traffic disruptions. To properly handle that
> update the datapath reference instead. This should do the update
> in a single transaction instead.
> 
> Fixes: e8a0ade51cc1 ("northd: Remove stale Static MAC Bindings during SB 
> datapath re-creation.")
> Suggested-by: Ilya Maximets <[email protected]>
> Signed-off-by: Ales Musil <[email protected]>
> ---
>  northd/northd.c | 61 ++++++++++++++++++++-----------------------------
>  1 file changed, 25 insertions(+), 36 deletions(-)
> 
> diff --git a/northd/northd.c b/northd/northd.c
> index e0a329a17..3456e2918 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -2867,19 +2867,6 @@ common:
>      }
>  }
>  
> -static bool
> -mac_binding_is_stale(const struct hmap *lr_datapaths,
> -                     const struct hmap *lr_ports,
> -                     const struct sbrec_datapath_binding *dp,
> -                     const char *logical_port)
> -{
> -    const struct ovn_datapath *od =
> -        ovn_datapath_from_sbrec(NULL, lr_datapaths, dp);
> -
> -    return !od || ovn_datapath_is_stale(od) ||
> -           !ovn_port_find(lr_ports, logical_port);
> -}
> -
>  /* Remove mac_binding entries that refer to logical_ports which are
>   * deleted. */
>  static void
> @@ -2889,8 +2876,11 @@ cleanup_mac_bindings(
>  {
>      const struct sbrec_mac_binding *b;
>      SBREC_MAC_BINDING_TABLE_FOR_EACH_SAFE (b, sbrec_mac_binding_table) {
> -        if (mac_binding_is_stale(lr_datapaths, lr_ports, b->datapath,
> -                                 b->logical_port)) {
> +        const struct ovn_datapath *od =
> +            ovn_datapath_from_sbrec(NULL, lr_datapaths, b->datapath);
> +
> +        if (!od || ovn_datapath_is_stale(od) ||
> +            !ovn_port_find(lr_ports, b->logical_port)) {
>              sbrec_mac_binding_delete(b);
>          }
>      }
> @@ -18860,34 +18850,19 @@ build_static_mac_binding_table(
>      struct ovsdb_idl_txn *ovnsb_txn,
>      const struct nbrec_static_mac_binding_table *nbrec_static_mb_table,
>      const struct sbrec_static_mac_binding_table *sbrec_static_mb_table,
> -    const struct hmap *lr_datapaths, const struct hmap *lr_ports)
> +    const struct hmap *lr_ports)
>  {
> -    /* Cleanup SB Static_MAC_Binding entries which do not have corresponding
> -     * NB Static_MAC_Binding entries, and SB Static_MAC_Binding entries for
> -     * which there is not a NB Logical_Router_Port of the same name or
> -     * entries which SB Datapath_Binding reference is considered
> -     * stale/removed. */
> -    const struct nbrec_static_mac_binding *nb_smb;
> +    struct hmapx stale = HMAPX_INITIALIZER(&stale);
>      const struct sbrec_static_mac_binding *sb_smb;
>      SBREC_STATIC_MAC_BINDING_TABLE_FOR_EACH_SAFE (sb_smb,

Nit: this can be SBREC_STATIC_MAC_BINDING_TABLE_FOR_EACH() now.

>          sbrec_static_mb_table) {
> -        nb_smb = nbrec_static_mac_binding_table_get_for_uuid(
> -            nbrec_static_mb_table, &sb_smb->header_.uuid);
> -        if (!nb_smb) {
> -            sbrec_static_mac_binding_delete(sb_smb);
> -            continue;
> -        }
> -
> -        if (mac_binding_is_stale(lr_datapaths, lr_ports, sb_smb->datapath,
> -                                 sb_smb->logical_port)) {
> -            sbrec_static_mac_binding_delete(sb_smb);
> -        }
> +        hmapx_add(&stale, CONST_CAST(void *, sb_smb));
>      }
>  
>      /* Create/Update SB Static_MAC_Binding entries with corresponding values
>       * from NB Static_MAC_Binding entries. */
> -    NBREC_STATIC_MAC_BINDING_TABLE_FOR_EACH (
> -        nb_smb, nbrec_static_mb_table) {
> +    const struct nbrec_static_mac_binding *nb_smb;
> +    NBREC_STATIC_MAC_BINDING_TABLE_FOR_EACH (nb_smb, nbrec_static_mb_table) {
>          struct ovn_port *op = ovn_port_find(lr_ports, nb_smb->logical_port);
>          if (op && op->nbrp) {
>              struct ovn_datapath *od = op->od;
> @@ -18909,6 +18884,11 @@ build_static_mac_binding_table(
>                      sbrec_static_mac_binding_set_datapath(mb, 
> od->sdp->sb_dp);
>                  } else {
>                      /* Update existing entry if there is a change*/
> +                    if (mb->datapath != od->sdp->sb_dp) {
> +                        sbrec_static_mac_binding_set_datapath(
> +                            mb, od->sdp->sb_dp);
> +                    }
> +
>                      if (strcmp(mb->mac, nb_smb->mac)) {
>                          sbrec_static_mac_binding_set_mac(mb, nb_smb->mac);
>                      }
> @@ -18927,10 +18907,19 @@ build_static_mac_binding_table(
>                          sbrec_static_mac_binding_set_override_dynamic_mac(mb,
>                              nb_smb->override_dynamic_mac);
>                      }
> +
> +                    hmapx_find_and_delete(&stale, mb);
>                  }
>              }
>          }
>      }
> +
> +    /* Cleanup SB Static_MAC_Binding entries which are no longer needed. */
> +    struct hmapx_node *node;
> +    HMAPX_FOR_EACH (node, &stale) {
> +        sbrec_static_mac_binding_delete(node->data);
> +    }
> +    hmapx_destroy(&stale);
>  }
>  
>  static void
> @@ -19209,7 +19198,7 @@ ovnnb_db_run(struct northd_input *input_data,
>      build_static_mac_binding_table(ovnsb_txn,
>          input_data->nbrec_static_mac_binding_table,
>          input_data->sbrec_static_mac_binding_table,
> -        &data->lr_datapaths.datapaths, &data->lr_ports);
> +        &data->lr_ports);
>      stopwatch_stop(BUILD_LFLOWS_CTX_STOPWATCH_NAME, time_msec());
>      stopwatch_start(CLEAR_LFLOWS_CTX_STOPWATCH_NAME, time_msec());
>  

With the small nit addressed:

Acked-by: Dumitru Ceara <[email protected]>

Regards,
Dumitru

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

Reply via email to