ovn-controller: Add incremental processing to lflow_run and physical_run
[cascardo/ovs.git] / ovn / controller / patch.c
index 589529e..823389d 100644 (file)
 #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
@@ -252,18 +260,52 @@ static void
 add_patched_datapath(struct hmap *patched_datapaths,
                      const struct sbrec_port_binding *binding_rec, bool local)
 {
-    if (get_patched_datapath(patched_datapaths,
-                             binding_rec->datapath->tunnel_key)) {
+    struct patched_datapath *pd = get_patched_datapath(patched_datapaths,
+                                       binding_rec->datapath->tunnel_key);
+    if (pd) {
+        /* If the patched datapath is referenced by a logical patch port it is
+         * not stale, by definition, so set 'stale' to false */
+        pd->stale = false;
         return;
     }
 
-    struct patched_datapath *pd = xzalloc(sizeof *pd);
+    pd = xzalloc(sizeof *pd);
     pd->local = local;
-    pd->port_binding = binding_rec;
+    pd->key = xasprintf(UUID_FMT,
+                        UUID_ARGS(&binding_rec->datapath->header_.uuid));
+    /* stale is set to false. */
     hmap_insert(patched_datapaths, &pd->hmap_node,
                 binding_rec->datapath->tunnel_key);
 }
 
+static void
+add_logical_patch_ports_preprocess(struct hmap *patched_datapaths)
+{
+    /* Mark all patched datapaths as stale for later cleanup by
+     * add_logical_patch_ports_postprocess(). */
+    struct patched_datapath *pd;
+    HMAP_FOR_EACH (pd, hmap_node, patched_datapaths) {
+        pd->stale = true;
+    }
+}
+
+/* This function should cleanup stale patched datapaths and any memory
+ * allocated for fields within a stale patched datapath. */
+static void
+add_logical_patch_ports_postprocess(struct hmap *patched_datapaths)
+{
+    /* Clean up stale patched datapaths. */
+    struct patched_datapath *pd_cur_node, *pd_next_node;
+    HMAP_FOR_EACH_SAFE (pd_cur_node, pd_next_node, hmap_node,
+                        patched_datapaths) {
+        if (pd_cur_node->stale == true) {
+            hmap_remove(patched_datapaths, &pd_cur_node->hmap_node);
+            free(pd_cur_node->key);
+            free(pd_cur_node);
+        }
+    }
+}
+
 /* Add one OVS patch port for each OVN logical patch port.
  *
  * This is suboptimal for several reasons.  First, it creates an OVS port for
@@ -299,6 +341,8 @@ add_logical_patch_ports(struct controller_ctx *ctx,
         return;
     }
 
+    add_logical_patch_ports_preprocess(patched_datapaths);
+
     const struct sbrec_port_binding *binding;
     SBREC_PORT_BINDING_FOR_EACH (binding, ctx->ovnsb_idl) {
         bool local_port = false;
@@ -332,6 +376,7 @@ add_logical_patch_ports(struct controller_ctx *ctx,
             }
         }
     }
+    add_logical_patch_ports_postprocess(patched_datapaths);
 }
 
 void