From: Han Zhou <[email protected]> Processing transit switches and sync between INB, ISB and NB.
Signed-off-by: Han Zhou <[email protected]> --- ic/ovn-ic.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++ northd/ovn-northd.c | 8 ++++ 2 files changed, 121 insertions(+) diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c index 59f798d..4de3e17 100644 --- a/ic/ovn-ic.c +++ b/ic/ovn-ic.c @@ -126,11 +126,124 @@ az_run(struct ic_context *ctx) return NULL; } +static uint32_t +allocate_ts_dp_key(struct hmap *dp_tnlids) +{ + static uint32_t hint = OVN_MIN_DP_KEY_GLOBAL; + return ovn_allocate_tnlid(dp_tnlids, "transit switch datapath", + OVN_MIN_DP_KEY_GLOBAL, OVN_MAX_DP_KEY_GLOBAL, + &hint); +} + +static void +ts_run(struct ic_context *ctx) +{ + const struct inbrec_transit_switch *ts; + + /* Sync INB TS to AZ NB */ + if (ctx->ovnnb_txn) { + struct shash nb_tses = SHASH_INITIALIZER(&nb_tses); + const struct nbrec_logical_switch *ls; + + /* Get current NB Logical_Switch with other_config:interconn-ts */ + NBREC_LOGICAL_SWITCH_FOR_EACH (ls, ctx->ovnnb_idl) { + const char *ts_name = smap_get(&ls->other_config, "interconn-ts"); + if (ts_name) { + shash_add(&nb_tses, ts_name, ls); + } + } + + /* Create NB Logical_Switch for each TS */ + INBREC_TRANSIT_SWITCH_FOR_EACH (ts, ctx->ovninb_idl) { + ls = shash_find_and_delete(&nb_tses, ts->name); + if (!ls) { + ls = nbrec_logical_switch_insert(ctx->ovnnb_txn); + nbrec_logical_switch_set_name(ls, ts->name); + nbrec_logical_switch_update_other_config_setkey(ls, + "interconn-ts", + ts->name); + } + } + + /* Delete extra NB Logical_Switch with other_config:interconn-ts */ + struct shash_node *node; + SHASH_FOR_EACH (node, &nb_tses) { + nbrec_logical_switch_delete(node->data); + } + shash_destroy(&nb_tses); + } + + struct hmap dp_tnlids = HMAP_INITIALIZER(&dp_tnlids); + struct shash isb_dps = SHASH_INITIALIZER(&isb_dps); + const struct isbrec_datapath_binding *isb_dp; + ISBREC_DATAPATH_BINDING_FOR_EACH (isb_dp, ctx->ovnisb_idl) { + shash_add(&isb_dps, isb_dp->transit_switch, isb_dp); + ovn_add_tnlid(&dp_tnlids, isb_dp->tunnel_key); + } + + /* Sync ISB TS tunnel key to AZ SB datapath. (AZ SB datapath is created by + * northd.) */ + if (ctx->ovnsb_txn) { + const struct sbrec_datapath_binding *sb_dp; + SBREC_DATAPATH_BINDING_FOR_EACH (sb_dp, ctx->ovnsb_idl) { + const char *ts_name = smap_get(&sb_dp->external_ids, + "interconn-ts"); + if (ts_name) { + isb_dp = shash_find_data(&isb_dps, ts_name); + if (!isb_dp) { + VLOG_DBG("SB datapath "UUID_FMT" with interconn-ts %s not " + "found in ISB, ignore.", + UUID_ARGS(&sb_dp->header_.uuid), + ts_name); + continue; + } + sbrec_datapath_binding_set_tunnel_key(sb_dp, + isb_dp->tunnel_key); + } + } + } + + /* Sync TS between INB and ISB. This is performed after syncing with AZ + * SB, to avoid uncommitted ISB datapath tunnel key to be synced back to + * AZ. */ + if (ctx->ovnisb_txn) { + /* Create ISB Datapath_Binding */ + INBREC_TRANSIT_SWITCH_FOR_EACH (ts, ctx->ovninb_idl) { + isb_dp = shash_find_and_delete(&isb_dps, ts->name); + if (!isb_dp) { + /* Allocate tunnel key */ + int64_t dp_key = allocate_ts_dp_key(&dp_tnlids); + if (!dp_key) { + continue; + } + + isb_dp = isbrec_datapath_binding_insert(ctx->ovnisb_txn); + isbrec_datapath_binding_set_transit_switch(isb_dp, ts->name); + isbrec_datapath_binding_set_tunnel_key(isb_dp, dp_key); + } + } + + /* Delete extra ISB Datapath_Binding */ + struct shash_node *node; + SHASH_FOR_EACH (node, &isb_dps) { + isbrec_datapath_binding_delete(node->data); + } + } + ovn_destroy_tnlids(&dp_tnlids); + shash_destroy(&isb_dps); +} + static void ovn_db_run(struct ic_context *ctx) { const struct isbrec_availability_zone *az = az_run(ctx); VLOG_DBG("Availability zone: %s", az ? az->name : "not created yet."); + + if (!az) { + return; + } + + ts_run(ctx); } static void diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index f99adfb..32d70f8 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -823,6 +823,14 @@ ovn_datapath_update_external_ids(struct ovn_datapath *od) if (name2 && name2[0]) { smap_add(&ids, "name2", name2); } + + /* Set interconn-ts. */ + if (od->nbs) { + const char *ts = smap_get(&od->nbs->other_config, "interconn-ts"); + if (ts) { + smap_add(&ids, "interconn-ts", ts); + } + } sbrec_datapath_binding_set_external_ids(od->sb, &ids); smap_destroy(&ids); } -- 2.1.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
