On Mon, Jun 22, 2026 at 10:49 AM Mairtin O'Loingsigh <[email protected]> wrote:
> 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! > > Thank you Mairtin, with that applied to main. Regards, Ales _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
