2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-22 01:51:26 +00:00

vswitchd: Add "enable-async-messages" setting for controllers.

An OpenFlow connection can start receiving asynchronous messages such as
"packet-ins" immediately at connect time.  If there is a lot of traffic on
the network then this can swamp the controller before it gets a chance to
set up an initial flow table.  This setting overrides this OpenFlow
behavior, changing it so that the connection initially enables no
asynchronous messages at all.  The controller can enable any messages that
it actually wants when it is ready for them.

Feature #7086.
Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
Ben Pfaff 2012-01-26 14:50:41 -08:00
parent 80d5aefd65
commit 9886b6620e
6 changed files with 69 additions and 26 deletions

3
NEWS
View File

@ -25,6 +25,9 @@ post-v1.5.0
table, with configurable policy for evicting flows upon
overflow. See the Flow_Table table in ovs-vswitch.conf.db(5)
for more information.
- New "enable-async-messages" column in the Controller table. If set to
false, OpenFlow connections to the controller will initially have all
asynchronous messages disabled, overriding normal OpenFlow behavior.
- ofproto-provider interface:
- "struct rule" has a new member "used" that ofproto implementations
should maintain by updating with ofproto_rule_update_used().

View File

@ -52,6 +52,7 @@ struct ofconn {
struct rconn *rconn; /* OpenFlow connection. */
enum ofconn_type type; /* Type. */
enum ofproto_band band; /* In-band or out-of-band? */
bool enable_async_msgs; /* Initially enable async messages? */
/* State that should be cleared from one connection to the next. */
@ -88,7 +89,7 @@ struct ofconn {
};
static struct ofconn *ofconn_create(struct connmgr *, struct rconn *,
enum ofconn_type);
enum ofconn_type, bool enable_async_msgs);
static void ofconn_destroy(struct ofconn *);
static void ofconn_flush(struct ofconn *);
@ -120,6 +121,7 @@ struct ofservice {
int probe_interval; /* Max idle time before probing, in seconds. */
int rate_limit; /* Max packet-in rate in packets per second. */
int burst_limit; /* Limit on accumulating packet credits. */
bool enable_async_msgs; /* Initially enable async messages? */
};
static void ofservice_reconfigure(struct ofservice *,
@ -283,7 +285,8 @@ connmgr_run(struct connmgr *mgr,
rconn_connect_unreliably(rconn, vconn, name);
free(name);
ofconn = ofconn_create(mgr, rconn, OFCONN_SERVICE);
ofconn = ofconn_create(mgr, rconn, OFCONN_SERVICE,
ofservice->enable_async_msgs);
ofconn_set_rate_limit(ofconn, ofservice->rate_limit,
ofservice->burst_limit);
} else if (retval != EAGAIN) {
@ -561,7 +564,7 @@ add_controller(struct connmgr *mgr, const char *target)
char *name = ofconn_make_name(mgr, target);
struct ofconn *ofconn;
ofconn = ofconn_create(mgr, rconn_create(5, 8), OFCONN_PRIMARY);
ofconn = ofconn_create(mgr, rconn_create(5, 8), OFCONN_PRIMARY, true);
ofconn->pktbuf = pktbuf_create();
rconn_connect(ofconn->rconn, target, name);
hmap_insert(&mgr->controllers, &ofconn->hmap_node, hash_string(target, 0));
@ -953,7 +956,8 @@ ofconn_get_target(const struct ofconn *ofconn)
}
static struct ofconn *
ofconn_create(struct connmgr *mgr, struct rconn *rconn, enum ofconn_type type)
ofconn_create(struct connmgr *mgr, struct rconn *rconn, enum ofconn_type type,
bool enable_async_msgs)
{
struct ofconn *ofconn;
@ -962,6 +966,7 @@ ofconn_create(struct connmgr *mgr, struct rconn *rconn, enum ofconn_type type)
list_push_back(&mgr->all_conns, &ofconn->node);
ofconn->rconn = rconn;
ofconn->type = type;
ofconn->enable_async_msgs = enable_async_msgs;
list_init(&ofconn->opgroups);
@ -975,8 +980,6 @@ ofconn_create(struct connmgr *mgr, struct rconn *rconn, enum ofconn_type type)
static void
ofconn_flush(struct ofconn *ofconn)
{
uint32_t *master = ofconn->master_async_config;
uint32_t *slave = ofconn->slave_async_config;
int i;
ofconn->role = NX_ROLE_OTHER;
@ -1018,23 +1021,33 @@ ofconn_flush(struct ofconn *ofconn)
rconn_packet_counter_destroy(ofconn->reply_counter);
ofconn->reply_counter = rconn_packet_counter_create();
/* "master" and "other" roles get all asynchronous messages by default,
* except that the controller needs to enable nonstandard "packet-in"
* reasons itself. */
master[OAM_PACKET_IN] = (1u << OFPR_NO_MATCH) | (1u << OFPR_ACTION);
master[OAM_PORT_STATUS] = ((1u << OFPPR_ADD)
| (1u << OFPPR_DELETE)
| (1u << OFPPR_MODIFY));
master[OAM_FLOW_REMOVED] = ((1u << OFPRR_IDLE_TIMEOUT)
| (1u << OFPRR_HARD_TIMEOUT)
| (1u << OFPRR_DELETE));
if (ofconn->enable_async_msgs) {
uint32_t *master = ofconn->master_async_config;
uint32_t *slave = ofconn->slave_async_config;
/* "slave" role gets port status updates by default. */
slave[OAM_PACKET_IN] = 0;
slave[OAM_PORT_STATUS] = ((1u << OFPPR_ADD)
| (1u << OFPPR_DELETE)
| (1u << OFPPR_MODIFY));
slave[OAM_FLOW_REMOVED] = 0;
/* "master" and "other" roles get all asynchronous messages by default,
* except that the controller needs to enable nonstandard "packet-in"
* reasons itself. */
master[OAM_PACKET_IN] = (1u << OFPR_NO_MATCH) | (1u << OFPR_ACTION);
master[OAM_PORT_STATUS] = ((1u << OFPPR_ADD)
| (1u << OFPPR_DELETE)
| (1u << OFPPR_MODIFY));
master[OAM_FLOW_REMOVED] = ((1u << OFPRR_IDLE_TIMEOUT)
| (1u << OFPRR_HARD_TIMEOUT)
| (1u << OFPRR_DELETE));
/* "slave" role gets port status updates by default. */
slave[OAM_PACKET_IN] = 0;
slave[OAM_PORT_STATUS] = ((1u << OFPPR_ADD)
| (1u << OFPPR_DELETE)
| (1u << OFPPR_MODIFY));
slave[OAM_FLOW_REMOVED] = 0;
} else {
memset(ofconn->master_async_config, 0,
sizeof ofconn->master_async_config);
memset(ofconn->slave_async_config, 0,
sizeof ofconn->slave_async_config);
}
}
static void
@ -1597,6 +1610,7 @@ ofservice_reconfigure(struct ofservice *ofservice,
ofservice->probe_interval = c->probe_interval;
ofservice->rate_limit = c->rate_limit;
ofservice->burst_limit = c->burst_limit;
ofservice->enable_async_msgs = c->enable_async_msgs;
}
/* Finds and returns the ofservice within 'mgr' that has the given

View File

@ -121,7 +121,8 @@ 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_band band; /* In-band or out-of-band? */
enum ofproto_band band; /* In-band or out-of-band? */
bool enable_async_msgs; /* Initially enable asynchronous messages? */
/* OpenFlow packet-in rate-limiting. */
int rate_limit; /* Max packet-in rate in packets per second. */

View File

@ -2328,6 +2328,7 @@ bridge_ofproto_controller_for_mgmt(const struct bridge *br,
oc->band = OFPROTO_OUT_OF_BAND;
oc->rate_limit = 0;
oc->burst_limit = 0;
oc->enable_async_msgs = true;
}
/* Converts ovsrec_controller 'c' into an ofproto_controller in 'oc'. */
@ -2343,6 +2344,8 @@ bridge_ofproto_controller_from_ovsrec(const struct ovsrec_controller *c,
oc->rate_limit = c->controller_rate_limit ? *c->controller_rate_limit : 0;
oc->burst_limit = (c->controller_burst_limit
? *c->controller_burst_limit : 0);
oc->enable_async_msgs = (!c->enable_async_messages
|| *c->enable_async_messages);
}
/* Configures the IP stack for 'br''s local interface properly according to the

View File

@ -1,6 +1,6 @@
{"name": "Open_vSwitch",
"version": "6.6.0",
"cksum": "3676036878 16515",
"version": "6.7.0",
"cksum": "1451320369 16635",
"tables": {
"Open_vSwitch": {
"columns": {
@ -389,6 +389,9 @@
"local_gateway": {
"type": {"key": {"type": "string"},
"min": 0, "max": 1}},
"enable_async_messages": {
"type": {"key": {"type": "boolean"},
"min": 0, "max": 1}},
"controller_rate_limit": {
"type": {"key": {"type": "integer",
"minInteger": 100},

View File

@ -2489,7 +2489,26 @@
</column>
</group>
<group title="OpenFlow Rate Limiting">
<group title="Asynchronous Message Configuration">
<p>
OpenFlow switches send certain messages to controllers spontanenously,
that is, not in response to any request from the controller. These
messages are called ``asynchronous messages.'' These columns allow
asynchronous messages to be limited or disabled to ensure the best use
of network resources.
</p>
<column name="enable_async_messages">
The OpenFlow protocol enables asynchronous messages at time of
connection establishment, which means that a controller can receive
asynchronous messages, potentially many of them, even if it turns them
off immediately after connecting. Set this column to
<code>false</code> to change Open vSwitch behavior to disable, by
default, all asynchronous messages. The controller can use the
<code>NXT_SET_ASYNC_CONFIG</code> Nicira extension to OpenFlow to turn
on any messages that it does want to receive, if any.
</column>
<column name="controller_rate_limit">
<p>
The maximum rate at which the switch will forward packets to the