X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=lib%2Frconn.c;h=3241ab8bdf7cf92a0fc17d991e175ad3df150b3f;hb=e1fef0f921cbee185ce728f43f6b6ddbc4942e24;hp=0e18ab48f7b64985d683f9fafda7d2b9c614e5de;hpb=195c8086244e33ec42fd9fc8354eaedfd849bbba;p=sliver-openvswitch.git diff --git a/lib/rconn.c b/lib/rconn.c index 0e18ab48f..3241ab8bd 100644 --- a/lib/rconn.c +++ b/lib/rconn.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks. + * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -119,8 +119,9 @@ struct rconn { * * 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; + ovs_be32 local_ip, remote_ip; + ovs_be16 remote_port; + uint8_t dscp; /* Messages sent or received are copied to the monitor connections. */ #define MAX_MONITORS 8 @@ -160,7 +161,7 @@ static bool rconn_logging_connection_attempts__(const struct rconn *); * The new rconn is initially unconnected. Use rconn_connect() or * rconn_connect_unreliably() to connect it. */ struct rconn * -rconn_create(int probe_interval, int max_backoff) +rconn_create(int probe_interval, int max_backoff, uint8_t dscp) { struct rconn *rc = xzalloc(sizeof *rc); @@ -194,6 +195,7 @@ rconn_create(int probe_interval, int max_backoff) rc->total_time_connected = 0; rconn_set_probe_interval(rc, probe_interval); + rconn_set_dscp(rc, dscp); rc->n_monitors = 0; @@ -218,6 +220,18 @@ rconn_get_max_backoff(const struct rconn *rc) return rc->max_backoff; } +void +rconn_set_dscp(struct rconn *rc, uint8_t dscp) +{ + rc->dscp = dscp; +} + +uint8_t +rconn_get_dscp(const struct rconn *rc) +{ + return rc->dscp; +} + void rconn_set_probe_interval(struct rconn *rc, int probe_interval) { @@ -335,7 +349,7 @@ reconnect(struct rconn *rc) VLOG_INFO("%s: connecting...", rc->name); } rc->n_attempted_connections++; - retval = vconn_open(rc->target, OFP_VERSION, &rc->vconn); + retval = vconn_open(rc->target, OFP10_VERSION, &rc->vconn, rc->dscp); if (!retval) { rc->remote_ip = vconn_get_remote_ip(rc->vconn); rc->local_ip = vconn_get_local_ip(rc->vconn); @@ -552,9 +566,8 @@ rconn_recv_wait(struct rconn *rc) } } -/* Sends 'b' on 'rc'. Returns 0 if successful (in which case 'b' is - * destroyed), or ENOTCONN if 'rc' is not currently connected (in which case - * the caller retains ownership of 'b'). +/* Sends 'b' on 'rc'. Returns 0 if successful, or ENOTCONN if 'rc' is not + * currently connected. Takes ownership of 'b'. * * If 'counter' is non-null, then 'counter' will be incremented while the * packet is in flight, then decremented when it has been sent (or discarded @@ -587,6 +600,7 @@ rconn_send(struct rconn *rc, struct ofpbuf *b, } return 0; } else { + ofpbuf_delete(b); return ENOTCONN; } } @@ -611,7 +625,6 @@ rconn_send_with_limit(struct rconn *rc, struct ofpbuf *b, retval = counter->n >= queue_limit ? EAGAIN : rconn_send(rc, b, counter); if (retval) { COVERAGE_INC(rconn_overflow); - ofpbuf_delete(b); } return retval; } @@ -700,7 +713,7 @@ rconn_failure_duration(const struct rconn *rconn) /* Returns the IP address of the peer, or 0 if the peer's IP address is not * known. */ -uint32_t +ovs_be32 rconn_get_remote_ip(const struct rconn *rconn) { return rconn->remote_ip; @@ -708,7 +721,7 @@ rconn_get_remote_ip(const struct rconn *rconn) /* Returns the transport port of the peer, or 0 if the peer's port is not * known. */ -uint16_t +ovs_be16 rconn_get_remote_port(const struct rconn *rconn) { return rconn->remote_port; @@ -717,7 +730,7 @@ rconn_get_remote_port(const struct rconn *rconn) /* Returns the IP address used to connect to the peer, or 0 if the * connection is not an IP-based protocol or if its IP address is not * known. */ -uint32_t +ovs_be32 rconn_get_local_ip(const struct rconn *rconn) { return rconn->local_ip; @@ -725,12 +738,20 @@ rconn_get_local_ip(const struct rconn *rconn) /* Returns the transport port used to connect to the peer, or 0 if the * connection does not contain a port or if the port is not known. */ -uint16_t +ovs_be16 rconn_get_local_port(const struct rconn *rconn) { return rconn->vconn ? vconn_get_local_port(rconn->vconn) : 0; } +/* Returns the OpenFlow version negotiated with the peer, or -1 if there is + * currently no connection or if version negotiation is not yet complete. */ +int +rconn_get_version(const struct rconn *rconn) +{ + return rconn->vconn ? vconn_get_version(rconn->vconn) : -1; +} + /* Returns the total number of packets successfully received by the underlying * vconn. */ unsigned int @@ -840,6 +861,13 @@ rconn_get_last_error(const struct rconn *rc) { return rc->last_error; } + +/* Returns the number of messages queued for transmission on 'rc'. */ +unsigned int +rconn_count_txqlen(const struct rconn *rc) +{ + return list_size(&rc->txq); +} struct rconn_packet_counter * rconn_packet_counter_create(void)