Fix routes not deleted when lr is disabled and pb address is cleared
simultaneously. When a logical router is disabled, northd clears the
IC-SB port binding address. If ovn-ic handles both changes in the same
iteration, learned routes were not deleted.
This issue was highlighted by sporadic failures of test [0].
[0] "ovn-ic -- Check loop with lsp orphan in same subnet of new lsp in other
TS".
Fixes: ddc020051e0a ("ic: Fix loop disable/enable logical router.")
Signed-off-by: Xavier Simonart <[email protected]>
---
ic/ovn-ic.c | 34 ++++++++++++++++++++++++++++++++++
tests/ovn-ic.at | 19 +++++++++++++++++++
2 files changed, 53 insertions(+)
diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c
index 0a3f2336b..9611f477d 100644
--- a/ic/ovn-ic.c
+++ b/ic/ovn-ic.c
@@ -2404,6 +2404,32 @@ advertise_routes(struct ic_context *ctx,
}
}
+static void
+collect_learned_routes(struct ic_router_info *ic_lr)
+{
+ const struct nbrec_logical_router *lr = ic_lr->lr;
+
+ /* Check static routes of the LR and collect learned routes */
+ for (int i = 0; i < lr->n_static_routes; i++) {
+ const struct nbrec_logical_router_static_route *nb_route
+ = lr->static_routes[i];
+ struct uuid isb_uuid;
+ if (smap_get_uuid(&nb_route->external_ids, "ic-learned-route",
+ &isb_uuid)) {
+ /* It is a learned route */
+ if (!add_to_routes_learned(&ic_lr->routes_learned, nb_route, lr,
+ &isb_uuid)) {
+ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
+ VLOG_WARN_RL(&rl, "Bad format of learned route in NB: "
+ "%s -> %s. Delete it.", nb_route->ip_prefix,
+ nb_route->nexthop);
+ nbrec_logical_router_update_static_routes_delvalue(lr,
+ nb_route);
+ }
+ }
+ }
+}
+
static void
build_ts_routes_to_adv(struct ic_context *ctx,
struct ic_router_info *ic_lr,
@@ -2526,6 +2552,7 @@ collect_lr_routes(struct ic_context *ctx,
struct hmap *routes_ad;
const struct icnbrec_transit_switch *t_sw;
+ bool routes_built = false;
VECTOR_FOR_EACH (&ic_lr->isb_pbs, isb_pb) {
key = icnbrec_transit_switch_index_init_row(
ctx->icnbrec_transit_switch_by_name);
@@ -2561,10 +2588,17 @@ collect_lr_routes(struct ic_context *ctx,
route_table = "";
route_tag = "";
}
+ routes_built = true;
build_ts_routes_to_adv(ctx, ic_lr, routes_ad, &ts_port_addrs,
nb_global, route_table, route_tag, lrp);
destroy_lport_addresses(&ts_port_addrs);
}
+ /* If no port binding had valid addresses (e.g. LR disabled
+ * and PB address cleared simultaneously), collect learned routes so
+ * they can be deleted by sync_learned_routes(). */
+ if (!routes_built) {
+ collect_learned_routes(ic_lr);
+ }
}
static void
diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at
index 68d78d9e4..6f4a5b381 100644
--- a/tests/ovn-ic.at
+++ b/tests/ovn-ic.at
@@ -3407,6 +3407,25 @@ OVS_WAIT_FOR_OUTPUT([ovn_as az1 ovn-nbctl lr-route-list
lr11 | grep 192.168 |
192.168.0.0/24 169.254.101.22
])
+# Do the same but with ovn-ic handling both northd and isb change at the same
time.
+echo az1/ic going to sleep
+AT_CHECK([kill -STOP $(cat az1/ic/ovn-ic.pid)])
+on_exit "test -e az1/ic/ovn-ic.pid && kill -CONT $(cat az1/ic/ovn-ic.pid)"
+
+check ovn_as az1 ovn-nbctl --wait=sb set logical_router lr11 enable=false
+echo az1/ic going to wake up
+AT_CHECK([kill -CONT $(cat az1/ic/ovn-ic.pid)])
+
+OVS_WAIT_FOR_OUTPUT([ovn_as az1 ovn-nbctl lr-route-list lr11 | grep 192.168 |
+ grep learned | awk '{print $1, $2}' | sort ], [0], [dnl
+])
+
+check ovn_as az1 ovn-nbctl set logical_router lr11 enable=true
+OVS_WAIT_FOR_OUTPUT([ovn_as az1 ovn-nbctl lr-route-list lr11 | grep 192.168 |
+ grep learned | awk '{print $1, $2}' | sort ], [0], [dnl
+192.168.0.0/24 169.254.101.22
+])
+
OVN_CLEANUP_IC([az1], [az2])
AT_CLEANUP
--
2.47.1
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev