[ovs-dev] [PATCH ovn v2] ovn-controller: Propagate nb_cfg to the local OVS DB.

Dumitru Ceara dceara at redhat.com
Wed Nov 18 12:56:25 UTC 2020


The NB.NB_Global.nb_cfg value gets propagated to
Chassis_Private.nb_cfg (and then to NB.NB_Global.hv_cfg) as soon as
ovn-controller has finished installing OVS flows corresponding to
the NB DB state.

However, if the CMS runs monitoring applications on the chassis itself,
in order to detect that the NB changes have been applied, it has to
connect to the NB/SB database.  In a scaled deployment this additional
connection might induce performance issues.

In order to avoid that we now (also) propagate nb_cfg to the local OVS
DB, in the record corresponding to the integration bridge in table
Bridge, as external_id "ovn-nb-cfg".

Signed-off-by: Dumitru Ceara <dceara at redhat.com>
---
V2:
- Addressed Numan's comments:
  - Update ovn-controller doc.
  - Store the seqno in OVS.<integration-bridge>.external_ids:ovn-nb-cfg.
- Update NEWS.
---
 NEWS                            |  2 ++
 controller/ovn-controller.8.xml | 12 ++++++++++
 controller/ovn-controller.c     | 51 ++++++++++++++++++++++++++++++-----------
 tests/ovn-controller.at         | 21 +++++++++++++++++
 4 files changed, 73 insertions(+), 13 deletions(-)

diff --git a/NEWS b/NEWS
index 6010230..a681573 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,8 @@ Post-v20.09.0
      server.
    - Support other_config:vlan-passthru=true to allow VLAN tagged incoming
      traffic.
+   - Propagate currently processed SB_Global.nb_cfg in ovn-controller to the
+     local OVS DB integration bridge external_ids:ovn-nb-cfg.
 
 OVN v20.09.0 - 28 Sep 2020
 --------------------------
diff --git a/controller/ovn-controller.8.xml b/controller/ovn-controller.8.xml
index 16bc47b..0d57355 100644
--- a/controller/ovn-controller.8.xml
+++ b/controller/ovn-controller.8.xml
@@ -378,6 +378,18 @@
           logical patch port that it implements.
         </p>
       </dd>
+
+      <dt>
+        <code>external-ids:ovn-nb-cfg</code> in the <code>Bridge</code> table
+      </dt>
+
+      <dd>
+        <p>
+          This key represents the last known
+          <code>OVN_Southbound.SB_Global.nb_cfg</code> value for which all
+          flows have been successfully installed in OVS.
+        </p>
+      </dd>
     </dl>
 
     <h1>OVN Southbound Database Usage</h1>
diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
index 25de0c7..70a193b 100644
--- a/controller/ovn-controller.c
+++ b/controller/ovn-controller.c
@@ -85,6 +85,8 @@ static unixctl_cb_func debug_delay_nb_cfg_report;
 
 #define CONTROLLER_LOOP_STOPWATCH_NAME "ovn-controller-flow-generation"
 
+#define OVS_NB_CFG_NAME "ovn-nb-cfg"
+
 static char *parse_options(int argc, char *argv[]);
 OVS_NO_RETURN static void usage(void);
 
@@ -792,6 +794,40 @@ get_nb_cfg(const struct sbrec_sb_global_table *sb_global_table)
     return sb ? sb->nb_cfg : 0;
 }
 
+/* Propagates the local cfg seqno, 'cur_cfg', to the chassis_private record
+ * and to the local OVS DB.
+ */
+static void
+store_nb_cfg(struct ovsdb_idl_txn *sb_txn, struct ovsdb_idl_txn *ovs_txn,
+             const struct sbrec_chassis_private *chassis,
+             const struct ovsrec_bridge *br_int,
+             unsigned int delay_nb_cfg_report,
+             int64_t cur_cfg)
+{
+    if (!cur_cfg) {
+        return;
+    }
+
+    if (sb_txn && chassis && cur_cfg != chassis->nb_cfg) {
+        sbrec_chassis_private_set_nb_cfg(chassis, cur_cfg);
+        sbrec_chassis_private_set_nb_cfg_timestamp(chassis, time_wall_msec());
+
+        if (delay_nb_cfg_report) {
+            VLOG_INFO("Sleep for %u sec", delay_nb_cfg_report);
+            xsleep(delay_nb_cfg_report);
+        }
+    }
+
+    if (ovs_txn && br_int &&
+            cur_cfg != smap_get_ullong(&br_int->external_ids,
+                                       OVS_NB_CFG_NAME, 0)) {
+        char *cur_cfg_str = xasprintf("%"PRId64, cur_cfg);
+        ovsrec_bridge_update_external_ids_setkey(br_int, OVS_NB_CFG_NAME,
+                                                 cur_cfg_str);
+        free(cur_cfg_str);
+    }
+}
+
 static const char *
 get_transport_zones(const struct ovsrec_open_vswitch_table *ovs_table)
 {
@@ -2692,19 +2728,8 @@ main(int argc, char *argv[])
                 engine_set_force_recompute(false);
             }
 
-            if (ovnsb_idl_txn && chassis_private) {
-                int64_t cur_cfg = ofctrl_get_cur_cfg();
-                if (cur_cfg && cur_cfg != chassis_private->nb_cfg) {
-                    sbrec_chassis_private_set_nb_cfg(chassis_private, cur_cfg);
-                    sbrec_chassis_private_set_nb_cfg_timestamp(
-                        chassis_private, time_wall_msec());
-                    if (delay_nb_cfg_report) {
-                        VLOG_INFO("Sleep for %u sec", delay_nb_cfg_report);
-                        xsleep(delay_nb_cfg_report);
-                    }
-                }
-            }
-
+            store_nb_cfg(ovnsb_idl_txn, ovs_idl_txn, chassis_private,
+                         br_int, delay_nb_cfg_report, ofctrl_get_cur_cfg());
 
             if (pending_pkt.conn) {
                 struct ed_type_addr_sets *as_data =
diff --git a/tests/ovn-controller.at b/tests/ovn-controller.at
index 014a977..a1f35fb 100644
--- a/tests/ovn-controller.at
+++ b/tests/ovn-controller.at
@@ -411,3 +411,24 @@ AT_CHECK([ovn-nbctl --timeout=1 --wait=hv sync])
 
 OVN_CLEANUP([hv])
 AT_CLEANUP
+
+AT_SETUP([ovn -- nb_cfg sync to OVS])
+ovn_start
+
+net_add n1
+sim_add hv1
+ovs-vsctl add-br br-phys
+ovn_attach n1 br-phys 192.168.0.1
+
+# Wait for ovn-controller to register in the SB.
+wait_row_count Chassis 1
+
+# Increment nb_cfg.
+check ovn-nbctl --wait=hv sync
+
+# And check that it gets propagated to br-int external_ids.
+as hv1
+OVS_WAIT_UNTIL([ovs-vsctl get Bridge br-int external_ids:ovn-nb-cfg], [0], [1])
+
+OVN_CLEANUP([hv1])
+AT_CLEANUP
-- 
1.8.3.1



More information about the dev mailing list