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.
/* 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;
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;
}
}
- fail_mode = OFPROTO_FAIL_STANDALONE;
ss_exists = false;
HMAP_FOR_EACH_SAFE (ofconn, next, struct ofconn, hmap_node,
&p->controllers) {
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),
}
}
+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
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. */
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);
datapath_id : []
datapath_type : ""
external_ids : {}
+fail_mode : []
flood_vlans : []
mirrors : []
name : "br0"
datapath_id : []
datapath_type : ""
external_ids : {}
+fail_mode : []
flood_vlans : []
mirrors : []
name : "br0"
/* Controller configuration. */
struct ofproto_controller *controllers;
size_t n_controllers;
+ enum ofproto_fail_mode fail_mode;
/* Datapath. */
uint64_t datapath_id; /* Datapath ID. */
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();
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;
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\"");
struct ovsrec_bridge *br_cfg;
char *name;
struct ovsrec_controller **ctrl;
+ char *fail_mode;
size_t n_ctrl;
struct vsctl_bridge *parent;
int vlan;
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;
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)
{
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);
}
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);
}
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. */
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?) */
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
"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": {
"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": {
will be used.
</column>
+ <column name="fail_mode">
+ <p>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:
+ <dl>
+ <dt><code>standalone</code></dt>
+ <dd>If no message is received from the controller for three
+ times the inactivity probe interval
+ (see <ref column="inactivity_probe"/>), 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.</dd>
+ <dt><code>secure</code></dt>
+ <dd>Open vSwitch will not set up flows on its own when the
+ controller connection fails. It will continue retry
+ connecting to the controller forever.</dd>
+ </dl>
+ </p>
+ <p>If this value is unset, the default is implementation-specific.</p>
+ <p>When more than one controller is configured,
+ <ref column="fail_mode"/> is considered only when none of the
+ configured controllers can be contacted.</p>
+ </column>
+
<column name="datapath_id">
Reports the OpenFlow datapath ID in use. Exactly 16 hex
digits. (Setting this column will have no useful effect. Set
assumes the connection has been broken and attempts to reconnect.
Default is implementation-specific.
</column>
-
- <column name="fail_mode">
- <p>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:
- <dl>
- <dt><code>standalone</code></dt>
- <dd>If no message is received from the controller for three
- times the inactivity probe interval
- (see <ref column="inactivity_probe"/>), 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.</dd>
- <dt><code>secure</code></dt>
- <dd>Open vSwitch will not set up flows on its own when the
- controller connection fails. It will continue retry
- connecting to the controller forever.</dd>
- </dl>
- </p>
- <p>If this value is unset, the default is implementation-specific.</p>
- <p>When more than one controller is configured,
- <ref column="fail_mode"/> 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'
- <ref column="fail_mode"/> is set to <code>secure</code>. Otherwise,
- it enters standalone mode if at least one <ref column="fail_mode"/>
- is set to <code>standalone</code>. If none of the
- <ref column="fail_mode"/> values are set, the default is
- implementation-defined.</p>
- </column>
</group>
<group title="OpenFlow Rate Limiting">