From: "RYAN D. MOATS" <rmo...@us.ibm.com>

This code changes to allow incremental processing of the
logical flow and physical binding tables whenver possible.

Note: flows created by physical_run for multicast_groups are
*NOT* handled incrementally due to to be solved issues
with GWs and local routers.

Signed-off-by: Ryan Moats <rmo...@us.ibm.com>
---
 ovn/controller/binding.c        |  6 ++++
 ovn/controller/encaps.c         |  5 +++
 ovn/controller/lflow.c          | 68 +++++++++++++++++++++++++++++++++----
 ovn/controller/lflow.h          |  1 +
 ovn/controller/lport.c          | 14 ++++++--
 ovn/controller/lport.h          |  4 ++-
 ovn/controller/ovn-controller.c |  1 -
 ovn/controller/patch.c          |  8 +++++
 ovn/controller/physical.c       | 75 +++++++++++++++++++++++++++++++++++++----
 ovn/controller/physical.h       |  1 +
 10 files changed, 165 insertions(+), 18 deletions(-)

diff --git a/ovn/controller/binding.c b/ovn/controller/binding.c
index 80f38b9..4a2bd0d 100644
--- a/ovn/controller/binding.c
+++ b/ovn/controller/binding.c
@@ -15,6 +15,8 @@
 
 #include <config.h>
 #include "binding.h"
+#include "lflow.h"
+#include "lport.h"
 
 #include "lib/bitmap.h"
 #include "lib/hmap.h"
@@ -118,6 +120,7 @@ remove_local_datapath(struct hmap *local_datapaths, struct 
local_datapath *ld)
     hmap_remove(local_datapaths, &ld->hmap_node);
     hmap_remove(&local_datapaths_by_uuid, &ld->uuid_hmap_node);
     free(ld);
+    lflow_reset_processing();
 }
 
 static void
@@ -156,6 +159,9 @@ add_local_datapath(struct hmap *local_datapaths,
                 binding_rec->datapath->tunnel_key);
     hmap_insert(&local_datapaths_by_uuid, &ld->uuid_hmap_node,
                 uuid_hash(uuid));
+    lport_index_reset();
+    mcgroup_index_reset();
+    lflow_reset_processing();
 }
 
 static void
diff --git a/ovn/controller/encaps.c b/ovn/controller/encaps.c
index b5f874f..736da8e 100644
--- a/ovn/controller/encaps.c
+++ b/ovn/controller/encaps.c
@@ -17,6 +17,7 @@
 #include "encaps.h"
 #include "binding.h"
 #include "lflow.h"
+#include "lport.h"
 
 #include "lib/hash.h"
 #include "lib/sset.h"
@@ -234,6 +235,9 @@ tunnel_add(const struct sbrec_chassis *chassis_rec,
     free(port_name);
     free(ports);
     binding_reset_processing();
+    lport_index_reset();
+    mcgroup_index_reset();
+    lflow_reset_processing();
     process_full_encaps = true;
 }
 
@@ -417,6 +421,7 @@ encaps_run(struct controller_ctx *ctx, const struct 
ovsrec_bridge *br_int,
                                 &port_hash->uuid_node);
                     free(port_hash);
                     binding_reset_processing();
+                    lflow_reset_processing();
                 }
                 continue;
             }
diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c
index 464f9c8..702624d 100644
--- a/ovn/controller/lflow.c
+++ b/ovn/controller/lflow.c
@@ -26,6 +26,7 @@
 #include "ovn/lib/expr.h"
 #include "ovn/lib/ovn-sb-idl.h"
 #include "packets.h"
+#include "physical.h"
 #include "simap.h"
 
 VLOG_DEFINE_THIS_MODULE(lflow);
@@ -35,6 +36,17 @@ VLOG_DEFINE_THIS_MODULE(lflow);
 /* Contains "struct expr_symbol"s for fields supported by OVN lflows. */
 static struct shash symtab;
 
