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

Reply via email to