[ovs-dev] [PATCH] rconn: Speed up in-band control connections, by caching the remote address.

Justin Pettit jpettit at nicira.com
Wed Sep 2 21:54:08 UTC 2009


Looks good. Thanks for tracking this down!

--Justin


On Sep 2, 2009, at 12:53 PM, Ben Pfaff <blp at nicira.com> wrote:

> In-band control needs to know the IP and port of the controller, so  
> that
> it can set up the correct flows to talk to that controller.  Until  
> now,
> the rconn code has only made this available when a connection was  
> actually
> in progress.  This means that, say, ARP packets will not be allowed  
> through
> when the rconn backs off.  The same is true of packets sent by  
> switches
> that access the controller through this one.
>
> This commit makes the rconn cache the remote IP and port and local IP
> across connection attempts, improving the situation.  In particular,  
> it
> reduces the overall amount of time that it takes to connect in my own
> simple test case from over 10 seconds to about 2 seconds.
> ---
> lib/rconn.c |   52 ++++++++++++++++++++++++++++++++++++++ 
> +-------------
> 1 files changed, 39 insertions(+), 13 deletions(-)
>
> diff --git a/lib/rconn.c b/lib/rconn.c
> index 09c0e9d..be030d4 100644
> --- a/lib/rconn.c
> +++ b/lib/rconn.c
> @@ -111,6 +111,18 @@ struct rconn {
>      * a response. */
>     int probe_interval;         /* Secs of inactivity before sending  
> probe. */
>
> +    /* When we create a vconn we obtain these values, to save them  
> past the end
> +     * of the vconn's lifetime.  Otherwise, in-band control will  
> only allow
> +     * traffic when a vconn is actually open, but it is nice to  
> allow ARP to
> +     * complete even between connection attempts, and it is also  
> polite to
> +     * allow traffic from other switches to go through to the  
> controller
> +     * whether or not we are connected.
> +     *
> +     * We don't cache the local port, because that changes from one  
> connection
> +     * attempt to the next. */
> +    uint32_t local_ip, remote_ip;
> +    uint16_t remote_port;
> +
>     /* Messages sent or received are copied to the monitor  
> connections. */
> #define MAX_MONITORS 8
>     struct vconn *monitors[8];
> @@ -121,6 +133,7 @@ static unsigned int elapsed_in_this_state(const  
> struct rconn *);
> static unsigned int timeout(const struct rconn *);
> static bool timed_out(const struct rconn *);
> static void state_transition(struct rconn *, enum state);
> +static void set_vconn_name(struct rconn *, const char *name);
> static int try_send(struct rconn *);
> static int reconnect(struct rconn *);
> static void disconnect(struct rconn *, int error);
> @@ -236,8 +249,7 @@ int
> rconn_connect(struct rconn *rc, const char *name)
> {
>     rconn_disconnect(rc);
> -    free(rc->name);
> -    rc->name = xstrdup(name);
> +    set_vconn_name(rc, name);
>     rc->reliable = true;
>     return reconnect(rc);
> }
> @@ -248,8 +260,7 @@ rconn_connect_unreliably(struct rconn *rc,
> {
>     assert(vconn != NULL);
>     rconn_disconnect(rc);
> -    free(rc->name);
> -    rc->name = xstrdup(name);
> +    set_vconn_name(rc, name);
>     rc->reliable = false;
>     rc->vconn = vconn;
>     rc->last_connected = time_now();
> @@ -273,8 +284,7 @@ rconn_disconnect(struct rconn *rc)
>             vconn_close(rc->vconn);
>             rc->vconn = NULL;
>         }
> -        free(rc->name);
> -        rc->name = xstrdup("void");
> +        set_vconn_name(rc, "void");
>         rc->reliable = false;
>
>         rc->backoff = 0;
> @@ -323,6 +333,9 @@ reconnect(struct rconn *rc)
>     rc->n_attempted_connections++;
>     retval = vconn_open(rc->name, OFP_VERSION, &rc->vconn);
>     if (!retval) {
> +        rc->remote_ip = vconn_get_remote_ip(rc->vconn);
> +        rc->local_ip = vconn_get_local_ip(rc->vconn);
> +        rc->remote_port = vconn_get_remote_port(rc->vconn);
>         rc->backoff_deadline = time_now() + rc->backoff;
>         state_transition(rc, S_CONNECTING);
>     } else {
> @@ -635,20 +648,20 @@ rconn_failure_duration(const struct rconn  
> *rconn)
>     return rconn_is_connected(rconn) ? 0 : time_now() - rconn- 
> >last_admitted;
> }
>
> -/* Returns the IP address of the peer, or 0 if the peer is not  
> connected over
> - * an IP-based protocol or if its IP address is not known. */
> +/* Returns the IP address of the peer, or 0 if the peer's IP  
> address is not
> + * known. */
> uint32_t
> rconn_get_remote_ip(const struct rconn *rconn)
> {
> -    return rconn->vconn ? vconn_get_remote_ip(rconn->vconn) : 0;
> +    return rconn->remote_ip;
> }
>
> -/* Returns the transport port of the peer, or 0 if the peer does not
> - * contain a port or if the port is not known. */
> +/* Returns the transport port of the peer, or 0 if the peer's port  
> is not
> + * known. */
> uint16_t
> rconn_get_remote_port(const struct rconn *rconn)
> {
> -    return rconn->vconn ? vconn_get_remote_port(rconn->vconn) : 0;
> +    return rconn->remote_port;
> }
>
> /* Returns the IP address used to connect to the peer, or 0 if the
> @@ -657,7 +670,7 @@ rconn_get_remote_port(const struct rconn *rconn)
> uint32_t
> rconn_get_local_ip(const struct rconn *rconn)
> {
> -    return rconn->vconn ? vconn_get_local_ip(rconn->vconn) : 0;
> +    return rconn->local_ip;
> }
>
> /* Returns the transport port used to connect to the peer, or 0 if the
> @@ -805,6 +818,19 @@ rconn_packet_counter_dec(struct  
> rconn_packet_counter *c)
>     }
> }
> 
> +/* Set the name of the remote vconn to 'name' and clear out the  
> cached IP
> + * address and port information, since changing the name also  
> likely changes
> + * these values. */
> +static void
> +set_vconn_name(struct rconn *rc, const char *name)
> +{
> +    free(rc->name);
> +    rc->name = xstrdup(name);
> +    rc->local_ip = 0;
> +    rc->remote_ip = 0;
> +    rc->remote_port = 0;
> +}
> +
> /* Tries to send a packet from 'rc''s send buffer.  Returns 0 if  
> successful,
>  * otherwise a positive errno value. */
> static int
> -- 
> 1.6.3.3
>
>
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev_openvswitch.org




More information about the dev mailing list