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