summaryrefslogtreecommitdiff
path: root/ovn
diff options
context:
space:
mode:
authorJustin Pettit <jpettit@nicira.com>2015-10-14 11:32:12 -0700
committerJustin Pettit <jpettit@nicira.com>2015-10-16 00:55:24 -0700
commitbf388125f6b294224d31366b81c69908543d2671 (patch)
tree1489ab820dbcef343776da7d2462d80ac27004b0 /ovn
parent379109949ece0c818e49e153d95f3a9f4057c68e (diff)
downloadopenvswitch-bf388125f6b294224d31366b81c69908543d2671.tar.gz
ovn-controller: Support multiple encaps simultaneously.
Signed-off-by: Justin Pettit <jpettit@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'ovn')
-rw-r--r--ovn/controller/chassis.c91
-rw-r--r--ovn/controller/encaps.c20
-rw-r--r--ovn/controller/ovn-controller.8.xml10
-rw-r--r--ovn/controller/ovn-controller.c14
-rw-r--r--ovn/controller/ovn-controller.h11
-rw-r--r--ovn/controller/physical.c2
6 files changed, 112 insertions, 36 deletions
diff --git a/ovn/controller/chassis.c b/ovn/controller/chassis.c
index abe2e4df9..6617bf3b5 100644
--- a/ovn/controller/chassis.c
+++ b/ovn/controller/chassis.c
@@ -16,6 +16,7 @@
#include <config.h>
#include "chassis.h"
+#include "lib/dynamic-string.h"
#include "lib/vswitch-idl.h"
#include "openvswitch/vlog.h"
#include "ovn/lib/ovn-sb-idl.h"
@@ -30,6 +31,23 @@ chassis_register_ovs_idl(struct ovsdb_idl *ovs_idl)
ovsdb_idl_add_column(ovs_idl, &ovsrec_open_vswitch_col_external_ids);
}
+static const char *
+pop_tunnel_name(uint32_t *type)
+{
+ if (*type & GENEVE) {
+ *type &= ~GENEVE;
+ return "geneve";
+ } else if (*type & STT) {
+ *type &= ~STT;
+ return "stt";
+ } else if (*type & VXLAN) {
+ *type &= ~VXLAN;
+ return "vxlan";
+ }
+
+ OVS_NOT_REACHED();
+}
+
void
chassis_run(struct controller_ctx *ctx, const char *chassis_id)
{
@@ -40,13 +58,10 @@ chassis_run(struct controller_ctx *ctx, const char *chassis_id)
const struct sbrec_chassis *chassis_rec;
const struct ovsrec_open_vswitch *cfg;
const char *encap_type, *encap_ip;
- struct sbrec_encap *encap_rec;
static bool inited = false;
chassis_rec = get_chassis(ctx->ovnsb_idl, chassis_id);
- /* xxx Need to support more than one encap. Also need to support
- * xxx encap options. */
cfg = ovsrec_open_vswitch_first(ctx->ovs_idl);
if (!cfg) {
VLOG_INFO("No Open_vSwitch row defined.");
@@ -60,23 +75,48 @@ chassis_run(struct controller_ctx *ctx, const char *chassis_id)
return;
}
+ char *tokstr = xstrdup(encap_type);
+ char *save_ptr = NULL;
+ char *token;
+ uint32_t req_tunnels = 0;
+ for (token = strtok_r(tokstr, ",", &save_ptr); token != NULL;
+ token = strtok_r(NULL, ",", &save_ptr)) {
+ uint32_t type = get_tunnel_type(token);
+ if (!type) {
+ VLOG_INFO("Unknown tunnel type: %s", token);
+ }
+ req_tunnels |= type;
+ }
+ free(tokstr);
+
if (chassis_rec) {
- int i;
-
- for (i = 0; i < chassis_rec->n_encaps; i++) {
- if (!strcmp(chassis_rec->encaps[i]->type, encap_type)
- && !strcmp(chassis_rec->encaps[i]->ip, encap_ip)) {
- /* Nothing changed. */
- inited = true;
- return;
- } else if (!inited) {
- VLOG_WARN("Chassis config changing on startup, make sure "
- "multiple chassis are not configured : %s/%s->%s/%s",
- chassis_rec->encaps[i]->type,
- chassis_rec->encaps[i]->ip,
- encap_type, encap_ip);
+ /* Compare desired tunnels against those currently in the database. */
+ uint32_t cur_tunnels = 0;
+ bool 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);
+ }
+ same = same && req_tunnels == cur_tunnels;
+
+ if (same) {
+ /* Nothing changed. */
+ inited = true;
+ return;
+ } else if (!inited) {
+ struct ds cur_encaps = DS_EMPTY_INITIALIZER;
+ for (int i = 0; i < chassis_rec->n_encaps; i++) {
+ ds_put_format(&cur_encaps, "%s,",
+ chassis_rec->encaps[i]->type);
}
-
+ ds_chomp(&cur_encaps, ',');
+
+ VLOG_WARN("Chassis config changing on startup, make sure "
+ "multiple chassis are not configured : %s/%s->%s/%s",
+ ds_cstr(&cur_encaps),
+ chassis_rec->encaps[0]->ip,
+ encap_type, encap_ip);
+ ds_destroy(&cur_encaps);
}
}
@@ -89,12 +129,19 @@ chassis_run(struct controller_ctx *ctx, const char *chassis_id)
sbrec_chassis_set_name(chassis_rec, chassis_id);
}
- encap_rec = sbrec_encap_insert(ctx->ovnsb_idl_txn);
+ int n_encaps = count_1bits(req_tunnels);
+ struct sbrec_encap **encaps = xmalloc(n_encaps * sizeof *encaps);
+ for (int i = 0; i < n_encaps; i++) {
+ const char *type = pop_tunnel_name(&req_tunnels);
+
+ encaps[i] = sbrec_encap_insert(ctx->ovnsb_idl_txn);
- sbrec_encap_set_type(encap_rec, encap_type);
- sbrec_encap_set_ip(encap_rec, encap_ip);
+ sbrec_encap_set_type(encaps[i], type);
+ sbrec_encap_set_ip(encaps[i], encap_ip);
+ }
- sbrec_chassis_set_encaps(chassis_rec, &encap_rec, 1);
+ sbrec_chassis_set_encaps(chassis_rec, encaps, n_encaps);
+ free(encaps);
inited = true;
}
diff --git a/ovn/controller/encaps.c b/ovn/controller/encaps.c
index de1aef3a7..dfb11c081 100644
--- a/ovn/controller/encaps.c
+++ b/ovn/controller/encaps.c
@@ -210,20 +210,18 @@ bridge_delete_port(const struct ovsrec_bridge *br,
static struct sbrec_encap *
preferred_encap(const struct sbrec_chassis *chassis_rec)
{
- size_t i;
-
- /* For hypervisors, we only support Geneve and STT encapsulations.
- * Sets are returned alphabetically, so "geneve" will be preferred
- * over "stt". For gateways, we only support VXLAN encapsulation. */
- for (i = 0; i < chassis_rec->n_encaps; i++) {
- if (!strcmp(chassis_rec->encaps[i]->type, "geneve")
- || !strcmp(chassis_rec->encaps[i]->type, "stt")
- || !strcmp(chassis_rec->encaps[i]->type, "vxlan")) {
- return chassis_rec->encaps[i];
+ struct sbrec_encap *best_encap = NULL;
+ uint32_t best_type = 0;
+
+ for (int i = 0; i < chassis_rec->n_encaps; i++) {
+ uint32_t tun_type = get_tunnel_type(chassis_rec->encaps[i]->type);
+ if (tun_type > best_type) {
+ best_type = tun_type;
+ best_encap = chassis_rec->encaps[i];
}
}
- return NULL;
+ return best_encap;
}
void
diff --git a/ovn/controller/ovn-controller.8.xml b/ovn/controller/ovn-controller.8.xml
index 4aaf97b86..e79e66508 100644
--- a/ovn/controller/ovn-controller.8.xml
+++ b/ovn/controller/ovn-controller.8.xml
@@ -104,7 +104,13 @@
<dd>
<p>
The encapsulation type that a chassis should use to connect to
- this node. Supported tunnel types for connecting hypervisors
+ this node. Multiple encapsulation types may be specified with
+ a comma-separated list. Each listed encapsulation type will
+ be paired with <code>ovn-encap-ip</code>.
+ </p>
+
+ <p>
+ Supported tunnel types for connecting hypervisors
are <code>geneve</code> and <code>stt</code>. Gateways may
use <code>geneve</code>, <code>vxlan</code>, or
<code>stt</code>.
@@ -120,7 +126,7 @@
<dt><code>external_ids:ovn-encap-ip</code></dt>
<dd>
The IP address that a chassis should use to connect to this node
- using encapsulation type specified by
+ using encapsulation types specified by
<code>external_ids:ovn-encap-type</code>.
</dd>
diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c
index 85df099e1..3bd072aa3 100644
--- a/ovn/controller/ovn-controller.c
+++ b/ovn/controller/ovn-controller.c
@@ -73,6 +73,20 @@ get_chassis(struct ovsdb_idl *ovnsb_idl, const char *chassis_id)
return chassis_rec;
}
+uint32_t
+get_tunnel_type(const char *name)
+{
+ if (!strcmp(name, "geneve")) {
+ return GENEVE;
+ } else if (!strcmp(name, "stt")) {
+ return STT;
+ } else if (!strcmp(name, "vxlan")) {
+ return VXLAN;
+ }
+
+ return 0;
+}
+
static const struct ovsrec_bridge *
get_bridge(struct ovsdb_idl *ovs_idl, const char *br_name)
{
diff --git a/ovn/controller/ovn-controller.h b/ovn/controller/ovn-controller.h
index 85e13a658..ded7fce95 100644
--- a/ovn/controller/ovn-controller.h
+++ b/ovn/controller/ovn-controller.h
@@ -34,4 +34,15 @@ struct controller_ctx {
const struct sbrec_chassis *get_chassis(struct ovsdb_idl *,
const char *chassis_id);
+/* Must be a bit-field ordered from most-preferred (higher number) to
+ * least-preferred (lower number). */
+enum chassis_tunnel_type {
+ GENEVE = 1 << 2,
+ STT = 1 << 1,
+ VXLAN = 1 << 0
+};
+
+uint32_t get_tunnel_type(const char *name);
+
+
#endif /* ovn/ovn-controller.h */
diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c
index 17fa63588..1f5f71630 100644
--- a/ovn/controller/physical.c
+++ b/ovn/controller/physical.c
@@ -54,7 +54,7 @@ struct chassis_tunnel {
struct hmap_node hmap_node;
const char *chassis_id;
ofp_port_t ofport;
- enum chassis_tunnel_type { GENEVE, STT, VXLAN } type;
+ enum chassis_tunnel_type type;
};
static struct chassis_tunnel *