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     | 10 +++--
 northd/en-multicast.c |  3 +-
 northd/lflow-mgr.c    |  4 ++
 northd/northd.c       | 97 +++++++++++++++++++++++++++++++++++--------
 northd/northd.h       |  7 +++-
 tests/ovn-northd.at   | 11 +++--
 6 files changed, 105 insertions(+), 27 deletions(-)

diff --git a/northd/en-lflow.c b/northd/en-lflow.c
index cc525c806..15431262a 100644
--- a/northd/en-lflow.c
+++ b/northd/en-lflow.c
@@ -148,9 +148,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;
@@ -165,6 +162,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,
diff --git a/northd/en-multicast.c b/northd/en-multicast.c
index a7dfd71c4..97b12f6a3 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 bc02697b7..d5303a571 100644
--- a/northd/lflow-mgr.c
+++ b/northd/lflow-mgr.c
@@ -772,6 +772,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);
diff --git a/northd/northd.c b/northd/northd.c
index 8d034ee1d..ca8ca9fa2 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -5848,10 +5848,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
@@ -19074,29 +19077,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);
 }
@@ -19871,6 +19881,57 @@ 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->dps,
+                    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->dps,
+                    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,
diff --git a/northd/northd.h b/northd/northd.h
index 8bfd9b804..5f21ec487 100644
--- a/northd/northd.h
+++ b/northd/northd.h
@@ -482,8 +482,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;
 };
 
@@ -954,6 +953,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 *,
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 81c36887e..cace07dfd 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" \
@@ -3148,11 +3152,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)
@@ -14958,7 +14963,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.
@@ -14996,7 +15001,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.53.0

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

Reply via email to