[ovs-dev] [PATCH v4] ovn-controller: Add datapath-type and iface-types in chassis:external_ids

Numan Siddique nusiddiq at redhat.com
Sat Jul 30 10:02:01 UTC 2016


This patch reads the 'Bridge.datapath_type' column value of the integration
bridge and 'Open_vSwitch.iface_types' column value and sets these in the
external_ids:datapath-type and external_ids:iface-types of Chassis table.

This will provide hints to the CMS or clients monitoring OVN SB DB to
determine the datapath type (DPDK or non-DPDK) configured and take some
actions based on it.

One usecase is, OVN neutron plugin can use this information to set the
vif_type (ovs or vhostuser) during the port binding.

Signed-off-by: Numan Siddique <nusiddiq at redhat.com>
---
 ovn/controller/chassis.c            | 63 ++++++++++++++++++++++++++++++++++---
 ovn/controller/chassis.h            |  3 +-
 ovn/controller/ovn-controller.8.xml | 24 ++++++++++++++
 ovn/controller/ovn-controller.c     |  2 +-
 ovn/ovn-sb.xml                      | 16 ++++++++++
 tests/ovn-controller.at             | 60 +++++++++++++++++++++++++++++++++++
 6 files changed, 161 insertions(+), 7 deletions(-)

v3 -> v4
--------
    * Also storing the supported iface-types in the chassis external_ids.
    * Updated the documentation.

v2 -> v3
--------
   * Fixed the compilation error which I accidentally introduced by deleting "<" in the ovn-controller.8.xml
     in v2.

v1 -> v2
--------
   * Addressed the review comments. Reading the datapath-type from Bridge.datapath_type column
     instead of adding a new configuration option.

diff --git a/ovn/controller/chassis.c b/ovn/controller/chassis.c
index a1545ec..4adf110 100644
--- a/ovn/controller/chassis.c
+++ b/ovn/controller/chassis.c
@@ -38,6 +38,9 @@ chassis_register_ovs_idl(struct ovsdb_idl *ovs_idl)
 {
     ovsdb_idl_add_table(ovs_idl, &ovsrec_table_open_vswitch);
     ovsdb_idl_add_column(ovs_idl, &ovsrec_open_vswitch_col_external_ids);
+    ovsdb_idl_add_column(ovs_idl, &ovsrec_open_vswitch_col_iface_types);
+    ovsdb_idl_add_table(ovs_idl, &ovsrec_table_bridge);
+    ovsdb_idl_add_column(ovs_idl, &ovsrec_bridge_col_datapath_type);
 }
 
 static const char *
@@ -67,7 +70,8 @@ get_bridge_mappings(const struct smap *ext_ids)
 /* Returns this chassis's Chassis record, if it is available and is currently
  * amenable to a transaction. */
 const struct sbrec_chassis *
