Introduce logical-flows incremental processing support for
logical_switch creation/deletion.

Reported-at: https://issues.redhat.com/browse/FDP-759
Signed-off-by: Lorenzo Bianconi <[email protected]>
---
 northd/en-lflow.c       |  13 ++--
 northd/en-ls-stateful.c |   6 +-
 northd/en-multicast.c   |   3 +-
 northd/lflow-mgr.c      |   8 ++-
 northd/northd.c         | 131 ++++++++++++++++++++++++++++++++--------
 northd/northd.h         |   8 ++-
 tests/ovn-northd.at     |  13 +++-
 7 files changed, 144 insertions(+), 38 deletions(-)

diff --git a/northd/en-lflow.c b/northd/en-lflow.c
index 30bf7e35c..14a211bbb 100644
--- a/northd/en-lflow.c
+++ b/northd/en-lflow.c
@@ -145,10 +145,6 @@ lflow_northd_handler(struct engine_node *node,
         return EN_UNHANDLED;
     }
 
-    if (northd_has_lswitches_in_tracked_data(&northd_data->trk_data)) {
-        return EN_UNHANDLED;
-    }
-
     const struct engine_context *eng_ctx = engine_get_context();
     struct lflow_data *lflow_data = data;
 
@@ -162,6 +158,13 @@ lflow_northd_handler(struct engine_node *node,
         return EN_UNHANDLED;
     }
 
+    if (!lflow_handle_northd_ls_changes(eng_ctx->ovnsb_idl_txn,
+                                        &northd_data->trk_data.trk_switches,
+                                        &lflow_input,
+                                        lflow_data->lflow_table)) {
+        return EN_UNHANDLED;
+    }
+
     if (!lflow_handle_northd_port_changes(eng_ctx->ovnsb_idl_txn,
                                           &northd_data->trk_data.trk_lsps,
                                           &lflow_input,
@@ -214,6 +217,7 @@ lflow_ls_stateful_handler(struct engine_node *node, void 
*data)
         return EN_UNHANDLED;
     }
 
+    struct northd_data *northd_data = engine_get_input_data("northd", node);
     const struct engine_context *eng_ctx = engine_get_context();
     struct lflow_data *lflow_data = data;
     struct lflow_input lflow_input;
@@ -221,6 +225,7 @@ lflow_ls_stateful_handler(struct engine_node *node, void 
*data)
     lflow_get_input_data(node, &lflow_input);
     if (!lflow_handle_ls_stateful_changes(eng_ctx->ovnsb_idl_txn,
                                           &ls_sful_data->trk_data,
+                                          &northd_data->trk_data.trk_switches,
                                           &lflow_input,
                                           lflow_data->lflow_table)) {
         return EN_UNHANDLED;
diff --git a/northd/en-ls-stateful.c b/northd/en-ls-stateful.c
index a9a685504..0dea24aee 100644
--- a/northd/en-ls-stateful.c
+++ b/northd/en-ls-stateful.c
@@ -161,8 +161,10 @@ ls_stateful_northd_handler(struct engine_node *node, void 
*data_)
         const struct ovn_datapath *od = hmapx_node->data;
 
         if (!ls_stateful_table_find_(&data->table, od->nbs)) {
-            ls_stateful_record_create(&data->table, od,
-                                      input_data.ls_port_groups);
+            struct ls_stateful_record *ls_stateful_rec =
+                ls_stateful_record_create(&data->table, od,
+                                          input_data.ls_port_groups);
+            hmapx_add(&data->trk_data.crupdated, ls_stateful_rec);
         }
     }
 
diff --git a/northd/en-multicast.c b/northd/en-multicast.c
index f63825c8d..73f73db9b 100644
--- a/northd/en-multicast.c
+++ b/northd/en-multicast.c
@@ -153,7 +153,8 @@ multicast_igmp_northd_handler(struct engine_node *node, 
void *data OVS_UNUSED)
         return EN_UNHANDLED;
     }
 
