On Mon, Jun 22, 2026 at 09:46:17AM +0200, Ales Musil wrote: > On Fri, Jun 19, 2026 at 2:32 PM Mairtin O'Loingsigh <[email protected]> > wrote: > > > Enable the creation and management of transit switch ports, when > > created, these ports are available across multiple AZs and may share > > port binding depending on configuration. This patch also includes tests > > and a multinode test. > > > > Commands to add, set address and delete port > > ovn-ic-nbctl tsp-add ts0 ts0-p0 chassis=chassis > > ovn-ic-nbctl tsp-set-addr ts0-p0 "00:11:22:11:22:34 > > 192.168.10.11/24" > > ovn-ic-nbctl tsp-del ts0-p0 > > > > Reported-at: https://issues.redhat.com/browse/FDP-2878 > > Signed-off-by: Mairtin O'Loingsigh <[email protected]> > > --- > > > > Hi Mairtin, > > thank you for the v8. I think this still requires a few changes. > I suggest the following diff, if you agree I will apply it > with the diff to main: > > diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c > index e9ad422c6..f07e74866 100644 > --- a/ic/ovn-ic.c > +++ b/ic/ovn-ic.c > @@ -826,17 +826,18 @@ update_isb_pb_external_ids(struct ic_context *ctx, > > /* Sync a local port's fields from TSP INB->ISB. */ > static void > -sync_tsp_port(struct ic_context *ctx, > - const struct icnbrec_transit_switch_port *tsp, > - const struct icsbrec_port_binding *isb_pb, > - const struct nbrec_logical_switch_port *lsp) > +sync_tsp_pb(const struct icnbrec_transit_switch_port *tsp, > + const struct icsbrec_port_binding *isb_pb) > { > + if (!isb_pb) { > + return; > + } > + > /* Sync address to ISB. */ > - if (!tsp->n_addresses) { > - if (isb_pb->address[0]) { > - icsbrec_port_binding_set_address(isb_pb, ""); > - } > - } else if (strcmp(tsp->addresses[0], isb_pb->address)) { > + if (!tsp->n_addresses && isb_pb->address[0]) { > + icsbrec_port_binding_set_address(isb_pb, ""); > + } else if (tsp->n_addresses && > + strcmp(tsp->addresses[0], isb_pb->address)) { > icsbrec_port_binding_set_address(isb_pb, tsp->addresses[0]); > } > > @@ -844,49 +845,6 @@ sync_tsp_port(struct ic_context *ctx, > if (strcmp(tsp->chassis, isb_pb->gateway)) { > icsbrec_port_binding_set_gateway(isb_pb, tsp->chassis); > } > - > - /* Sync router-id information to ISB. */ > - struct uuid uuid; > - if (!strcmp(tsp->type, "router")) { > - if (tsp->peer[0]) { > - const struct nbrec_logical_router *lr = NULL; > - const struct nbrec_logical_router *iter = NULL; > - NBREC_LOGICAL_ROUTER_FOR_EACH (iter, ctx->ovnnb_idl) { > - for (size_t i = 0; i < iter->n_ports; i++) { > - if (!strcmp(tsp->peer, iter->ports[i]->name)) { > - lr = iter; > - break; > - } > - } > - if (lr) { > - break; > - } > - } > - > - if (lr) { > - if (!smap_get_uuid(&isb_pb->external_ids, "router-id", > &uuid) > - || !uuid_equals(&lr->header_.uuid, &uuid)) { > - char *uuid_s = > - xasprintf(UUID_FMT, UUID_ARGS(&lr->header_.uuid)); > - icsbrec_port_binding_update_external_ids_setkey( > - isb_pb, "router-id", uuid_s); > - free(uuid_s); > - } > - } else { > - if (smap_get_uuid(&isb_pb->external_ids, "router-id", > &uuid)) { > - icsbrec_port_binding_update_external_ids_delkey( > - isb_pb, "router-id"); > - } > - } > - } > - } else { > - if (smap_get_uuid(&isb_pb->external_ids, "router-id", &uuid)) { > - icsbrec_port_binding_update_external_ids_delkey(isb_pb, > - "router-id"); > - } > - } > - > - sync_lsp_tnl_key(lsp, isb_pb->tunnel_key); > } > > /* For each local port: > @@ -937,26 +895,52 @@ sync_local_port(struct ic_context *ctx, > sync_lsp_tnl_key(lsp, isb_pb->tunnel_key); > } > > +static void > +sync_tsp_router_peer(const struct icnbrec_transit_switch_port *tsp, > + const struct nbrec_logical_switch_port *lsp) > +{ > + /* Clear the peer for router port type. */ > + if (lsp->peer && lsp->peer[0]) { > + nbrec_logical_switch_port_set_peer(lsp, NULL); > + } > + > + if (tsp->peer[0]) { > + const char *rp = smap_get(&lsp->options, "router-port"); > + if (!rp || strcmp(rp, tsp->peer)) { > + nbrec_logical_switch_port_update_options_setkey( > + lsp, "router-port", tsp->peer); > + } > + } else if (smap_get(&lsp->options, "router-port")) { > + nbrec_logical_switch_port_update_options_delkey(lsp, > "router-port"); > + } > +} > + > +static void > +sync_tsp_non_router_peer(const struct icnbrec_transit_switch_port *tsp, > + const struct nbrec_logical_switch_port *lsp) > +{ > + /* Clear router-port setting for non-routers. */ > + if (smap_get(&lsp->options, "router-port")) { > + nbrec_logical_switch_port_update_options_delkey(lsp, > "router-port"); > + } > + > + if (tsp->peer[0]) { > + if (!lsp->peer || strcmp(lsp->peer, tsp->peer)) { > + nbrec_logical_switch_port_set_peer(lsp, tsp->peer); > + } > + } else if (lsp->peer && lsp->peer[0]) { > + nbrec_logical_switch_port_set_peer(lsp, NULL); > + } > +} > + > static void > sync_tsp_common(const struct icnbrec_transit_switch_port *tsp, > const struct icsbrec_port_binding *isb_pb, > const struct nbrec_logical_switch_port *lsp) > { > /* Sync addresses from TSP to NB. */ > - if (!tsp->n_addresses) { > - if (lsp->n_addresses) { > - nbrec_logical_switch_port_set_addresses(lsp, NULL, 0); > - } > - } else if (lsp->n_addresses) { > - if (strcmp(lsp->addresses[0], tsp->addresses[0])) { > - nbrec_logical_switch_port_set_addresses( > - lsp, (const char **) &tsp->addresses[0], > - tsp->n_addresses); > - } > - } else { > - nbrec_logical_switch_port_set_addresses( > - lsp, (const char **) &tsp->addresses[0], 1); > - } > + nbrec_logical_switch_port_set_addresses( > + lsp, (const char **) tsp->addresses, tsp->n_addresses); > > if (tsp->chassis[0]) { > const char *current = smap_get(&lsp->options, "requested-chassis"); > @@ -973,30 +957,9 @@ sync_tsp_common(const struct > icnbrec_transit_switch_port *tsp, > sync_lsp_tnl_key(lsp, isb_pb->tunnel_key); > > if (!strcmp(tsp->type, "router")) { > - const char *rp = smap_get(&lsp->options, "router-port"); > - if (!rp || strcmp(rp, tsp->peer)) { > - nbrec_logical_switch_port_update_options_setkey( > - lsp, "router-port", tsp->peer); > - } > - } > - > - if (strcmp(tsp->type, "router")) { > - if (tsp->peer[0]) { > - if (!lsp->peer || strcmp(lsp->peer, tsp->peer)) { > - nbrec_logical_switch_port_set_peer(lsp, tsp->peer); > - } > - } else if (lsp->peer && lsp->peer[0]) { > - nbrec_logical_switch_port_set_peer(lsp, NULL); > - } > - /* Clear router-port setting for non-routers. */ > - if (smap_get(&lsp->options, "router-port")) { > - nbrec_logical_switch_port_update_options_delkey(lsp, > - "router-port"); > - } > + sync_tsp_router_peer(tsp, lsp); > } else { > - if (lsp->peer && lsp->peer[0]) { > - nbrec_logical_switch_port_set_peer(lsp, NULL); > - } > + sync_tsp_non_router_peer(tsp, lsp); > } > } > > @@ -1246,7 +1209,7 @@ lsp_create(struct ic_context *ctx, const struct > nbrec_logical_switch *ls, > nbrec_logical_switch_port_insert(ctx->ovnnb_txn); > nbrec_logical_switch_port_set_name(lsp, tsp->name); > > - nbrec_logical_switch_port_update_options_setkey(lsp, "interconn-ts", > + nbrec_logical_switch_port_update_options_setkey(lsp, "interconn-tsp", > tsp->name); > nbrec_logical_switch_update_ports_addvalue(ls, lsp); > return lsp; > @@ -1303,7 +1266,7 @@ port_binding_run(struct ic_context *ctx) > > for (size_t i = 0; i < ls->n_ports; i++) { > const struct nbrec_logical_switch_port *lsp = ls->ports[i]; > - if (smap_get(&lsp->options, "interconn-ts")) { > + if (smap_get(&lsp->options, "interconn-tsp")) { > shash_add(&nb_ports, lsp->name, lsp); > } else { > shash_add(&old_nb_ports, lsp->name, lsp); > @@ -1328,7 +1291,6 @@ port_binding_run(struct ic_context *ctx) > > for (size_t i = 0; i < ts->n_ports; i++) { > struct icnbrec_transit_switch_port *tsp = ts->ports[i]; > - bool is_owner = false; > > if (!tsp->chassis[0]) { > isb_pb = shash_find_and_delete(&local_pbs, tsp->name); > @@ -1343,7 +1305,7 @@ port_binding_run(struct ic_context *ctx) > ts->name, &ts->header_.uuid, > "transit-switch-port", > &pb_tnlids); > } > - is_owner = true; > + sync_tsp_pb(tsp, isb_pb); > } > } else if (!chassis_is_remote(ctx, tsp->chassis)) { > /* Create ISB port_binding as its chassis is local. */ > @@ -1354,7 +1316,7 @@ port_binding_run(struct ic_context *ctx) > ts->name, &ts->header_.uuid, > "transit-switch-port", > &pb_tnlids); > } > - is_owner = true; > + sync_tsp_pb(tsp, isb_pb); > } else { > isb_pb = shash_find_and_delete(&remote_pbs, tsp->name); > } > @@ -1369,10 +1331,6 @@ port_binding_run(struct ic_context *ctx) > lsp = lsp_create(ctx, ls, tsp); > } > > - if (is_owner) { > - sync_tsp_port(ctx, tsp, isb_pb, lsp); > - } > - > if (!tsp->chassis[0] || !chassis_is_remote(ctx, tsp->chassis)) > { > sync_tsp_local(tsp, isb_pb, lsp); > } else { > diff --git a/lib/ovn-util.h b/lib/ovn-util.h > index caf5d2cf4..b911a59b0 100644 > --- a/lib/ovn-util.h > +++ b/lib/ovn-util.h > @@ -796,7 +796,7 @@ char *normalize_addr_str(const char *orig_addr); > > bool port_contains_duplicate_ip(struct lport_addresses *laddrs1, > struct lport_addresses *laddrs2, > - const char *name, char **error_str); > + const char *port_name, char **error_str); > > #define NEIGH_REDISTRIBUTE_MODES \ > NEIGH_REDISTRIBUTE_MODE(FDB, 0) \ > diff --git a/ovn-ic-nb.xml b/ovn-ic-nb.xml > index 669f9f7aa..f6110324c 100644 > --- a/ovn-ic-nb.xml > +++ b/ovn-ic-nb.xml > @@ -222,8 +222,7 @@ > </column> > > <column name="addresses"> > - The addresses associated with this port. Used when > - <ref column="type"/> is not <code>router</code>. > + The addresses associated with this port. > </column> > > <group title="Common Columns"> > diff --git a/tests/ovn-ic-nbctl.at b/tests/ovn-ic-nbctl.at > index eb333edec..4615f73f4 100644 > --- a/tests/ovn-ic-nbctl.at > +++ b/tests/ovn-ic-nbctl.at > @@ -108,6 +108,26 @@ AT_CHECK([ovn-ic-nbctl tsp-del ts0-p0], [1], [], > ]) > AT_CHECK([ovn-ic-nbctl --if-exists trp-del tr0-p0]) > > +dnl tsp-del --if-exists on nonexistent port should succeed silently > +AT_CHECK([ovn-ic-nbctl --if-exists tsp-del nonexistent-port]) > + > +dnl tsp-add to nonexistent transit switch should fail > +AT_CHECK([ovn-ic-nbctl tsp-add no-such-ts port1], [1], [], > + [ovn-ic-nbctl: no-such-ts: switch name not found > +]) > + > +dnl tsp-set-addr with invalid address format > +AT_CHECK([ovn-ic-nbctl tsp-add ts0 ts0-p1]) > +AT_CHECK([ovn-ic-nbctl tsp-set-addr ts0-p1 "not-a-valid-address"], [1], [], > + [ovn-ic-nbctl: not-a-valid-address: Invalid address format. See > ovn-ic-nb(5). Hint: An Ethernet address must be listed before an IP > address, together as a single argument. > +]) > + > +dnl tsp-set-addr with multiple address arguments > +AT_CHECK([ovn-ic-nbctl tsp-set-addr ts0-p1 "aa:bb:cc:dd:ee:f1 10.0.0.1" > "aa:bb:cc:dd:ee:f2 10.0.0.2"]) > +check_column "aa:bb:cc:dd:ee:f1 10.0.0.1 aa:bb:cc:dd:ee:f2 10.0.0.2" > ic-nb:transit_switch_port addresses name=ts0-p1 > + > +AT_CHECK([ovn-ic-nbctl tsp-del ts0-p1]) > + > OVN_IC_NBCTL_TEST_STOP > AT_CLEANUP > > diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at > index 260346a48..cf42a5cd0 100644 > --- a/tests/ovn-ic.at > +++ b/tests/ovn-ic.at > @@ -210,10 +210,7 @@ wait_row_count Datapath_Binding 1 > external_ids:interconn-ts=ts1 > check ovn-ic-nbctl --wait=sb sync > check_column "router" nb:Logical_Switch_Port type name=tsp1 > check_column "" nb:Logical_Switch_Port peer name=tsp1 > -check_column "interconn-ts=tsp1 router-port=lrp1 requested-chassis=gw-az1 > requested-tnl-key=1" nb:Logical_Switch_Port options name=tsp1 > - > -ROUTER_UUID=$(ovn-nbctl --bare --columns=_uuid find Logical_Router > name=lr1) > -check_column "router-id=$ROUTER_UUID" ic-sb:port_binding external-ids > logical_port=tsp1 > +check_column "interconn-tsp=tsp1 router-port=lrp1 requested-chassis=gw-az1 > requested-tnl-key=1" nb:Logical_Switch_Port options name=tsp1 > > AT_CHECK([ovn-ic-sbctl show | grep -A2 tsp1], [0], [dnl > port tsp1 > @@ -221,9 +218,53 @@ AT_CHECK([ovn-ic-sbctl show | grep -A2 tsp1], [0], [dnl > address: [["00:00:00:00:00:02 10.0.1.2/24"]] > ]) > > -# remove transit switch and check if port_binding is deleted > -check ovn-ic-nbctl --wait=sb ts-del ts1 > +dnl Verify ISB metadata fields > +check_column "transit-switch-port" ic-sb:port_binding type > logical_port=tsp1 > +check_column "gw-az1" ic-sb:port_binding gateway logical_port=tsp1 > + > +dnl Add a second TSP on az2 to test individual tsp-del > +check ovn-ic-nbctl tsp-add ts1 tsp2 chassis=gw-az2 > +check ovn-ic-nbctl tsp-set-addr tsp2 "00:00:00:00:00:03 10.0.2.3/24" > +check ovn-ic-nbctl --wait=sb sync > + > +ovn_as az2 > +wait_row_count nb:Logical_Switch_Port 1 name=tsp2 > +check_column "" nb:Logical_Switch_Port type name=tsp2 > +check_row_count ic-sb:Port_Binding 1 logical_port=tsp2 > +check_column "transit-switch-port" ic-sb:port_binding type > logical_port=tsp2 > +check_column "gw-az2" ic-sb:port_binding gateway logical_port=tsp2 > + > +dnl Delete tsp1 via tsp-del (not ts-del) and verify orphan cleanup > +ovn_as az1 > +check ovn-ic-nbctl tsp-del tsp1 > +check ovn-ic-nbctl --wait=sb sync > + > +dnl ISB port_binding for tsp1 should be gone > check_row_count ic-sb:Port_Binding 0 logical_port=tsp1 > + > +dnl NB LSP for tsp1 should be cleaned up (orphan removal) > +wait_row_count nb:Logical_Switch_Port 0 name=tsp1 > +ovn_as az2 > +wait_row_count nb:Logical_Switch_Port 0 name=tsp1 > + > +dnl tsp2 should still be intact > +check_row_count ic-sb:Port_Binding 1 logical_port=tsp2 > +wait_row_count nb:Logical_Switch_Port 1 name=tsp2 > + > +dnl The TS itself should still exist > +check_row_count ic-sb:Datapath_Binding 1 transit_switch=ts1 > + > +dnl Now delete tsp2 as well > +ovn_as az1 > +check ovn-ic-nbctl tsp-del tsp2 > +check ovn-ic-nbctl --wait=sb sync > +check_row_count ic-sb:Port_Binding 0 logical_port=tsp2 > +wait_row_count nb:Logical_Switch_Port 0 name=tsp2 > + > +dnl TS still exists after all ports are deleted > +check_row_count ic-sb:Datapath_Binding 1 transit_switch=ts1 > + > +check ovn-ic-nbctl --wait=sb ts-del ts1 > for i in 1 2; do > az=az$i > ovn_as $az > @@ -266,8 +307,6 @@ wait_row_count Datapath_Binding 1 > external_ids:interconn-ts=ts1 > # Sync ic-sb DB to see the TS changes. > check ovn-ic-nbctl --wait=sb sync > > -ROUTER_UUID=$(ovn-nbctl --bare --columns=_uuid find Logical_Router > name=lr1) > -check_column "router-id=$ROUTER_UUID" ic-sb:port_binding external-ids > logical_port=tsp1 > AT_CHECK([ovn-ic-sbctl show | grep -A2 tsp1], [0], [dnl > port tsp1 > transit switch: ts1 > @@ -287,9 +326,8 @@ check ovn-ic-nbctl set Transit_Switch_Port $PORT_UUID > 'type=""' > check ovn-ic-nbctl --wait=sb sync > check_column "" nb:Logical_Switch_Port type name=tsp1 > check_row_count nb:Logical_Switch_Port 1 name=tsp1 peer=lrp1 > -check_column "interconn-ts=tsp1 requested-chassis=gw-az1 > requested-tnl-key=1" nb:Logical_Switch_Port options name=tsp1 > +check_column "interconn-tsp=tsp1 requested-chassis=gw-az1 > requested-tnl-key=1" nb:Logical_Switch_Port options name=tsp1 > > -check_row_count ic-sb:Port_Binding 0 logical_port=tsp1 > 'external_ids:router-id!=""' > AT_CHECK([ovn-ic-sbctl show | grep -A2 tsp1], [0], [dnl > port tsp1 > transit switch: ts1 > @@ -306,15 +344,51 @@ PORT_UUID=$(ovn-ic-nbctl --bare --columns=_uuid find > Transit_Switch_Port name=ts > check ovn-ic-nbctl set Transit_Switch_Port $PORT_UUID 'type="router"' > check ovn-ic-nbctl --wait=sb sync > check_column "router" nb:Logical_Switch_Port type name=tsp1 > -check_column "interconn-ts=tsp1 router-port=lrp1 requested-chassis=gw-az1 > requested-tnl-key=1" nb:Logical_Switch_Port options name=tsp1 > +check_column "interconn-tsp=tsp1 router-port=lrp1 requested-chassis=gw-az1 > requested-tnl-key=1" nb:Logical_Switch_Port options name=tsp1 > > -check_column "router-id=$ROUTER_UUID" ic-sb:port_binding external-ids > logical_port=tsp1 > AT_CHECK([ovn-ic-sbctl show | grep -A2 tsp1], [0], [dnl > port tsp1 > transit switch: ts1 > address: [["00:00:00:00:00:02 10.0.1.2/24"]] > ]) > > +dnl Verify remote AZ NB LSP details beyond just type="remote" > +ovn_as az2 > +wait_row_count nb:Logical_Switch_Port 1 name=tsp1 > +check_column "remote" nb:Logical_Switch_Port type name=tsp1 > +check_column "00:00:00:00:00:02 10.0.1.2/24" nb:Logical_Switch_Port > addresses name=tsp1 > +check_column "" nb:Logical_Switch_Port peer name=tsp1 > +ovn_as az1 > + > +dnl Test address change after initial sync > +check ovn-ic-nbctl tsp-set-addr tsp1 "aa:bb:cc:dd:ee:ff 192.168.1.1/24" > +check ovn-ic-nbctl --wait=sb sync > + > +dnl Verify NB LSP address updated in owning AZ > +check_column "aa:bb:cc:dd:ee:ff 192.168.1.1/24" nb:Logical_Switch_Port > addresses name=tsp1 > + > +dnl Verify ISB address updated > +AT_CHECK([ovn-ic-sbctl show | grep -A2 tsp1], [0], [dnl > + port tsp1 > + transit switch: ts1 > + address: [["aa:bb:cc:dd:ee:ff 192.168.1.1/24"]] > +]) > + > +dnl Verify remote AZ reflects the new address > +ovn_as az2 > +check_column "aa:bb:cc:dd:ee:ff 192.168.1.1/24" nb:Logical_Switch_Port > addresses name=tsp1 > +ovn_as az1 > + > +dnl Clear address and verify propagation > +check ovn-ic-nbctl tsp-set-addr tsp1 > +check ovn-ic-nbctl --wait=sb sync > +check_column "" nb:Logical_Switch_Port addresses name=tsp1 > + > +dnl Set address again to verify recovery > +check ovn-ic-nbctl tsp-set-addr tsp1 "00:00:00:00:00:02 10.0.1.2/24" > +check ovn-ic-nbctl --wait=sb sync > +check_column "00:00:00:00:00:02 10.0.1.2/24" nb:Logical_Switch_Port > addresses name=tsp1 > + > # remove transit switch and check if port_binding is deleted > check ovn-ic-nbctl --wait=sb ts-del ts1 > check_row_count ic-sb:Port_Binding 0 logical_port=tsp1 > @@ -422,17 +496,22 @@ check ovn-ic-nbctl tsp-add ts1 tsp1 > check ovn-ic-nbctl tsp-set-addr tsp1 "00:00:00:00:00:02 10.0.0.2" > check ovn-ic-nbctl --wait=sb sync > > -# Leader AZ should have the NB LSP > +dnl Leader AZ should have the NB LSP with correct address > wait_row_count nb:Logical_Switch_Port 1 name=tsp1 > check_column "" nb:Logical_Switch_Port type name=tsp1 > +check_column "00:00:00:00:00:02 10.0.0.2" nb:Logical_Switch_Port addresses > name=tsp1 > > -# Non-leader AZ should also have it (found via index lookup) > +dnl Non-leader AZ should also have it with address > ovn_as az2 > check ovn-ic-nbctl --wait=sb sync > wait_row_count nb:Logical_Switch_Port 1 name=tsp1 > +check_column "" nb:Logical_Switch_Port type name=tsp1 > +check_column "00:00:00:00:00:02 10.0.0.2" nb:Logical_Switch_Port addresses > name=tsp1 > > -# Verify ISB port binding exists > +dnl Verify ISB port binding exists with correct metadata > check_row_count ic-sb:Port_Binding 1 logical_port=tsp1 > +check_column "transit-switch-port" ic-sb:port_binding type > logical_port=tsp1 > +check_column "" ic-sb:port_binding gateway logical_port=tsp1 > > # Cleanup > ovn_as az1 > @@ -473,28 +552,31 @@ check ovn-ic-nbctl tsp-add ts1 tsp1 chassis=gw-az1 > check ovn-ic-nbctl tsp-set-addr tsp1 "00:00:00:00:00:01 10.0.0.1" > check ovn-ic-nbctl --wait=sb sync > > -# az1 owns it > +dnl az1 owns it, verify ISB gateway > wait_row_count nb:Logical_Switch_Port 1 name=tsp1 > check_column "" nb:Logical_Switch_Port type name=tsp1 > +check_column "gw-az1" ic-sb:port_binding gateway logical_port=tsp1 > > -# az2 sees it as remote > +dnl az2 sees it as remote with synced address > ovn_as az2 > wait_row_count nb:Logical_Switch_Port 1 name=tsp1 > check_column "remote" nb:Logical_Switch_Port type name=tsp1 > +check_column "00:00:00:00:00:01 10.0.0.1" nb:Logical_Switch_Port addresses > name=tsp1 > > -# Reassign chassis to gw-az2 > +dnl Reassign chassis to gw-az2 > ovn_as az1 > PORT_UUID=$(ovn-ic-nbctl --bare --columns=_uuid find Transit_Switch_Port > name=tsp1) > check ovn-ic-nbctl set Transit_Switch_Port $PORT_UUID chassis=gw-az2 > check ovn-ic-nbctl --wait=sb sync > > -# az1 now sees it as remote > +dnl az1 now sees it as remote > wait_column "remote" nb:Logical_Switch_Port type name=tsp1 > > -# az2 now owns it > +dnl az2 now owns it, ISB gateway updated > ovn_as az2 > check ovn-ic-nbctl --wait=sb sync > wait_column "" nb:Logical_Switch_Port type name=tsp1 > +check_column "gw-az2" ic-sb:port_binding gateway logical_port=tsp1 > > # Change type to router with peer on az2 > check ovn-nbctl lr-add lr1 > @@ -794,6 +876,44 @@ switch <0> (ts1) > check ovn-nbctl lsp-del lsp-ts1-lr1 > OVS_WAIT_WHILE([ovn_as az2 ovn-nbctl show | grep lsp-ts1-lr1]) > > +dnl Test mixed legacy + TSP coexistence on the same TS. > +dnl Re-create the legacy port > +check ovn-nbctl lrp-add lr1 lrp-lr1-ts1 aa:aa:aa:aa:aa:01 169.254.100.1/24 > +check ovn-nbctl lrp-set-gateway-chassis lrp-lr1-ts1 gw1 > +check ovn-nbctl --wait=hv lsp-add-router-port ts1 lsp-ts1-lr1 lrp-lr1-ts1 > +OVS_WAIT_UNTIL([ovn_as az2 ovn-nbctl show | grep -q lsp-ts1-lr1]) > + > +dnl Add a TSP alongside the legacy port > +check ovn-ic-nbctl tsp-add ts1 tsp-mixed chassis=gw1 > +check ovn-ic-nbctl tsp-set-addr tsp-mixed "bb:bb:bb:bb:bb:01 10.0.0.50" > +check ovn-ic-nbctl --wait=sb sync > + > +dnl Both ports should exist in NB > +ovn_as az1 > +wait_row_count nb:Logical_Switch_Port 1 name=lsp-ts1-lr1 > +wait_row_count nb:Logical_Switch_Port 1 name=tsp-mixed > + > +dnl Legacy port should NOT have interconn-tsp option > +AT_CHECK([ovn-nbctl --bare --columns=options find Logical_Switch_Port > name=lsp-ts1-lr1 | grep -q interconn-tsp], [1]) > + > +dnl TSP port SHOULD have interconn-tsp option > +AT_CHECK([ovn-nbctl --bare --columns=options find Logical_Switch_Port > name=tsp-mixed | grep -q interconn-tsp]) > + > +dnl Both should have ISB port bindings > +check_row_count ic-sb:Port_Binding 1 logical_port=lsp-ts1-lr1 > +check_row_count ic-sb:Port_Binding 1 logical_port=tsp-mixed > + > +dnl Delete the TSP - legacy port should be unaffected > +check ovn-ic-nbctl tsp-del tsp-mixed > +check ovn-ic-nbctl --wait=sb sync > +wait_row_count nb:Logical_Switch_Port 0 name=tsp-mixed > +wait_row_count nb:Logical_Switch_Port 1 name=lsp-ts1-lr1 > +check_row_count ic-sb:Port_Binding 1 logical_port=lsp-ts1-lr1 > + > +dnl Delete the legacy port - should clean up normally > +check ovn-nbctl lsp-del lsp-ts1-lr1 > +OVS_WAIT_WHILE([ovn_as az2 ovn-nbctl show | grep -q lsp-ts1-lr1]) > + > # ts1 should not be local datapath since lsp-ts1-lr1 has been deleted. > OVN_CLEANUP_SBOX(gw1, [], [], [ts1,lr1]) > OVN_CLEANUP_IC([az1], [az2]) > diff --git a/utilities/ovn-ic-nbctl.c b/utilities/ovn-ic-nbctl.c > index 4bf922212..6f5bc0826 100644 > --- a/utilities/ovn-ic-nbctl.c > +++ b/utilities/ovn-ic-nbctl.c > @@ -1023,7 +1023,7 @@ ic_nbctl_tsp_set_addr(struct ctl_context *ctx) > && !ovs_scan(ctx->argv[i], "dynamic "IPV6_SCAN_FMT, ipv6_s) > && !ovs_scan(ctx->argv[i], "dynamic "IP_SCAN_FMT, > IP_SCAN_ARGS(&ip))) { > - ctl_error(ctx, "%s: Invalid address format. See ovn-nb(5). " > + ctl_error(ctx, "%s: Invalid address format. See ovn-ic-nb(5). " > "Hint: An Ethernet address must be " > "listed before an IP address, together as a single " > "argument.", ctx->argv[i]); > > > > > [...] > > > Regards, > Ales
Looks good to me. Thanks Ales! _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
