diff mbox

[ovs-dev,ovn-controller] Add logical flow incremental processing

Message ID 1455038345-24441-2-git-send-email-rmoats@us.ibm.com
State Not Applicable
Headers show

Commit Message

Ryan Moats Feb. 9, 2016, 5:19 p.m. UTC
From: RYAN D. MOATS <rmoats@us.ibm.com>

Add incremental processing of logical flows in ovn-controller by
tracking changes to the match column of the Logical_Flow
OVN SB table.  Code is included to properly handle the order of
checked sequence numbers and rechecking of rows skipped due to
a logical_datapath not existing.

Signed-off-by: RYAN D. MOATS <rmoats@us.ibm.com>
---
 ovn/controller/lflow.c          |   49 +++++++++++++++++++++++++++++++++++----
 ovn/controller/lflow.h          |    5 ++-
 ovn/controller/ovn-controller.c |   20 ++++++++++++---
 3 files changed, 63 insertions(+), 11 deletions(-)
diff mbox

Patch

diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c
index d53213c..7ae2c12 100644
--- a/ovn/controller/lflow.c
+++ b/ovn/controller/lflow.c
@@ -273,25 +273,60 @@  lflow_init(void)
 
 /* Translates logical flows in the Logical_Flow table in the OVN_SB database
  * into OpenFlow flows.  See ovn-architecture(7) for more information. */
