Skip to content

Commit

Permalink
ic: remove orphan ovn interconnection routes
Browse files Browse the repository at this point in the history
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.

Acked-by: Numan Siddique <numans@ovn.org>
Signed-off-by: Vladislav Odintsov <odivlad@gmail.com>
Signed-off-by: Dumitru Ceara <dceara@redhat.com>
(cherry picked from commit 4ea2f80)
  • Loading branch information
odivlad authored and dceara committed Dec 16, 2022
1 parent d73b641 commit 366512f
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 0 deletions.
41 changes: 41 additions & 0 deletions ic/ovn-ic.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down Expand Up @@ -1616,6 +1617,39 @@ 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) {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
VLOG_INFO_RL(&rl, "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)
Expand All @@ -1624,6 +1658,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 =
Expand Down Expand Up @@ -1912,6 +1948,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);
Expand Down Expand Up @@ -1966,6 +2006,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,
};
Expand Down
73 changes: 73 additions & 0 deletions tests/ovn-ic.at
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,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])

Expand Down

0 comments on commit 366512f

Please sign in to comment.