@@ -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);
@@ -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,
@@ -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 */
@@ -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
])
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(-)