+static bool full_flow_processing = false;
+static bool full_logical_flow_processing = false;
+static bool full_neighbor_flow_processing = false;
+
+void
+lflow_reset_processing(void)
+{
+    full_flow_processing = true;
+    physical_reset_processing();
+}
+
 static void
 add_logical_register(struct shash *symtab, enum mf_field_id id)
 {
@@ -365,12 +377,30 @@ add_logical_flows(struct controller_ctx *ctx, const 
struct lport_index *lports,
                   const struct simap *ct_zones)
 {
     uint32_t conj_id_ofs = 1;
-
     const struct sbrec_logical_flow *lflow;
-    SBREC_LOGICAL_FLOW_FOR_EACH (lflow, ctx->ovnsb_idl) {
-        consider_logical_flow(lports, mcgroups, lflow, local_datapaths,
-                              patched_datapaths, ct_zones, &conj_id_ofs,
-                              true);
+
+    if (full_logical_flow_processing) {
+        SBREC_LOGICAL_FLOW_FOR_EACH (lflow, ctx->ovnsb_idl) {
+            consider_logical_flow(lports, mcgroups, lflow, local_datapaths,
+                                  patched_datapaths, ct_zones, &conj_id_ofs,
+                                  true);
+        }
+        full_logical_flow_processing = false;
+    } else {
+        SBREC_LOGICAL_FLOW_FOR_EACH_TRACKED (lflow, ctx->ovnsb_idl) {
+            bool is_deleted = sbrec_logical_flow_row_get_seqno(lflow,
+                OVSDB_IDL_CHANGE_DELETE) > 0;
+            bool is_new = sbrec_logical_flow_row_get_seqno(lflow,
+                OVSDB_IDL_CHANGE_MODIFY) == 0;
+
+            if (is_deleted) {
+                ofctrl_remove_flows(&lflow->header_.uuid);
+                continue;
+            }
+            consider_logical_flow(lports, mcgroups, lflow, local_datapaths,
+                                  patched_datapaths, ct_zones, &conj_id_ofs,
+                                  is_new);
+        }
     }
 }
 
@@ -438,9 +468,26 @@ add_neighbor_flows(struct controller_ctx *ctx,
     ofpbuf_init(&ofpacts, 0);
 
     const struct sbrec_mac_binding *b;
-    SBREC_MAC_BINDING_FOR_EACH (b, ctx->ovnsb_idl) {
-        consider_neighbor_flow(lports, b, &ofpacts, &match, true);
+    if (full_neighbor_flow_processing) {
+        SBREC_MAC_BINDING_FOR_EACH (b, ctx->ovnsb_idl) {
+            consider_neighbor_flow(lports, b, &ofpacts, &match, true);
+        }
+        full_neighbor_flow_processing = false;
+    } else {
+        SBREC_MAC_BINDING_FOR_EACH_TRACKED (b, ctx->ovnsb_idl) {
+            bool is_deleted = sbrec_mac_binding_row_get_seqno(b,
+                OVSDB_IDL_CHANGE_DELETE) > 0;
+            bool is_new = sbrec_mac_binding_row_get_seqno(b,
+                OVSDB_IDL_CHANGE_MODIFY) == 0;
+
+            if (is_deleted) {
+                ofctrl_remove_flows(&b->header_.uuid);
+                continue;
+            }
+            consider_neighbor_flow(lports, b, &ofpacts, &match, is_new);
+        }
     }
+
     ofpbuf_uninit(&ofpacts);
 }
 
@@ -453,6 +500,13 @@ lflow_run(struct controller_ctx *ctx, const struct 
lport_index *lports,
           const struct hmap *patched_datapaths,
           const struct simap *ct_zones)
 {
+    if (full_flow_processing) {
+        ovn_flow_table_clear();
+        full_logical_flow_processing = true;
+        full_neighbor_flow_processing = true;
+        full_flow_processing = false;
+        physical_reset_processing();
+    }
     add_logical_flows(ctx, lports, mcgroups, local_datapaths,
                       patched_datapaths, ct_zones);
     add_neighbor_flows(ctx, lports);
diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h
index 8f8f81a..abbb10a 100644
--- a/ovn/controller/lflow.h
+++ b/ovn/controller/lflow.h
@@ -65,5 +65,6 @@ void lflow_run(struct controller_ctx *, const struct 
lport_index *,
                const struct hmap *patched_datapaths,
                const struct simap *ct_zones);
 void lflow_destroy(void);
+void lflow_reset_processing(void);
 
 #endif /* ovn/lflow.h */
diff --git a/ovn/controller/lport.c b/ovn/controller/lport.c
index 461cabd..e81d306 100644
--- a/ovn/controller/lport.c
+++ b/ovn/controller/lport.c
@@ -49,7 +49,7 @@ lport_index_init(struct lport_index *lports)
     hmap_init(&lports->by_uuid);
 }
 
-void
+bool
 lport_index_remove(struct lport_index *lports, const struct uuid *uuid)
 {
     const struct lport *port = lport_lookup_by_uuid(lports, uuid);
@@ -58,7 +58,9 @@ lport_index_remove(struct lport_index *lports, const struct 
uuid *uuid)
         hmap_remove(&lports->by_key, (struct hmap_node *) &port->key_node);
         hmap_remove(&lports->by_uuid, (struct hmap_node *) &port->uuid_node);
         free((void *) port);
+        return true;
     }
+    return false;
 }
 
 void
@@ -74,6 +76,7 @@ lport_index_clear(struct lport_index *lports)
         hmap_remove(&lports->by_uuid, &port->uuid_node);
         free(port);
     }
+    lflow_reset_processing();
 }
 
 static void
