It's not enough to check that ovn_port_find() returns non-NULL, that
also happens when in the current iteration the router (and router port)
have been deleted and new ones were added (with the same router port
name).  However, the Learned_Route was learned by ovn-controller for the
old Port_Binding and is potentially not applicable anymore.

Remove it by making sure we also match on the actual
Learned_Route.logical_port Port_Binding pointer being the correct one
when determining if a dynamic route is valid.

Otherwise we end up with an inconsistent SB database transaction that
fails integrity checks on the server side.

Fixes: 0ccaea177420 ("northd: Remove learned routes if lrp is removed.")
Signed-off-by: Dumitru Ceara <[email protected]>
---
 northd/en-learned-route-sync.c |  4 +++-
 tests/ovn-northd.at            | 27 +++++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/northd/en-learned-route-sync.c b/northd/en-learned-route-sync.c
index f14f610ac3..7ba43ec10a 100644
--- a/northd/en-learned-route-sync.c
+++ b/northd/en-learned-route-sync.c
@@ -220,7 +220,9 @@ routes_table_sync(
     const struct sbrec_learned_route *sb_route;
     SBREC_LEARNED_ROUTE_TABLE_FOR_EACH_SAFE (sb_route,
                                              sbrec_learned_route_table) {
-        if (!ovn_port_find(lr_ports, sb_route->logical_port->logical_port)) {
+        struct ovn_port *op =
+            ovn_port_find(lr_ports, sb_route->logical_port->logical_port);
+        if (!op || op->sb != sb_route->logical_port) {
             sbrec_learned_route_delete(sb_route);
             continue;
         }
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index b2b9f092c6..aea8a81615 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -15410,6 +15410,33 @@ AT_CHECK([grep -w "lr_in_ip_routing" lr0flows | sed -e 
's/reg8\[[0..15\]] = [[12
 AT_CLEANUP
 ])
 
+OVN_FOR_EACH_NORTHD_NO_HV([
+AT_SETUP([dynamic-routing - route learning cleanup - router recreation])
+AT_KEYWORDS([dynamic-routing])
+ovn_start
+
+check ovn-nbctl --wait=sb                             \
+    -- lr-add lr                                      \
+       -- lrp-add lr lrp 00:00:00:00:00:01 1.1.1.1/24
+
+lr_dp=$(fetch_column Datapath_Binding _uuid external_ids:name=lr)
+lrp_pb=$(fetch_column Port_Binding _uuid logical_port=lrp)
+check_uuid ovn-sbctl create Learned_Route       \
+    datapath=$lr_dp logical_port=$lrp_pb        \
+    ip_prefix=42.42.42.42/32 nexthop=1.1.1.2/24
+
+dnl Delete old router, create a new one with the same name, learned routes
+dnl should be removed.
+check ovn-nbctl --wait=sb                             \
+    -- lrp-del lrp                                    \
+    -- lr-del lr                                      \
+    -- lr-add lr                                      \
+       -- lrp-add lr lrp 00:00:00:00:00:01 1.1.1.1/24
+check_row_count Learned_Route 0
+
+AT_CLEANUP
+])
+
 OVN_FOR_EACH_NORTHD_NO_HV([
 AT_SETUP([dynamic-routing - host routes])
 AT_KEYWORDS([dynamic-routing])
-- 
2.50.1

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to