When a router is created or destroyed add the ability to en-lflow
engine to compute the new router lflows instead of recalculating the
whole database.

Acked-by: Lorenzo Bianconi <[email protected]>
Reported-by: Dumitru Ceara <[email protected]>
Reported-at: https://issues.redhat.com/browse/FDP-757
Signed-off-by: Jacob Tanenbaum <[email protected]>

----

v4:
    - added ack by Lorenzo

v5:
    - changed lflow_ref name to be more generic

diff --git a/northd/en-lflow.c b/northd/en-lflow.c
index 95c88ecea..e80fd9f9c 100644
--- a/northd/en-lflow.c
+++ b/northd/en-lflow.c
@@ -146,16 +146,19 @@ lflow_northd_handler(struct engine_node *node,
         return EN_UNHANDLED;
     }
 
-    if (northd_has_lrouters_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;
 
     struct lflow_input lflow_input;
     lflow_get_input_data(node, &lflow_input);
 
+    if (!lflow_handle_northd_lr_changes(eng_ctx->ovnsb_idl_txn,
+                                        &northd_data->trk_data.trk_routers,
+                                        &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/northd.c b/northd/northd.c
index 79a25a37b..ee08cf8fb 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -540,6 +540,7 @@ ovn_datapath_create(struct hmap *datapaths, const struct 
uuid *key,
     od->ipam_info_initialized = false;
     od->tunnel_key = sdp->sb_dp->tunnel_key;
     init_mcast_info_for_datapath(od);
+    od->datapath_lflows = lflow_ref_create();
     return od;
 }
 
@@ -568,6 +569,7 @@ ovn_datapath_destroy(struct ovn_datapath *od)
         destroy_mcast_info_for_datapath(od);
         destroy_ports_for_datapath(od);
         sset_destroy(&od->router_ips);
+        lflow_ref_destroy(od->datapath_lflows);
         free(od);
     }
 }
@@ -13965,12 +13967,12 @@ build_default_route_flows_for_lrouter(
         struct simap *route_tables)
 {
     ovn_lflow_add_default_drop(lflows, od, S_ROUTER_IN_IP_ROUTING_ECMP,
-                               NULL);
+                               od->datapath_lflows);
     ovn_lflow_add_default_drop(lflows, od, S_ROUTER_IN_IP_ROUTING,
-                               NULL);
+                               od->datapath_lflows);
     ovn_lflow_add(lflows, od, S_ROUTER_IN_IP_ROUTING_ECMP, 150,
                   REG_ECMP_GROUP_ID" == 0", "next;",
-                  NULL);
+                  od->datapath_lflows);
 
     for (int i = 0; i < od->nbr->n_ports; i++) {
         build_route_table_lflow(od, lflows, od->nbr->ports[i],
@@ -17779,40 +17781,50 @@ build_lswitch_and_lrouter_iterate_by_lr(struct 
ovn_datapath *od,
                                         struct lswitch_flow_build_info *lsi)
 {
     ovs_assert(od->nbr);
-    build_adm_ctrl_flows_for_lrouter(od, lsi->lflows, NULL);
+    build_adm_ctrl_flows_for_lrouter(od, lsi->lflows, od->datapath_lflows);
     build_neigh_learning_flows_for_lrouter(od, lsi->lflows, &lsi->match,
                                            &lsi->actions,
-                                           lsi->meter_groups, NULL);
-    build_ND_RA_flows_for_lrouter(od, lsi->lflows, NULL);
-    build_ip_routing_pre_flows_for_lrouter(od, lsi->lflows, NULL);
+                                           lsi->meter_groups,
+                                           od->datapath_lflows);
+    build_ND_RA_flows_for_lrouter(od, lsi->lflows, od->datapath_lflows);
+    build_ip_routing_pre_flows_for_lrouter(od, lsi->lflows,
+                                           od->datapath_lflows);
     build_route_flows_for_lrouter(od, lsi->lflows,
                                   lsi->route_data, lsi->route_tables,
                                   lsi->bfd_ports);
-    build_mcast_lookup_flows_for_lrouter(od, lsi->lflows, &lsi->match, NULL);
+    build_mcast_lookup_flows_for_lrouter(od, lsi->lflows, &lsi->match,
+                                         od->datapath_lflows);
     build_ingress_policy_flows_for_lrouter(od, lsi->lflows, lsi->lr_ports,
-                                           lsi->route_policies, NULL);
-    build_arp_resolve_flows_for_lrouter(od, lsi->lflows, NULL);
+                                           lsi->route_policies,
+                                           od->datapath_lflows);
+    build_arp_resolve_flows_for_lrouter(od, lsi->lflows, od->datapath_lflows);
     build_check_pkt_len_flows_for_lrouter(od, lsi->lflows, lsi->lr_ports,
                                           &lsi->match, &lsi->actions,
-                                          lsi->meter_groups, NULL,
+                                          lsi->meter_groups,
+                                          od->datapath_lflows,
                                           lsi->features);
     build_gateway_redirect_flows_for_lrouter(od, lsi->lflows, &lsi->match,
-                                             &lsi->actions, NULL);
+                                             &lsi->actions,
+                                             od->datapath_lflows);
     build_arp_request_flows_for_lrouter(od, lsi->lflows, &lsi->match,
                                         &lsi->actions,
                                         lsi->meter_groups,
-                                        NULL);
+                                        od->datapath_lflows);
     build_lrouter_network_id_flows(od, lsi->lflows, &lsi->match,
-                                   &lsi->actions, NULL);
-    build_misc_local_traffic_drop_flows_for_lrouter(od, lsi->lflows, NULL);
+                                   &lsi->actions, od->datapath_lflows);
+    build_misc_local_traffic_drop_flows_for_lrouter(od, lsi->lflows,
+                                                    od->datapath_lflows);
 