@@ -93,6 +96,7 @@ consider_lport_index(struct lport_index *lports,
                 uuid_hash(&pb->header_.uuid));
     p->uuid = &pb->header_.uuid;
     p->pb = pb;
+    lflow_reset_processing();
 }
 
 void
@@ -111,7 +115,10 @@ lport_index_fill(struct lport_index *lports, struct 
ovsdb_idl *ovnsb_idl)
                 OVSDB_IDL_CHANGE_DELETE) > 0;
 
             if (is_delete) {
-                lport_index_remove(lports, &pb->header_.uuid);
+                while (lport_index_remove(lports, &pb->header_.uuid)) {
+                    ;
+                }
+                lflow_reset_processing();
                 continue;
             }
             consider_lport_index(lports, pb);
@@ -204,6 +211,7 @@ mcgroup_index_remove(struct mcgroup_index *mcgroups, const 
struct uuid *uuid)
                     (struct hmap_node *) &mcgroup->uuid_node);
         free((void *) mcgroup);
     }
+    lflow_reset_processing();
 }
 
 void
@@ -233,6 +241,7 @@ consider_mcgroup_index(struct mcgroup_index *mcgroups,
                 uuid_hash(&mg->header_.uuid));
     m->uuid = &mg->header_.uuid;
     m->mg = mg;
+    lflow_reset_processing();
 }
 
 void
@@ -252,6 +261,7 @@ mcgroup_index_fill(struct mcgroup_index *mcgroups, struct 
ovsdb_idl *ovnsb_idl)
 
             if (is_delete) {
                 mcgroup_index_remove(mcgroups, &mg->header_.uuid);
+                lflow_reset_processing();
                 continue;
             }
             consider_mcgroup_index(mcgroups, mg);
