diff mbox series

[ovs-dev,v3,14/33] northd: Remove learned routes if lrp is removed.

Message ID 958697f33fa3838dadfa14ed7d3e93f0c97147e7.1732630355.git.felix.huettner@stackit.cloud
State Changes Requested
Headers show
Series OVN Fabric integration | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success

Commit Message

Felix Huettner Nov. 26, 2024, 2:38 p.m. UTC
learned routes must be bound to a lrp on which the routes where learned.
In case the lrp is deleted for whatever reason no ovn-controller would
clean these routes up, therefor we do this in northd.

Signed-off-by: Felix Huettner <felix.huettner@stackit.cloud>
---
 northd/en-routes-sync.c |  4 ++++
 northd/northd.c         | 35 +----------------------------------
 northd/northd.h         | 34 ++++++++++++++++++++++++++++++++++
 tests/ovn-northd.at     | 15 +++++++++++++++
 4 files changed, 54 insertions(+), 34 deletions(-)
diff mbox series

Patch

diff --git a/northd/en-routes-sync.c b/northd/en-routes-sync.c
index ed23c82f4..7ca87c76a 100644
--- a/northd/en-routes-sync.c
+++ b/northd/en-routes-sync.c
@@ -290,6 +290,10 @@  routes_table_sync(struct ovsdb_idl_txn *ovnsb_txn,
     const struct sbrec_route *sb_route;
     SBREC_ROUTE_TABLE_FOR_EACH (sb_route, sbrec_route_table) {
         if (!strcmp(sb_route->type, "receive")) {
+            if (!ovn_port_find(lr_ports, sb_route->logical_port)) {
+                sbrec_route_delete(sb_route);
+                continue;
+            }
             parse_route_from_sbrec_route(parsed_routes_out, lr_ports,
                                          &lr_datapaths->datapaths,
                                          sb_route);
diff --git a/northd/northd.c b/northd/northd.c
index 0002c31a2..4439a74da 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -1287,34 +1287,6 @@  ovn_port_destroy(struct hmap *ports, struct ovn_port *port)
     }
 }
 
-/* Returns the ovn_port that matches 'name'.  If 'prefer_bound' is true and
- * multiple ports share the same name, gives precendence to ports bound to
- * an ovn_datapath.
- */
-static struct ovn_port *
-ovn_port_find__(const struct hmap *ports, const char *name,
-                bool prefer_bound)
-{
-    struct ovn_port *matched_op = NULL;
-    struct ovn_port *op;
-
-    HMAP_FOR_EACH_WITH_HASH (op, key_node, hash_string(name, 0), ports) {
-        if (!strcmp(op->key, name)) {
-            matched_op = op;
-            if (!prefer_bound || op->od) {
-                return op;
-            }
-        }
-    }
-    return matched_op;
-}
-
-static struct ovn_port *
-ovn_port_find(const struct hmap *ports, const char *name)
-{
-    return ovn_port_find__(ports, name, false);
-}
-
 static bool
 lsp_is_clone_to_unknown(const struct nbrec_logical_switch_port *nbsp)
 {
@@ -1329,12 +1301,6 @@  lsp_is_clone_to_unknown(const struct nbrec_logical_switch_port *nbsp)
     return false;
 }
 
-static struct ovn_port *
-ovn_port_find_bound(const struct hmap *ports, const char *name)
-{
-    return ovn_port_find__(ports, name, true);
-}
-
 /* Returns true if the logical switch port 'enabled' column is empty or
  * set to true.  Otherwise, returns false. */
 static bool
@@ -3416,6 +3382,7 @@  cleanup_mac_bindings(
     }
 }
 
+
 static void
 cleanup_sb_ha_chassis_groups(
     const struct sbrec_ha_chassis_group_table *sbrec_ha_chassis_group_table,
diff --git a/northd/northd.h b/northd/northd.h
index ebf94be48..991ba5f9f 100644
--- a/northd/northd.h
+++ b/northd/northd.h
@@ -902,4 +902,38 @@  is_vxlan_mode(const struct smap *nb_options,
 
 uint32_t get_ovn_max_dp_key_local(bool _vxlan_mode);
 
+/* Returns the ovn_port that matches 'name'.  If 'prefer_bound' is true and
+ * multiple ports share the same name, gives precendence to ports bound to
+ * an ovn_datapath.
+ */
+static struct ovn_port *
+ovn_port_find__(const struct hmap *ports, const char *name,
+                bool prefer_bound)
+{
+    struct ovn_port *matched_op = NULL;
+    struct ovn_port *op;
+
+    HMAP_FOR_EACH_WITH_HASH (op, key_node, hash_string(name, 0), ports) {
+        if (!strcmp(op->key, name)) {
+            matched_op = op;
+            if (!prefer_bound || op->od) {
+                return op;
+            }
+        }
+    }
+    return matched_op;
+}
+
+static inline struct ovn_port *
+ovn_port_find(const struct hmap *ports, const char *name)
+{
+    return ovn_port_find__(ports, name, false);
+}
+
+static inline struct ovn_port *
+ovn_port_find_bound(const struct hmap *ports, const char *name)
+{
+    return ovn_port_find__(ports, name, true);
+}
+
 #endif /* NORTHD_H */
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 13301257e..213536707 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -14026,6 +14026,21 @@  AT_CHECK([grep -w "lr_in_ip_routing" lr0flows | ovn_strip_lflows], [0], [dnl
   table=??(lr_in_ip_routing   ), priority=99   , match=(ip4.dst == 100.100.100.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg1 = 100.100.100.10; eth.src = 00:00:00:00:ff:02; outport = "lr0-sw1"; flags.loopback = 1; next;)
 ])
 
+# deleting lr0-sw1 will remove the flows and also the learned route
+check ovn-nbctl --wait=sb lrp-del lr0-sw1
+check_row_count Route 2 type=advertise
+check_row_count Route 1 type=receive
+check_row_count Route 1 type=receive logical_port=lr0-sw0
+ovn-sbctl dump-flows lr0 > lr0flows
+AT_CHECK([grep -w "lr_in_ip_routing" lr0flows | ovn_strip_lflows], [0], [dnl
+  table=??(lr_in_ip_routing   ), priority=0    , match=(1), action=(drop;)
+  table=??(lr_in_ip_routing   ), priority=10550, match=(nd_rs || nd_ra), action=(drop;)
+  table=??(lr_in_ip_routing   ), priority=259  , match=(inport == "lr0-sw0" && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; xxreg1 = fe80::200:ff:fe00:ff01; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 1; next;)
+  table=??(lr_in_ip_routing   ), priority=97   , match=(reg7 == 0 && ip4.dst == 172.16.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.11; reg1 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 1; next;)
+  table=??(lr_in_ip_routing   ), priority=98   , match=(reg7 == 0 && ip4.dst == 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 10.0.0.10; reg1 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 1; next;)
+  table=??(lr_in_ip_routing   ), priority=99   , match=(ip4.dst == 10.0.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg1 = 10.0.0.1; eth.src = 00:00:00:00:ff:01; outport = "lr0-sw0"; flags.loopback = 1; next;)
+])
+
 
 AT_CLEANUP
 ])