Looks good,
Ethan

On Thu, Jan 26, 2012 at 15:53, Ben Pfaff <b...@nicira.com> wrote:
> 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 <b...@nicira.com>
> ---
>  NEWS                       |    3 ++
>  ofproto/connmgr.c          |   60 
> +++++++++++++++++++++++++++-----------------
>  ofproto/ofproto.h          |    5 ++-
>  vswitchd/bridge.c          |    3 ++
>  vswitchd/vswitch.ovsschema |    7 +++-
>  vswitchd/vswitch.xml       |   21 ++++++++++++++-
>  6 files changed, 71 insertions(+), 28 deletions(-)
>
> diff --git a/NEWS b/NEWS
> index 0b97149..f52f912 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -10,6 +10,9 @@ post-v1.5.0
>         - Added an OpenFlow extension NXT_SET_ASYNC_CONFIG that allows
>           controllers more precise control over which OpenFlow messages they
>           receive asynchronously.
> +    - 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.
>
>
>  v1.5.0 - xx xxx xxxx
> diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c
> index 5caa6bf..12319fe 100644
> --- a/ofproto/connmgr.c
> +++ b/ofproto/connmgr.c
> @@ -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. */
>
> @@ -90,7 +91,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 *);
>
> @@ -122,6 +123,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 *,
> @@ -285,7 +287,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) {
> @@ -563,7 +566,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));
> @@ -955,7 +958,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;
>
> @@ -964,6 +968,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);
>
> @@ -977,8 +982,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;
> @@ -1020,23 +1023,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));
> -
> -    /* "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;
> +    if (ofconn->enable_async_msgs) {
> +        uint32_t *master = ofconn->master_async_config;
> +        uint32_t *slave = ofconn->slave_async_config;
> +
> +        /* "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
> @@ -1599,6 +1612,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
> diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h
> index 2d47878..ef9ccf5 100644
> --- a/ofproto/ofproto.h
> +++ b/ofproto/ofproto.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright (c) 2009, 2010, 2011 Nicira Networks.
> + * Copyright (c) 2009, 2010, 2011, 2012 Nicira Networks.
>  *
>  * Licensed under the Apache License, Version 2.0 (the "License");
>  * you may not use this file except in compliance with the License.
> @@ -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. 
> */
> diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
> index c40bcb5..ad2ff22 100644
> --- a/vswitchd/bridge.c
> +++ b/vswitchd/bridge.c
> @@ -2293,6 +2293,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'.  */
> @@ -2308,6 +2309,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
> diff --git a/vswitchd/vswitch.ovsschema b/vswitchd/vswitch.ovsschema
> index 9d91b0f..66fc39c 100644
> --- a/vswitchd/vswitch.ovsschema
> +++ b/vswitchd/vswitch.ovsschema
> @@ -1,6 +1,6 @@
>  {"name": "Open_vSwitch",
> - "version": "6.4.0",
> - "cksum": "923041702 15687",
> + "version": "6.5.0",
> + "cksum": "870121236 15807",
>  "tables": {
>    "Open_vSwitch": {
>      "columns": {
> @@ -367,6 +367,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},
> diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
> index 4b99b99..097ecb6 100644
> --- a/vswitchd/vswitch.xml
> +++ b/vswitchd/vswitch.xml
> @@ -2336,7 +2336,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
> --
> 1.7.2.5
>
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to