From: Lorenzo Bianconi <lorenzo.bianc...@redhat.com>

Introduce Incremental Processing logic for en-datapath-logical-switch
node.

Reported-at: https://issues.redhat.com/browse/FDP-1519
Signed-off-by: Lorenzo Bianconi <lorenzo.bianc...@redhat.com>
---
 northd/en-datapath-logical-switch.c | 182 ++++++++++++++++++++--------
 northd/en-datapath-logical-switch.h |   3 +
 northd/inc-proc-northd.c            |   8 +-
 tests/ovn-northd.at                 |  28 +++++
 4 files changed, 168 insertions(+), 53 deletions(-)

diff --git a/northd/en-datapath-logical-switch.c 
b/northd/en-datapath-logical-switch.c
index 23fa9725f..83d065dae 100644
--- a/northd/en-datapath-logical-switch.c
+++ b/northd/en-datapath-logical-switch.c
@@ -38,72 +38,154 @@ en_datapath_logical_switch_init(struct engine_node *node 
OVS_UNUSED,
     return map;
 }
 
-enum engine_node_state
-en_datapath_logical_switch_run(struct engine_node *node , void *data)
+static uint32_t
+get_requested_tunnel_key(const struct nbrec_logical_switch *nbs,
+                         bool vxlan_mode)
+{
+    uint32_t requested_tunnel_key = smap_get_int(&nbs->other_config,
+                                                 "requested-tnl-key", 0);
+    const char *ts = smap_get(&nbs->other_config, "interconn-ts");
+
+    if (!ts && vxlan_mode && requested_tunnel_key >= 1 << 12) {
+        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
+        VLOG_WARN_RL(&rl, "Tunnel key %"PRIu32" for datapath %s is "
+                     "incompatible with VXLAN", requested_tunnel_key,
+                     nbs->name);
+        requested_tunnel_key = 0;
+    }
+
+    return requested_tunnel_key;
+}
+
+static void
+gather_external_ids(const struct nbrec_logical_switch *nbs,
+                    struct smap *external_ids)
+{
+    smap_add(external_ids, "name", nbs->name);
+    const char *neutron_network = smap_get(&nbs->other_config,
+                                           "neutron:network_name");
+    if (neutron_network && neutron_network[0]) {
+        smap_add(external_ids, "name2", neutron_network);
+    }
+
+    int64_t ct_zone_limit = ovn_smap_get_llong(&nbs->other_config,
+                                               "ct-zone-limit", -1);
+    if (ct_zone_limit > 0) {
+        smap_add_format(external_ids, "ct-zone-limit", "%"PRId64,
+                        ct_zone_limit);
+    }
+
+    const char *ts = smap_get(&nbs->other_config, "interconn-ts");
+    if (ts) {
+        smap_add(external_ids, "interconn-ts", ts);
+    }
+
+    uint32_t age_threshold = smap_get_uint(&nbs->other_config,
+                                           "fdb_age_threshold", 0);
+    if (age_threshold) {
+        smap_add_format(external_ids, "fdb_age_threshold",
+                        "%u", age_threshold);
+    }
+
+    /* For backwards-compatibility, also store the NB UUID in
+     * external-ids:logical-switch. This is useful if ovn-controller
+     * has not updated and expects this to be where to find the
+     * UUID.
+     */
+    smap_add_format(external_ids, "logical-switch", UUID_FMT,
+                    UUID_ARGS(&nbs->header_.uuid));
+}
+
+static struct ovn_unsynced_datapath *
+datapath_unsynced_new_logical_switch_handler(
+        const struct nbrec_logical_switch *nbs,
+        const struct ed_type_global_config *global_config,
+        struct ovn_unsynced_datapath_map *map)
+{
+    uint32_t requested_tunnel_key = get_requested_tunnel_key(
+        nbs, global_config->vxlan_mode);
+
+    struct ovn_unsynced_datapath *udp =
+        ovn_unsynced_datapath_alloc(nbs->name, DP_SWITCH,
+                                    requested_tunnel_key, &nbs->header_);
+
+    gather_external_ids(nbs, &udp->external_ids);
+    hmap_insert(&map->dps, &udp->hmap_node, uuid_hash(&nbs->header_.uuid));
+    return udp;
+}
+
+enum engine_input_handler_result
+datapath_logical_switch_handler(struct engine_node *node, void *data)
 {
     const struct nbrec_logical_switch_table *nb_ls_table =
         EN_OVSDB_GET(engine_get_input("NB_logical_switch", node));
     const struct ed_type_global_config *global_config =
         engine_get_input_data("global_config", node);
-
+    enum engine_input_handler_result ret = EN_HANDLED_UNCHANGED;
     struct ovn_unsynced_datapath_map *map = data;
 
-    ovn_unsynced_datapath_map_destroy(map);
-    ovn_unsynced_datapath_map_init(map, DP_SWITCH);
-
     const struct nbrec_logical_switch *nbs;
-    NBREC_LOGICAL_SWITCH_TABLE_FOR_EACH (nbs, nb_ls_table) {
-        uint32_t requested_tunnel_key = smap_get_int(&nbs->other_config,
-                                                     "requested-tnl-key", 0);
-        const char *ts = smap_get(&nbs->other_config, "interconn-ts");
-
-        if (!ts && global_config->vxlan_mode &&
-            requested_tunnel_key >= 1 << 12) {
-            static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
-            VLOG_WARN_RL(&rl, "Tunnel key %"PRIu32" for datapath %s is "
-                         "incompatible with VXLAN", requested_tunnel_key,
-                         nbs->name);
-            requested_tunnel_key = 0;
-        }
+    NBREC_LOGICAL_SWITCH_TABLE_FOR_EACH_TRACKED (nbs, nb_ls_table) {
+        struct ovn_unsynced_datapath *udp =
+            ovn_unsynced_datapath_find(map, &nbs->header_.uuid);
 
-        struct ovn_unsynced_datapath *dp
-            = ovn_unsynced_datapath_alloc(nbs->name, DP_SWITCH,
-                                          requested_tunnel_key, &nbs->header_);
+        if (nbrec_logical_switch_is_new(nbs)) {
+            if (udp) {
+                return EN_UNHANDLED;
+            }
+            udp = datapath_unsynced_new_logical_switch_handler(nbs,
+                                                               global_config,
+                                                               map);
+            hmapx_add(&map->new, udp);
+            ret = EN_HANDLED_UPDATED;
+        } else if (nbrec_logical_switch_is_deleted(nbs)) {
+            if (!udp) {
+                return EN_UNHANDLED;
+            }
+            hmap_remove(&map->dps, &udp->hmap_node);
+            hmapx_add(&map->deleted, udp);
+            ret = EN_HANDLED_UPDATED;
+        } else {
+            if (!udp) {
+                return EN_UNHANDLED;
+            }
 
-        smap_add(&dp->external_ids, "name", dp->name);
-        const char *neutron_network = smap_get(&nbs->other_config,
-                                               "neutron:network_name");
-        if (neutron_network && neutron_network[0]) {
-            smap_add(&dp->external_ids, "name2", neutron_network);
+            udp->requested_tunnel_key = get_requested_tunnel_key(
+                    nbs, global_config->vxlan_mode);
+            smap_destroy(&udp->external_ids);
+            smap_init(&udp->external_ids);
+            gather_external_ids(nbs, &udp->external_ids);
+            hmapx_add(&map->updated, udp);
+            ret = EN_HANDLED_UPDATED;
         }
+    }
 
-        int64_t ct_zone_limit = ovn_smap_get_llong(&nbs->other_config,
-                                                   "ct-zone-limit", -1);
-        if (ct_zone_limit > 0) {
-            smap_add_format(&dp->external_ids, "ct-zone-limit", "%"PRId64,
-                            ct_zone_limit);
-        }
+    return ret;
+}
 
-        if (ts) {
-            smap_add(&dp->external_ids, "interconn-ts", ts);
-        }
+void
+en_datapath_logical_switch_clear_tracked_data(void *data)
+{
+    struct ovn_unsynced_datapath_map *map = data;
+    ovn_unsynced_datapath_map_clear_tracked_data(map);
+}
 
-        uint32_t age_threshold = smap_get_uint(&nbs->other_config,
-                                               "fdb_age_threshold", 0);
-        if (age_threshold) {
-            smap_add_format(&dp->external_ids, "fdb_age_threshold",
-                            "%u", age_threshold);
-        }
+enum engine_node_state
+en_datapath_logical_switch_run(struct engine_node *node , void *data)
+{
+    const struct nbrec_logical_switch_table *nb_ls_table =
+        EN_OVSDB_GET(engine_get_input("NB_logical_switch", node));
+    const struct ed_type_global_config *global_config =
+        engine_get_input_data("global_config", node);
 
-        /* For backwards-compatibility, also store the NB UUID in
-         * external-ids:logical-switch. This is useful if ovn-controller
-         * has not updated and expects this to be where to find the
-         * UUID.
-         */
-        smap_add_format(&dp->external_ids, "logical-switch", UUID_FMT,
-                        UUID_ARGS(&nbs->header_.uuid));
+    struct ovn_unsynced_datapath_map *map = data;
+
+    ovn_unsynced_datapath_map_destroy(map);
+    ovn_unsynced_datapath_map_init(map, DP_SWITCH);
 
-        hmap_insert(&map->dps, &dp->hmap_node, uuid_hash(&nbs->header_.uuid));
+    const struct nbrec_logical_switch *nbs;
+    NBREC_LOGICAL_SWITCH_TABLE_FOR_EACH (nbs, nb_ls_table) {
+        datapath_unsynced_new_logical_switch_handler(nbs, global_config, map);
     }
 
     return EN_UPDATED;
diff --git a/northd/en-datapath-logical-switch.h 
b/northd/en-datapath-logical-switch.h
index 1bd5fea83..2a5a97b18 100644
--- a/northd/en-datapath-logical-switch.h
+++ b/northd/en-datapath-logical-switch.h
@@ -23,9 +23,12 @@
 void *en_datapath_logical_switch_init(struct engine_node *,
                                       struct engine_arg *);
 
+enum engine_input_handler_result
+datapath_logical_switch_handler(struct engine_node *, void *data);
 enum engine_node_state en_datapath_logical_switch_run(struct engine_node *,
                                                       void *data);
 void en_datapath_logical_switch_cleanup(void *data);
+void en_datapath_logical_switch_clear_tracked_data(void *data);
 
 struct ovn_synced_logical_switch {
     struct hmap_node hmap_node;
diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c
index bf1a09c08..0dfbf00b5 100644
--- a/northd/inc-proc-northd.c
+++ b/northd/inc-proc-northd.c
@@ -183,7 +183,7 @@ static ENGINE_NODE(learned_route_sync, CLEAR_TRACKED_DATA);
 static ENGINE_NODE(dynamic_routes);
 static ENGINE_NODE(group_ecmp_route, CLEAR_TRACKED_DATA);
 static ENGINE_NODE(datapath_logical_router, CLEAR_TRACKED_DATA);
-static ENGINE_NODE(datapath_logical_switch);
+static ENGINE_NODE(datapath_logical_switch, CLEAR_TRACKED_DATA);
 static ENGINE_NODE(datapath_sync);
 static ENGINE_NODE(datapath_synced_logical_router);
 static ENGINE_NODE(datapath_synced_logical_switch);
@@ -217,8 +217,10 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
     engine_add_input(&en_acl_id, &en_nb_acl, NULL);
     engine_add_input(&en_acl_id, &en_sb_acl_id, NULL);
 
-    engine_add_input(&en_datapath_logical_switch, &en_nb_logical_switch, NULL);
-    engine_add_input(&en_datapath_logical_switch, &en_global_config, NULL);
+    engine_add_input(&en_datapath_logical_switch, &en_nb_logical_switch,
+                     datapath_logical_switch_handler);
+    engine_add_input(&en_datapath_logical_switch, &en_global_config,
+                     datapath_logical_switch_handler);
 
     engine_add_input(&en_datapath_logical_router, &en_nb_logical_router,
                      en_datapath_logical_router_logical_router_handler);
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 64506e79e..76b59408c 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -17778,3 +17778,31 @@ CHECK_NO_CHANGE_AFTER_RECOMPUTE
 
 AT_CLEANUP
 ])
+
+OVN_FOR_EACH_NORTHD_NO_HV([
+AT_SETUP([Datapath Logical switch incremental processing])
+ovn_start
+
+check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
+check ovn-nbctl --wait=sb ls-add sw0
+check_engine_stats datapath_logical_switch norecompute compute
+CHECK_NO_CHANGE_AFTER_RECOMPUTE
+
+check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
+check ovn-nbctl --wait=sb set logical_switch sw0 
other_config:fdb_age_threshold=5
+check_engine_stats datapath_logical_switch norecompute compute
+CHECK_NO_CHANGE_AFTER_RECOMPUTE
+
+check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
+check ovn-nbctl --wait=sb set logical_switch sw0 
other_config:requested-tnl-key=123
+check_engine_stats datapath_logical_switch norecompute compute
+CHECK_NO_CHANGE_AFTER_RECOMPUTE
+
+check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
+check ovn-nbctl --wait=sb ls-del sw0
+check_engine_stats datapath_logical_switch norecompute compute
+CHECK_NO_CHANGE_AFTER_RECOMPUTE
+
+AT_CLEANUP
+])
+
-- 
2.49.0

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

Reply via email to