On Wed, Oct 22, 2025 at 5:11 PM Mairtin O'Loingsigh via dev < [email protected]> wrote:
> This series extends ovn-ic to include support for transit routers. > The changes include new ovn-ic-nb commands to add and manipulate transit > routers and ports, schema updates and new tests. > Transit routers added using these new commands will have to same > tunnel-key across AZs. > > In the future I also want to create a new ovn-fake-multinode tests suite > similar to make check-multinode, but with ovn-ic enabled on the worker > chassis. > > v7: > - Use int64_t for tunnel_key. > - Don't free tunnel ID. > - Remove unnecessary shash_deletes. > - Move addition of port command to correct patch. > - Delay creation of Logical Router Port until ICSB port binding > transaction has completed successfully. > - Simplify Logical Router Port requested-tnl-key validation. > > v6: > - Revert transit switch changes releated to using nb_ic_uuid and type. > - Use SHASH_FOR_EACH instead of SHASH_FOR_EACH_SAFE. > - Use check instead of AT_CHECK. > - Remove unnecessary variable creation in nb-ic-ctl tests. > - Remove unnecessary OVS_UNUSED. > - Move config of datapath tunnel key to correct patch. > - Split create_isb_pb function due to reliance on sb_pb. > - Replace wait_row_count with check_row_count where possible. > > v5: > - Fix sync issues in tests. > > v4: > - Seperate collection of datapath tunnel ids from ts_run function. > - Remove ability to set requested-tnl-key manually. > - Split move of network parsing code into seperate patch. > - Add transit router port to transit router table in schema. > - Remove ic_trp_data struct and use shash instead. > - Remove ic_pb_info struct and use shash instead. > - Only support ports bound to a chassis. > - Add test for port network collision. > - Use wait_row_count instead of grep in tests. > > v3: > - Remove unrelated changes > - Fix coding standard violation > - Create a ICSB entry for every port > - Update schema versions. > - Set min number of types and nb_ic_uuid to zero. > - Remove changes releated to routes. > - Update ic-nbctl trp-add network parsing to match nbctl_lrp_add. > - Split patches > - Add ovn-ic-nbctl tests for transit router port. > > v2: > - Combine patches into a single patch > > Mairtin O'Loingsigh (4): > ic: Update schema to add Transit Router. > ic: Add Transit router support. > ovn-util: Add network and prefix parsing to utils. > ic: Add Transit Router port support. > > NEWS | 7 + > TODO.rst | 2 + > ic/ovn-ic.c | 563 ++++++++++++++++++++++++++++++++------- > lib/ovn-util.c | 101 +++++++ > lib/ovn-util.h | 14 + > ovn-architecture.7.xml | 10 +- > ovn-ic-nb.ovsschema | 36 ++- > ovn-ic-nb.xml | 70 +++++ > ovn-ic-sb.ovsschema | 23 +- > ovn-ic-sb.xml | 18 ++ > tests/ovn-ic-nbctl.at | 65 +++++ > tests/ovn-ic.at | 255 ++++++++++++++++++ > utilities/ovn-ic-nbctl.c | 326 ++++++++++++++++++++++- > utilities/ovn-nbctl.c | 98 ------- > 14 files changed, 1377 insertions(+), 211 deletions(-) > > -- > 2.51.0 > > _______________________________________________ > dev mailing list > [email protected] > https://mail.openvswitch.org/mailman/listinfo/ovs-dev > > Hi Mairtin, I would merge this into main with the following diff and your permission: diff --git a/NEWS b/NEWS index 4648d9d87..a17a61b41 100644 --- a/NEWS +++ b/NEWS @@ -44,7 +44,6 @@ Post v25.09.0 function and the chassis hosting the port where the ACL is being enforced). Proper MTU needs to be configured to accomodate this encapsulation. - - Added Transit Router support: * Support the creation of Transit Routers. * Added new ovn-ic-nbctl 'tr-add','tr-del','tr-list' commands to manage @@ -52,6 +51,7 @@ Post v25.09.0 * Support the creation of Transit Router Ports. * Added new ovn-ic-nbctl 'trp-add' and 'tpr-del' commands to manage Transit Router Ports. + OVN v25.09.0 - xxx xx xxxx -------------------------- - STT tunnels are no longer supported in ovn-encap-type. diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c index 43aca7ea7..16fb962f1 100644 --- a/ic/ovn-ic.c +++ b/ic/ovn-ic.c @@ -76,10 +76,8 @@ struct ic_context { struct ovsdb_idl_index *sbrec_service_monitor_by_remote_type_logical_port; struct ovsdb_idl_index *icnbrec_transit_switch_by_name; struct ovsdb_idl_index *icsbrec_port_binding_by_az; - struct ovsdb_idl_index *icsbrec_port_binding_by_tr; + struct ovsdb_idl_index *icsbrec_port_binding_by_ts; struct ovsdb_idl_index *icsbrec_port_binding_by_ts_az; - struct ovsdb_idl_index *icsbrec_port_binding_by_nb_ic_uuid; - struct ovsdb_idl_index *icsbrec_port_binding_by_nb_ic_uuid_type; struct ovsdb_idl_index *icsbrec_route_by_az; struct ovsdb_idl_index *icsbrec_route_by_ts; struct ovsdb_idl_index *icsbrec_route_by_ts_az; @@ -349,21 +347,6 @@ ts_run(struct ic_context *ctx, struct hmap *dp_tnlids, isb_dp = icsbrec_datapath_binding_insert(ctx->ovnisb_txn); icsbrec_datapath_binding_set_transit_switch(isb_dp, ts->name); icsbrec_datapath_binding_set_tunnel_key(isb_dp, dp_key); - icsbrec_datapath_binding_set_nb_ic_uuid(isb_dp, - &ts->header_.uuid, 1); - icsbrec_datapath_binding_set_type(isb_dp, "transit-switch"); - if (!isb_dp->type) { - icsbrec_datapath_binding_set_type(isb_dp, - "transit-switch"); - } - - if (!isb_dp->nb_ic_uuid) { - icsbrec_datapath_binding_set_nb_ic_uuid( - isb_dp, &ts->header_.uuid, 1); - } - - ovn_add_tnlid(dp_tnlids, isb_dp->tunnel_key); - } else if (dp_key_refresh) { /* Refresh tunnel key since encap mode has changed. */ int64_t dp_key = allocate_dp_key(dp_tnlids, vxlan_mode, @@ -372,11 +355,20 @@ ts_run(struct ic_context *ctx, struct hmap *dp_tnlids, icsbrec_datapath_binding_set_tunnel_key(isb_dp, dp_key); } } + + if (!isb_dp->type) { + icsbrec_datapath_binding_set_type(isb_dp, "transit-switch"); + } + + if (!isb_dp->nb_ic_uuid) { + icsbrec_datapath_binding_set_nb_ic_uuid(isb_dp, + &ts->header_.uuid, 1); + } } + struct shash_node *node; SHASH_FOR_EACH (node, isb_ts_dps) { - const struct icsbrec_datapath_binding *isb_dp = node->data; - icsbrec_datapath_binding_delete(isb_dp); + icsbrec_datapath_binding_delete(node->data); } } } @@ -436,6 +428,7 @@ tr_run(struct ic_context *ctx, struct hmap *dp_tnlids, struct icsbrec_datapath_binding *isb_dp = shash_find_and_delete(isb_tr_dps, uuid_str); free(uuid_str); + if (!isb_dp) { int dp_key = allocate_dp_key(dp_tnlids, false, "transit router datapath"); @@ -452,7 +445,7 @@ tr_run(struct ic_context *ctx, struct hmap *dp_tnlids, } struct shash_node *node; - SHASH_FOR_EACH_SAFE (node, isb_tr_dps) { + SHASH_FOR_EACH (node, isb_tr_dps) { icsbrec_datapath_binding_delete(node->data); } } @@ -777,7 +770,7 @@ sync_lrp_tnl_key(const struct nbrec_logical_router_port *lrp, if (tnl_key != isb_tnl_key) { VLOG_DBG("Set options:requested-tnl-key %" PRId64 " for lrp %s in NB.", isb_tnl_key, lrp->name); - char *tnl_key_str = xasprintf("%" PRId64, isb_tnl_key); + char *tnl_key_str = xasprintf("%"PRId64, isb_tnl_key); nbrec_logical_router_port_update_options_setkey( lrp, "requested-tnl-key", tnl_key_str); free(tnl_key_str); @@ -988,12 +981,6 @@ create_nb_lsp(struct ic_context *ctx, nbrec_logical_switch_update_ports_addvalue(ls, lsp); } -static const struct sbrec_port_binding * -find_lp_in_sb(struct ic_context *ctx, const char *name) -{ - return find_sb_pb_by_name(ctx->sbrec_port_binding_by_name, name); -} - static uint32_t allocate_port_key(struct hmap *pb_tnlids) { @@ -1009,7 +996,7 @@ create_isb_pb(struct ic_context *ctx, const char *logical_port, struct hmap *pb_tnlids) { uint32_t pb_tnl_key = allocate_port_key(pb_tnlids); - if (pb_tnl_key == 0) { + if (!pb_tnl_key) { return NULL; } @@ -1039,7 +1026,7 @@ get_lrp_by_lrp_name(struct ic_context *ctx, const char *lrp_name) } static bool -trp_port_is_remote(struct ic_context *ctx, const char *chassis_name) +trp_is_remote(struct ic_context *ctx, const char *chassis_name) { if (chassis_name) { const struct sbrec_chassis *chassis = @@ -1055,8 +1042,8 @@ trp_port_is_remote(struct ic_context *ctx, const char *chassis_name) } static struct nbrec_logical_router_port * -trp_port_create(struct ic_context *ctx, const struct nbrec_logical_router *lr, - const struct icnbrec_transit_router_port *trp) +lrp_create(struct ic_context *ctx, const struct nbrec_logical_router *lr, + const struct icnbrec_transit_router_port *trp) { struct nbrec_logical_router_port *lrp = nbrec_logical_router_port_insert(ctx->ovnnb_txn); @@ -1079,11 +1066,24 @@ sync_ts_isb_pb(struct ic_context *ctx, const struct sbrec_port_binding *sb_pb, const struct sbrec_port_binding *crp = find_crp_for_sb_pb(ctx, sb_pb); if (crp && crp->chassis) { - icsbrec_port_binding_set_gateway(isb_pb, - crp->chassis->name); + icsbrec_port_binding_set_gateway(isb_pb, crp->chassis->name); } update_isb_pb_external_ids(ctx, sb_pb, isb_pb); + + /* XXX: Sync encap so that multiple encaps can be used for the same + * gateway. However, it is not needed for now, since we don't yet + * support specifying encap type/ip for gateway chassis or ha-chassis + * for logical router port in NB DB, and now encap should always be + * empty. The sync can be added if we add such support for gateway + * chassis/ha-chassis in NB DB. */ +} + +static const struct sbrec_port_binding * +find_lsp_in_sb(struct ic_context *ctx, + const struct nbrec_logical_switch_port *lsp) +{ + return find_sb_pb_by_name(ctx->sbrec_port_binding_by_name, lsp->name); } static void @@ -1098,12 +1098,14 @@ port_binding_run(struct ic_context *ctx) struct shash router_all_local_pbs = SHASH_INITIALIZER(&router_all_local_pbs); struct hmap pb_tnlids = HMAP_INITIALIZER(&pb_tnlids); + struct shash_node *node; const struct icsbrec_port_binding *isb_pb; const struct icsbrec_port_binding *isb_pb_key = icsbrec_port_binding_index_init_row(ctx->icsbrec_port_binding_by_az); icsbrec_port_binding_index_set_availability_zone(isb_pb_key, ctx->runned_az); + ICSBREC_PORT_BINDING_FOR_EACH_EQUAL (isb_pb, isb_pb_key, ctx->icsbrec_port_binding_by_az) { ic_pb_get_type(isb_pb) != IC_ROUTER_PORT @@ -1126,20 +1128,17 @@ port_binding_run(struct ic_context *ctx) struct shash remote_pbs = SHASH_INITIALIZER(&remote_pbs); isb_pb_key = icsbrec_port_binding_index_init_row( - ctx->icsbrec_port_binding_by_nb_ic_uuid_type); - icsbrec_port_binding_index_set_nb_ic_uuid(isb_pb_key, - &ts->header_.uuid, 1); - icsbrec_port_binding_index_set_type(isb_pb_key, "transit-switch-port"); - ICSBREC_PORT_BINDING_FOR_EACH_EQUAL ( - isb_pb, isb_pb_key, ctx->icsbrec_port_binding_by_nb_ic_uuid_type) { + ctx->icsbrec_port_binding_by_ts); + icsbrec_port_binding_index_set_transit_switch(isb_pb_key, ts->name); + + ICSBREC_PORT_BINDING_FOR_EACH_EQUAL (isb_pb, isb_pb_key, + ctx->icsbrec_port_binding_by_ts) { if (isb_pb->availability_zone == ctx->runned_az) { + shash_add(&local_pbs, isb_pb->logical_port, isb_pb); shash_find_and_delete(&switch_all_local_pbs, isb_pb->logical_port); - shash_add(&local_pbs, isb_pb->logical_port, isb_pb); } else { - if (!shash_find_data(&remote_pbs, isb_pb->logical_port)) { - shash_add(&remote_pbs, isb_pb->logical_port, isb_pb); - } + shash_add(&remote_pbs, isb_pb->logical_port, isb_pb); } } icsbrec_port_binding_index_destroy_row(isb_pb_key); @@ -1151,11 +1150,10 @@ port_binding_run(struct ic_context *ctx) if (!strcmp(lsp->type, "router") || !strcmp(lsp->type, "switch")) { /* The port is local. */ - sb_pb = find_lp_in_sb(ctx, lsp->name); + sb_pb = find_lsp_in_sb(ctx, lsp); if (!sb_pb) { continue; } - isb_pb = shash_find_and_delete(&local_pbs, lsp->name); if (!isb_pb) { isb_pb = create_isb_pb( @@ -1165,13 +1163,23 @@ port_binding_run(struct ic_context *ctx) } else { sync_local_port(ctx, isb_pb, sb_pb, lsp); } + + if (isb_pb->type) { + icsbrec_port_binding_set_type(isb_pb, + "transit-switch-port"); + } + + if (isb_pb->nb_ic_uuid) { + icsbrec_port_binding_set_nb_ic_uuid(isb_pb, + &ts->header_.uuid, 1); + } } else if (!strcmp(lsp->type, "remote")) { /* The port is remote. */ isb_pb = shash_find_and_delete(&remote_pbs, lsp->name); if (!isb_pb) { nbrec_logical_switch_update_ports_delvalue(ls, lsp); } else { - sb_pb = find_lp_in_sb(ctx, lsp->name); + sb_pb = find_lsp_in_sb(ctx, lsp); if (!sb_pb) { continue; } @@ -1183,96 +1191,103 @@ port_binding_run(struct ic_context *ctx) } } - struct shash_node *node; - SHASH_FOR_EACH_SAFE (node, &local_pbs) { - isb_pb = node->data; - icsbrec_port_binding_delete(isb_pb); + /* Delete extra port-binding from ISB */ + SHASH_FOR_EACH (node, &local_pbs) { + icsbrec_port_binding_delete(node->data); } /* Create lsp in NB for remote ports */ - SHASH_FOR_EACH_SAFE (node, &remote_pbs) { - isb_pb = node->data; - create_nb_lsp(ctx, isb_pb, ls); + SHASH_FOR_EACH (node, &remote_pbs) { + create_nb_lsp(ctx, node->data, ls); } shash_destroy(&local_pbs); shash_destroy(&remote_pbs); } - struct shash_node *node; - SHASH_FOR_EACH_SAFE (node, &switch_all_local_pbs) { - isb_pb = node->data; - icsbrec_port_binding_delete(isb_pb); + SHASH_FOR_EACH (node, &switch_all_local_pbs) { + icsbrec_port_binding_delete(node->data); } shash_destroy(&switch_all_local_pbs); const struct icnbrec_transit_router *tr; ICNBREC_TRANSIT_ROUTER_FOR_EACH (tr, ctx->ovninb_idl) { - struct shash nb_ports = SHASH_INITIALIZER(&nb_ports); const struct nbrec_logical_router *lr = find_tr_in_nb(ctx, tr->name); if (!lr) { VLOG_DBG("Transit router %s not found in NB.", tr->name); continue; } + struct shash nb_ports = SHASH_INITIALIZER(&nb_ports); + struct shash local_pbs = SHASH_INITIALIZER(&local_pbs); + struct shash remote_pbs = SHASH_INITIALIZER(&remote_pbs); + + for (size_t i = 0; i < lr->n_ports; i++) { + const struct nbrec_logical_router_port *lrp = lr->ports[i]; + shash_add(&nb_ports, lrp->name, lrp); + } + + isb_pb_key = icsbrec_port_binding_index_init_row( + ctx->icsbrec_port_binding_by_ts); + icsbrec_port_binding_index_set_transit_switch(isb_pb_key, tr->name); + + ICSBREC_PORT_BINDING_FOR_EACH_EQUAL (isb_pb, isb_pb_key, + ctx->icsbrec_port_binding_by_ts) { + if (isb_pb->availability_zone == ctx->runned_az) { + shash_add(&local_pbs, isb_pb->logical_port, isb_pb); + shash_find_and_delete(&router_all_local_pbs, + isb_pb->logical_port); + } else { + shash_add(&remote_pbs, isb_pb->logical_port, isb_pb); + } + } + icsbrec_port_binding_index_destroy_row(isb_pb_key); + for (size_t i = 0; i < tr->n_ports; i++) { const struct icnbrec_transit_router_port *trp = tr->ports[i]; - shash_add(&nb_ports, trp->name, trp); - isb_pb = shash_find_and_delete(&router_all_local_pbs, trp->name); - if (!isb_pb) { - if (!trp_port_is_remote(ctx, trp->chassis)) { + + if (trp_is_remote(ctx, trp->chassis)) { + isb_pb = shash_find_and_delete(&remote_pbs, trp->name); + } else { + isb_pb = shash_find_and_delete(&local_pbs, trp->name); + if (!isb_pb) { isb_pb = create_isb_pb(ctx, trp->name, ctx->runned_az, tr->name, &tr->header_.uuid, "transit-router-port", &pb_tnlids); icsbrec_port_binding_set_address(isb_pb, trp->mac); - continue; - } else { - isb_pb_key = icsbrec_port_binding_index_init_row( - ctx->icsbrec_port_binding_by_tr); - icsbrec_port_binding_index_set_transit_switch(isb_pb_key, - tr->name); - ICSBREC_PORT_BINDING_FOR_EACH_EQUAL ( - isb_pb, isb_pb_key, ctx->icsbrec_port_binding_by_tr) { - if (!strcmp(trp->name, isb_pb->logical_port)) { - break; - } - } - icsbrec_port_binding_index_destroy_row(isb_pb_key); } } + /* Don't allow remote ports to create NB LRP until ICSB entry is * created in the appropriate AZ. */ if (isb_pb) { const struct nbrec_logical_router_port *lrp = - get_lrp_by_lrp_name(ctx, trp->name); - + shash_find_and_delete(&nb_ports, trp->name); if (!lrp) { - lrp = trp_port_create(ctx, lr, trp); + lrp = lrp_create(ctx, lr, trp); } sync_router_port(isb_pb, trp, lrp); } } - for (size_t i = 0; i < lr->n_ports; i++) { - const struct nbrec_logical_router_port *lrp = lr->ports[i]; - if (!shash_find_and_delete(&nb_ports, lrp->name) && - smap_get(&lrp->options, "interconn-tr")) { - nbrec_logical_router_port_delete(lrp); - nbrec_logical_router_update_ports_delvalue(lr, lrp); - } + SHASH_FOR_EACH(node, &nb_ports) { + nbrec_logical_router_port_delete(node->data); + nbrec_logical_router_update_ports_delvalue(lr, node->data); } shash_destroy(&nb_ports); + shash_destroy(&local_pbs); + shash_destroy(&remote_pbs); } - ovn_destroy_tnlids(&pb_tnlids); - SHASH_FOR_EACH_SAFE (node, &router_all_local_pbs) { - isb_pb = node->data; - icsbrec_port_binding_delete(isb_pb); - shash_delete(&router_all_local_pbs, node); + SHASH_FOR_EACH (node, &router_all_local_pbs) { + icsbrec_port_binding_delete(node->data); } + ovn_destroy_tnlids(&pb_tnlids); shash_destroy(&router_all_local_pbs); } @@ -3091,16 +3106,7 @@ ovn_db_run(struct ic_context *ctx) sync_service_monitor(ctx); ovn_destroy_tnlids(&dp_tnlids); - - struct shash_node *node; - SHASH_FOR_EACH_SAFE (node, &isb_ts_dps) { - shash_delete(&isb_ts_dps, node); - } shash_destroy(&isb_ts_dps); - - SHASH_FOR_EACH_SAFE (node, &isb_tr_dps) { - shash_delete(&isb_tr_dps, node); - } shash_destroy(&isb_tr_dps); } @@ -3507,18 +3513,14 @@ main(int argc, char *argv[]) = ovsdb_idl_index_create1(ovnisb_idl_loop.idl, &icsbrec_port_binding_col_availability_zone); - struct ovsdb_idl_index *icsbrec_port_binding_by_tr + struct ovsdb_idl_index *icsbrec_port_binding_by_ts = ovsdb_idl_index_create1(ovnisb_idl_loop.idl, &icsbrec_port_binding_col_transit_switch); - struct ovsdb_idl_index *icsbrec_port_binding_by_nb_ic_uuid = - ovsdb_idl_index_create1(ovnisb_idl_loop.idl, - &icsbrec_port_binding_col_nb_ic_uuid); - - struct ovsdb_idl_index *icsbrec_port_binding_by_nb_ic_uuid_type = - ovsdb_idl_index_create2(ovnisb_idl_loop.idl, - &icsbrec_port_binding_col_nb_ic_uuid, - &icsbrec_port_binding_col_type); + struct ovsdb_idl_index *icsbrec_port_binding_by_ts_az + = ovsdb_idl_index_create2(ovnisb_idl_loop.idl, + &icsbrec_port_binding_col_transit_switch, + &icsbrec_port_binding_col_availability_zone); struct ovsdb_idl_index *icsbrec_route_by_az = ovsdb_idl_index_create1(ovnisb_idl_loop.idl, @@ -3607,11 +3609,8 @@ main(int argc, char *argv[]) .icnbrec_transit_switch_by_name = icnbrec_transit_switch_by_name, .icsbrec_port_binding_by_az = icsbrec_port_binding_by_az, - .icsbrec_port_binding_by_tr = icsbrec_port_binding_by_tr, - .icsbrec_port_binding_by_nb_ic_uuid = - icsbrec_port_binding_by_nb_ic_uuid, - .icsbrec_port_binding_by_nb_ic_uuid_type = - icsbrec_port_binding_by_nb_ic_uuid_type, + .icsbrec_port_binding_by_ts = icsbrec_port_binding_by_ts, + .icsbrec_port_binding_by_ts_az = icsbrec_port_binding_by_ts_az, .icsbrec_route_by_az = icsbrec_route_by_az, .icsbrec_route_by_ts = icsbrec_route_by_ts, .icsbrec_route_by_ts_az = icsbrec_route_by_ts_az, diff --git a/ovn-ic-sb.ovsschema b/ovn-ic-sb.ovsschema index a11c9a333..8981a4eef 100644 --- a/ovn-ic-sb.ovsschema +++ b/ovn-ic-sb.ovsschema @@ -1,7 +1,7 @@ { "name": "OVN_IC_Southbound", - "version": "2.3.0", - "cksum": "3834405974 9713", + "version": "2.4.0", + "cksum": "859073048 9662", "tables": { "IC_SB_Global": { "columns": { @@ -73,7 +73,7 @@ "external_ids": { "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}}}, - "indexes": [["nb_ic_uuid","tunnel_key"]], + "indexes": [["nb_ic_uuid", "tunnel_key"]], "isRoot": true}, "Port_Binding": { "columns": { @@ -103,8 +103,7 @@ "value": "string", "min": 0, "max": "unlimited"}}}, - "indexes": [["transit_switch", "nb_ic_uuid", "tunnel_key"], - ["nb_ic_uuid", "logical_port"]], + "indexes": [["transit_switch", "tunnel_key"], ["logical_port"]], "isRoot": true}, "Route": { "columns": { diff --git a/ovn-ic-sb.xml b/ovn-ic-sb.xml index a2a7d13d8..b59fe1d03 100644 --- a/ovn-ic-sb.xml +++ b/ovn-ic-sb.xml @@ -208,9 +208,13 @@ </p> <column name="transit_switch"> - The name of the transit logical switch that is configured in the OVN - Interconnection Northbound database's <ref table="Transit_Switch" + The name of the transit logical switch or router that is configured in + the OVN Interconnection Northbound database's <ref table="Transit_Switch" + db="OVN_IC_Northbound"/> or <ref table="Transit_Router" db="OVN_IC_Northbound"/> table. + + Note: The name of transit router is stored in the same column due to + the backward compatibility. </column> <column name="type"> diff --git a/utilities/ovn-ic-nbctl.c b/utilities/ovn-ic-nbctl.c index 24d376559..94d63bd2f 100644 --- a/utilities/ovn-ic-nbctl.c +++ b/utilities/ovn-ic-nbctl.c @@ -494,8 +494,9 @@ ic_nbctl_ts_del(struct ctl_context *ctx) const char *id = ctx->argv[1]; const struct icnbrec_transit_switch *ts = NULL; - ctx->error = ts_by_name_or_uuid(ctx, id, must_exist, &ts); - if (ctx->error) { + char *error = ts_by_name_or_uuid(ctx, id, must_exist, &ts); + if (error) { + ctx->error = error; return; } if (!ts) { Regards, Ales _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
