On 8/6/25 7:40 PM, Mark Michelson via dev wrote:
> Calling sbrec_datapath_binding_insert() returns a pointer to the
> datapath binding that will be inserted once the transaction is
> committed. This pointer is only valid until the point the transaction is
> committed. At that point, the IDL will free the pointer and it is no
> longer valid. Caching this pointer, therefore, is dangerous, since you
> could be holding a pointer to freed data. Once the IDL runs again, it
> will provide a permanent pointer to the datapath binding, which is safe
> to cache.
>
> This patch introduces a wrapper structure, ovn_datapath_binding. This
> wrapper structure is safe to cache since it is not deleted by the IDL.
> The inner sbrec_datapath_binding pointer can be updated by datapath
> syncing nodes when the IDL provides a new datapath binding pointer.
>
> This particular patch does nothing other than to introduce the structure
> and cache it where necessary. Upcoming commits will cause datapath
> syncing nodes to update their inner pointers as necessary, making
> downstream engine node caching safe.
>
> Signed-off-by: Mark Michelson <[email protected]>
> ---
> v13
> * This is the first version of the series with this patch.
> ---
Hi Mark,
> northd/aging.c | 8 ++---
> northd/datapath-sync.h | 21 ++++++++++++
> northd/en-advertised-route-sync.c | 10 +++---
> northd/en-datapath-logical-router.c | 4 ++-
> northd/en-datapath-logical-router.h | 3 +-
> northd/en-datapath-logical-switch.c | 4 ++-
> northd/en-datapath-logical-switch.h | 3 +-
> northd/en-multicast.c | 4 +--
> northd/en-port-group.c | 2 +-
> northd/lflow-mgr.c | 4 +--
> northd/northd.c | 50 ++++++++++++++---------------
> northd/northd.h | 2 +-
> 12 files changed, 71 insertions(+), 44 deletions(-)
>
> diff --git a/northd/aging.c b/northd/aging.c
> index aa62a90dc..6afeeacff 100644
> --- a/northd/aging.c
> +++ b/northd/aging.c
> @@ -412,7 +412,7 @@ en_mac_binding_aging_run(struct engine_node *node, void
> *data OVS_UNUSED)
> HMAP_FOR_EACH (od, key_node, &northd_data->lr_datapaths.datapaths) {
> ovs_assert(od->nbr);
>
> - if (!od->sb) {
> + if (!od->dp->sb_dp) {
> continue;
> }
>
> @@ -425,7 +425,7 @@ en_mac_binding_aging_run(struct engine_node *node, void
> *data OVS_UNUSED)
>
> aging_context_set_threshold(&ctx, &threshold_config);
>
> - mac_binding_aging_run_for_datapath(od->sb,
> + mac_binding_aging_run_for_datapath(od->dp->sb_dp,
> sbrec_mac_binding_by_datapath,
> &ctx);
> threshold_config_destroy(&threshold_config);
> @@ -544,7 +544,7 @@ en_fdb_aging_run(struct engine_node *node, void *data
> OVS_UNUSED)
> HMAP_FOR_EACH (od, key_node, &northd_data->ls_datapaths.datapaths) {
> ovs_assert(od->nbs);
>
> - if (!od->sb) {
> + if (!od->dp->sb_dp) {
> continue;
> }
>
> @@ -553,7 +553,7 @@ en_fdb_aging_run(struct engine_node *node, void *data
> OVS_UNUSED)
> threshold_config.default_threshold =
> smap_get_uint(&od->nbs->other_config, "fdb_age_threshold", 0);
> aging_context_set_threshold(&ctx, &threshold_config);
> - fdb_run_for_datapath(od->sb, sbrec_fdb_by_dp_key, &ctx);
> + fdb_run_for_datapath(od->dp->sb_dp, sbrec_fdb_by_dp_key, &ctx);
>
> if (aging_context_is_at_limit(&ctx)) {
> /* Schedule the next run after specified delay. */
> diff --git a/northd/datapath-sync.h b/northd/datapath-sync.h
> index 246500c7b..aa374dd15 100644
> --- a/northd/datapath-sync.h
> +++ b/northd/datapath-sync.h
> @@ -74,6 +74,27 @@ struct ovn_synced_datapaths {
> struct hmap synced_dps;
> };
>
> +/* This is a simple wrapper for a southbound datapath binding. Its purpose
> + * is to allow for engine nodes to cache datapath binding pointers safely.
> + *
> + * When an sbrec_datapath_binding is inserted into the southbound
> + * database, the pointer from sbrec_datapath_binding_insert() is not
> + * safe to cache. The pointer is freed when the IDL loop is run and
> + * the transaction is committed. Once the next IDL loop is run and the
> + * southbound database sends an update message with the newly-inserted
> + * datapath binding, the pointer provided by the IDL is now safe to cache
> + * until the datapath binding is deleted.
> + *
> + * Engine nodes can safely cache an ovn_datapath_binding, though. The
> + * reason is that datapath syncing nodes will update the inner sb_dp
> + * pointer to be the permanent version of the pointer once the IDL
> + * provides the pointer. So long as the outer ovn_datapath_binding is
> + * what is cached, it is perfectly safe.
> + */
> +struct ovn_datapath_binding {
> + const struct sbrec_datapath_binding *sb_dp;
> +};
> +
As discussed a bit offline, we could just use pointers to 'struct
ovn_synced_datapath' instead. We have them available every time we
create 'struct ovn_datapath' and they're (a bit more than) wrappers on
top of raw 'const struct sbrec_datapath_binding *'.
> struct ovn_unsynced_datapath *ovn_unsynced_datapath_alloc(
> const char *name, enum ovn_datapath_type type,
> uint32_t requested_tunnel_key, const struct ovsdb_idl_row *nb_row);
> diff --git a/northd/en-advertised-route-sync.c
> b/northd/en-advertised-route-sync.c
> index e75ab15c5..b2eeefa85 100644
> --- a/northd/en-advertised-route-sync.c
> +++ b/northd/en-advertised-route-sync.c
> @@ -56,7 +56,7 @@ ar_entry_add_nocopy(struct hmap *routes, const struct
> ovn_datapath *od,
> route_e->ip_prefix = ip_prefix;
> route_e->tracked_port = tracked_port;
> route_e->source = source;
> - uint32_t hash = uuid_hash(&od->sb->header_.uuid);
> + uint32_t hash = uuid_hash(&od->dp->sb_dp->header_.uuid);
> hash = hash_string(op->sb->logical_port, hash);
> hash = hash_string(ip_prefix, hash);
> hmap_insert(routes, &route_e->hmap_node, hash);
> @@ -92,7 +92,7 @@ ar_entry_find(struct hmap *route_map,
>
> HMAP_FOR_EACH_WITH_HASH (route_e, hmap_node, hash, route_map) {
> if (!uuid_equals(&sb_db->header_.uuid,
> - &route_e->od->sb->header_.uuid)) {
> + &route_e->od->dp->sb_dp->header_.uuid)) {
> continue;
> }
> if (!uuid_equals(&logical_port->header_.uuid,
> @@ -281,7 +281,7 @@ build_nat_route_for_port(const struct ovn_port
> *advertising_op,
> ? ovn_port_find(ls_ports, nat->nb->logical_port)
> : nat->l3dgw_port;
>
> - if (!ar_entry_find(routes, advertising_od->sb, advertising_op->sb,
> + if (!ar_entry_find(routes, advertising_od->dp->sb_dp,
> advertising_op->sb,
> nat->nb->external_ip,
> tracked_port ? tracked_port->sb : NULL)) {
> ar_entry_add(routes, advertising_od, advertising_op,
> @@ -767,7 +767,7 @@ advertised_route_table_sync(
>
> const struct sbrec_port_binding *tracked_pb =
> route_e->tracked_port ? route_e->tracked_port->sb : NULL;
> - if (ar_entry_find(&sync_routes, route_e->od->sb, route_e->op->sb,
> + if (ar_entry_find(&sync_routes, route_e->od->dp->sb_dp,
> route_e->op->sb,
> route_e->ip_prefix, tracked_pb)) {
> /* We could already have advertised route entry for LRP IP that
> * corresponds to "snat" when "connected-as-host" is combined
> @@ -802,7 +802,7 @@ advertised_route_table_sync(
> HMAP_FOR_EACH_POP (route_e, hmap_node, &sync_routes) {
> const struct sbrec_advertised_route *sr =
> sbrec_advertised_route_insert(ovnsb_txn);
> - sbrec_advertised_route_set_datapath(sr, route_e->od->sb);
> + sbrec_advertised_route_set_datapath(sr, route_e->od->dp->sb_dp);
> sbrec_advertised_route_set_logical_port(sr, route_e->op->sb);
> sbrec_advertised_route_set_ip_prefix(sr, route_e->ip_prefix);
> if (route_e->tracked_port) {
> diff --git a/northd/en-datapath-logical-router.c
> b/northd/en-datapath-logical-router.c
> index 86c3eb365..d15907d6b 100644
> --- a/northd/en-datapath-logical-router.c
> +++ b/northd/en-datapath-logical-router.c
> @@ -172,7 +172,9 @@ en_datapath_synced_logical_router_run(struct engine_node
> *node , void *data)
> *lr = (struct ovn_synced_logical_router) {
> .nb = CONTAINER_OF(sdp->nb_row, struct nbrec_logical_router,
> header_),
> - .sb = sdp->sb_dp,
> + .dp = (struct ovn_datapath_binding) {
> + .sb_dp = sdp->sb_dp,
> + }
> };
> hmap_insert(&router_map->synced_routers, &lr->hmap_node,
> uuid_hash(&lr->nb->header_.uuid));
> diff --git a/northd/en-datapath-logical-router.h
> b/northd/en-datapath-logical-router.h
> index 31e70fbf5..ce1b321e5 100644
> --- a/northd/en-datapath-logical-router.h
> +++ b/northd/en-datapath-logical-router.h
> @@ -18,6 +18,7 @@
> #define EN_DATAPATH_LOGICAL_ROUTER_H
>
> #include "lib/inc-proc-eng.h"
> +#include "datapath-sync.h"
> #include "openvswitch/hmap.h"
>
> void *en_datapath_logical_router_init(struct engine_node *,
> @@ -30,7 +31,7 @@ void en_datapath_logical_router_cleanup(void *data);
> struct ovn_synced_logical_router {
> struct hmap_node hmap_node;
> const struct nbrec_logical_router *nb;
> - const struct sbrec_datapath_binding *sb;
> + struct ovn_datapath_binding dp;
> };
>
> struct ovn_synced_logical_router_map {
> diff --git a/northd/en-datapath-logical-switch.c
> b/northd/en-datapath-logical-switch.c
> index 23fa9725f..3a6cd2e0a 100644
> --- a/northd/en-datapath-logical-switch.c
> +++ b/northd/en-datapath-logical-switch.c
> @@ -166,7 +166,9 @@ en_datapath_synced_logical_switch_run(struct engine_node
> *node , void *data)
> *lsw = (struct ovn_synced_logical_switch) {
> .nb = CONTAINER_OF(sdp->nb_row, struct nbrec_logical_switch,
> header_),
> - .sb = sdp->sb_dp,
> + .dp = (struct ovn_datapath_binding) {
> + .sb_dp = sdp->sb_dp,
> + },
> };
> hmap_insert(&switch_map->synced_switches, &lsw->hmap_node,
> uuid_hash(&lsw->nb->header_.uuid));
> diff --git a/northd/en-datapath-logical-switch.h
> b/northd/en-datapath-logical-switch.h
> index 1bd5fea83..55928d705 100644
> --- a/northd/en-datapath-logical-switch.h
> +++ b/northd/en-datapath-logical-switch.h
> @@ -18,6 +18,7 @@
> #define EN_DATAPATH_LOGICAL_SWITCH_H
>
> #include "lib/inc-proc-eng.h"
> +#include "datapath-sync.h"
> #include "openvswitch/hmap.h"
>
> void *en_datapath_logical_switch_init(struct engine_node *,
> @@ -30,7 +31,7 @@ void en_datapath_logical_switch_cleanup(void *data);
> struct ovn_synced_logical_switch {
> struct hmap_node hmap_node;
> const struct nbrec_logical_switch *nb;
> - const struct sbrec_datapath_binding *sb;
> + struct ovn_datapath_binding dp;
> };
>
> struct ovn_synced_logical_switch_map {
> diff --git a/northd/en-multicast.c b/northd/en-multicast.c
> index d51db557e..fb34c55f5 100644
> --- a/northd/en-multicast.c
> +++ b/northd/en-multicast.c
> @@ -434,7 +434,7 @@ sync_multicast_groups_to_sb(
> continue;
> }
>
> - sbmc = create_sb_multicast_group(ovnsb_txn, mc->datapath->sb,
> + sbmc = create_sb_multicast_group(ovnsb_txn, mc->datapath->dp->sb_dp,
> mc->group->name, mc->group->key);
> ovn_multicast_update_sbrec(mc, sbmc);
> }
> @@ -579,7 +579,7 @@ ovn_igmp_group_add(struct ovsdb_idl_index
> *sbrec_mcast_group_by_name_dp,
> const struct sbrec_multicast_group *mcgroup =
> mcast_group_lookup(sbrec_mcast_group_by_name_dp,
> address_s,
> - datapath->sb);
> + datapath->dp->sb_dp);
>
> igmp_group->datapath = datapath;
> igmp_group->address = *address;
> diff --git a/northd/en-port-group.c b/northd/en-port-group.c
> index 4fc1a4f24..b2dd4aa59 100644
> --- a/northd/en-port-group.c
> +++ b/northd/en-port-group.c
> @@ -255,7 +255,7 @@ ls_port_group_process(struct ls_port_group_table
> *ls_port_groups,
> struct ls_port_group *ls_pg =
> ls_port_group_table_find(ls_port_groups, od->nbs);
> if (!ls_pg) {
> - ls_pg = ls_port_group_create(ls_port_groups, od->nbs, od->sb);
> + ls_pg = ls_port_group_create(ls_port_groups, od->nbs,
> od->dp->sb_dp);
> }
>
> struct ls_port_group_record *ls_pg_rec =
> diff --git a/northd/lflow-mgr.c b/northd/lflow-mgr.c
> index 18b88cf9e..28156c1e1 100644
> --- a/northd/lflow-mgr.c
> +++ b/northd/lflow-mgr.c
> @@ -1118,7 +1118,7 @@ sync_lflow_to_sb(struct ovn_lflow *lflow,
> }
>
> if (lflow->od) {
> - sbrec_logical_flow_set_logical_datapath(sbflow, lflow->od->sb);
> + sbrec_logical_flow_set_logical_datapath(sbflow,
> lflow->od->dp->sb_dp);
> sbrec_logical_flow_set_logical_dp_group(sbflow, NULL);
> } else {
> sbrec_logical_flow_set_logical_datapath(sbflow, NULL);
> @@ -1226,7 +1226,7 @@ ovn_sb_insert_or_update_logical_dp_group(
>
> sb = xmalloc(bitmap_count1(dpg_bitmap, ods_size(datapaths)) * sizeof
> *sb);
> BITMAP_FOR_EACH_1 (index, ods_size(datapaths), dpg_bitmap) {
> - sb[n++] = datapaths->array[index]->sb;
> + sb[n++] = datapaths->array[index]->dp->sb_dp;
> }
> if (!dp_group) {
> struct uuid dpg_uuid = uuid_random();
> diff --git a/northd/northd.c b/northd/northd.c
> index 4d5ed6701..992c18d23 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -518,11 +518,11 @@ static struct ovn_datapath *
> ovn_datapath_create(struct hmap *datapaths, const struct uuid *key,
> const struct nbrec_logical_switch *nbs,
> const struct nbrec_logical_router *nbr,
> - const struct sbrec_datapath_binding *sb)
> + const struct ovn_datapath_binding *dp)
> {
> struct ovn_datapath *od = xzalloc(sizeof *od);
> od->key = *key;
> - od->sb = sb;
> + od->dp = dp;
> od->nbs = nbs;
> od->nbr = nbr;
> hmap_init(&od->port_tnlids);
> @@ -537,7 +537,7 @@ ovn_datapath_create(struct hmap *datapaths, const struct
> uuid *key,
> od->localnet_ports = VECTOR_EMPTY_INITIALIZER(struct ovn_port *);
> od->lb_with_stateless_mode = false;
> od->ipam_info_initialized = false;
> - od->tunnel_key = sb->tunnel_key;
> + od->tunnel_key = dp->sb_dp->tunnel_key;
> init_mcast_info_for_datapath(od);
> return od;
> }
> @@ -628,7 +628,7 @@ ovn_datapath_from_sbrec(const struct hmap *ls_datapaths,
> }
>
> struct ovn_datapath *od = ovn_datapath_find_(dps, &key);
> - if (od && (od->sb == sb)) {
> + if (od && (od->dp->sb_dp == sb)) {
> return od;
> }
>
> @@ -747,7 +747,7 @@ store_mcast_info_for_switch_datapath(const struct
> sbrec_ip_multicast *sb,
> {
> struct mcast_switch_info *mcast_sw_info = &od->mcast_info.sw;
>
> - sbrec_ip_multicast_set_datapath(sb, od->sb);
> + sbrec_ip_multicast_set_datapath(sb, od->dp->sb_dp);
> sbrec_ip_multicast_set_enabled(sb, &mcast_sw_info->enabled, 1);
> sbrec_ip_multicast_set_querier(sb, &mcast_sw_info->querier, 1);
> sbrec_ip_multicast_set_table_size(sb, &mcast_sw_info->table_size, 1);
> @@ -856,7 +856,7 @@ build_datapaths(const struct
> ovn_synced_logical_switch_map *ls_map,
> struct ovn_datapath *od =
> ovn_datapath_create(&ls_datapaths->datapaths,
> &ls->nb->header_.uuid,
> - ls->nb, NULL, ls->sb);
> + ls->nb, NULL, &ls->dp);
This is a problem because we pass a pointer to a field of 'ls' (struct
ovn_synced_logical_switch) and the 'ls' record gets freed before the
next incremental processing run. This results in use after free.
> init_ipam_info_for_datapath(od);
> if (smap_get_bool(&od->nbs->other_config,
> "enable-stateless-acl-with-lb",
> @@ -870,7 +870,7 @@ build_datapaths(const struct
> ovn_synced_logical_switch_map *ls_map,
> struct ovn_datapath *od =
> ovn_datapath_create(&lr_datapaths->datapaths,
> &lr->nb->header_.uuid,
> - NULL, lr->nb, lr->sb);
> + NULL, lr->nb, &lr->dp);
Same here.
That's mainly why the CI is red with this patch.
> if (smap_get(&od->nbr->options, "chassis")) {
> od->is_gw_router = true;
> }
> @@ -1441,7 +1441,7 @@ create_mirror_port(struct ovn_port *op, struct hmap
> *ports,
> struct ovs_list *both_dbs, struct ovs_list *nb_only,
> const struct nbrec_mirror *nb_mirror)
> {
> - char *mp_name = ovn_mirror_port_name(ovn_datapath_name(op->od->sb),
> + char *mp_name =
> ovn_mirror_port_name(ovn_datapath_name(op->od->dp->sb_dp),
> nb_mirror->sink);
> struct ovn_port *mp = ovn_port_find(ports, mp_name);
> struct ovn_port *target_port = ovn_port_find(ports, nb_mirror->sink);
> @@ -1485,7 +1485,7 @@ join_logical_ports_lsp(struct hmap *ports,
> = VLOG_RATE_LIMIT_INIT(5, 1);
> VLOG_WARN_RL(&rl, "duplicate logical port %s", name);
> return NULL;
> - } else if (op && (!op->sb || op->sb->datapath == od->sb)) {
> + } else if (op && (!op->sb || op->sb->datapath == od->dp->sb_dp)) {
> /*
> * Handle cases where lport type was explicitly changed
> * in the NBDB, in such cases:
> @@ -1582,7 +1582,7 @@ join_logical_ports_lrp(struct hmap *ports,
> name);
> destroy_lport_addresses(lrp_networks);
> return NULL;
> - } else if (op && (!op->sb || op->sb->datapath == od->sb)) {
> + } else if (op && (!op->sb || op->sb->datapath == od->dp->sb_dp)) {
> ovn_port_set_nb(op, NULL, nbrp);
> ovs_list_remove(&op->list);
> ovs_list_push_back(both, &op->list);
> @@ -1655,7 +1655,7 @@ create_cr_port(struct ovn_port *op, struct hmap *ports,
> op->nbsp ? op->nbsp->name : op->nbrp->name);
>
> struct ovn_port *crp = ovn_port_find(ports, redirect_name);
> - if (crp && crp->sb && crp->sb->datapath == op->od->sb) {
> + if (crp && crp->sb && crp->sb->datapath == op->od->dp->sb_dp) {
> ovn_port_set_nb(crp, op->nbsp, op->nbrp);
> ovs_list_remove(&crp->list);
> ovs_list_push_back(both_dbs, &crp->list);
> @@ -2513,7 +2513,7 @@ ovn_port_update_sbrec(struct ovsdb_idl_txn *ovnsb_txn,
> unsigned long *queue_id_bitmap,
> struct sset *active_ha_chassis_grps)
> {
> - sbrec_port_binding_set_datapath(op->sb, op->od->sb);
> + sbrec_port_binding_set_datapath(op->sb, op->od->dp->sb_dp);
> if (op->nbrp) {
> /* Note: SB port binding options for router ports are set in
> * sync_pbs(). */
> @@ -3829,7 +3829,7 @@ build_ports(struct ovsdb_idl_txn *ovnsb_txn,
> /* When reusing stale Port_Bindings, make sure that stale
> * Mac_Bindings are purged.
> */
> - if (op->od->sb != op->sb->datapath) {
> + if (op->od->dp->sb_dp != op->sb->datapath) {
> remove_mac_bindings = true;
> }
> if (op->nbsp) {
> @@ -5340,7 +5340,7 @@ build_mirror_lflows(struct ovn_port *op,
> }
>
> char *serving_port_name = ovn_mirror_port_name(
> - ovn_datapath_name(op->od->sb),
> + ovn_datapath_name(op->od->dp->sb_dp),
> mirror->sink);
>
> struct ovn_port *serving_port = ovn_port_find(ls_ports,
> @@ -18037,13 +18037,13 @@ lflow_handle_northd_port_changes(struct
> ovsdb_idl_txn *ovnsb_txn,
>
> const struct sbrec_multicast_group *sbmc_flood =
> mcast_group_lookup(lflow_input->sbrec_mcast_group_by_name_dp,
> - MC_FLOOD, op->od->sb);
> + MC_FLOOD, op->od->dp->sb_dp);
> const struct sbrec_multicast_group *sbmc_flood_l2 =
> mcast_group_lookup(lflow_input->sbrec_mcast_group_by_name_dp,
> - MC_FLOOD_L2, op->od->sb);
> + MC_FLOOD_L2, op->od->dp->sb_dp);
> const struct sbrec_multicast_group *sbmc_unknown =
> mcast_group_lookup(lflow_input->sbrec_mcast_group_by_name_dp,
> - MC_UNKNOWN, op->od->sb);
> + MC_UNKNOWN, op->od->dp->sb_dp);
>
> struct ds match = DS_EMPTY_INITIALIZER;
> struct ds actions = DS_EMPTY_INITIALIZER;
> @@ -18083,13 +18083,13 @@ lflow_handle_northd_port_changes(struct
> ovsdb_idl_txn *ovnsb_txn,
> /* Update SB multicast groups for the new port. */
> if (!sbmc_flood) {
> sbmc_flood = create_sb_multicast_group(ovnsb_txn,
> - op->od->sb, MC_FLOOD, OVN_MCAST_FLOOD_TUNNEL_KEY);
> + op->od->dp->sb_dp, MC_FLOOD, OVN_MCAST_FLOOD_TUNNEL_KEY);
> }
> sbrec_multicast_group_update_ports_addvalue(sbmc_flood, op->sb);
>
> if (!sbmc_flood_l2) {
> sbmc_flood_l2 = create_sb_multicast_group(ovnsb_txn,
> - op->od->sb, MC_FLOOD_L2,
> + op->od->dp->sb_dp, MC_FLOOD_L2,
> OVN_MCAST_FLOOD_L2_TUNNEL_KEY);
> }
> sbrec_multicast_group_update_ports_addvalue(sbmc_flood_l2, op->sb);
> @@ -18097,7 +18097,7 @@ lflow_handle_northd_port_changes(struct ovsdb_idl_txn
> *ovnsb_txn,
> if (op->has_unknown) {
> if (!sbmc_unknown) {
> sbmc_unknown = create_sb_multicast_group(ovnsb_txn,
> - op->od->sb, MC_UNKNOWN,
> + op->od->dp->sb_dp, MC_UNKNOWN,
> OVN_MCAST_UNKNOWN_TUNNEL_KEY);
> }
> sbrec_multicast_group_update_ports_addvalue(sbmc_unknown,
> @@ -18418,7 +18418,7 @@ sync_dns_entries(struct ovsdb_idl_txn *ovnsb_txn,
> dns_info->n_sbs++;
> dns_info->sbs = xrealloc(dns_info->sbs,
> dns_info->n_sbs * sizeof
> *dns_info->sbs);
> - dns_info->sbs[dns_info->n_sbs - 1] = od->sb;
> + dns_info->sbs[dns_info->n_sbs - 1] = od->dp->sb_dp;
> }
> }
>
> @@ -18535,7 +18535,7 @@ build_ip_mcast(struct ovsdb_idl_txn *ovnsb_txn,
> ovs_assert(od->nbs);
>
> const struct sbrec_ip_multicast *ip_mcast =
> - ip_mcast_lookup(sbrec_ip_mcast_by_dp, od->sb);
> + ip_mcast_lookup(sbrec_ip_mcast_by_dp, od->dp->sb_dp);
>
> if (!ip_mcast) {
> ip_mcast = sbrec_ip_multicast_insert(ovnsb_txn);
> @@ -18576,7 +18576,7 @@ build_static_mac_binding_table(
> }
>
> struct ovn_port *op = ovn_port_find(lr_ports, nb_smb->logical_port);
> - if (!op || !op->nbrp || !op->od || !op->od->sb) {
> + if (!op || !op->nbrp || !op->od || !op->od->dp->sb_dp) {
> sbrec_static_mac_binding_delete(sb_smb);
> }
> }
> @@ -18588,7 +18588,7 @@ build_static_mac_binding_table(
> struct ovn_port *op = ovn_port_find(lr_ports, nb_smb->logical_port);
> if (op && op->nbrp) {
> struct ovn_datapath *od = op->od;
> - if (od && od->sb) {
> + if (od && od->dp->sb_dp) {
> const struct uuid *nb_uuid = &nb_smb->header_.uuid;
> const struct sbrec_static_mac_binding *mb =
> sbrec_static_mac_binding_table_get_for_uuid(
> @@ -18603,7 +18603,7 @@ build_static_mac_binding_table(
> sbrec_static_mac_binding_set_mac(mb, nb_smb->mac);
> sbrec_static_mac_binding_set_override_dynamic_mac(mb,
> nb_smb->override_dynamic_mac);
> - sbrec_static_mac_binding_set_datapath(mb, od->sb);
> + sbrec_static_mac_binding_set_datapath(mb, od->dp->sb_dp);
> } else {
> /* Update existing entry if there is a change*/
> if (strcmp(mb->mac, nb_smb->mac)) {
> diff --git a/northd/northd.h b/northd/northd.h
> index 2f1b8ceb5..e223a54da 100644
> --- a/northd/northd.h
> +++ b/northd/northd.h
> @@ -369,7 +369,7 @@ struct ovn_datapath {
>
> const struct nbrec_logical_switch *nbs; /* May be NULL. */
> const struct nbrec_logical_router *nbr; /* May be NULL. */
> - const struct sbrec_datapath_binding *sb; /* May be NULL. */
> + const struct ovn_datapath_binding *dp; /* May be NULL. */
>
> struct ovs_list list; /* In list of similar records. */
>
Regards,
Dumitru
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev