From 31681a5d627cec70864764586829bdb92abf2f30 Mon Sep 17 00:00:00 2001
From: Justin Pettit
Date: Thu, 15 Jul 2010 20:56:43 -0700
Subject: [PATCH] vswitchd: Move fail-mode config to Bridge table
Configuration of the fail-mode was an attribute of the Controller table.
However, it makes more sense as an attribute of the Bridge table, since
the behavior defines what a bridge should do if it can't connect to
*any* controller. This commit makes the move.
---
ofproto/ofproto.c | 63 ++++++++++++++++++++---------------
ofproto/ofproto.h | 2 +-
tests/ovs-vsctl.at | 2 ++
utilities/ovs-openflowd.c | 8 +++--
utilities/ovs-vsctl.c | 49 ++++-----------------------
vswitchd/bridge.c | 13 +++++---
vswitchd/vswitch.ovsschema | 8 ++---
vswitchd/vswitch.xml | 68 +++++++++++++++++---------------------
8 files changed, 95 insertions(+), 118 deletions(-)
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index 66b957e1..69004bc4 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -274,6 +274,7 @@ struct ofproto {
/* OpenFlow connections. */
struct hmap controllers; /* Controller "struct ofconn"s. */
struct list all_conns; /* Contains "struct ofconn"s. */
+ enum ofproto_fail_mode fail_mode;
struct pvconn **listeners;
size_t n_listeners;
struct pvconn **snoops;
@@ -586,13 +587,40 @@ update_in_band_remotes(struct ofproto *ofproto)
free(addrs);
}
+static void
+update_fail_open(struct ofproto *p)
+{
+ struct ofconn *ofconn;
+
+ if (!hmap_is_empty(&p->controllers)
+ && p->fail_mode == OFPROTO_FAIL_STANDALONE) {
+ struct rconn **rconns;
+ size_t n;
+
+ if (!p->fail_open) {
+ p->fail_open = fail_open_create(p, p->switch_status);
+ }
+
+ n = 0;
+ rconns = xmalloc(hmap_count(&p->controllers) * sizeof *rconns);
+ HMAP_FOR_EACH (ofconn, struct ofconn, hmap_node, &p->controllers) {
+ rconns[n++] = ofconn->rconn;
+ }
+
+ fail_open_set_controllers(p->fail_open, rconns, n);
+ /* p->fail_open takes ownership of 'rconns'. */
+ } else {
+ fail_open_destroy(p->fail_open);
+ p->fail_open = NULL;
+ }
+}
+
void
ofproto_set_controllers(struct ofproto *p,
const struct ofproto_controller *controllers,
size_t n_controllers)
{
struct shash new_controllers;
- enum ofproto_fail_mode fail_mode;
struct ofconn *ofconn, *next;
bool ss_exists;
size_t i;
@@ -607,7 +635,6 @@ ofproto_set_controllers(struct ofproto *p,
}
}
- fail_mode = OFPROTO_FAIL_STANDALONE;
ss_exists = false;
HMAP_FOR_EACH_SAFE (ofconn, next, struct ofconn, hmap_node,
&p->controllers) {
@@ -621,36 +648,13 @@ ofproto_set_controllers(struct ofproto *p,
if (ofconn->ss) {
ss_exists = true;
}
- if (c->fail == OFPROTO_FAIL_SECURE) {
- fail_mode = OFPROTO_FAIL_SECURE;
- }
}
}
shash_destroy(&new_controllers);
update_in_band_remotes(p);
- if (!hmap_is_empty(&p->controllers)
- && fail_mode == OFPROTO_FAIL_STANDALONE) {
- struct rconn **rconns;
- size_t n;
-
- if (!p->fail_open) {
- p->fail_open = fail_open_create(p, p->switch_status);
- }
-
- n = 0;
- rconns = xmalloc(hmap_count(&p->controllers) * sizeof *rconns);
- HMAP_FOR_EACH (ofconn, struct ofconn, hmap_node, &p->controllers) {
- rconns[n++] = ofconn->rconn;
- }
-
- fail_open_set_controllers(p->fail_open, rconns, n);
- /* p->fail_open takes ownership of 'rconns'. */
- } else {
- fail_open_destroy(p->fail_open);
- p->fail_open = NULL;
- }
+ update_fail_open(p);
if (!hmap_is_empty(&p->controllers) && !ss_exists) {
ofconn = CONTAINER_OF(hmap_first(&p->controllers),
@@ -660,6 +664,13 @@ ofproto_set_controllers(struct ofproto *p,
}
}
+void
+ofproto_set_fail_mode(struct ofproto *p, enum ofproto_fail_mode fail_mode)
+{
+ p->fail_mode = fail_mode;
+ update_fail_open(p);
+}
+
/* Drops the connections between 'ofproto' and all of its controllers, forcing
* them to reconnect. */
void
diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h
index 9880e825..56c54f5f 100644
--- a/ofproto/ofproto.h
+++ b/ofproto/ofproto.h
@@ -72,7 +72,6 @@ struct ofproto_controller {
char *target; /* e.g. "tcp:127.0.0.1" */
int max_backoff; /* Maximum reconnection backoff, in seconds. */
int probe_interval; /* Max idle time before probing, in seconds. */
- enum ofproto_fail_mode fail; /* Controller failure handling mode. */
enum ofproto_band band; /* In-band or out-of-band? */
/* Discovery options. */
@@ -104,6 +103,7 @@ bool ofproto_is_alive(const struct ofproto *);
void ofproto_set_datapath_id(struct ofproto *, uint64_t datapath_id);
void ofproto_set_controllers(struct ofproto *,
const struct ofproto_controller *, size_t n);
+void ofproto_set_fail_mode(struct ofproto *, enum ofproto_fail_mode fail_mode);
void ofproto_reconnect_controllers(struct ofproto *);
void ofproto_set_extra_in_band_remotes(struct ofproto *,
const struct sockaddr_in *, size_t n);
diff --git a/tests/ovs-vsctl.at b/tests/ovs-vsctl.at
index a8dc8546..72090d02 100644
--- a/tests/ovs-vsctl.at
+++ b/tests/ovs-vsctl.at
@@ -522,6 +522,7 @@ controller : []
datapath_id : []
datapath_type : ""
external_ids : {}
+fail_mode : []
flood_vlans : []
mirrors : []
name : "br0"
@@ -718,6 +719,7 @@ controller : []
datapath_id : []
datapath_type : ""
external_ids : {}
+fail_mode : []
flood_vlans : []
mirrors : []
name : "br0"
diff --git a/utilities/ovs-openflowd.c b/utilities/ovs-openflowd.c
index bb77d589..6dda8fb9 100644
--- a/utilities/ovs-openflowd.c
+++ b/utilities/ovs-openflowd.c
@@ -53,6 +53,7 @@ struct ofsettings {
/* Controller configuration. */
struct ofproto_controller *controllers;
size_t n_controllers;
+ enum ofproto_fail_mode fail_mode;
/* Datapath. */
uint64_t datapath_id; /* Datapath ID. */
@@ -165,6 +166,7 @@ main(int argc, char *argv[])
ovs_fatal(error, "failed to configure STP");
}
ofproto_set_controllers(ofproto, s.controllers, s.n_controllers);
+ ofproto_set_fail_mode(ofproto, s.fail_mode);
daemonize_complete();
@@ -265,12 +267,12 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
controller_opts.target = NULL;
controller_opts.max_backoff = 8;
controller_opts.probe_interval = 5;
- controller_opts.fail = OFPROTO_FAIL_STANDALONE;
controller_opts.band = OFPROTO_IN_BAND;
controller_opts.accept_re = NULL;
controller_opts.update_resolv_conf = true;
controller_opts.rate_limit = 0;
controller_opts.burst_limit = 0;
+ s->fail_mode = OFPROTO_FAIL_STANDALONE;
s->datapath_id = 0;
s->mfr_desc = NULL;
s->hw_desc = NULL;
@@ -329,10 +331,10 @@ parse_options(int argc, char *argv[], struct ofsettings *s)
case OPT_FAIL_MODE:
if (!strcmp(optarg, "open") || !strcmp(optarg, "standalone")) {
- controller_opts.fail = OFPROTO_FAIL_STANDALONE;
+ s->fail_mode = OFPROTO_FAIL_STANDALONE;
} else if (!strcmp(optarg, "closed")
|| !strcmp(optarg, "secure")) {
- controller_opts.fail = OFPROTO_FAIL_SECURE;
+ s->fail_mode = OFPROTO_FAIL_SECURE;
} else {
ovs_fatal(0, "--fail argument must be \"standalone\" "
"or \"secure\"");
diff --git a/utilities/ovs-vsctl.c b/utilities/ovs-vsctl.c
index 88ddd996..d68e4740 100644
--- a/utilities/ovs-vsctl.c
+++ b/utilities/ovs-vsctl.c
@@ -512,6 +512,7 @@ struct vsctl_bridge {
struct ovsrec_bridge *br_cfg;
char *name;
struct ovsrec_controller **ctrl;
+ char *fail_mode;
size_t n_ctrl;
struct vsctl_bridge *parent;
int vlan;
@@ -570,9 +571,11 @@ add_bridge(struct vsctl_info *b,
if (parent) {
br->ctrl = parent->br_cfg->controller;
br->n_ctrl = parent->br_cfg->n_controller;
+ br->fail_mode = parent->br_cfg->fail_mode;
} else {
br->ctrl = br_cfg->controller;
br->n_ctrl = br_cfg->n_controller;
+ br->fail_mode = br_cfg->fail_mode;
}
shash_add(&b->bridges, br->name, br);
return br;
@@ -1625,57 +1628,22 @@ cmd_set_controller(struct vsctl_context *ctx)
free_info(&info);
}
-static const char *
-get_fail_mode(struct ovsrec_controller **controllers, size_t n_controllers)
-{
- const char *fail_mode;
- size_t i;
-
- fail_mode = NULL;
- for (i = 0; i < n_controllers; i++) {
- const char *s = controllers[i]->fail_mode;
- if (s) {
- if (!strcmp(s, "secure")) {
- return s;
- } else {
- fail_mode = s;
- }
- }
- }
-
- return fail_mode;
-}
-
static void
cmd_get_fail_mode(struct vsctl_context *ctx)
{
struct vsctl_info info;
struct vsctl_bridge *br;
- const char *fail_mode = NULL;
get_info(ctx->ovs, &info);
br = find_bridge(&info, ctx->argv[1], true);
- fail_mode = get_fail_mode(br->ctrl, br->n_ctrl);
-
- if (fail_mode && strlen(fail_mode)) {
- ds_put_format(&ctx->output, "%s\n", fail_mode);
+ if (br->fail_mode && strlen(br->fail_mode)) {
+ ds_put_format(&ctx->output, "%s\n", br->fail_mode);
}
free_info(&info);
}
-static void
-set_fail_mode(struct ovsrec_controller **controllers, size_t n_controllers,
- const char *fail_mode)
-{
- size_t i;
-
- for (i = 0; i < n_controllers; i++) {
- ovsrec_controller_set_fail_mode(controllers[i], fail_mode);
- }
-}
-
static void
cmd_del_fail_mode(struct vsctl_context *ctx)
{
@@ -1685,7 +1653,7 @@ cmd_del_fail_mode(struct vsctl_context *ctx)
get_info(ctx->ovs, &info);
br = find_real_bridge(&info, ctx->argv[1], true);
- set_fail_mode(br->ctrl, br->n_ctrl, NULL);
+ ovsrec_bridge_set_fail_mode(br->br_cfg, NULL);
free_info(&info);
}
@@ -1704,10 +1672,7 @@ cmd_set_fail_mode(struct vsctl_context *ctx)
vsctl_fatal("fail-mode must be \"standalone\" or \"secure\"");
}
- if (!br->ctrl) {
- vsctl_fatal("no controller declared for %s", br->name);
- }
- set_fail_mode(br->ctrl, br->n_ctrl, fail_mode);
+ ovsrec_bridge_set_fail_mode(br->br_cfg, fail_mode);
free_info(&info);
}
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index fc03a122..507c70ce 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -1423,6 +1423,7 @@ bridge_reconfigure_one(struct bridge *br)
struct svec listeners, old_listeners;
struct svec snoops, old_snoops;
struct shash_node *node;
+ enum ofproto_fail_mode fail_mode;
size_t i;
/* Collect old ports. */
@@ -1491,6 +1492,13 @@ bridge_reconfigure_one(struct bridge *br)
shash_destroy(&old_ports);
shash_destroy(&new_ports);
+ /* Set the fail-mode */
+ fail_mode = !br->cfg->fail_mode
+ || !strcmp(br->cfg->fail_mode, "standalone")
+ ? OFPROTO_FAIL_STANDALONE
+ : OFPROTO_FAIL_SECURE;
+ ofproto_set_fail_mode(br->ofproto, fail_mode);
+
/* Delete all flows if we're switching from connected to standalone or vice
* versa. (XXX Should we delete all flows if we are switching from one
* controller to another?) */
@@ -1604,11 +1612,6 @@ bridge_reconfigure_remotes(struct bridge *br,
oc->max_backoff = c->max_backoff ? *c->max_backoff / 1000 : 8;
oc->probe_interval = (c->inactivity_probe
? *c->inactivity_probe / 1000 : 5);
- oc->fail = (!c->fail_mode
- || !strcmp(c->fail_mode, "standalone")
- || !strcmp(c->fail_mode, "open")
- ? OFPROTO_FAIL_STANDALONE
- : OFPROTO_FAIL_SECURE);
oc->band = (!c->connection_mode
|| !strcmp(c->connection_mode, "in-band")
? OFPROTO_IN_BAND
diff --git a/vswitchd/vswitch.ovsschema b/vswitchd/vswitch.ovsschema
index 417ce96a..5df97b91 100644
--- a/vswitchd/vswitch.ovsschema
+++ b/vswitchd/vswitch.ovsschema
@@ -62,6 +62,10 @@
"type": {"key": {"type": "uuid",
"refTable": "Controller"},
"min": 0, "max": "unlimited"}},
+ "fail_mode": {
+ "type": {"key": {"type": "string",
+ "enum": ["set", ["standalone", "secure"]]},
+ "min": 0, "max": 1}},
"other_config": {
"type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}},
"external_ids": {
@@ -226,10 +230,6 @@
"min": 0, "max": 1}},
"inactivity_probe": {
"type": {"key": "integer", "min": 0, "max": 1}},
- "fail_mode": {
- "type": {"key": {"type": "string",
- "enum": ["set", ["standalone", "secure"]]},
- "min": 0, "max": 1}},
"discover_accept_regex": {
"type": {"key": "string", "min": 0, "max": 1}},
"discover_update_resolv_conf": {
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index da3652b9..f5e010ba 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -130,6 +130,37 @@
will be used.
+
+ When a controller is configured, it is, ordinarily, responsible
+ for setting up all flows on the switch. Thus, if the connection to
+ the controller fails, no new network connections can be set up.
+ If the connection to the controller stays down long enough,
+ no packets can pass through the switch at all. This setting
+ determines the switch's response to such a situation. It may be set
+ to one of the following:
+
+ standalone
+ - If no message is received from the controller for three
+ times the inactivity probe interval
+ (see
), then Open vSwitch
+ will take over responsibility for setting up flows. In
+ this mode, Open vSwitch causes the bridge to act like an
+ ordinary MAC-learning switch. Open vSwitch will continue
+ to retry connecting to the controller in the background
+ and, when the connection succeeds, it will discontinue its
+ standalone behavior.
+ secure
+ - Open vSwitch will not set up flows on its own when the
+ controller connection fails. It will continue retry
+ connecting to the controller forever.
+
+
+ If this value is unset, the default is implementation-specific.
+ When more than one controller is configured,
+ is considered only when none of the
+ configured controllers can be contacted.
+
+
Reports the OpenFlow datapath ID in use. Exactly 16 hex
digits. (Setting this column will have no useful effect. Set
@@ -869,43 +900,6 @@
assumes the connection has been broken and attempts to reconnect.
Default is implementation-specific.
-
-
- When a controller is configured, it is, ordinarily, responsible
- for setting up all flows on the switch. Thus, if the connection to
- the controller fails, no new network connections can be set up.
- If the connection to the controller stays down long enough,
- no packets can pass through the switch at all. This setting
- determines the switch's response to such a situation. It may be set
- to one of the following:
-
- standalone
- - If no message is received from the controller for three
- times the inactivity probe interval
- (see
), then Open vSwitch
- will take over responsibility for setting up flows. In
- this mode, Open vSwitch causes the bridge to act like an
- ordinary MAC-learning switch. Open vSwitch will continue
- to retry connecting to the controller in the background
- and, when the connection succeeds, it will discontinue its
- standalone behavior.
- secure
- - Open vSwitch will not set up flows on its own when the
- controller connection fails. It will continue retry
- connecting to the controller forever.
-
-
- If this value is unset, the default is implementation-specific.
- When more than one controller is configured,
- is considered only when none of the
- configured controllers can be contacted. At that point, the bridge
- enters secure mode if any of the controllers'
- is set to secure
. Otherwise,
- it enters standalone mode if at least one
- is set to standalone
. If none of the
- values are set, the default is
- implementation-defined.
-
--
2.30.2