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 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
