This fixes two issues at once:
1. previously we did not treat changed potential route-exchange ports
   correctly as route_exchange_relevant_port does not consider
   chassisredirect ports.
2. The sbrec_advertised_route change handler also triggered for updates
   which would cause it to also trigger on any changed port_binding that
   is referenced. As these changes are already handled in the other
   handlers this is unnecessary.

We can also remove the change handling of local<->remote port in the
port_binding handler as [1] now handles them in runtime_data without a
roundtrip to southbound.

[1]: a3f72e44ddde72fbc82d72568ac517455648cbc1

Signed-off-by: Felix Huettner <felix.huettner@stackit.cloud>
---
 controller/ovn-controller.c | 81 ++++++++++++++++++++++++++-----------
 1 file changed, 57 insertions(+), 24 deletions(-)

diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
index 37406f923..b3e50f7aa 100644
--- a/controller/ovn-controller.c
+++ b/controller/ovn-controller.c
@@ -5096,10 +5096,36 @@ route_runtime_data_handler(struct engine_node *node, 
void *data)
     struct ed_type_runtime_data *rt_data =
         engine_get_input_data("runtime_data", node);
 
+    const struct ovsrec_open_vswitch_table *ovs_table =
+        EN_OVSDB_GET(engine_get_input("OVS_open_vswitch", node));
+    const char *chassis_id = get_ovs_chassis_id(ovs_table);
+    ovs_assert(chassis_id);
+
+    struct ovsdb_idl_index *sbrec_chassis_by_name =
+        engine_ovsdb_node_get_index(
+                engine_get_input("SB_chassis", node),
+                "name");
+    const struct sbrec_chassis *chassis
+        = chassis_lookup_by_name(sbrec_chassis_by_name, chassis_id);
+    ovs_assert(chassis);
+
+    struct ovsdb_idl_index *sbrec_port_binding_by_name =
+        engine_ovsdb_node_get_index(
+                engine_get_input("SB_port_binding", node),
+                "name");
+
     if (!rt_data->tracked) {
         return false;
     }
 
+    /* There are the following cases where we need to handle updates to
+     * runtime_data:
+     * 1. A datapath binding has changed that is already taking part in route
+     *    exchange.
+     * 2. A route-exchange relevant port went form local to remote or the
+     *    other way round.
+     * 2. A tracked_port went from local to remote or the other way round.
+     * */
     struct tracked_datapath *t_dp;
     HMAP_FOR_EACH (t_dp, node, &rt_data->tracked_dp_bindings) {
         struct tracked_datapath *re_t_dp =
@@ -5114,7 +5140,10 @@ route_runtime_data_handler(struct engine_node *node, 
void *data)
         struct shash_node *shash_node;
         SHASH_FOR_EACH (shash_node, &t_dp->lports) {
             struct tracked_lport *lport = shash_node->data;
-            if (route_exchange_relevant_port(lport->pb)) {
+
+            if (route_exchange_find_port(sbrec_port_binding_by_name, chassis,
+                                         &rt_data->active_tunnels,
+                                         lport->pb)) {
                 /* XXX: Until we get I-P support for route exchange we need to
                  * request recompute. */
                 return false;
@@ -5174,6 +5203,16 @@ route_sb_port_binding_data_handler(struct engine_node 
*node, void *data)
     struct ed_type_runtime_data *rt_data =
         engine_get_input_data("runtime_data", node);
 
+
+    /* There are the following cases where we need to handle updates to the
+     * port_binding table:
+     * 1. The port_binding is part of a router datapath that already takes
+     *    part in route exchange.
+     * 2. The port_binding is now becoming part of route exchange.
+     *
+     * We do not need to handle port_bindings that are tracked_ports and switch
+     * between being local and remote. This is handled as part of the
+     * runtime_data handler. */
     const struct sbrec_port_binding *sbrec_pb;
     SBREC_PORT_BINDING_TABLE_FOR_EACH_TRACKED (sbrec_pb, pb_table) {
         struct tracked_datapath *re_t_dp =
@@ -5185,32 +5224,12 @@ route_sb_port_binding_data_handler(struct engine_node 
*node, void *data)
             return false;
         }
 
-        if (route_exchange_relevant_port(sbrec_pb)) {
+        if (route_exchange_find_port(sbrec_port_binding_by_name, chassis,
+                                     &rt_data->active_tunnels, sbrec_pb)) {
             /* XXX: Until we get I-P support for route exchange we need to
              * request recompute. */
             return false;
         }
-
-        if (sset_contains(&re_data->tracked_ports_local,
-                          sbrec_pb->logical_port)) {
-            if (!route_exchange_find_port(sbrec_port_binding_by_name, chassis,
-                                          &rt_data->active_tunnels,
-                                          sbrec_pb)) {
-                /* The port was previously local but now it no longer is. */
-                return false;
-            }
-        }
-
-        if (sset_contains(&re_data->tracked_ports_remote,
-                          sbrec_pb->logical_port)) {
-            if (route_exchange_find_port(sbrec_port_binding_by_name, chassis,
-                                         &rt_data->active_tunnels,
-                                         sbrec_pb)) {
-                /* The port was previously remote but now we bound it. */
-                return false;
-            }
-        }
-
     }
 
     return true;
@@ -5223,13 +5242,27 @@ route_sb_advertised_route_data_handler(struct 
engine_node *node, void *data)
     const struct sbrec_advertised_route_table *advertised_route_table =
         EN_OVSDB_GET(engine_get_input("SB_advertised_route", node));
 
+    /* There are the following cases where we need to handle updates to the
+     * advertised_route table:
+     * 1. The advertised_route is created or deleted and we know about its
+     *    datapath locally.
+     *
+     * Updates to advertised_route can generally be ignored as northd will not
+     * update these entries. We also get update notifications if a referenced
+     * port_binding is updated, but these are handled in the runtime_data
+     * handler. */
     const struct sbrec_advertised_route *sbrec_route;
     SBREC_ADVERTISED_ROUTE_TABLE_FOR_EACH_TRACKED (sbrec_route,
                                                    advertised_route_table) {
         struct tracked_datapath *re_t_dp =
             tracked_datapath_find(&re_data->tracked_route_datapaths,
                                   sbrec_route->datapath);
-        if (re_t_dp) {
+        if (!re_t_dp) {
+            continue;
+        }
+
+        if (sbrec_advertised_route_is_new(sbrec_route) ||
+                sbrec_advertised_route_is_deleted(sbrec_route)) {
             /* XXX: Until we get I-P support for route exchange we need to
              * request recompute. */
             return false;
-- 
2.43.0


_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to