@@ -19,6 +19,7 @@
#include "chassis.h"
#include "lib/smap.h"
+#include "lib/sset.h"
#include "lib/vswitch-idl.h"
#include "openvswitch/dynamic-string.h"
#include "openvswitch/vlog.h"
@@ -57,6 +58,20 @@ pop_tunnel_name(uint32_t *type)
}
static const char *
+pop_compute_type(uint32_t *type)
+{
+ if (*type & VIF) {
+ *type &= ~VIF;
+ return "vif";
+ } else if (*type & GATEWAY_ROUTER) {
+ *type &= ~GATEWAY_ROUTER;
+ return "gateway_router";
+ }
+
+ OVS_NOT_REACHED();
+}
+
+static const char *
get_bridge_mappings(const struct smap *ext_ids)
{
const char *bridge_mappings = smap_get(ext_ids, "ovn-bridge-mappings");
@@ -110,6 +125,28 @@ chassis_run(struct controller_ctx *ctx, const char *chassis_id)
hostname = hostname_;
}
+ const char *str_compute_types = smap_get(&cfg->external_ids,
+ "ovn-compute-types");
+ uint32_t req_compute_types = 0;
+ if (str_compute_types) {
+ tokstr = xstrdup(str_compute_types);
+ save_ptr = NULL;
+ for (token = strtok_r(tokstr, ",", &save_ptr); token != NULL;
+ token = strtok_r(NULL, ", ", &save_ptr)) {
+ uint32_t type = get_compute_type(token);
+ if (!type) {
+ VLOG_INFO("Unknown compute type: \'%s\'", token);
+ }
+ req_compute_types |= type;
+ }
+ free(tokstr);
+ }
+ if (!req_compute_types) {
+ /* If no compute-type preference has been set by the user, the
+ * default preference is that the chassis supports all compute types*/
+ req_compute_types = VIF | GATEWAY_ROUTER;
+ }
+
const char *bridge_mappings = get_bridge_mappings(&cfg->external_ids);
const struct sbrec_chassis *chassis_rec
@@ -131,9 +168,32 @@ chassis_run(struct controller_ctx *ctx, const char *chassis_id)
smap_destroy(&new_ids);
}
+ /* Compare desired compute_types against those currently in the db. */
+ uint32_t cur_compute_types = 0;
+ bool same = true;
+ for (int i = 0; i < chassis_rec->n_compute_types; i++) {
+ cur_compute_types |=
+ get_compute_type(chassis_rec->compute_types[i]);
+ }
+ if (cur_compute_types != req_compute_types) {
+ int n_compute_types = count_1bits(req_compute_types);
+ struct sset compute_types = SSET_INITIALIZER(&compute_types);
+
+ for (int i = 0; i < n_compute_types; i++) {
+ const char *type = pop_compute_type(&req_compute_types);
+ sset_add(&compute_types, type);
+ }
+
+ const char **ct_arr = sset_array(&compute_types);
+ sbrec_chassis_set_compute_types(chassis_rec, ct_arr,
+ sset_count(&compute_types));
+ free(ct_arr);
+ sset_destroy(&compute_types);
+ }
+
/* Compare desired tunnels against those currently in the database. */
uint32_t cur_tunnels = 0;
- bool same = true;
+ same = true;
for (int i = 0; i < chassis_rec->n_encaps; i++) {
cur_tunnels |= get_tunnel_type(chassis_rec->encaps[i]->type);
same = same && !strcmp(chassis_rec->encaps[i]->ip, encap_ip);
@@ -154,6 +154,25 @@
value mapping two physical network names to two ovs bridges would be:
<code>physnet1:br-eth0,physnet2:br-eth1</code>.
</dd>
+
+ <dt><code>external_ids:ovn-compute-types</code></dt>
+ <dd>
+ <p>
+ A hypervisor in OVN can host 2 types of non-distributed ports,
+ <code>VM/VIFs</code> and <code>Gateway Router</code>. In some cloud
+ deployments, the CMS operator may want to schedule the ports on
+ specific hypervisors based on their type. The hypervisor/compute
+ administrator can provide a hint of the type of non-distributed
+ port it would prefer to support using this field.
+ </p>
+
+ <p>
+ Supported ovn-compute-types are <code>vif</code> and
+ <code>gateway</code>. The CMS can choose to ignore the hints provided
+ by the hypervisor; this implies that the ovn-controller will not
+ verify the type of non-distributed port scheduled on the hypervisor.
+ </p>
+ </dd>
</dl>
<h1>Open vSwitch Database Usage</h1>
@@ -113,6 +113,18 @@ get_tunnel_type(const char *name)
return 0;
}
+uint32_t
+get_compute_type(const char *name)
+{
+ if (!strcmp(name, "vif")) {
+ return VIF;
+ } else if (!strcmp(name, "gateway_router")) {
+ return GATEWAY_ROUTER;
+ }
+
+ return 0;
+}
+
const struct ovsrec_bridge *
get_bridge(struct ovsdb_idl *ovs_idl, const char *br_name)
{
@@ -71,5 +71,11 @@ enum chassis_tunnel_type {
uint32_t get_tunnel_type(const char *name);
+enum chassis_compute_type {
+ VIF = 1 << 0,
+ GATEWAY_ROUTER = 1 << 1
+};
+
+uint32_t get_compute_type(const char *name);
#endif /* ovn/ovn-controller.h */
@@ -1,7 +1,7 @@
{
"name": "OVN_Southbound",
"version": "1.3.0",
- "cksum": "654726257 5528",
+ "cksum": "2794990643 5696",
"tables": {
"Chassis": {
"columns": {
@@ -13,6 +13,9 @@
"vtep_logical_switches" : {"type": {"key": "string",
"min": 0,
"max": "unlimited"}},
+ "compute_types": {"type": {"key": "string",
+ "min": 1,
+ "max": 2}},
"external_ids": {
"type": {"key": "string", "value": "string",
"min": 0, "max": "unlimited"}}},
@@ -199,8 +199,8 @@
</column>
</group>
- <group title="Gateway Configuration">
- <p>
+ <group title="Gateway Configuration">
+ <p>
A <dfn>gateway</dfn> is a chassis that forwards traffic between the
OVN-managed part of a logical network and a physical VLAN, extending a
tunnel-based logical network into a physical network. Gateways are
@@ -218,7 +218,23 @@
<ref column="vtep_logical_switches" table="Chassis"/>, will be
associated with this <ref table="Chassis"/>.
</column>
- </group>
+ </group>
+
+ <group title='Chassis Specifications'>
+ <p>
+ A chassis in OVN can host 2 types of non-distributed ports,
+ <code>VM/VIFs</code> and <code>Gateway Router</code>. In some cloud
+ deployments, the CMS operator may want to schedule the ports on
+ specific hypervisors based on their type. The hypervisor/compute
+ administrator can provide a hint of the type of non-distributed
+ port it would prefer to support using this field.
+ </p>
+
+ <column name="compute_types">
+ Supported ovn-compute-types are <code>vif</code> and
+ <code>gateway</code>.
+ </column>
+ </group>
</table>
<table name="Encap" title="Encapsulation Types">
This patch allows a OVN hypervisor administator to specify the type(s) of non-distributed logical port, the hypervisor would prefer to support. In some cloud deployments such as OpenStack, the operator may want to dedicate certain hypervisors to host VMs and other hypervisors to host the gateway port of a router. The hypervisor administrator can provide a hint regarding the type of non-distributed port it would prefer to support. This is similar to existing Network and Compute Node concept in OpenStack. There are 2 types of non-distributed ports: 1. vif - VMs or containers 2. gateway_router - The OVN L3 gateway router The operator can set the preference in the using the external-id 'ovn-compute-types'. The default preference (when the external-id is not set) is that the hypervisor supports all non-distributed ports. ovs-vsctl set open_vswitch external-ids:ovn-compute-types="vif" ovs-vsctl set open_vswitch external-ids:ovn-compute-types="gateway_router" ovs-vsctl set open_vswitch external-ids:ovn-compute-types="vif,gateway_router" The ovn-controller reads the external-ids from the Open_vSwitch DB and sets the compute_types column in the corresponding chassis. The operator can read the preference in from the Chassis Table of the OVN_Southbound DB and schedule the VM and the Gateway Router accordingly. Note: It is possible that operator may choose to ignore the preference set by the hypervisor, so the ovn-controller does not verify that the ports it is hosting matches the its preference. Signed-off-by: Amitabha Biswas <abiswas@us.ibm.com> --- ovn/controller/chassis.c | 62 ++++++++++++++++++++++++++++++++++++- ovn/controller/ovn-controller.8.xml | 19 ++++++++++++ ovn/controller/ovn-controller.c | 12 +++++++ ovn/controller/ovn-controller.h | 6 ++++ ovn/ovn-sb.ovsschema | 5 ++- ovn/ovn-sb.xml | 22 +++++++++++-- 6 files changed, 121 insertions(+), 5 deletions(-)