@@ -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++) {
@@ -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 */
@@ -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>
@@ -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);
@@ -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.
@@ -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
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> --- 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.