-void
+unsigned int
 lflow_run(struct controller_ctx *ctx, struct hmap *flow_table,
           const struct simap *ct_zones,
-          struct hmap *local_datapaths)
+          struct hmap *local_datapaths,
+          unsigned int seqno)
 {
     struct hmap flows = HMAP_INITIALIZER(&flows);
     uint32_t conj_id_ofs = 1;
+    unsigned int skipped_seqno;
+    unsigned int processed_seqno = seqno;
+    unsigned int last_seqno = 0;
 
     ldp_run(ctx);
 
     const struct sbrec_logical_flow *lflow;
-    SBREC_LOGICAL_FLOW_FOR_EACH (lflow, ctx->ovnsb_idl) {
-        /* Find the "struct logical_datapath" associated with this
+    SBREC_LOGICAL_FLOW_FOR_EACH_TRACKED (lflow, ctx->ovnsb_idl) {
+        unsigned int del_seqno = sbrec_logical_flow_row_get_seqno(lflow,
+            OVSDB_IDL_CHANGE_DELETE);
+        unsigned int mod_seqno = sbrec_logical_flow_row_get_seqno(lflow,
+            OVSDB_IDL_CHANGE_MODIFY);
+        unsigned int ins_seqno = sbrec_logical_flow_row_get_seqno(lflow,
+            OVSDB_IDL_CHANGE_INSERT);
+        if (del_seqno < seqno && mod_seqno < seqno && ins_seqno < seqno) {
+            continue;
+        }
+        if (del_seqno > processed_seqno) {
+            processed_seqno = del_seqno;
+        }
+        if (mod_seqno > processed_seqno) {
+            processed_seqno = mod_seqno;
+        }
+        if (ins_seqno > processed_seqno) {
+            processed_seqno = ins_seqno;
+        }
+
+        /* Find the "struct logical_datapath" asssociated with this
          * Logical_Flow row.  If there's no such struct, that must be because
          * no logical ports are bound to that logical datapath, so there's no
-         * point in maintaining any flows for it anyway, so skip it. */
+         * point in maintaining any flows for it anyway, so skip it.
+         * Further, we have to remember the smallest sequence number of
+         * a skipped flow to ensure that we return the correct value
+         * and don't skip things in a later pass */
         const struct logical_datapath *ldp;
         ldp = ldp_lookup(lflow->logical_datapath);
         if (!ldp) {
+            if (last_seqno == 0 || (del_seqno > 0 && last_seqno > del_seqno)) {
+                last_seqno = del_seqno;
+            }
+            if (last_seqno == 0 || (mod_seqno > 0 && last_seqno > mod_seqno)) {
+                last_seqno = mod_seqno;
+            }
+            if (last_seqno == 0 || (ins_seqno > 0 && last_seqno > ins_seqno)) {
+                last_seqno = ins_seqno;
+            }
             continue;
         }
 
@@ -425,6 +460,10 @@  lflow_run(struct controller_ctx *ctx, struct hmap *flow_table,
         ofpbuf_uninit(&ofpacts);
         conj_id_ofs += n_conjs;
     }
+    if (last_seqno > 0) {
+        processed_seqno = last_seqno;
+    }
+    return(processed_seqno);
 }
 
 void
diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h
index ccbad30..91320a7 100644
--- a/ovn/controller/lflow.h
+++ b/ovn/controller/lflow.h
@@ -56,9 +56,10 @@  struct uuid;
 #define LOG_PIPELINE_LEN 16
 
 void lflow_init(void);
-void lflow_run(struct controller_ctx *, struct hmap *flow_table,
+unsigned int lflow_run(struct controller_ctx *, struct hmap *flow_table,
                const struct simap *ct_zones,
-               struct hmap *local_datapaths);
+               struct hmap *local_datapaths,
+               unsigned int seqno);
 void lflow_destroy(void);
 
 #endif /* ovn/lflow.h */
diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c
index 3638342..32d2a0e 100644
--- a/ovn/controller/ovn-controller.c
+++ b/ovn/controller/ovn-controller.c
@@ -204,6 +204,7 @@  main(int argc, char *argv[])
     struct unixctl_server *unixctl;
     bool exiting;
     int retval;
+    unsigned int last_seqno;
 
     ovs_cmdl_proctitle_init(argc, argv);
     set_program_name(argv[0]);
@@ -257,9 +258,16 @@  main(int argc, char *argv[])
 
     /* Connect to OVN SB database. */
     char *ovnsb_remote = get_ovnsb_remote(ovs_idl_loop.idl);
-    struct ovsdb_idl_loop ovnsb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER(
-        ovsdb_idl_create(ovnsb_remote, &sbrec_idl_class, true, true));
-    ovsdb_idl_get_initial_snapshot(ovnsb_idl_loop.idl);
+    struct ovsdb_idl *sb_idl = ovsdb_idl_create(ovnsb_remote,
+                                                &sbrec_idl_class, true, true);
+    /* set to track the southbound idl */
+    ovsdb_idl_track_add_column(sb_idl, &sbrec_logical_flow_col_match);
+        
+    /*ovsdb_idl_track_add_all(sb_idl);*/
+    struct ovsdb_idl_loop ovnsb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER(sb_idl);
+
+
+    ovsdb_idl_get_initial_snapshot(sb_idl);
 
     /* Initialize connection tracking zones. */
     struct simap ct_zones = SIMAP_INITIALIZER(&ct_zones);
@@ -271,6 +279,9 @@  main(int argc, char *argv[])
     /* Main loop. */
     exiting = false;
     while (!exiting) {
+        if (last_seqno == 0) {
+            last_seqno = ovsdb_idl_get_seqno(ovnsb_idl_loop.idl);
+        }
         struct controller_ctx ctx = {
             .ovs_idl = ovs_idl_loop.idl,
             .ovs_idl_txn = ovsdb_idl_loop_run(&ovs_idl_loop),
@@ -300,7 +311,8 @@  main(int argc, char *argv[])
             pinctrl_run(&ctx, br_int);
 
             struct hmap flow_table = HMAP_INITIALIZER(&flow_table);
-            lflow_run(&ctx, &flow_table, &ct_zones, &local_datapaths);
+            last_seqno = lflow_run(&ctx, &flow_table, &ct_zones,
+                                   &local_datapaths, last_seqno);
             if (chassis_id) {
                 physical_run(&ctx, mff_ovn_geneve,
                              br_int, chassis_id, &ct_zones, &flow_table);