This patch handles the logical router creation incrementally in the
northd engine node. This patch covers the depended node lr-nat but
further dependant nodes will be handled in upcoming patches.

This is built on Mark Michelson's patch series located here

https://patchwork.ozlabs.org/project/ovn/list/?series=465828

this is required because the datapath refactor was required in order to
accomplish incremental processing of the logical routers

also built with the first two patches of this series by Lorenzo Bianconi
located  https://patchwork.ozlabs.org/project/ovn/list/?series=466579.
He brought in some changes required to dynamically allocate the sizes of
the datapaths array.

Reported-by: Dumitru Ceara <dce...@redhat.com>
Reported-at: https://issues.redhat.com/browse/FDP-757
Signed-off-by: Jacob Tanenbaum <jtane...@redhat.com>

diff --git a/northd/en-lflow.c b/northd/en-lflow.c
index 63565ef80..719ccb1ae 100644
--- a/northd/en-lflow.c
+++ b/northd/en-lflow.c
@@ -132,6 +132,9 @@ lflow_northd_handler(struct engine_node *node,
 {
     struct northd_data *northd_data = engine_get_input_data("northd", node);
     if (!northd_has_tracked_data(&northd_data->trk_data)) {
+    }
+    if (!northd_has_tracked_data(&northd_data->trk_data)
+        || northd_has_lr_new_in_tracked_data(&northd_data->trk_data)) {
         return EN_UNHANDLED;
     }
 
diff --git a/northd/en-lr-nat.c b/northd/en-lr-nat.c
index 5a7b857f4..6622b4ef4 100644
--- a/northd/en-lr-nat.c
+++ b/northd/en-lr-nat.c
@@ -125,7 +125,8 @@ lr_nat_northd_handler(struct engine_node *node, void *data_)
         return EN_UNHANDLED;
     }
 
-    if (!northd_has_lr_nats_in_tracked_data(&northd_data->trk_data)) {
+    if (!northd_has_lr_nats_in_tracked_data(&northd_data->trk_data)
+        && !northd_has_lr_new_in_tracked_data(&northd_data->trk_data)) {
         return EN_HANDLED_UNCHANGED;
     }
 
@@ -133,6 +134,21 @@ lr_nat_northd_handler(struct engine_node *node, void 
*data_)
     struct lr_nat_record *lrnat_rec;
     const struct ovn_datapath *od;
     struct hmapx_node *hmapx_node;
+    struct lr_nat_table *table = &data->lr_nats;
+    const struct ovn_datapaths *lr_datapaths = &northd_data->lr_datapaths;
+
+    /* If there is a new router we need to reallocate the size of the
+     * lr_nat_table. */
+    if (northd_has_lr_new_in_tracked_data(&northd_data->trk_data)) {
+        table->array = xrealloc(table->array,
+                                ods_size(lr_datapaths) * sizeof *table->array);
+    }
+
+    HMAPX_FOR_EACH (hmapx_node, &northd_data->trk_data.trk_new_lrs) {
+        od = hmapx_node->data;
+        lrnat_rec = lr_nat_record_create(table, od, &northd_data->lr_ports);
+        hmapx_add(&data->trk_data.crupdated, lrnat_rec);
+    }
 
     HMAPX_FOR_EACH (hmapx_node, &northd_data->trk_data.trk_nat_lrs) {
         od = hmapx_node->data;
diff --git a/northd/en-lr-stateful.c b/northd/en-lr-stateful.c
index 56e93f3c4..3b1dec0b1 100644
--- a/northd/en-lr-stateful.c
+++ b/northd/en-lr-stateful.c
@@ -138,6 +138,9 @@ lr_stateful_northd_handler(struct engine_node *node, void 
*data OVS_UNUSED)
     if (!northd_has_tracked_data(&northd_data->trk_data)) {
         return EN_UNHANDLED;
     }
+    if (northd_has_lr_new_in_tracked_data(&northd_data->trk_data)) {
+        return EN_UNHANDLED;
+    }
 
     /* This node uses the below data from the en_northd engine node.
      * See (lr_stateful_get_input_data())
diff --git a/northd/en-northd.c b/northd/en-northd.c
index ff89830bd..53663d8cf 100644
--- a/northd/en-northd.c
+++ b/northd/en-northd.c
@@ -193,7 +193,8 @@ northd_nb_logical_router_handler(struct engine_node *node,
         return EN_UNHANDLED;
     }
 
-    if (northd_has_lr_nats_in_tracked_data(&nd->trk_data)) {
+    if (northd_has_lr_nats_in_tracked_data(&nd->trk_data)
+        || northd_has_lr_new_in_tracked_data(&nd->trk_data)) {
         return EN_HANDLED_UPDATED;
     }
 
diff --git a/northd/northd.c b/northd/northd.c
index 7afb94b2c..6d7b37238 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -839,7 +839,7 @@ ods_assign_array_index(struct ovn_datapaths *datapaths,
             datapaths->array,
             datapaths->n_allocated_array * sizeof *datapaths->array);
         }
-        datapaths->array[datapaths->n_array] = od;
+        datapaths->array[datapaths->n_array++] = od;
         od->datapaths = datapaths;
 
 }
@@ -4416,6 +4416,7 @@ init_northd_tracked_data(struct northd_data *nd)
     hmapx_init(&trk_data->trk_nat_lrs);
     hmapx_init(&trk_data->ls_with_changed_lbs);
     hmapx_init(&trk_data->ls_with_changed_acls);
+    hmapx_init(&trk_data->trk_new_lrs);
 }
 
 static void
@@ -4431,6 +4432,7 @@ destroy_northd_tracked_data(struct northd_data *nd)
     hmapx_destroy(&trk_data->trk_nat_lrs);
     hmapx_destroy(&trk_data->ls_with_changed_lbs);
     hmapx_destroy(&trk_data->ls_with_changed_acls);
+    hmapx_destroy(&trk_data->trk_new_lrs);
 }
 
 /* Check if a changed LSP can be handled incrementally within the I-P engine
@@ -5097,13 +5099,37 @@ northd_handle_lr_changes(const struct northd_input *ni,
                          struct northd_data *nd)
 {
     const struct nbrec_logical_router *changed_lr;
+    const struct nbrec_logical_router *new_lr;
 
-    if (!hmapx_is_empty(&ni->synced_lrs->new) ||
-        !hmapx_is_empty(&ni->synced_lrs->deleted)) {
+    if (!hmapx_is_empty(&ni->synced_lrs->deleted)) {
         goto fail;
     }
 
     struct hmapx_node *node;
+    HMAPX_FOR_EACH (node, &ni->synced_lrs->new) {
+        const struct ovn_synced_logical_router *synced = node->data;
+        new_lr = synced->nb;
+
+        if (new_lr->n_ports > 0
+            || new_lr->n_policies > 0
+            || new_lr->n_static_routes > 0
+            || !lrouter_is_enabled(new_lr)
+            || !smap_is_empty(&new_lr->options)
+            || !smap_is_empty(&new_lr->external_ids)) {
+            goto fail;
+        }
+
+        struct ovn_datapath *od =
+            ovn_datapath_create(&nd->lr_datapaths.datapaths,
+                                &new_lr->header_.uuid,
+                                NULL,
+                                new_lr,
+                                synced->sb);
+        ods_assign_array_index(&nd->lr_datapaths, od);
+        nd->trk_data.type |= NORTHD_TRACKED_LR_NEW;
+        hmapx_add(&nd->trk_data.trk_new_lrs, od);
+    }
+
     HMAPX_FOR_EACH (node, &ni->synced_lrs->updated) {
         const struct ovn_synced_logical_router *synced = node->data;
         changed_lr = synced->nb;
diff --git a/northd/northd.h b/northd/northd.h
index 9883442ee..e9042cd5f 100644
--- a/northd/northd.h
+++ b/northd/northd.h
@@ -143,6 +143,7 @@ enum northd_tracked_data_type {
     NORTHD_TRACKED_LR_NATS  = (1 << 2),
     NORTHD_TRACKED_LS_LBS   = (1 << 3),
     NORTHD_TRACKED_LS_ACLS  = (1 << 4),
+    NORTHD_TRACKED_LR_NEW   = (1 << 6),
 };
 
 /* Track what's changed in the northd engine node.
@@ -154,6 +155,10 @@ struct northd_tracked_data {
     struct tracked_ovn_ports trk_lsps;
     struct tracked_lbs trk_lbs;
 
+    /* Tracked logical routers that are new.
+     * hmapx node is 'struct ovn_datapath *'. */
+    struct hmapx trk_new_lrs;
+
     /* Tracked logical routers whose NATs have changed.
      * hmapx node is 'struct ovn_datapath *'. */
     struct hmapx trk_nat_lrs;
@@ -955,6 +960,12 @@ northd_has_ls_acls_in_tracked_data(struct 
northd_tracked_data *trk_nd_changes)
     return trk_nd_changes->type & NORTHD_TRACKED_LS_ACLS;
 }
 
+static inline bool
+northd_has_lr_new_in_tracked_data(struct northd_tracked_data *trk_nd_changes)
+{
+    return trk_nd_changes->type & NORTHD_TRACKED_LR_NEW;
+}
+
 /* Returns 'true' if the IPv4 'addr' is on the same subnet with one of the
  * IPs configured on the router port.
  */
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index d78c5f29a..ff00bedf1 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -7603,6 +7603,7 @@ check ovn-nbctl --wait=sb sync
 
 flow="eth.dst == 00:00:00:00:01:00 && inport == \"rtr-ls\" && ip4.src == 
42.42.42.42 && ip4.dst == 43.43.43.43 && ip.ttl == 64 && tcp && tcp.dst == 4343"
 
+CHECK_NO_CHANGE_AFTER_RECOMPUTE
 AT_CHECK_UNQUOTED([ovn_trace --ct new --minimal "${flow}" --lb-dst 
42.42.42.42:4242], [0], [dnl
 ct_dnat /* assuming no un-dnat entry, so no change */ {
     ct_lb_mark /* default (use --ct to customize) */ {
@@ -12595,11 +12596,11 @@ check ovn-nbctl --wait=sb lsp-add sw0 sw0p1 -- 
lsp-set-addresses sw0p1 "00:00:20
 
 check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
 check ovn-nbctl --wait=sb lr-add lr0
-check_engine_stats northd recompute nocompute
-check_engine_stats lr_nat recompute nocompute
+check_engine_stats northd norecompute compute
+check_engine_stats lr_nat norecompute compute
 check_engine_stats lr_stateful recompute nocompute
 check_engine_stats sync_to_sb_pb recompute nocompute
-check_engine_stats sync_to_sb_lb recompute nocompute
+check_engine_stats sync_to_sb_lb norecompute compute
 check_engine_stats lflow recompute nocompute
 CHECK_NO_CHANGE_AFTER_RECOMPUTE
 
-- 
2.50.1

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

Reply via email to