-    if (hmapx_count(&northd_data->trk_data.trk_switches.deleted)) {
+    if (hmapx_count(&northd_data->trk_data.trk_switches.crupdated) ||
+        hmapx_count(&northd_data->trk_data.trk_switches.deleted)) {
         return EN_UNHANDLED;
     }
 
diff --git a/northd/lflow-mgr.c b/northd/lflow-mgr.c
index d1fbc2196..f2eb2851c 100644
--- a/northd/lflow-mgr.c
+++ b/northd/lflow-mgr.c
@@ -745,6 +745,10 @@ lflow_table_add_lflow(struct lflow_table *lflow_table,
             hmap_insert(&lflow_ref->lflow_ref_nodes, &lrn->ref_node, hash);
         }
 
+        if (lrn->dpgrp_lflow) {
+            dynamic_bitmap_realloc(&lrn->dpgrp_bitmap, dp_bitmap_len);
+        }
+
         if (!lrn->linked) {
             if (lrn->dpgrp_lflow) {
                 ovs_assert(lrn->dpgrp_bitmap.capacity == dp_bitmap_len);
@@ -1277,7 +1281,9 @@ ovn_sb_insert_or_update_logical_dp_group(
     BITMAP_FOR_EACH_1 (index, ods_size(datapaths), dpg_bitmap) {
         struct ovn_datapath *od = vector_get(&datapaths->dps, index,
                                              struct ovn_datapath *);
-        sb[n++] = od->sdp->sb_dp;
+        if (od) {
+            sb[n++] = od->sdp->sb_dp;
+        }
     }
     if (!dp_group) {
         struct uuid dpg_uuid = uuid_random();
diff --git a/northd/northd.c b/northd/northd.c
index e978b66c2..8042298f1 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -5729,10 +5729,13 @@ enum mirror_filter {
 
 static void
 build_mirror_default_lflow(struct ovn_datapath *od,
-                           struct lflow_table *lflows)
+                           struct lflow_table *lflows,
+                           struct lflow_ref *lflow_ref)
 {
-    ovn_lflow_add(lflows, od, S_SWITCH_IN_MIRROR, 0, "1", "next;", NULL);
-    ovn_lflow_add(lflows, od, S_SWITCH_OUT_MIRROR, 0, "1", "next;", NULL);
+    ovn_lflow_add(lflows, od, S_SWITCH_IN_MIRROR, 0, "1", "next;",
+                  lflow_ref);
+    ovn_lflow_add(lflows, od, S_SWITCH_OUT_MIRROR, 0, "1", "next;",
+                  lflow_ref);
 }
 
 static void
@@ -18582,29 +18585,36 @@ build_lswitch_and_lrouter_iterate_by_ls(struct 
ovn_datapath *od,
                                         struct lswitch_flow_build_info *lsi)
 {
     ovs_assert(od->nbs);
-    build_mirror_default_lflow(od, lsi->lflows);
+    build_mirror_default_lflow(od, lsi->lflows, od->datapath_lflows);
     build_lswitch_lflows_pre_acl_and_acl(od, lsi->lflows,
-                                         lsi->meter_groups, NULL);
-    build_network_function(od, lsi->lflows, lsi->ls_port_groups, NULL);
-    build_fwd_group_lflows(od, lsi->lflows, NULL);
-    build_lswitch_lflows_admission_control(od, lsi->lflows, NULL);
-    build_lswitch_learn_fdb_od(od, lsi->lflows, NULL);
-    build_lswitch_arp_nd_responder_default(od, lsi->lflows, NULL);
+                                         lsi->meter_groups,
+                                         od->datapath_lflows);
+    build_network_function(od, lsi->lflows, lsi->ls_port_groups,
+                           od->datapath_lflows);
+    build_fwd_group_lflows(od, lsi->lflows, od->datapath_lflows);
+    build_lswitch_lflows_admission_control(od, lsi->lflows,
+                                           od->datapath_lflows);
+    build_lswitch_learn_fdb_od(od, lsi->lflows, od->datapath_lflows);
+    build_lswitch_arp_nd_responder_default(od, lsi->lflows,
+                                           od->datapath_lflows);
     build_lswitch_dns_lookup_and_response(od, lsi->lflows, lsi->meter_groups,
-                                          NULL);
-    build_lswitch_dhcp_and_dns_defaults(od, lsi->lflows, NULL);
+                                          od->datapath_lflows);
+    build_lswitch_dhcp_and_dns_defaults(od, lsi->lflows, od->datapath_lflows);
     build_lswitch_destination_lookup_bmcast(od, lsi->lflows, &lsi->actions,
-                                            lsi->meter_groups, NULL);
-    build_lswitch_output_port_sec_od(od, lsi->lflows, NULL);
+                                            lsi->meter_groups,
+                                            od->datapath_lflows);
+    build_lswitch_output_port_sec_od(od, lsi->lflows, od->datapath_lflows);
     /* CT extraction flows are built with stateful flows, but default rule is
      * always needed */
     ovn_lflow_add(lsi->lflows, od, S_SWITCH_IN_CT_EXTRACT, 0, "1", "next;",
-                  NULL);
-    build_lswitch_lb_affinity_default_flows(od, lsi->lflows, NULL);
+                  od->datapath_lflows);
+    build_lswitch_lb_affinity_default_flows(od, lsi->lflows,
+                                            od->datapath_lflows);
     if (od->has_evpn_vni) {
-        build_lswitch_lflows_evpn_l2_unknown(od, lsi->lflows, NULL);
+        build_lswitch_lflows_evpn_l2_unknown(od, lsi->lflows,
+                                             od->datapath_lflows);
     } else {
-        build_lswitch_lflows_l2_unknown(od, lsi->lflows, NULL);
+        build_lswitch_lflows_l2_unknown(od, lsi->lflows, od->datapath_lflows);
     }
     build_mcast_flood_lswitch(od, lsi->lflows, &lsi->actions, NULL);
 }
@@ -19341,6 +19351,61 @@ lflow_handle_northd_lr_changes(struct ovsdb_idl_txn 
*ovnsb_txn,
     return handled;
 }
 
+bool
+lflow_handle_northd_ls_changes(struct ovsdb_idl_txn *ovnsb_txn,
+                               struct tracked_dps *tracked_ls,
+                               struct lflow_input *lflow_input,
+                               struct lflow_table *lflows)
+{
+    struct hmapx_node *hmapx_node;
+    struct ovn_datapath *od;
+
+    HMAPX_FOR_EACH (hmapx_node, &tracked_ls->deleted) {
+        od = hmapx_node->data;
+        if (!lflow_ref_resync_flows(
+                    od->datapath_lflows, lflows, ovnsb_txn,
+                    lflow_input->ls_datapaths,
+                    lflow_input->lr_datapaths,
+                    lflow_input->ovn_internal_version_changed,
+                    lflow_input->sbrec_logical_flow_table,
+                    lflow_input->sbrec_logical_dp_group_table)) {
+            return false;
+        }
+    }
+
+    struct lswitch_flow_build_info lsi = {
+        .meter_groups = lflow_input->meter_groups,
+        .ls_port_groups = lflow_input->ls_port_groups,
+        .lflows = lflows,
+        .match = DS_EMPTY_INITIALIZER,
+        .actions = DS_EMPTY_INITIALIZER,
+    };
+
+    HMAPX_FOR_EACH (hmapx_node, &tracked_ls->crupdated) {
+        od = hmapx_node->data;
+        lflow_ref_unlink_lflows(od->datapath_lflows);
+        build_lswitch_and_lrouter_iterate_by_ls(od, &lsi);
+    }
+
+    ds_destroy(&lsi.actions);
+    ds_destroy(&lsi.match);
+
+    HMAPX_FOR_EACH (hmapx_node, &tracked_ls->crupdated) {
+        od = hmapx_node->data;
+        if (!lflow_ref_sync_lflows(
+                    od->datapath_lflows, lflows, ovnsb_txn,
+                    lflow_input->ls_datapaths,
+                    lflow_input->lr_datapaths,
+                    lflow_input->ovn_internal_version_changed,
+                    lflow_input->sbrec_logical_flow_table,
+                    lflow_input->sbrec_logical_dp_group_table)) {
+            return false;
+         }
+    }
+
+    return true;
+}
+
 bool
 lflow_handle_northd_port_changes(struct ovsdb_idl_txn *ovnsb_txn,
                                  struct tracked_ovn_ports *trk_lsps,
@@ -19658,6 +19723,7 @@ exit:
 bool
 lflow_handle_ls_stateful_changes(struct ovsdb_idl_txn *ovnsb_txn,
                                 struct ls_stateful_tracked_data *trk_data,
+                                struct tracked_dps *tracked_ls,
                                 struct lflow_input *lflow_input,
                                 struct lflow_table *lflows)
 {
@@ -19700,13 +19766,28 @@ lflow_handle_ls_stateful_changes(struct ovsdb_idl_txn 
*ovnsb_txn,
 
     HMAPX_FOR_EACH (hmapx_node, &trk_data->deleted) {
         struct ls_stateful_record *ls_stateful_rec = hmapx_node->data;
-        const struct ovn_datapath *od =
-            ovn_datapaths_find_by_index(lflow_input->ls_datapaths,
-                                        ls_stateful_rec->ls_index);
-        ovs_assert(od->nbs && uuid_equals(&od->nbs->header_.uuid,
-                                          &ls_stateful_rec->nbs_uuid));
-
-        lflow_ref_unlink_lflows(ls_stateful_rec->lflow_ref);
+        const struct ovn_datapath *od = NULL;
+        struct hmapx_node *n;
+        HMAPX_FOR_EACH (n, &tracked_ls->deleted) {
+           const struct ovn_datapath *iter = n->data;
+           if (iter->index == ls_stateful_rec->ls_index) {
+               od = iter;
+               break;
+           }
+        }
+        if (od) {
+            ovs_assert(od->nbs && uuid_equals(&od->nbs->header_.uuid,
+                                              &ls_stateful_rec->nbs_uuid));
+            if (!lflow_ref_resync_flows(
+                        ls_stateful_rec->lflow_ref, lflows, ovnsb_txn,
+                        lflow_input->ls_datapaths,
+                        lflow_input->lr_datapaths,
+                        lflow_input->ovn_internal_version_changed,
+                        lflow_input->sbrec_logical_flow_table,
+                        lflow_input->sbrec_logical_dp_group_table)) {
+                return false;
+            }
+        }
     }
 
     return true;
diff --git a/northd/northd.h b/northd/northd.h
index 32134d36e..2af238eea 100644
--- a/northd/northd.h
+++ b/northd/northd.h
@@ -473,8 +473,7 @@ struct ovn_datapath {
     /* Map of ovn_port objects belonging to this datapath.
      * This map doesn't include derived ports. */
     struct hmap ports;
-    /* Reference to the lflows belonging to this datapath currently router
-     * only lflows. */
+    /* Reference to the lflows belonging to this datapath. */
     struct lflow_ref *datapath_lflows;
 };
 
@@ -941,6 +940,10 @@ bool lflow_handle_northd_lr_changes(struct ovsdb_idl_txn 
*ovnsh_txn,
                                      struct tracked_dps *,
                                      struct lflow_input *,
                                      struct lflow_table *lflows);
+bool lflow_handle_northd_ls_changes(struct ovsdb_idl_txn *ovnsb_txn,
+                                    struct tracked_dps *,
+                                    struct lflow_input *,
+                                    struct lflow_table *lflows);
 bool lflow_handle_northd_port_changes(struct ovsdb_idl_txn *ovnsb_txn,
                                       struct tracked_ovn_ports *,
                                       struct lflow_input *,
@@ -955,6 +958,7 @@ bool lflow_handle_lr_stateful_changes(struct ovsdb_idl_txn 
*,
                                       struct lflow_table *lflows);
 bool lflow_handle_ls_stateful_changes(struct ovsdb_idl_txn *,
                                       struct ls_stateful_tracked_data *,
+                                      struct tracked_dps *,
                                       struct lflow_input *,
                                       struct lflow_table *lflows);
 bool northd_handle_sb_port_binding_changes(
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index f7ec6a33a..7f97e02f1 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -2959,6 +2959,8 @@ OVN_FOR_EACH_NORTHD_NO_HV([
 AT_SETUP([check VXLAN mode disabling])
 ovn_start
 
+OVS_CTL_TIMEOUT=120
+
 # Create a fake chassis with vxlan encap to implicitly enable VXLAN mode.
 check_uuid ovn-sbctl \
     --id=@e create encap chassis_name=hv1 ip="192.168.0.1" type="vxlan" \
@@ -2994,6 +2996,8 @@ OVN_FOR_EACH_NORTHD_NO_HV([
 AT_SETUP([check datapath tunnel ids exhaustion])
 ovn_start
 
+OVS_CTL_TIMEOUT=120
+
 # Create a fake chassis with vxlan encap to lower MAX DP tunnel key to 2^12
 check_uuid ovn-sbctl \
     --id=@e create encap chassis_name=hv1 ip="192.168.0.1" type="vxlan" \
@@ -3057,6 +3061,8 @@ OVN_FOR_EACH_NORTHD_NO_HV([
 AT_SETUP([check LS/LR single line configuration])
 ovn_start
 
+OVS_CTL_TIMEOUT=120
+
 cmd=""
 for i in {1..2048..1}; do
     cmd="${cmd} -- ls-add lsw-${i}"
@@ -3147,11 +3153,12 @@ check_row_count sb:logical_dp_group 1
 echo "$sw2_sb_uuid" >> sw_sb_uuids
 
 AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find 
Logical_DP_Group dnl
-                    | grep -A1 $ls_dpg_uuid | tail -1 | tr ' ' '\n' | sort], 
[0], [dnl
+                    | tail -1 | tr ' ' '\n' | sort], [0], [dnl
 $(cat sw_sb_uuids | sort)
 ])
 
 dnl Add two routers and check that they are in their new separate group.
+ls_dpg_uuid=$(ovn-sbctl --bare --columns _uuid list Logical_DP_Group .)
 check ovn-nbctl --wait=sb lr-add lr0 -- lr-add lr1
 lr0_sb_uuid=$(fetch_column datapath_binding _uuid external_ids:name=lr0)
 lr1_sb_uuid=$(fetch_column datapath_binding _uuid external_ids:name=lr1)
@@ -14685,7 +14692,7 @@ check as northd ovn-appctl -t ovn-northd 
inc-engine/clear-stats
 check ovn-nbctl --wait=sb ls-add sw0
 check_engine_stats northd norecompute compute
 check_engine_stats ls_stateful norecompute compute
-check_engine_stats lflow recompute nocompute
+check_engine_stats lflow norecompute compute
 
 # For the below engine nodes, en_northd is input.  So check
 # their engine status.
@@ -14723,7 +14730,7 @@ check as northd ovn-appctl -t ovn-northd 
inc-engine/clear-stats
 check ovn-nbctl --wait=sb ls-del sw0
 check_engine_stats northd norecompute compute
 check_engine_stats ls_stateful norecompute compute
-check_engine_stats lflow recompute nocompute
+check_engine_stats lflow norecompute compute
 
 # For the below engine nodes, en_northd is input.  So check
 # their engine status.
-- 
2.52.0

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

Reply via email to