diff --git a/ovn/controller/lport.h b/ovn/controller/lport.h
index 33f81d5..bb8d8cd 100644
--- a/ovn/controller/lport.h
+++ b/ovn/controller/lport.h
@@ -39,9 +39,10 @@ struct lport_index {
 void lport_index_reset(void);
 void lport_index_init(struct lport_index *);
 void lport_index_fill(struct lport_index *, struct ovsdb_idl *);
-void lport_index_remove(struct lport_index *, const struct uuid *);
+bool lport_index_remove(struct lport_index *, const struct uuid *);
 void lport_index_clear(struct lport_index *);
 void lport_index_destroy(struct lport_index *);
+void lport_index_rebuild(void);
 
 const struct sbrec_port_binding *lport_lookup_by_name(
     const struct lport_index *, const char *name);
@@ -73,6 +74,7 @@ void mcgroup_index_fill(struct mcgroup_index *, struct 
ovsdb_idl *);
 void mcgroup_index_remove(struct mcgroup_index *, const struct uuid *);
 void mcgroup_index_clear(struct mcgroup_index *);
 void mcgroup_index_destroy(struct mcgroup_index *);
+void mcgroup_index_rebuild(void);
 
 const struct sbrec_multicast_group *mcgroup_lookup_by_dp_name(
     const struct mcgroup_index *,
diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c
index 1aa25dc..ba66fea 100644
--- a/ovn/controller/ovn-controller.c
+++ b/ovn/controller/ovn-controller.c
@@ -460,7 +460,6 @@ main(int argc, char *argv[])
             update_ct_zones(&all_lports, &patched_datapaths, &ct_zones,
                             ct_zone_bitmap);
 
-            ovn_flow_table_clear();
             lflow_run(&ctx, &lports, &mcgroups, &local_datapaths,
                       &patched_datapaths, &ct_zones);
             if (chassis_id) {
diff --git a/ovn/controller/patch.c b/ovn/controller/patch.c
index fa4e624..f80c8ae 100644
--- a/ovn/controller/patch.c
+++ b/ovn/controller/patch.c
@@ -18,8 +18,10 @@
 #include "patch.h"
 
 #include "hash.h"
+#include "lflow.h"
 #include "lib/hmap.h"
 #include "lib/vswitch-idl.h"
+#include "lport.h"
 #include "openvswitch/vlog.h"
 #include "ovn-controller.h"
 
@@ -93,6 +95,9 @@ create_patch_port(struct controller_ctx *ctx,
     ovsrec_bridge_verify_ports(src);
     ovsrec_bridge_set_ports(src, ports, src->n_ports + 1);
 
+    lport_index_reset();
+    mcgroup_index_reset();
+    lflow_reset_processing();
     free(ports);
 }
 
@@ -125,6 +130,9 @@ remove_port(struct controller_ctx *ctx,
             return;
         }
     }
+    lport_index_reset();
+    mcgroup_index_reset();
+    lflow_reset_processing();
 }
 
 /* Obtains external-ids:ovn-bridge-mappings from OVSDB and adds patch ports for
diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c
index 3aa0cad..8323fd2 100644
--- a/ovn/controller/physical.c
+++ b/ovn/controller/physical.c
@@ -58,6 +58,14 @@ static struct simap localvif_to_ofport =
     SIMAP_INITIALIZER(&localvif_to_ofport);
 static struct hmap tunnels = HMAP_INITIALIZER(&tunnels);
 
+static bool full_binding_processing = false;
+
+void
+physical_reset_processing(void)
+{
+    full_binding_processing = true;
+}
+
 /* Maps from a chassis to the OpenFlow port number of the tunnel that can be
  * used to reach that chassis. */
 struct chassis_tunnel {
@@ -621,11 +629,35 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id 
mff_ovn_geneve,
             bool is_patch = !strcmp(iface_rec->type, "patch");
             if (is_patch && localnet) {
                 /* localnet patch ports can be handled just like VIFs. */
-                simap_put(&localvif_to_ofport, localnet, ofport);
+                if (simap_find(&localvif_to_ofport, localnet)) {
+                    unsigned int old_port = simap_get(&localvif_to_ofport,
+                                                      localnet);
+                    if (old_port != ofport) {
+                        simap_put(&localvif_to_ofport, localnet, ofport);
+                        full_binding_processing = true;
+                        lflow_reset_processing();
+                    }
+                } else {
+                    simap_put(&localvif_to_ofport, localnet, ofport);
+                    full_binding_processing = true;
+                    lflow_reset_processing();
+                }
                 break;
             } else if (is_patch && logpatch) {
                 /* Logical patch ports can be handled just like VIFs. */
-                simap_put(&localvif_to_ofport, logpatch, ofport);
+                if (simap_find(&localvif_to_ofport, logpatch)) {
+                    unsigned int old_port = simap_get(&localvif_to_ofport,
+                                                      logpatch);
+                    if (old_port != ofport) {
+                        simap_put(&localvif_to_ofport, logpatch, ofport);
+                        full_binding_processing = true;
+                        lflow_reset_processing();
+                    }
+                } else {
+                    simap_put(&localvif_to_ofport, logpatch, ofport);
+                    full_binding_processing = true;
+                    lflow_reset_processing();
+                }
                 break;
             } else if (chassis_id) {
                 enum chassis_tunnel_type tunnel_type;
@@ -653,7 +685,19 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id 
mff_ovn_geneve,
                 const char *iface_id = smap_get(&iface_rec->external_ids,
                                                 "iface-id");
                 if (iface_id) {
-                    simap_put(&localvif_to_ofport, iface_id, ofport);
+                    if (simap_find(&localvif_to_ofport, iface_id)) {
+                        unsigned int old_port = simap_get(&localvif_to_ofport,
+                                                          iface_id);
+                        if (old_port != ofport) {
+                            simap_put(&localvif_to_ofport, iface_id, ofport);
+                            full_binding_processing = true;
+                            lflow_reset_processing();
+                        }
+                    } else {
+                        simap_put(&localvif_to_ofport, iface_id, ofport);
+                        full_binding_processing = true;
+                        lflow_reset_processing();
+                    }
                 }
             }
         }
@@ -665,10 +709,28 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id 
mff_ovn_geneve,
     /* Set up flows in table 0 for physical-to-logical translation and in table
      * 64 for logical-to-physical translation. */
     const struct sbrec_port_binding *binding;
-    SBREC_PORT_BINDING_FOR_EACH (binding, ctx->ovnsb_idl) {
-        consider_port_binding(mff_ovn_geneve, ct_zones, local_datapaths,
-                              patched_datapaths, binding, &ofpacts, true);
+    if (full_binding_processing) {
+        SBREC_PORT_BINDING_FOR_EACH (binding, ctx->ovnsb_idl) {
+            consider_port_binding(mff_ovn_geneve, ct_zones, local_datapaths,
+                                  patched_datapaths, binding, &ofpacts, true);
         }
+        full_binding_processing = false;
+    } else {
+        SBREC_PORT_BINDING_FOR_EACH_TRACKED (binding, ctx->ovnsb_idl) {
+            bool is_deleted = sbrec_port_binding_row_get_seqno(binding,
+                OVSDB_IDL_CHANGE_DELETE) > 0;
+            bool is_new = sbrec_port_binding_row_get_seqno(binding,
+                OVSDB_IDL_CHANGE_MODIFY) == 0;
+
+            if (is_deleted) {
+                ofctrl_remove_flows(&binding->header_.uuid);
+                continue;
+            }
+            consider_port_binding(mff_ovn_geneve, ct_zones, local_datapaths,
+                                  patched_datapaths, binding, &ofpacts,
+                                  is_new);
+        }
+    }
 
     /* Handle output to multicast groups, in tables 32 and 33. */
     const struct sbrec_multicast_group *mc;
@@ -784,7 +846,6 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id 
mff_ovn_geneve,
                     hc_uuid, true);
 
     ofpbuf_uninit(&ofpacts);
-    simap_clear(&localvif_to_ofport);
     HMAP_FOR_EACH_POP (tun, hmap_node, &tunnels) {
         free(tun);
     }
diff --git a/ovn/controller/physical.h b/ovn/controller/physical.h
index 1f98f71..92680dc 100644
--- a/ovn/controller/physical.h
+++ b/ovn/controller/physical.h
@@ -45,5 +45,6 @@ void physical_run(struct controller_ctx *, enum mf_field_id 
mff_ovn_geneve,
                   const struct ovsrec_bridge *br_int, const char *chassis_id,
                   const struct simap *ct_zones,
                   struct hmap *local_datapaths, struct hmap 
*patched_datapaths);
+void physical_reset_processing(void);
 
 #endif /* ovn/physical.h */
-- 
1.9.1

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to