-chassis_run(struct controller_ctx *ctx, const char *chassis_id)
+chassis_run(struct controller_ctx *ctx, const char *chassis_id,
+            const struct ovsrec_bridge *br_int)
 {
     if (!ctx->ovnsb_idl_txn) {
         return NULL;
@@ -114,6 +118,16 @@ chassis_run(struct controller_ctx *ctx, const char *chassis_id)
     }
 
     const char *bridge_mappings = get_bridge_mappings(&cfg->external_ids);
+    const char *datapath_type =
+        br_int && br_int->datapath_type ? br_int->datapath_type : "";
+
+    struct ds iface_types = DS_EMPTY_INITIALIZER;
+    ds_put_cstr(&iface_types, "");
+    for (int j = 0; j < cfg->n_iface_types; j++) {
+        ds_put_format(&iface_types, "%s,", cfg->iface_types[j]);
+    }
+    ds_chomp(&iface_types, ',');
+    const char *iface_types_str = ds_cstr(&iface_types);
 
     const struct sbrec_chassis *chassis_rec
         = get_chassis(ctx->ovnsb_idl, chassis_id);
@@ -125,10 +139,45 @@ chassis_run(struct controller_ctx *ctx, const char *chassis_id)
 
         const char *chassis_bridge_mappings
             = get_bridge_mappings(&chassis_rec->external_ids);
-        if (strcmp(bridge_mappings, chassis_bridge_mappings)) {
+        const char *chassis_datapath_type
+            = smap_get(&chassis_rec->external_ids, "datapath-type");
+        const char *chassis_iface_types
+            = smap_get(&chassis_rec->external_ids, "iface-types");
+
+        if (!chassis_datapath_type) {
+            chassis_datapath_type = "";
+        }
+
+        if (!chassis_iface_types) {
+            chassis_iface_types = "";
+        }
+
+        if (!strcmp(bridge_mappings, chassis_bridge_mappings)) {
+            bridge_mappings = NULL;
+        }
+        if (!strcmp(datapath_type, chassis_datapath_type)) {
+            datapath_type = NULL;
+        }
+
+        if (!strcmp(iface_types_str, chassis_iface_types)) {
+            iface_types_str = NULL;
+        }
+
+        if (bridge_mappings || datapath_type || iface_types_str) {
             struct smap new_ids;
             smap_clone(&new_ids, &chassis_rec->external_ids);
-            smap_replace(&new_ids, "ovn-bridge-mappings", bridge_mappings);
+            if (bridge_mappings) {
+                smap_replace(&new_ids, "ovn-bridge-mappings", bridge_mappings);
+            }
+
+            if (datapath_type) {
+                smap_replace(&new_ids, "datapath-type", datapath_type);
+            }
+
+            if (iface_types_str) {
+                smap_replace(&new_ids, "iface-types", iface_types_str);
+            }
+
             sbrec_chassis_verify_external_ids(chassis_rec);
             sbrec_chassis_set_external_ids(chassis_rec, &new_ids);
             smap_destroy(&new_ids);
@@ -169,14 +218,18 @@ chassis_run(struct controller_ctx *ctx, const char *chassis_id)
                               chassis_id);
 
     if (!chassis_rec) {
-        struct smap ext_ids = SMAP_CONST1(&ext_ids, "ovn-bridge-mappings",
-                                          bridge_mappings);
+        struct smap ext_ids = SMAP_INITIALIZER(&ext_ids);
+        smap_add(&ext_ids, "ovn-bridge-mappings", bridge_mappings);
+        smap_add(&ext_ids, "datapath-type", datapath_type);
+        smap_add(&ext_ids, "iface-types", iface_types_str);
         chassis_rec = sbrec_chassis_insert(ctx->ovnsb_idl_txn);
         sbrec_chassis_set_name(chassis_rec, chassis_id);
         sbrec_chassis_set_hostname(chassis_rec, hostname);
         sbrec_chassis_set_external_ids(chassis_rec, &ext_ids);
+        smap_destroy(&ext_ids);
     }
 
+    ds_destroy(&iface_types);
     int n_encaps = count_1bits(req_tunnels);
     struct sbrec_encap **encaps = xmalloc(n_encaps * sizeof *encaps);
     for (int i = 0; i < n_encaps; i++) {
diff --git a/ovn/controller/chassis.h b/ovn/controller/chassis.h
index a14da1c..016d71c 100644
--- a/ovn/controller/chassis.h
+++ b/ovn/controller/chassis.h
@@ -24,7 +24,8 @@ struct ovsrec_bridge;
 
 void chassis_register_ovs_idl(struct ovsdb_idl *);
 const struct sbrec_chassis *chassis_run(struct controller_ctx *,
-                                        const char *chassis_id);
+                                        const char *chassis_id,
+                                        const struct ovsrec_bridge *br_int);
 bool chassis_cleanup(struct controller_ctx *, const char *chassis_id);
 
 #endif /* ovn/chassis.h */
diff --git a/ovn/controller/ovn-controller.8.xml b/ovn/controller/ovn-controller.8.xml
index 3fda8e7..75151af 100644
--- a/ovn/controller/ovn-controller.8.xml
+++ b/ovn/controller/ovn-controller.8.xml
@@ -156,6 +156,30 @@
       </dd>
     </dl>
 
+    <p>
+      <code>ovn-controller</code> reads the following values from the
+      <code>Open_vSwitch</code> database of the local OVS instance:
+    </p>
+
+    <dl>
+      <dt><code>datapath-type</code> from <ref table="Bridge" db="Open_vSwitch"/> table</dt>
+      <dd>
+        This value is read from local OVS integration bridge row of
+        <ref table="Bridge" db="Open_vSwitch"/> table and populated in
+        <ref key="datapath-type" table="Chassis" column="external_ids"
+        db="OVN_Southbound"/> of the <ref table="Chassis" db="OVN_Southbound"/>
+        table in the OVN_Southbound database.
+      </dd>
+
+      <dt><code>iface-types</code> from <ref table="Open_vSwitch" db="Open_vSwitch"/> table</dt>
+      <dd>
+        This value is populated in <ref key="iface-types" table="Chassis"
+        column="external_ids" db="OVN_Southbound"/> of the
+        <ref table="Chassis" db="OVN_Southbound"/> table in the OVN_Southbound
+        database.
+      </dd>
+    </dl>
+
     <h1>Open vSwitch Database Usage</h1>
 
     <p>
diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c
index 2ca0295..09a11ab 100644
--- a/ovn/controller/ovn-controller.c
+++ b/ovn/controller/ovn-controller.c
@@ -435,7 +435,7 @@ main(int argc, char *argv[])
 
         const struct sbrec_chassis *chassis = NULL;
         if (chassis_id) {
-            chassis = chassis_run(&ctx, chassis_id);
+            chassis = chassis_run(&ctx, chassis_id, br_int);
             encaps_run(&ctx, br_int, chassis_id);
             binding_run(&ctx, br_int, chassis_id, &local_datapaths,
                         &all_lports);
diff --git a/ovn/ovn-sb.xml b/ovn/ovn-sb.xml
index c5f236e..96897f7 100644
--- a/ovn/ovn-sb.xml
+++ b/ovn/ovn-sb.xml
@@ -213,6 +213,22 @@
       information.
     </column>
 
+    <column name="external_ids" key="datapath-type">
+      <code>ovn-controller</code> populates this key with the datapath type
+      configured in the <ref table="Bridge" column="datapath_type"/> of the
+      Open_vSwitch database's <ref table="Bridge" db="Open_vSwitch"/> table.
+      Other applications should treat this key as read-only. See
+      <code>ovn-controller</code>(8) for more information.
+    </column>
+
+    <column name="external_ids" key="iface-types">
+      <code>ovn-controller</code> populates this key with the iface-types
+      configured in the <ref table="Open_vSwitch" column="iface_types"/> of the
+      Open_vSwitch database's <ref table="Open_vSwitch" db="Open_vSwitch"/> table.
+      Other applications should treat this key as read-only. See
+      <code>ovn-controller</code>(8) for more information.
+    </column>
+
     <group title="Common Columns">
       The overall purpose of these columns is described under <code>Common
       Columns</code> at the beginning of this document.
diff --git a/tests/ovn-controller.at b/tests/ovn-controller.at
index a2349a4..91fb2af 100644
--- a/tests/ovn-controller.at
+++ b/tests/ovn-controller.at
@@ -151,3 +151,63 @@ OVS_APP_EXIT_AND_WAIT_BY_TARGET([$ovs_base/ovn-sb/ovsdb-server-2.ctl], [$ovs_bas
 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
 
 AT_CLEANUP
+
+AT_SETUP([ovn-controller - chassis:external_ids - datapath-type and iface-types])
+AT_KEYWORDS([ovn])
+ovn_init_db ovn-sb
+
+net_add n1
+sim_add hv
+as hv
+ovs-vsctl \
+    -- add-br br-phys \
+    -- add-br br-eth0 \
+    -- add-br br-eth1 \
+    -- add-br br-eth2
+ovn_attach n1 br-phys 192.168.0.1
+
+# Make sure that the datapath_type set in the bridge table
+# is mirrored into the Chassis record in the OVN_Southbound db.
+check_datapath_type () {
+    datapath_type=$1
+    sysid=$(ovs-vsctl get Open_vSwitch . external_ids:system-id)
+    chassis_datapath_type=$(ovn-sbctl get Chassis ${sysid} external_ids:datapath-type | sed -e 's/\"//g')
+    AT_CHECK([test "${datapath_type}" = "${chassis_datapath_type}"])
+}
+
+check_datapath_type ""
+
+ovs-vsctl set Bridge br-int datapath-type=foo
+check_datapath_type foo
+
+# Change "ovn-bridge-mappings" value. It should not change the "datapath-type".
+ovs-vsctl set Open_vSwitch . external_ids:ovn-bridge-mappings=foo-mapping
+check_datapath_type foo
+
+ovs-vsctl set Bridge br-int datapath-type=bar
+check_datapath_type bar
+
+ovs-vsctl set Bridge br-int datapath-type=\"\"
+check_datapath_type ""
+
+expected_iface_types="dummy,dummy-pmd,geneve,gre,internal,ipsec_gre,lisp,patch,stt,system,tap,vxlan"
+sysid=$(ovs-vsctl get Open_vSwitch . external_ids:system-id)
+chassis_iface_types=$(ovn-sbctl get Chassis ${sysid} external_ids:iface-types | sed -e 's/\"//g')
+echo "chassis_iface_types = ${chassis_iface_types}"
+AT_CHECK([test "${expected_iface_types}" = "${chassis_iface_types}"])
+
+# Change the value of external_ids:iface-types using ovn-sbctl.
+# ovn-controller should again set it back to proper one.
+ovn-sbctl set Chassis ${sysid} external_ids:iface-types="foo"
+sleep 1
+chassis_iface_types=$(ovn-sbctl get Chassis ${sysid} external_ids:iface-types | sed -e 's/\"//g')
+echo "chassis_iface_types = ${chassis_iface_types}"
+AT_CHECK([test "${expected_iface_types}" = "${chassis_iface_types}"])
+
+# Gracefully terminate daemons
+OVN_CLEANUP_SBOX([hv])
+OVN_CLEANUP_VSWITCH([main])
+as ovn-sb
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
+
+AT_CLEANUP
-- 
2.7.4




More information about the dev mailing list