@@ -71,6 +71,7 @@ struct ic_context {
struct ovsdb_idl_index *icsbrec_port_binding_by_az;
struct ovsdb_idl_index *icsbrec_port_binding_by_ts;
struct ovsdb_idl_index *icsbrec_port_binding_by_ts_az;
+ 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;
};
@@ -1621,6 +1622,38 @@ advertise_lr_routes(struct ic_context *ctx,
hmap_destroy(&routes_ad);
}
+static void
+delete_orphan_ic_routes(struct ic_context *ctx,
+ const struct icsbrec_availability_zone *az)
+{
+ const struct icsbrec_route *isb_route, *isb_route_key =
+ icsbrec_route_index_init_row(ctx->icsbrec_route_by_az);
+ icsbrec_route_index_set_availability_zone(isb_route_key, az);
+
+ const struct icnbrec_transit_switch *t_sw, *t_sw_key;
+
+ ICSBREC_ROUTE_FOR_EACH_EQUAL (isb_route, isb_route_key,
+ ctx->icsbrec_route_by_az)
+ {
+ t_sw_key = icnbrec_transit_switch_index_init_row(
+ ctx->icnbrec_transit_switch_by_name);
+ icnbrec_transit_switch_index_set_name(t_sw_key,
+ isb_route->transit_switch);
+ t_sw = icnbrec_transit_switch_index_find(
+ ctx->icnbrec_transit_switch_by_name, t_sw_key);
+ icnbrec_transit_switch_index_destroy_row(t_sw_key);
+
+ if (!t_sw) {
+ VLOG_WARN("Deleting orphan ICDB:Route: %s->%s (%s, rtb:%s, "
+ "transit switch: %s)", isb_route->ip_prefix,
+ isb_route->nexthop, isb_route->origin,
+ isb_route->route_table, isb_route->transit_switch);
+ icsbrec_route_delete(isb_route);
+ }
+ }
+ icsbrec_route_index_destroy_row(isb_route_key);
+}
+
static void
route_run(struct ic_context *ctx,
const struct icsbrec_availability_zone *az)
@@ -1629,6 +1662,8 @@ route_run(struct ic_context *ctx,
return;
}
+ delete_orphan_ic_routes(ctx, az);
+
struct hmap ic_lrs = HMAP_INITIALIZER(&ic_lrs);
const struct icsbrec_port_binding *isb_pb;
const struct icsbrec_port_binding *isb_pb_key =
@@ -1917,6 +1952,10 @@ main(int argc, char *argv[])
&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,
+ &icsbrec_route_col_availability_zone);
+
struct ovsdb_idl_index *icsbrec_route_by_ts
= ovsdb_idl_index_create1(ovnisb_idl_loop.idl,
&icsbrec_route_col_transit_switch);
@@ -1971,6 +2010,7 @@ main(int argc, char *argv[])
.icsbrec_port_binding_by_az = icsbrec_port_binding_by_az,
.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,
};
@@ -121,6 +121,79 @@ OVN_CLEANUP_IC
AT_CLEANUP
])
+OVN_FOR_EACH_NORTHD([
+AT_SETUP([ovn-ic -- route deletion upon TS deletion])
+
+ovn_init_ic_db
+net_add n1
+
+# 1 GW per AZ
+for i in 1 2; do
+ az=az$i
+ ovn_start $az
+ sim_add gw-$az
+ as gw-$az
+ check ovs-vsctl add-br br-phys
+ ovn_az_attach $az n1 br-phys 192.168.1.$i
+ check ovs-vsctl set open . external-ids:ovn-is-interconn=true
+ check ovn-nbctl set nb-global . \
+ options:ic-route-adv=true \
+ options:ic-route-adv-default=true \
+ options:ic-route-learn=true \
+ options:ic-route-learn-default=true
+done
+
+create_ic_infra() {
+ az_id=$1
+ ts_id=$2
+ az=az$i
+
+ lsp=lsp${az_id}-${ts_id}
+ lrp=lrp${az_id}-${ts_id}
+ ts=ts${az_id}-${ts_id}
+ lr=lr${az_id}-${ts_id}
+
+ ovn_as $az
+
+ check ovn-ic-nbctl ts-add $ts
+ check ovn-nbctl lr-add $lr
+ check ovn-nbctl lrp-add $lr $lrp 00:00:00:00:00:0$az_id 10.0.$az_id.1/24
+ check ovn-nbctl lrp-set-gateway-chassis $lrp gw-$az
+
+ check ovn-nbctl lsp-add $ts $lsp -- \
+ lsp-set-addresses $lsp router -- \
+ lsp-set-type $lsp router -- \
+ lsp-set-options $lsp router-port=$lrp
+
+ check ovn-nbctl lr-route-add $lr 192.168.0.0/16 10.0.$az_id.10
+}
+
+create_ic_infra 1 1
+create_ic_infra 1 2
+create_ic_infra 2 1
+
+ovn_as az1
+
+wait_row_count ic-sb:Route 3 ip_prefix=192.168.0.0/16
+
+# remove transit switch 1 (from az1) and check if its route is deleted
+# same route from another AZ and ts should remain, as
+check ovn-ic-nbctl ts-del ts1-1
+sleep 2
+ovn-ic-sbctl list route
+ovn-ic-nbctl list transit_switch
+wait_row_count ic-sb:route 2 ip_prefix=192.168.0.0/16
+ovn-ic-sbctl list route
+
+for i in 1 2; do
+ az=az$i
+ OVN_CLEANUP_SBOX(gw-$az)
+ OVN_CLEANUP_AZ([$az])
+done
+OVN_CLEANUP_IC
+AT_CLEANUP
+])
+
OVN_FOR_EACH_NORTHD([
AT_SETUP([ovn-ic -- gateway sync])
Before this patch if one deletes transit switch through which there were routes in ICSB:Route table, such routes were left forever in the DB. Now we validate that each ICSB:Route has an appropriate transit switch. Signed-off-by: Vladislav Odintsov <odivlad@gmail.com> --- ic/ovn-ic.c | 40 +++++++++++++++++++++++++++ tests/ovn-ic.at | 73 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+)