-    build_lr_nat_defrag_and_lb_default_flows(od, lsi->lflows, NULL);
-    build_lrouter_lb_affinity_default_flows(od, lsi->lflows, NULL);
+    build_lr_nat_defrag_and_lb_default_flows(od, lsi->lflows,
+                                             od->datapath_lflows);
+    build_lrouter_lb_affinity_default_flows(od, lsi->lflows,
+                                            od->datapath_lflows);
 
     /* Default drop rule in lr_out_delivery stage.  See
      * build_egress_delivery_flows_for_lrouter_port() which adds a rule
      * for each router port. */
-    ovn_lflow_add_default_drop(lsi->lflows, od, S_ROUTER_OUT_DELIVERY, NULL);
+    ovn_lflow_add_default_drop(lsi->lflows, od, S_ROUTER_OUT_DELIVERY,
+                               od->datapath_lflows);
 }
 
 /* Helper function to combine all lflow generation which is iterated by logical
@@ -18432,6 +18444,56 @@ lflow_reset_northd_refs(struct lflow_input 
*lflow_input)
     }
 }
 
+bool
+lflow_handle_northd_lr_changes(struct ovsdb_idl_txn *ovnsb_txn,
+                                struct tracked_dps *tracked_lrs,
+                                struct lflow_input *lflow_input,
+                                struct lflow_table *lflows)
+{
+    bool handled = true;
+    struct hmapx_node *hmapx_node;
+    HMAPX_FOR_EACH (hmapx_node, &tracked_lrs->deleted) {
+        struct ovn_datapath *od = hmapx_node->data;
+        lflow_ref_unlink_lflows(od->datapath_lflows);
+        handled = 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);
+        if (!handled) {
+            return handled;
+        }
+    }
+
+    struct lswitch_flow_build_info lsi = {
+        .lr_datapaths = lflow_input->lr_datapaths,
+        .lr_stateful_table = lflow_input->lr_stateful_table,
+        .lflows =lflows,
+        .route_data = lflow_input->route_data,
+        .route_tables = lflow_input->route_tables,
+        .route_policies = lflow_input->route_policies,
+        .match = DS_EMPTY_INITIALIZER,
+        .actions = DS_EMPTY_INITIALIZER,
+    };
+    HMAPX_FOR_EACH (hmapx_node, &tracked_lrs->crupdated) {
+        struct ovn_datapath *od = hmapx_node->data;
+        build_lswitch_and_lrouter_iterate_by_lr(od, &lsi);
+        handled = 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);
+         if (!handled) {
+            break;
+         }
+    }
+    ds_destroy(&lsi.actions);
+    ds_destroy(&lsi.match);
+    return handled;
+}
+
 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 6836831d7..00e1c9316 100644
--- a/northd/northd.h
+++ b/northd/northd.h
@@ -461,6 +461,9 @@ 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. */
+    struct lflow_ref *datapath_lflows;
 };
 
 const struct ovn_datapath *ovn_datapath_find(const struct hmap *datapaths,
@@ -918,7 +921,10 @@ void build_route_data_flows_for_lrouter(
     const struct group_ecmp_datapath *route_node,
     const struct sset *bfd_ports);
 
-
+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_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 4c8a6aca2..b53942faf 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -12525,18 +12525,17 @@ check_engine_stats lr_nat norecompute compute
 check_engine_stats lr_stateful norecompute compute
 check_engine_stats sync_to_sb_pb recompute nocompute
 check_engine_stats sync_to_sb_lb norecompute compute
-check_engine_stats lflow recompute nocompute
+check_engine_stats lflow norecompute compute
 CHECK_NO_CHANGE_AFTER_RECOMPUTE
 
 check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
 check ovn-nbctl --wait=sb lr-del lr0
-
 check_engine_stats northd norecompute compute
 check_engine_stats lr_nat norecompute compute
 check_engine_stats lr_stateful norecompute compute
 check_engine_stats sync_to_sb_pb recompute nocompute
 check_engine_stats sync_to_sb_lb norecompute compute
-check_engine_stats lflow recompute nocompute
+check_engine_stats lflow norecompute compute
 CHECK_NO_CHANGE_AFTER_RECOMPUTE
 
 check ovn-nbctl --wait=sb lr-add lr0
-- 
2.51.0

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

Reply via email to