]> git.proxmox.com Git - ovs.git/commitdiff
ovn-controller: Add datapath-type and iface-types in chassis:external_ids
authorNuman Siddique <nusiddiq@redhat.com>
Sat, 30 Jul 2016 10:02:01 +0000 (15:32 +0530)
committerBen Pfaff <blp@ovn.org>
Sat, 13 Aug 2016 16:20:22 +0000 (09:20 -0700)
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@redhat.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
Acked-by: Ryan Moats <rmoats@us.ibm.com>
ovn/controller/chassis.c
ovn/controller/chassis.h
ovn/controller/ovn-controller.8.xml
ovn/controller/ovn-controller.c
ovn/ovn-sb.xml
tests/ovn-controller.at

index b5f022e456eb395152d8584ea085f9b3bf61609d..97fc2bf5592fd04a4c6b7621549c871d9f25f4d7 100644 (file)
@@ -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 *
@@ -66,7 +69,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;
@@ -113,6 +117,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);
@@ -122,12 +136,23 @@ chassis_run(struct controller_ctx *ctx, const char *chassis_id)
             sbrec_chassis_set_hostname(chassis_rec, hostname);
         }
 
+        /* Determine new values for Chassis external-ids. */
         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_def(&chassis_rec->external_ids, "datapath-type", "");
+        const char *chassis_iface_types
+            = smap_get_def(&chassis_rec->external_ids, "iface-types", "");
+
+        /* If any of the external-ids should change, update them. */
+        if (strcmp(bridge_mappings, chassis_bridge_mappings) ||
+            strcmp(datapath_type, chassis_datapath_type) ||
+            strcmp(iface_types_str, chassis_iface_types)) {
             struct smap new_ids;
             smap_clone(&new_ids, &chassis_rec->external_ids);
             smap_replace(&new_ids, "ovn-bridge-mappings", bridge_mappings);
+            smap_replace(&new_ids, "datapath-type", datapath_type);
+            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);
@@ -145,6 +170,7 @@ chassis_run(struct controller_ctx *ctx, const char *chassis_id)
         if (same) {
             /* Nothing changed. */
             inited = true;
+            ds_destroy(&iface_types);
             return chassis_rec;
         } else if (!inited) {
             struct ds cur_encaps = DS_EMPTY_INITIALIZER;
@@ -168,14 +194,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++) {
index a14da1cf3fcc7b59501a16c110253e849d29fa34..016d71c5f81c7e5faefc6caabd8d07594b756774 100644 (file)
@@ -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 */
index 4681b3ffaad5666c6623f53d19ed2bdd3c344756..345d104a06a9011b3b9945f54e46c9a93fc1f81a 100644 (file)
       </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>
index a2530a7c1e4eb50266519f562b4d34f8d642f12d..4694a31e3afed837bffa6f38a8e3ef2bae23cc2d 100644 (file)
@@ -433,7 +433,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);
index 13c9526963731d7f578c939231490f64202f38cf..795be68e171033de42b7578ca023755ecfbfd75e 100644 (file)
       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"/> column 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 interface types
+      configured in the <ref table="Open_vSwitch" column="iface_types"/> column
+      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.
index a2349a408b0c896da6a601c0b27d2df512486797..af64804e03fac2c439ed9fb2706997a28a86c76a 100644 (file)
@@ -151,3 +151,68 @@ 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
+
+# Checks that ovn-controller populates datapath-type and iface-types
+# correctly in the Chassis external-ids column.
+AT_SETUP([ovn-controller - Chassis external_ids])
+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
+
+sysid=$(ovs-vsctl get Open_vSwitch . external_ids:system-id)
+
+# 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
+    chassis_datapath_type=$(ovn-sbctl get Chassis ${sysid} external_ids:datapath-type | sed -e 's/"//g') #"
+    test "${datapath_type}" = "${chassis_datapath_type}"
+}
+
+OVS_WAIT_UNTIL([check_datapath_type ""])
+
+ovs-vsctl set Bridge br-int datapath-type=foo
+OVS_WAIT_UNTIL([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
+OVS_WAIT_UNTIL([check_datapath_type bar])
+
+ovs-vsctl set Bridge br-int datapath-type=\"\"
+OVS_WAIT_UNTIL([check_datapath_type ""])
+
+# The following will need to be updated as OVS starts to support more
+# interface types.
+expected_iface_types="dummy,dummy-pmd,geneve,gre,internal,ipsec_gre,lisp,patch,stt,system,tap,vxlan"
+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"
+OVS_WAIT_UNTIL([
+    chassis_iface_types=$(ovn-sbctl get Chassis ${sysid} external_ids:iface-types | sed -e 's/\"//g')
+    echo "chassis_iface_types = ${chassis_iface_types}"
+    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