[ovs-dev] [PATCH] Allow configuring DSCP on controller and manager connections.

Mehak Mahajan mmahajan at nicira.com
Fri Mar 23 05:24:33 UTC 2012


The changes allow the user to specify a separate dscp value for the
controller connection and the manager connection. The value will take
effect on resetting the connections. If no value is specified a default
value of 192 is chosen for each of the connections.

Feature #10074
Requested-by: Rajiv Ramanathan <rramanathan at nicira.com>
Signed-off-by: Mehak Mahajan <mmahajan at nicira.com>
---
 include/sparse/netinet/in.h |   21 +++++++++++++++
 lib/jsonrpc.c               |   22 +++++++++++----
 lib/jsonrpc.h               |    7 +++-
 lib/rconn.c                 |   12 +++++++-
 lib/rconn.h                 |    5 ++-
 lib/reconnect.c             |   18 +++++++++++++
 lib/reconnect.h             |    3 ++
 lib/socket-util.c           |   36 +++++++++++++++++++++++---
 lib/socket-util.h           |   14 ++++++++-
 lib/stream-provider.h       |   15 +++++++++-
 lib/stream-ssl.c            |   16 ++++++-----
 lib/stream-tcp.c            |   11 ++++---
 lib/stream-unix.c           |    5 ++-
 lib/stream.c                |   18 +++++++------
 lib/stream.h                |   10 ++++---
 lib/unixctl.c               |    5 ++-
 lib/util.c                  |    6 ++++
 lib/vconn-provider.h        |   14 ++++++++-
 lib/vconn-stream.c          |    8 +++---
 lib/vconn.c                 |   12 +++++---
 lib/vconn.h                 |    5 ++-
 ofproto/collectors.c        |    3 +-
 ofproto/connmgr.c           |   21 ++++++++-------
 ofproto/ofproto.h           |    6 +++-
 ovsdb/jsonrpc-server.c      |   12 ++++++---
 ovsdb/jsonrpc-server.h      |    1 +
 ovsdb/ovsdb-client.c        |    5 ++-
 ovsdb/ovsdb-server.c        |   59 ++++++++++++++++++++++++++++++++++++++++++-
 tests/test-jsonrpc.c        |    8 +++--
 tests/test-netflow.c        |    2 +-
 tests/test-ovsdb.c          |    4 +-
 tests/test-vconn.c          |   17 ++++++++----
 utilities/ovs-controller.c  |    7 +++--
 vswitchd/bridge.c           |   34 ++++++++++++++++++++++++
 vswitchd/vswitch.ovsschema  |    6 +++-
 vswitchd/vswitch.xml        |   45 ++++++++++++++++++++++++++++++++
 36 files changed, 396 insertions(+), 97 deletions(-)

diff --git a/include/sparse/netinet/in.h b/include/sparse/netinet/in.h
index d86431a..ed31463 100644
--- a/include/sparse/netinet/in.h
+++ b/include/sparse/netinet/in.h
@@ -60,6 +60,27 @@ extern const struct in6_addr in6addr_any;
 #define IPPROTO_NONE 59
 #define IPPROTO_DSTOPTS 60
 
+/* All the IP options documented in Linux ip(7). */
+#define IP_ADD_MEMBERSHIP 0
+#define IP_DROP_MEMBERSHIP 1
+#define IP_HDRINCL 2
+#define IP_MTU 3
+#define IP_MTU_DISCOVER 4
+#define IP_MULTICAST_IF 5
+#define IP_MULTICAST_LOOP 6
+#define IP_MULTICAST_TTL 7
+#define IP_NODEFRAG 8
+#define IP_OPTIONS 9
+#define IP_PKTINFO 10
+#define IP_RECVERR 11
+#define IP_RECVOPTS 12
+#define IP_RECVTOS 13
+#define IP_RECVTTL 14
+#define IP_RETOPTS 15
+#define IP_ROUTER_ALERT 16
+#define IP_TOS 17
+#define IP_TTL 18
+
 #define INADDR_ANY              0x00000000
 #define INADDR_BROADCAST        0xffffffff
 #define INADDR_NONE             0xffffffff
diff --git a/lib/jsonrpc.c b/lib/jsonrpc.c
index 09b1071..fa3362d 100644
--- a/lib/jsonrpc.c
+++ b/lib/jsonrpc.c
@@ -60,19 +60,20 @@ static void jsonrpc_error(struct jsonrpc *, int error);
 /* This is just the same as stream_open() except that it uses the default
  * JSONRPC ports if none is specified. */
 int
-jsonrpc_stream_open(const char *name, struct stream **streamp)
+jsonrpc_stream_open(const char *name, struct stream **streamp, uint8_t dscp)
 {
     return stream_open_with_default_ports(name, JSONRPC_TCP_PORT,
-                                          JSONRPC_SSL_PORT, streamp);
+                                          JSONRPC_SSL_PORT, streamp,
+                                          dscp);
 }
 
 /* This is just the same as pstream_open() except that it uses the default
  * JSONRPC ports if none is specified. */
 int
-jsonrpc_pstream_open(const char *name, struct pstream **pstreamp)
+jsonrpc_pstream_open(const char *name, struct pstream **pstreamp, uint8_t dscp)
 {
     return pstream_open_with_default_ports(name, JSONRPC_TCP_PORT,
-                                           JSONRPC_SSL_PORT, pstreamp);
+                                           JSONRPC_SSL_PORT, pstreamp, dscp);
 }
 
 /* Returns a new JSON-RPC stream that uses 'stream' for input and output.  The
@@ -825,12 +826,14 @@ jsonrpc_session_connect(struct jsonrpc_session *s)
 
     jsonrpc_session_disconnect(s);
     if (!reconnect_is_passive(s->reconnect)) {
-        error = jsonrpc_stream_open(name, &s->stream);
+        error = jsonrpc_stream_open(name, &s->stream,
+                                    reconnect_get_dscp(s->reconnect));
         if (!error) {
             reconnect_connecting(s->reconnect, time_msec());
         }
     } else {
-        error = s->pstream ? 0 : jsonrpc_pstream_open(name, &s->pstream);
+        error = s->pstream ? 0 : jsonrpc_pstream_open(name, &s->pstream,
+                                        reconnect_get_dscp(s->reconnect));
         if (!error) {
             reconnect_listening(s->reconnect, time_msec());
         }
@@ -1041,3 +1044,10 @@ jsonrpc_session_set_probe_interval(struct jsonrpc_session *s,
 {
     reconnect_set_probe_interval(s->reconnect, probe_interval);
 }
+
+void
+jsonrpc_session_set_dscp(struct jsonrpc_session *s,
+                         uint8_t dscp)
+{
+    reconnect_set_dscp(s->reconnect, dscp);
+}
diff --git a/lib/jsonrpc.h b/lib/jsonrpc.h
index ff04a54..16131d3 100644
--- a/lib/jsonrpc.h
+++ b/lib/jsonrpc.h
@@ -22,6 +22,7 @@
 
 #include <stdbool.h>
 #include <stddef.h>
+#include "openvswitch/types.h"
 
 struct json;
 struct jsonrpc_msg;
@@ -38,8 +39,8 @@ struct stream;
 #define JSONRPC_TCP_PORT 6632
 #define JSONRPC_SSL_PORT 6632
 
-int jsonrpc_stream_open(const char *name, struct stream **);
-int jsonrpc_pstream_open(const char *name, struct pstream **);
+int jsonrpc_stream_open(const char *name, struct stream **, uint8_t dscp);
+int jsonrpc_pstream_open(const char *name, struct pstream **, uint8_t dscp);
 
 struct jsonrpc *jsonrpc_open(struct stream *);
 void jsonrpc_close(struct jsonrpc *);
@@ -123,5 +124,7 @@ void jsonrpc_session_set_max_backoff(struct jsonrpc_session *,
                                      int max_backofF);
 void jsonrpc_session_set_probe_interval(struct jsonrpc_session *,
                                         int probe_interval);
+void jsonrpc_session_set_dscp(struct jsonrpc_session *,
+                              uint8_t dscp);
 
 #endif /* jsonrpc.h */
diff --git a/lib/rconn.c b/lib/rconn.c
index f6d85a7..56a7e19 100644
--- a/lib/rconn.c
+++ b/lib/rconn.c
@@ -121,6 +121,7 @@ struct rconn {
      * attempt to the next. */
     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;
 
@@ -219,6 +221,12 @@ rconn_get_max_backoff(const struct rconn *rc)
 }
 
 void
+rconn_set_dscp(struct rconn *rc, uint8_t dscp)
+{
+    rc->dscp = dscp;
+}
+
+void
 rconn_set_probe_interval(struct rconn *rc, int probe_interval)
 {
     rc->probe_interval = probe_interval ? MAX(5, probe_interval) : 0;
@@ -335,7 +343,7 @@ reconnect(struct rconn *rc)
         VLOG_INFO("%s: connecting...", rc->name);
     }
     rc->n_attempted_connections++;
-    retval = vconn_open(rc->target, OFP10_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);
diff --git a/lib/rconn.h b/lib/rconn.h
index d0326e6..eea054f 100644
--- a/lib/rconn.h
+++ b/lib/rconn.h
@@ -37,8 +37,9 @@
 struct vconn;
 struct rconn_packet_counter;
 
-struct rconn *rconn_create(int inactivity_probe_interval, int max_backoff);
-
+struct rconn *rconn_create(int inactivity_probe_interval,
+			   int max_backoff, uint8_t dscp);
+void rconn_set_dscp(struct rconn *rc, uint8_t dscp);
 void rconn_set_max_backoff(struct rconn *, int max_backoff);
 int rconn_get_max_backoff(const struct rconn *);
 void rconn_set_probe_interval(struct rconn *, int inactivity_probe_interval);
diff --git a/lib/reconnect.c b/lib/reconnect.c
index c169016..7737fcf 100644
--- a/lib/reconnect.c
+++ b/lib/reconnect.c
@@ -54,6 +54,8 @@ struct reconnect {
     bool passive;
     enum vlog_level info;       /* Used for informational messages. */
 
+    uint8_t dscp;
+
     /* State. */
     enum state state;
     long long int state_entered;
@@ -186,6 +188,14 @@ reconnect_get_probe_interval(const struct reconnect *fsm)
     return fsm->probe_interval;
 }
 
+/* Returns the dscp value used for establishing the connection between the
+ * manager and the database. */
+uint8_t
+reconnect_get_dscp(const struct reconnect *fsm)
+{
+    return fsm->dscp;
+}
+
 /* Limits the maximum number of times that 'fsm' will ask the client to try to
  * reconnect to 'max_tries'.  UINT_MAX (the default) means an unlimited number
  * of tries.
@@ -245,6 +255,14 @@ reconnect_set_probe_interval(struct reconnect *fsm, int probe_interval)
     fsm->probe_interval = probe_interval ? MAX(1000, probe_interval) : 0;
 }
 
+/* Sets the dscp value to be used for establishing a connection between the
+ * manager and the database. */
+void
+reconnect_set_dscp(struct reconnect *fsm, uint8_t dscp)
+{
+    fsm->dscp = dscp;
+}
+
 /* Returns true if 'fsm' is in passive mode, false if 'fsm' is in active mode
  * (the default). */
 bool
diff --git a/lib/reconnect.h b/lib/reconnect.h
index 997a03f..9dfcfd7 100644
--- a/lib/reconnect.h
+++ b/lib/reconnect.h
@@ -31,6 +31,7 @@
  * revisited later.) */
 
 #include <stdbool.h>
+#include "openvswitch/types.h"
 
 struct reconnect *reconnect_create(long long int now);
 void reconnect_destroy(struct reconnect *);
@@ -48,6 +49,7 @@ void reconnect_set_name(struct reconnect *, const char *name);
 int reconnect_get_min_backoff(const struct reconnect *);
 int reconnect_get_max_backoff(const struct reconnect *);
 int reconnect_get_probe_interval(const struct reconnect *);
+uint8_t reconnect_get_dscp(const struct reconnect *);
 
 void reconnect_set_max_tries(struct reconnect *, unsigned int max_tries);
 unsigned int reconnect_get_max_tries(struct reconnect *);
@@ -55,6 +57,7 @@ unsigned int reconnect_get_max_tries(struct reconnect *);
 void reconnect_set_backoff(struct reconnect *,
                            int min_backoff, int max_backoff);
 void reconnect_set_probe_interval(struct reconnect *, int probe_interval);
+void reconnect_set_dscp(struct reconnect *, uint8_t dscp);
 
 bool reconnect_is_passive(const struct reconnect *);
 void reconnect_set_passive(struct reconnect *, bool passive,
diff --git a/lib/socket-util.c b/lib/socket-util.c
index 37f8c9a..6554e97 100644
--- a/lib/socket-util.c
+++ b/lib/socket-util.c
@@ -544,10 +544,13 @@ exit:
  * and stores -1 into '*fdp'.
  *
  * If 'sinp' is non-null, then on success the target address is stored into
- * '*sinp'. */
+ * '*sinp'.
+ *
+ * 'dscp'  If not DSCP_INVALID, its value becomes the DSCP bits in the IP
+ * headers for the new connection. */
 int
 inet_open_active(int style, const char *target, uint16_t default_port,
-                 struct sockaddr_in *sinp, int *fdp)
+                 struct sockaddr_in *sinp, int *fdp, uint8_t dscp)
 {
     struct sockaddr_in sin;
     int fd = -1;
@@ -571,6 +574,17 @@ inet_open_active(int style, const char *target, uint16_t default_port,
         goto exit_close;
     }
 
+    /* The socket options set here ensure that the TOS bits are set during
+     * the connection establishment.  If set after connect(), the handshake
+     * SYN frames will be sent with a TOS of 0. */
+    if (dscp != DSCP_INVALID) {
+        if (setsockopt(fd, IPPROTO_IP, IP_TOS, &dscp, sizeof dscp)) {
+            VLOG_ERR("%s: socket: %s", target, strerror(errno));
+            error = errno;
+            goto exit;
+        }
+    }
+
     /* Connect. */
     error = connect(fd, (struct sockaddr *) &sin, sizeof sin) == 0 ? 0 : errno;
     if (error == EINPROGRESS) {
@@ -663,10 +677,13 @@ exit:
  * negative errno value.
  *
  * If 'sinp' is non-null, then on success the bound address is stored into
- * '*sinp'. */
+ * '*sinp'.
+ *
+ * 'dscp'  If not DSCP_INVALID, its value becomes the DSCP bits in the IP
+ * headers for the new connection. */
 int
 inet_open_passive(int style, const char *target, int default_port,
-                  struct sockaddr_in *sinp)
+                  struct sockaddr_in *sinp, uint8_t dscp)
 {
     struct sockaddr_in sin;
     int fd = 0, error;
@@ -701,6 +718,17 @@ inet_open_passive(int style, const char *target, int default_port,
         goto error;
     }
 
+    /* The socket options set here ensure that the TOS bits are set during
+     * the connection establishment.  If set after connect(), the handshake
+     * SYN frames will be sent with a TOS of 0. */
+    if (dscp != DSCP_INVALID) {
+        if (setsockopt(fd, IPPROTO_IP, IP_TOS, &dscp, sizeof dscp)) {
+            VLOG_ERR("%s: socket: %s", target, strerror(errno));
+            error = errno;
+            goto error;
+        }
+    }
+
     /* Listen. */
     if (style == SOCK_STREAM && listen(fd, 10) < 0) {
         error = errno;
diff --git a/lib/socket-util.h b/lib/socket-util.h
index 422cea9..a324517 100644
--- a/lib/socket-util.h
+++ b/lib/socket-util.h
@@ -46,12 +46,12 @@ int get_null_fd(void);
 bool inet_parse_active(const char *target, uint16_t default_port,
                        struct sockaddr_in *sinp);
 int inet_open_active(int style, const char *target, uint16_t default_port,
-                    struct sockaddr_in *sinp, int *fdp);
+		     struct sockaddr_in *sinp, int *fdp, uint8_t dscp);
 
 bool inet_parse_passive(const char *target, int default_port,
                         struct sockaddr_in *sinp);
 int inet_open_passive(int style, const char *target, int default_port,
-                      struct sockaddr_in *sinp);
+                      struct sockaddr_in *sinp, uint8_t dscp);
 
 int read_fully(int fd, void *, size_t, size_t *bytes_read);
 int write_fully(int fd, const void *, size_t, size_t *bytes_written);
@@ -63,4 +63,14 @@ void xpipe(int fds[2]);
 
 char *describe_fd(int fd);
 
+#define IPTOS_PREC_INTERNETCONTROL 0xc0
+/* Default value of dscp bits for connection between controller and
+ * manager.  Value of 0xc0 is used for now. */
+#define DSCP_DEFAULT IPTOS_PREC_INTERNETCONTROL
+
+/* Invalid dscp value.  If the dscp value will not be used, the dscp value
+ * passed must be invalid.  Set to 0xFF as the TOS bits passed can only be
+ * 6 bits. */
+#define DSCP_INVALID 0xFF
+
 #endif /* socket-util.h */
diff --git a/lib/stream-provider.h b/lib/stream-provider.h
index 03bf777..77d0a10 100644
--- a/lib/stream-provider.h
+++ b/lib/stream-provider.h
@@ -40,6 +40,7 @@ struct stream {
 void stream_init(struct stream *, const struct stream_class *,
                  int connect_status, const char *name);
 void stream_set_remote_ip(struct stream *, ovs_be32 remote_ip);
+void stream_set_dscp(struct stream *, uint8_t dscp);
 void stream_set_remote_port(struct stream *, ovs_be16 remote_port);
 void stream_set_local_ip(struct stream *, ovs_be32 local_ip);
 void stream_set_local_port(struct stream *, ovs_be16 local_port);
@@ -58,6 +59,10 @@ struct stream_class {
      * messages but must not be modified.
      *
      * 'suffix' is a copy of 'name' following the colon and may be modified.
+     * 'dscp' is the DSCP value that the new connection should use in the IP
+     * packets it sends.  (If no DSCP value should be set in the packet, dscp
+     * will be set to DSCP_INVALID.  If no DSCP value is specified, DSCP_DEFAULT
+     * value will be applied.)
      *
      * Returns 0 if successful, otherwise a positive errno value.  If
      * successful, stores a pointer to the new connection in '*streamp'.
@@ -66,7 +71,8 @@ struct stream_class {
      * If the connection cannot be completed immediately, it should return
      * EAGAIN (not EINPROGRESS, as returned by the connect system call) and
      * continue the connection in the background. */
-    int (*open)(const char *name, char *suffix, struct stream **streamp);
+    int (*open)(const char *name, char *suffix, struct stream **streamp,
+                uint8_t dscp);
 
     /* Closes 'stream' and frees associated memory. */
     void (*close)(struct stream *stream);
@@ -150,6 +156,10 @@ struct pstream_class {
      * useful for error messages but must not be modified.
      *
      * 'suffix' is a copy of 'name' following the colon and may be modified.
+     * 'dscp' is the DSCP value that the new connection should use in the IP
+     * packets it sends.  (If no DSCP value should be set in the packet, dscp
+     * will be set to DSCP_INVALID.  If no DSCP value is specified, DSCP_DEFAULT
+     * value will be applied.)
      *
      * Returns 0 if successful, otherwise a positive errno value.  If
      * successful, stores a pointer to the new connection in '*pstreamp'.
@@ -158,7 +168,8 @@ struct pstream_class {
      * completed immediately, it should return EAGAIN (not EINPROGRESS, as
      * returned by the connect system call) and continue the connection in the
      * background. */
-    int (*listen)(const char *name, char *suffix, struct pstream **pstreamp);
+    int (*listen)(const char *name, char *suffix, struct pstream **pstreamp,
+                  uint8_t dscp);
 
     /* Closes 'pstream' and frees associated memory. */
     void (*close)(struct pstream *pstream);
diff --git a/lib/stream-ssl.c b/lib/stream-ssl.c
index 22d4c99..5463388 100644
--- a/lib/stream-ssl.c
+++ b/lib/stream-ssl.c
@@ -204,8 +204,8 @@ want_to_poll_events(int want)
 
 static int
 new_ssl_stream(const char *name, int fd, enum session_type type,
-              enum ssl_state state, const struct sockaddr_in *remote,
-              struct stream **streamp)
+               enum ssl_state state, const struct sockaddr_in *remote,
+               struct stream **streamp)
 {
     struct sockaddr_in local;
     socklen_t local_len = sizeof local;
@@ -307,7 +307,7 @@ ssl_stream_cast(struct stream *stream)
 }
 
 static int
-ssl_open(const char *name, char *suffix, struct stream **streamp)
+ssl_open(const char *name, char *suffix, struct stream **streamp, uint8_t dscp)
 {
     struct sockaddr_in sin;
     int error, fd;
@@ -317,7 +317,8 @@ ssl_open(const char *name, char *suffix, struct stream **streamp)
         return error;
     }
 
-    error = inet_open_active(SOCK_STREAM, suffix, OFP_SSL_PORT, &sin, &fd);
+    error = inet_open_active(SOCK_STREAM, suffix, OFP_SSL_PORT, &sin, &fd,
+                             dscp);
     if (fd >= 0) {
         int state = error ? STATE_TCP_CONNECTING : STATE_SSL_CONNECTING;
         return new_ssl_stream(name, fd, CLIENT, state, &sin, streamp);
@@ -782,7 +783,8 @@ pssl_pstream_cast(struct pstream *pstream)
 }
 
 static int
-pssl_open(const char *name OVS_UNUSED, char *suffix, struct pstream **pstreamp)
+pssl_open(const char *name OVS_UNUSED, char *suffix, struct pstream **pstreamp,
+          uint8_t dscp)
 {
     struct pssl_pstream *pssl;
     struct sockaddr_in sin;
@@ -795,7 +797,7 @@ pssl_open(const char *name OVS_UNUSED, char *suffix, struct pstream **pstreamp)
         return retval;
     }
 
-    fd = inet_open_passive(SOCK_STREAM, suffix, OFP_SSL_PORT, &sin);
+    fd = inet_open_passive(SOCK_STREAM, suffix, OFP_SSL_PORT, &sin, dscp);
     if (fd < 0) {
         return -fd;
     }
@@ -847,7 +849,7 @@ pssl_accept(struct pstream *pstream, struct stream **new_streamp)
         sprintf(strchr(name, '\0'), ":%"PRIu16, ntohs(sin.sin_port));
     }
     return new_ssl_stream(name, new_fd, SERVER, STATE_SSL_CONNECTING, &sin,
-                         new_streamp);
+                          new_streamp);
 }
 
 static void
diff --git a/lib/stream-tcp.c b/lib/stream-tcp.c
index 052ad8c..c7a2ee2 100644
--- a/lib/stream-tcp.c
+++ b/lib/stream-tcp.c
@@ -38,7 +38,7 @@ VLOG_DEFINE_THIS_MODULE(stream_tcp);
 
 static int
 new_tcp_stream(const char *name, int fd, int connect_status,
-              const struct sockaddr_in *remote, struct stream **streamp)
+               const struct sockaddr_in *remote, struct stream **streamp)
 {
     struct sockaddr_in local;
     socklen_t local_len = sizeof local;
@@ -70,12 +70,12 @@ new_tcp_stream(const char *name, int fd, int connect_status,
 }
 
 static int
-tcp_open(const char *name, char *suffix, struct stream **streamp)
+tcp_open(const char *name, char *suffix, struct stream **streamp, uint8_t dscp)
 {
     struct sockaddr_in sin;
     int fd, error;
 
-    error = inet_open_active(SOCK_STREAM, suffix, 0, &sin, &fd);
+    error = inet_open_active(SOCK_STREAM, suffix, 0, &sin, &fd, dscp);
     if (fd >= 0) {
         return new_tcp_stream(name, fd, error, &sin, streamp);
     } else {
@@ -102,13 +102,14 @@ static int ptcp_accept(int fd, const struct sockaddr *sa, size_t sa_len,
                        struct stream **streamp);
 
 static int
-ptcp_open(const char *name OVS_UNUSED, char *suffix, struct pstream **pstreamp)
+ptcp_open(const char *name OVS_UNUSED, char *suffix, struct pstream **pstreamp,
+          uint8_t dscp)
 {
     struct sockaddr_in sin;
     char bound_name[128];
     int fd;
 
-    fd = inet_open_passive(SOCK_STREAM, suffix, -1, &sin);
+    fd = inet_open_passive(SOCK_STREAM, suffix, -1, &sin, dscp);
     if (fd < 0) {
         return -fd;
     }
diff --git a/lib/stream-unix.c b/lib/stream-unix.c
index d2e8e82..a9d76f2 100644
--- a/lib/stream-unix.c
+++ b/lib/stream-unix.c
@@ -40,7 +40,8 @@ VLOG_DEFINE_THIS_MODULE(stream_unix);
 /* Active UNIX socket. */
 
 static int
-unix_open(const char *name, char *suffix, struct stream **streamp)
+unix_open(const char *name, char *suffix, struct stream **streamp,
+          uint8_t dscp OVS_UNUSED)
 {
     const char *connect_path = suffix;
     int fd;
@@ -73,7 +74,7 @@ static int punix_accept(int fd, const struct sockaddr *sa, size_t sa_len,
 
 static int
 punix_open(const char *name OVS_UNUSED, char *suffix,
-           struct pstream **pstreamp)
+           struct pstream **pstreamp, uint8_t dscp OVS_UNUSED)
 {
     int fd, error;
 
diff --git a/lib/stream.c b/lib/stream.c
index 066de4e..2f418c4 100644
--- a/lib/stream.c
+++ b/lib/stream.c
@@ -194,7 +194,7 @@ stream_verify_name(const char *name)
  * stores a pointer to the new connection in '*streamp', otherwise a null
  * pointer.  */
 int
-stream_open(const char *name, struct stream **streamp)
+stream_open(const char *name, struct stream **streamp, uint8_t dscp)
 {
     const struct stream_class *class;
     struct stream *stream;
@@ -211,7 +211,7 @@ stream_open(const char *name, struct stream **streamp)
 
     /* Call class's "open" function. */
     suffix_copy = xstrdup(strchr(name, ':') + 1);
-    error = class->open(name, suffix_copy, &stream);
+    error = class->open(name, suffix_copy, &stream, dscp);
     free(suffix_copy);
     if (error) {
         goto error;
@@ -497,7 +497,7 @@ pstream_verify_name(const char *name)
  * stores a pointer to the new connection in '*pstreamp', otherwise a null
  * pointer.  */
 int
-pstream_open(const char *name, struct pstream **pstreamp)
+pstream_open(const char *name, struct pstream **pstreamp, uint8_t dscp)
 {
     const struct pstream_class *class;
     struct pstream *pstream;
@@ -514,7 +514,7 @@ pstream_open(const char *name, struct pstream **pstreamp)
 
     /* Call class's "open" function. */
     suffix_copy = xstrdup(strchr(name, ':') + 1);
-    error = class->listen(name, suffix_copy, &pstream);
+    error = class->listen(name, suffix_copy, &pstream, dscp);
     free(suffix_copy);
     if (error) {
         goto error;
@@ -682,7 +682,8 @@ int
 stream_open_with_default_ports(const char *name_,
                                uint16_t default_tcp_port,
                                uint16_t default_ssl_port,
-                               struct stream **streamp)
+                               struct stream **streamp,
+                               uint8_t dscp)
 {
     char *name;
     int error;
@@ -694,7 +695,7 @@ stream_open_with_default_ports(const char *name_,
     } else {
         name = xstrdup(name_);
     }
-    error = stream_open(name, streamp);
+    error = stream_open(name, streamp, dscp);
     free(name);
 
     return error;
@@ -707,7 +708,8 @@ int
 pstream_open_with_default_ports(const char *name_,
                                 uint16_t default_ptcp_port,
                                 uint16_t default_pssl_port,
-                                struct pstream **pstreamp)
+                                struct pstream **pstreamp,
+                                uint8_t dscp)
 {
     char *name;
     int error;
@@ -719,7 +721,7 @@ pstream_open_with_default_ports(const char *name_,
     } else {
         name = xstrdup(name_);
     }
-    error = pstream_open(name, pstreamp);
+    error = pstream_open(name, pstreamp, dscp);
     free(name);
 
     return error;
diff --git a/lib/stream.h b/lib/stream.h
index 5c111f9..c1f3adb 100644
--- a/lib/stream.h
+++ b/lib/stream.h
@@ -32,7 +32,7 @@ void stream_usage(const char *name, bool active, bool passive, bool bootstrap);
 
 /* Bidirectional byte streams. */
 int stream_verify_name(const char *name);
-int stream_open(const char *name, struct stream **);
+int stream_open(const char *name, struct stream **, uint8_t dscp);
 int stream_open_block(int error, struct stream **);
 void stream_close(struct stream *);
 const char *stream_get_name(const struct stream *);
@@ -59,7 +59,7 @@ void stream_send_wait(struct stream *);
 
 /* Passive streams: listeners for incoming stream connections. */
 int pstream_verify_name(const char *name);
-int pstream_open(const char *name, struct pstream **);
+int pstream_open(const char *name, struct pstream **, uint8_t dscp);
 const char *pstream_get_name(const struct pstream *);
 void pstream_close(struct pstream *);
 int pstream_accept(struct pstream *, struct stream **);
@@ -71,11 +71,13 @@ void pstream_wait(struct pstream *);
 int stream_open_with_default_ports(const char *name,
                                    uint16_t default_tcp_port,
                                    uint16_t default_ssl_port,
-                                   struct stream **);
+                                   struct stream **,
+                                   uint8_t dscp);
 int pstream_open_with_default_ports(const char *name,
                                     uint16_t default_ptcp_port,
                                     uint16_t default_pssl_port,
-                                    struct pstream **);
+                                    struct pstream **,
+                                    uint8_t dscp);
 bool stream_parse_target_with_default_ports(const char *target,
                                            uint16_t default_tcp_port,
                                            uint16_t default_ssl_port,
diff --git a/lib/unixctl.c b/lib/unixctl.c
index 054ce49..eb06835 100644
--- a/lib/unixctl.c
+++ b/lib/unixctl.c
@@ -221,7 +221,7 @@ unixctl_server_create(const char *path, struct unixctl_server **serverp)
                                program_name, (long int) getpid());
     }
 
-    error = pstream_open(punix_path, &listener);
+    error = pstream_open(punix_path, &listener, DSCP_INVALID);
     free(punix_path);
     punix_path = NULL;
 
@@ -422,7 +422,8 @@ unixctl_client_create(const char *path, struct jsonrpc **client)
 
     abs_path = abs_file_name(ovs_rundir(), path);
     unix_path = xasprintf("unix:%s", abs_path);
-    error = stream_open_block(stream_open(unix_path, &stream), &stream);
+    error = stream_open_block(stream_open(unix_path, &stream, DSCP_DEFAULT), 
+                              &stream);
     free(unix_path);
     free(abs_path);
 
diff --git a/lib/util.c b/lib/util.c
index 2402ac6..318a3c5 100644
--- a/lib/util.c
+++ b/lib/util.c
@@ -397,6 +397,12 @@ str_to_llong(const char *s, int base, long long *x)
     int save_errno = errno;
     char *tail;
     errno = 0;
+#if 0
+    if(strlen(s) != strspn(s, "0123456789")) {
+        *x = 0;
+        return false;
+    }
+#endif
     *x = strtoll(s, &tail, base);
     if (errno == EINVAL || errno == ERANGE || tail == s || *tail != '\0') {
         errno = save_errno;
diff --git a/lib/vconn-provider.h b/lib/vconn-provider.h
index 682a593..43d2072 100644
--- a/lib/vconn-provider.h
+++ b/lib/vconn-provider.h
@@ -62,6 +62,10 @@ struct vconn_class {
      * useful for error messages but must not be modified.
      *
      * 'suffix' is a copy of 'name' following the colon and may be modified.
+     * 'dscp' is the DSCP value that the new connection should use in the IP
+     * packets it sends.  (If no DSCP value should be set in the packet, dscp
+     * will be set to DSCP_INVALID.  If no DSCP value is specified, DSCP_DEFAULT
+     * value will be applied.)
      *
      * Returns 0 if successful, otherwise a positive errno value.  If
      * successful, stores a pointer to the new connection in '*vconnp'.
@@ -70,7 +74,8 @@ struct vconn_class {
      * If the connection cannot be completed immediately, it should return
      * EAGAIN (not EINPROGRESS, as returned by the connect system call) and
      * continue the connection in the background. */
-    int (*open)(const char *name, char *suffix, struct vconn **vconnp);
+    int (*open)(const char *name, char *suffix, struct vconn **vconnp,
+                uint8_t dscp);
 
     /* Closes 'vconn' and frees associated memory. */
     void (*close)(struct vconn *vconn);
@@ -149,6 +154,10 @@ struct pvconn_class {
      * is useful for error messages but must not be modified.
      *
      * 'suffix' is a copy of 'name' following the colon and may be modified.
+     * 'dscp' is the DSCP value that the new connection should use in the IP
+     * packets it sends.  (If no DSCP value should be set in the packet, dscp
+     * will be set to DSCP_INVALID.  If no DSCP value is specified, DSCP_DEFAULT
+     * value will be applied.)
      *
      * Returns 0 if successful, otherwise a positive errno value.  If
      * successful, stores a pointer to the new connection in '*pvconnp'.
@@ -157,7 +166,8 @@ struct pvconn_class {
      * completed immediately, it should return EAGAIN (not EINPROGRESS, as
      * returned by the connect system call) and continue the connection in the
      * background. */
-    int (*listen)(const char *name, char *suffix, struct pvconn **pvconnp);
+    int (*listen)(const char *name, char *suffix, struct pvconn **pvconnp,
+                  uint8_t dscp);
 
     /* Closes 'pvconn' and frees associated memory. */
     void (*close)(struct pvconn *pvconn);
diff --git a/lib/vconn-stream.c b/lib/vconn-stream.c
index a9890b5..03e5881 100644
--- a/lib/vconn-stream.c
+++ b/lib/vconn-stream.c
@@ -78,13 +78,13 @@ vconn_stream_new(struct stream *stream, int connect_status)
  * Returns 0 if successful, otherwise a positive errno value. */
 static int
 vconn_stream_open(const char *name, char *suffix OVS_UNUSED,
-                  struct vconn **vconnp)
+                  struct vconn **vconnp, uint8_t dscp)
 {
     struct stream *stream;
     int error;
 
     error = stream_open_with_default_ports(name, OFP_TCP_PORT, OFP_SSL_PORT,
-                                           &stream);
+                                           &stream, dscp);
     if (!error) {
         error = stream_connect(stream);
         if (!error || error == EAGAIN) {
@@ -311,14 +311,14 @@ pvconn_pstream_cast(struct pvconn *pvconn)
  * implementation never fails.) */
 static int
 pvconn_pstream_listen(const char *name, char *suffix OVS_UNUSED,
-                      struct pvconn **pvconnp)
+                      struct pvconn **pvconnp, uint8_t dscp)
 {
     struct pvconn_pstream *ps;
     struct pstream *pstream;
     int error;
 
     error = pstream_open_with_default_ports(name, OFP_TCP_PORT, OFP_SSL_PORT,
-                                            &pstream);
+                                            &pstream, dscp);
     if (error) {
         return error;
     }
diff --git a/lib/vconn.c b/lib/vconn.c
index f0be46a..4d04c83 100644
--- a/lib/vconn.c
+++ b/lib/vconn.c
@@ -38,6 +38,7 @@
 #include "random.h"
 #include "util.h"
 #include "vlog.h"
+#include "socket-util.h"
 
 VLOG_DEFINE_THIS_MODULE(vconn);
 
@@ -219,7 +220,8 @@ vconn_verify_name(const char *name)
  * stores a pointer to the new connection in '*vconnp', otherwise a null
  * pointer.  */
 int
-vconn_open(const char *name, int min_version, struct vconn **vconnp)
+vconn_open(const char *name, int min_version, struct vconn **vconnp,
+           uint8_t dscp)
 {
     struct vconn_class *class;
     struct vconn *vconn;
@@ -237,7 +239,7 @@ vconn_open(const char *name, int min_version, struct vconn **vconnp)
 
     /* Call class's "open" function. */
     suffix_copy = xstrdup(strchr(name, ':') + 1);
-    error = class->open(name, suffix_copy, &vconn);
+    error = class->open(name, suffix_copy, &vconn, dscp);
     free(suffix_copy);
     if (error) {
         goto error;
@@ -282,7 +284,7 @@ vconn_open_block(const char *name, int min_version, struct vconn **vconnp)
 
     fatal_signal_run();
 
-    error = vconn_open(name, min_version, &vconn);
+    error = vconn_open(name, min_version, &vconn, DSCP_DEFAULT);
     if (!error) {
         while ((error = vconn_connect(vconn)) == EAGAIN) {
             vconn_run(vconn);
@@ -899,7 +901,7 @@ pvconn_verify_name(const char *name)
  * stores a pointer to the new connection in '*pvconnp', otherwise a null
  * pointer.  */
 int
-pvconn_open(const char *name, struct pvconn **pvconnp)
+pvconn_open(const char *name, struct pvconn **pvconnp, uint8_t dscp)
 {
     struct pvconn_class *class;
     struct pvconn *pvconn;
@@ -916,7 +918,7 @@ pvconn_open(const char *name, struct pvconn **pvconnp)
 
     /* Call class's "open" function. */
     suffix_copy = xstrdup(strchr(name, ':') + 1);
-    error = class->listen(name, suffix_copy, &pvconn);
+    error = class->listen(name, suffix_copy, &pvconn, dscp);
     free(suffix_copy);
     if (error) {
         goto error;
diff --git a/lib/vconn.h b/lib/vconn.h
index 516e2d3..5971327 100644
--- a/lib/vconn.h
+++ b/lib/vconn.h
@@ -33,7 +33,8 @@ void vconn_usage(bool active, bool passive, bool bootstrap);
 
 /* Active vconns: virtual connections to OpenFlow devices. */
 int vconn_verify_name(const char *name);
-int vconn_open(const char *name, int min_version, struct vconn **);
+int vconn_open(const char *name, int min_version,
+               struct vconn **, uint8_t dscp);
 void vconn_close(struct vconn *);
 const char *vconn_get_name(const struct vconn *);
 ovs_be32 vconn_get_remote_ip(const struct vconn *);
@@ -69,7 +70,7 @@ void vconn_send_wait(struct vconn *);
 
 /* Passive vconns: virtual listeners for incoming OpenFlow connections. */
 int pvconn_verify_name(const char *name);
-int pvconn_open(const char *name, struct pvconn **);
+int pvconn_open(const char *name, struct pvconn **, uint8_t dscp);
 const char *pvconn_get_name(const struct pvconn *);
 void pvconn_close(struct pvconn *);
 int pvconn_accept(struct pvconn *, int min_version, struct vconn **);
diff --git a/ofproto/collectors.c b/ofproto/collectors.c
index bd3e89b..b41e8e6 100644
--- a/ofproto/collectors.c
+++ b/ofproto/collectors.c
@@ -63,7 +63,8 @@ collectors_create(const struct sset *targets, uint16_t default_port,
         int error;
         int fd;
 
-        error = inet_open_active(SOCK_DGRAM, name, default_port, NULL, &fd);
+        error = inet_open_active(SOCK_DGRAM, name, default_port, NULL, &fd,
+                                 DSCP_INVALID);
         if (fd >= 0) {
             c->fds[c->n_fds++] = fd;
         } else {
diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c
index ed1aac2..3836c48 100644
--- a/ofproto/connmgr.c
+++ b/ofproto/connmgr.c
@@ -126,7 +126,7 @@ struct ofservice {
 
 static void ofservice_reconfigure(struct ofservice *,
                                   const struct ofproto_controller *);
-static int ofservice_create(struct connmgr *, const char *target);
+static int ofservice_create(struct connmgr *, const char *target, uint8_t dscp);
 static void ofservice_destroy(struct connmgr *, struct ofservice *);
 static struct ofservice *ofservice_lookup(struct connmgr *,
                                           const char *target);
@@ -280,7 +280,8 @@ connmgr_run(struct connmgr *mgr,
             struct rconn *rconn;
             char *name;
 
-            rconn = rconn_create(ofservice->probe_interval, 0);
+            /* Passing default value for creation of the rconn */
+            rconn = rconn_create(ofservice->probe_interval, 0, DSCP_DEFAULT);
             name = ofconn_make_name(mgr, vconn_get_name(vconn));
             rconn_connect_unreliably(rconn, vconn, name);
             free(name);
@@ -358,7 +359,7 @@ connmgr_retry(struct connmgr *mgr)
 
 /* OpenFlow configuration. */
 
-static void add_controller(struct connmgr *, const char *target);
+static void add_controller(struct connmgr *, const char *target, uint8_t dscp);
 static struct ofconn *find_controller_by_target(struct connmgr *,
                                                 const char *target);
 static void update_fail_open(struct connmgr *);
@@ -465,11 +466,11 @@ connmgr_set_controllers(struct connmgr *mgr,
 
         if (!vconn_verify_name(c->target)) {
             if (!find_controller_by_target(mgr, c->target)) {
-                add_controller(mgr, c->target);
+                add_controller(mgr, c->target, c->dscp);
             }
         } else if (!pvconn_verify_name(c->target)) {
             if (!ofservice_lookup(mgr, c->target)) {
-                ofservice_create(mgr, c->target);
+                ofservice_create(mgr, c->target, c->dscp);
             }
         } else {
             VLOG_WARN_RL(&rl, "%s: unsupported controller \"%s\"",
@@ -559,12 +560,12 @@ connmgr_has_snoops(const struct connmgr *mgr)
 /* Creates a new controller for 'target' in 'mgr'.  update_controller() needs
  * to be called later to finish the new ofconn's configuration. */
 static void
-add_controller(struct connmgr *mgr, const char *target)
+add_controller(struct connmgr *mgr, const char *target, uint8_t dscp)
 {
     char *name = ofconn_make_name(mgr, target);
     struct ofconn *ofconn;
 
-    ofconn = ofconn_create(mgr, rconn_create(5, 8), OFCONN_PRIMARY, true);
+    ofconn = ofconn_create(mgr, rconn_create(5, 8, dscp), OFCONN_PRIMARY, true);
     ofconn->pktbuf = pktbuf_create();
     rconn_connect(ofconn->rconn, target, name);
     hmap_insert(&mgr->controllers, &ofconn->hmap_node, hash_string(target, 0));
@@ -672,7 +673,7 @@ set_pvconns(struct pvconn ***pvconnsp, size_t *n_pvconnsp,
         struct pvconn *pvconn;
         int error;
 
-        error = pvconn_open(name, &pvconn);
+        error = pvconn_open(name, &pvconn, OPENVSWITCH_INVALID_DSCP);
         if (!error) {
             pvconns[n_pvconns++] = pvconn;
         } else {
@@ -1551,13 +1552,13 @@ connmgr_flushed(struct connmgr *mgr)
  * ofservice_reconfigure() must be called to fully configure the new
  * ofservice. */
 static int
-ofservice_create(struct connmgr *mgr, const char *target)
+ofservice_create(struct connmgr *mgr, const char *target, uint8_t dscp)
 {
     struct ofservice *ofservice;
     struct pvconn *pvconn;
     int error;
 
-    error = pvconn_open(target, &pvconn);
+    error = pvconn_open(target, &pvconn, dscp);
     if (error) {
         return error;
     }
diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h
index adbb80d..2710130 100644
--- a/ofproto/ofproto.h
+++ b/ofproto/ofproto.h
@@ -127,6 +127,8 @@ struct ofproto_controller {
     /* OpenFlow packet-in rate-limiting. */
     int rate_limit;             /* Max packet-in rate in packets per second. */
     int burst_limit;            /* Limit on accumulating packet credits. */
+
+    uint8_t dscp;               /* DSCP value for controller connection. */
 };
 
 #define DEFAULT_MFR_DESC "Nicira Networks, Inc."
@@ -185,8 +187,8 @@ int ofproto_port_dump_done(struct ofproto_port_dump *);
           : (ofproto_port_dump_done(DUMP), false));         \
         )
 
-#define OFPROTO_FLOW_EVICTON_THRESHOLD_DEFAULT	1000
-#define OFPROTO_FLOW_EVICTION_THRESHOLD_MIN	100
+#define OFPROTO_FLOW_EVICTON_THRESHOLD_DEFAULT  1000
+#define OFPROTO_FLOW_EVICTION_THRESHOLD_MIN     100
 
 int ofproto_port_add(struct ofproto *, struct netdev *, uint16_t *ofp_portp);
 int ofproto_port_del(struct ofproto *, uint16_t ofp_port);
diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c
index 147dadc..9e6ed25 100644
--- a/ovsdb/jsonrpc-server.c
+++ b/ovsdb/jsonrpc-server.c
@@ -98,7 +98,9 @@ struct ovsdb_jsonrpc_remote {
 };
 
 static struct ovsdb_jsonrpc_remote *ovsdb_jsonrpc_server_add_remote(
-    struct ovsdb_jsonrpc_server *, const char *name);
+    struct ovsdb_jsonrpc_server *, const char *name,
+    const struct ovsdb_jsonrpc_options *options
+);
 static void ovsdb_jsonrpc_server_del_remote(struct shash_node *);
 
 struct ovsdb_jsonrpc_server *
@@ -156,7 +158,7 @@ ovsdb_jsonrpc_server_set_remotes(struct ovsdb_jsonrpc_server *svr,
 
         remote = shash_find_data(&svr->remotes, node->name);
         if (!remote) {
-            remote = ovsdb_jsonrpc_server_add_remote(svr, node->name);
+            remote = ovsdb_jsonrpc_server_add_remote(svr, node->name, options);
             if (!remote) {
                 continue;
             }
@@ -168,13 +170,14 @@ ovsdb_jsonrpc_server_set_remotes(struct ovsdb_jsonrpc_server *svr,
 
 static struct ovsdb_jsonrpc_remote *
 ovsdb_jsonrpc_server_add_remote(struct ovsdb_jsonrpc_server *svr,
-                                const char *name)
+                                const char *name,
+                                const struct ovsdb_jsonrpc_options *options)
 {
     struct ovsdb_jsonrpc_remote *remote;
     struct pstream *listener;
     int error;
 
-    error = jsonrpc_pstream_open(name, &listener);
+    error = jsonrpc_pstream_open(name, &listener, options->dscp);
     if (error && error != EAFNOSUPPORT) {
         VLOG_ERR_RL(&rl, "%s: listen failed: %s", name, strerror(error));
         return NULL;
@@ -388,6 +391,7 @@ ovsdb_jsonrpc_session_set_options(struct ovsdb_jsonrpc_session *session,
 {
     jsonrpc_session_set_max_backoff(session->js, options->max_backoff);
     jsonrpc_session_set_probe_interval(session->js, options->probe_interval);
+    jsonrpc_session_set_dscp(session->js, options->dscp);
 }
 
 static void
diff --git a/ovsdb/jsonrpc-server.h b/ovsdb/jsonrpc-server.h
index 78ddb82..c5ea6fa 100644
--- a/ovsdb/jsonrpc-server.h
+++ b/ovsdb/jsonrpc-server.h
@@ -28,6 +28,7 @@ void ovsdb_jsonrpc_server_destroy(struct ovsdb_jsonrpc_server *);
 struct ovsdb_jsonrpc_options {
     int max_backoff;            /* Maximum reconnection backoff, in msec. */
     int probe_interval;         /* Max idle time before probing, in msec. */
+    int dscp;                   /* Dscp value for manager connections */
 };
 struct ovsdb_jsonrpc_options *ovsdb_jsonrpc_default_options(void);
 
diff --git a/ovsdb/ovsdb-client.c b/ovsdb/ovsdb-client.c
index 8562fc9..53da6ae 100644
--- a/ovsdb/ovsdb-client.c
+++ b/ovsdb/ovsdb-client.c
@@ -306,11 +306,12 @@ open_jsonrpc(const char *server)
     struct stream *stream;
     int error;
 
-    error = stream_open_block(jsonrpc_stream_open(server, &stream), &stream);
+    error = stream_open_block(jsonrpc_stream_open(server, &stream,
+                              DSCP_DEFAULT), &stream);
     if (error == EAFNOSUPPORT) {
         struct pstream *pstream;
 
-        error = jsonrpc_pstream_open(server, &pstream);
+        error = jsonrpc_pstream_open(server, &pstream, DSCP_DEFAULT);
         if (error) {
             ovs_fatal(error, "failed to connect or listen to \"%s\"", server);
         }
diff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c
index 9e0636e..02ebf1b 100644
--- a/ovsdb/ovsdb-server.c
+++ b/ovsdb/ovsdb-server.c
@@ -318,6 +318,45 @@ get_datum(struct ovsdb_row *row, const char *column_name,
 
     return &row->fields[column->index];
 }
+ 
+/* This function is used to read the string-string key-values from a map.
+ * Returns the value associated with the "key", else returns NULL if the key is
+ * not present in the map. */
+static inline const union ovsdb_atom *
+read_map_column(const struct ovsdb_row *row, const char *column_name,
+                enum ovsdb_atomic_type type, const char *key)
+{
+    const struct ovsdb_datum *datum;
+    union ovsdb_atom *atom;
+    size_t i;
+
+    datum = get_datum((struct ovsdb_row *) row, column_name, type,
+                      OVSDB_TYPE_STRING, UINT_MAX);
+
+    if (!datum) {
+      return NULL;
+    }
+
+    for (i = 0; i < datum->n; i++) {
+        atom = &datum->keys[i];
+        if (!strcmp(atom->string, key)){
+            return &datum->values[i];
+        }
+    }
+    return NULL;
+}
+
+static bool
+read_map_string_column(const struct ovsdb_row *row, const char *column_name,
+                       const char **stringp, const char *key)
+{
+    const union ovsdb_atom *atom;
+
+    atom = read_map_column(row, column_name, OVSDB_TYPE_STRING, key);
+
+    *stringp = atom ? atom->string : NULL;
+    return atom != NULL;
+}
 
 static const union ovsdb_atom *
 read_column(const struct ovsdb_row *row, const char *column_name,
@@ -325,7 +364,8 @@ read_column(const struct ovsdb_row *row, const char *column_name,
 {
     const struct ovsdb_datum *datum;
 
-    datum = get_datum((struct ovsdb_row *) row, column_name, type, OVSDB_TYPE_VOID, 1);
+    datum = get_datum((struct ovsdb_row *) row, column_name, type, OVSDB_TYPE_VOID,
+                      1);
     return datum && datum->n ? datum->keys : NULL;
 }
 
@@ -395,6 +435,21 @@ write_string_string_column(struct ovsdb_row *row, const char *column_name,
     ovsdb_datum_sort_assert(datum, column->type.key.type);
 }
 
+/* Get the other config for the manager from the database. */
+static void
+manager_get_other_config(const struct ovsdb_row *row, 
+                         struct ovsdb_jsonrpc_options *options)
+{
+    const char *temp_string;
+
+    /* Retrieve the configs and store in the options. */
+    if (read_map_string_column(row, "other_config", &temp_string, "dscp")) {
+        options->dscp = atoi(temp_string);
+    } else {
+        options->dscp = DSCP_DEFAULT;
+    }
+}
+
 /* Adds a remote and options to 'remotes', based on the Manager table row in
  * 'row'. */
 static void
@@ -418,6 +473,8 @@ add_manager_options(struct shash *remotes, const struct ovsdb_row *row)
     if (read_integer_column(row, "inactivity_probe", &probe_interval)) {
         options->probe_interval = probe_interval;
     }
+
+    manager_get_other_config(row, options);
 }
 
 static void
diff --git a/tests/test-jsonrpc.c b/tests/test-jsonrpc.c
index f431f86..9c585aa 100644
--- a/tests/test-jsonrpc.c
+++ b/tests/test-jsonrpc.c
@@ -176,7 +176,7 @@ do_listen(int argc OVS_UNUSED, char *argv[])
     bool done;
     int error;
 
-    error = jsonrpc_pstream_open(argv[1], &pstream);
+    error = jsonrpc_pstream_open(argv[1], &pstream, DSCP_DEFAULT);
     if (error) {
         ovs_fatal(error, "could not listen on \"%s\"", argv[1]);
     }
@@ -269,7 +269,8 @@ do_request(int argc OVS_UNUSED, char *argv[])
         ovs_fatal(0, "not a valid JSON-RPC request: %s", string);
     }
 
-    error = stream_open_block(jsonrpc_stream_open(argv[1], &stream), &stream);
+    error = stream_open_block(jsonrpc_stream_open(argv[1], &stream,
+                              DSCP_DEFAULT), &stream);
     if (error) {
         ovs_fatal(error, "could not open \"%s\"", argv[1]);
     }
@@ -308,7 +309,8 @@ do_notify(int argc OVS_UNUSED, char *argv[])
         ovs_fatal(0, "not a JSON RPC-valid notification: %s", string);
     }
 
-    error = stream_open_block(jsonrpc_stream_open(argv[1], &stream), &stream);
+    error = stream_open_block(jsonrpc_stream_open(argv[1], &stream,
+                              DSCP_DEFAULT), &stream);
     if (error) {
         ovs_fatal(error, "could not open \"%s\"", argv[1]);
     }
diff --git a/tests/test-netflow.c b/tests/test-netflow.c
index 8b474ea..49cab49 100644
--- a/tests/test-netflow.c
+++ b/tests/test-netflow.c
@@ -202,7 +202,7 @@ main(int argc, char *argv[])
     }
     target = argv[optind];
 
-    sock = inet_open_passive(SOCK_DGRAM, target, 0, NULL);
+    sock = inet_open_passive(SOCK_DGRAM, target, 0, NULL, DSCP_INVALID);
     if (sock < 0) {
         ovs_fatal(0, "%s: failed to open (%s)", argv[1], strerror(-sock));
     }
diff --git a/tests/test-ovsdb.c b/tests/test-ovsdb.c
index 893532c..65d6e5f 100644
--- a/tests/test-ovsdb.c
+++ b/tests/test-ovsdb.c
@@ -1871,8 +1871,8 @@ do_idl(int argc, char *argv[])
     if (argc > 2) {
         struct stream *stream;
 
-        error = stream_open_block(jsonrpc_stream_open(argv[1], &stream),
-                                  &stream);
+        error = stream_open_block(jsonrpc_stream_open(argv[1], &stream,
+                                  DSCP_DEFAULT), &stream);
         if (error) {
             ovs_fatal(error, "failed to connect to \"%s\"", argv[1]);
         }
diff --git a/tests/test-vconn.c b/tests/test-vconn.c
index 8dfc1e4..8aa5a8d 100644
--- a/tests/test-vconn.c
+++ b/tests/test-vconn.c
@@ -82,14 +82,15 @@ fpv_create(const char *type, struct fake_pvconn *fpv)
         bind_path = xasprintf("fake-pvconn.%d", unix_count++);
         fpv->pvconn_name = xasprintf("punix:%s", bind_path);
         fpv->vconn_name = xasprintf("unix:%s", bind_path);
-        CHECK_ERRNO(pstream_open(fpv->pvconn_name, &fpv->pstream), 0);
+        CHECK_ERRNO(pstream_open(fpv->pvconn_name, &fpv->pstream,
+                                 DSCP_DEFAULT), 0);
         free(bind_path);
     } else if (!strcmp(type, "tcp") || !strcmp(type, "ssl")) {
         char *s, *port, *save_ptr = NULL;
         char *open_name;
 
         open_name = xasprintf("p%s:0:127.0.0.1", type);
-        CHECK_ERRNO(pstream_open(open_name, &fpv->pstream), 0);
+        CHECK_ERRNO(pstream_open(open_name, &fpv->pstream, DSCP_DEFAULT), 0);
 
         /* Extract bound port number from pstream name. */
         s = xstrdup(pstream_get_name(fpv->pstream));
@@ -147,7 +148,8 @@ test_refuse_connection(int argc OVS_UNUSED, char *argv[])
                       : EPROTO);
 
     fpv_create(type, &fpv);
-    CHECK_ERRNO(vconn_open(fpv.vconn_name, OFP10_VERSION, &vconn), 0);
+    CHECK_ERRNO(vconn_open(fpv.vconn_name, OFP10_VERSION, &vconn,
+                           DSCP_DEFAULT), 0);
     fpv_close(&fpv);
     vconn_run(vconn);
     CHECK_ERRNO(vconn_connect(vconn), expected_error);
@@ -171,7 +173,8 @@ test_accept_then_close(int argc OVS_UNUSED, char *argv[])
                       : EPROTO);
 
     fpv_create(type, &fpv);
-    CHECK_ERRNO(vconn_open(fpv.vconn_name, OFP10_VERSION, &vconn), 0);
+    CHECK_ERRNO(vconn_open(fpv.vconn_name, OFP10_VERSION, &vconn,
+                           DSCP_DEFAULT), 0);
     vconn_run(vconn);
     stream_close(fpv_accept(&fpv));
     fpv_close(&fpv);
@@ -192,7 +195,8 @@ test_read_hello(int argc OVS_UNUSED, char *argv[])
     struct stream *stream;
 
     fpv_create(type, &fpv);
-    CHECK_ERRNO(vconn_open(fpv.vconn_name, OFP10_VERSION, &vconn), 0);
+    CHECK_ERRNO(vconn_open(fpv.vconn_name, OFP10_VERSION, &vconn,
+                           DSCP_DEFAULT), 0);
     vconn_run(vconn);
     stream = fpv_accept(&fpv);
     fpv_destroy(&fpv);
@@ -238,7 +242,8 @@ test_send_hello(const char *type, const void *out, size_t out_size,
     size_t n_sent;
 
     fpv_create(type, &fpv);
-    CHECK_ERRNO(vconn_open(fpv.vconn_name, OFP10_VERSION, &vconn), 0);
+    CHECK_ERRNO(vconn_open(fpv.vconn_name, OFP10_VERSION, &vconn,
+                           DSCP_DEFAULT), 0);
     vconn_run(vconn);
     stream = fpv_accept(&fpv);
     fpv_destroy(&fpv);
diff --git a/utilities/ovs-controller.c b/utilities/ovs-controller.c
index da9b17d..fa60f8f 100644
--- a/utilities/ovs-controller.c
+++ b/utilities/ovs-controller.c
@@ -40,6 +40,7 @@
 #include "util.h"
 #include "vconn.h"
 #include "vlog.h"
+#include "socket-util.h"
 
 VLOG_DEFINE_THIS_MODULE(controller);
 
@@ -115,7 +116,7 @@ main(int argc, char *argv[])
         const char *name = argv[i];
         struct vconn *vconn;
 
-        retval = vconn_open(name, OFP10_VERSION, &vconn);
+        retval = vconn_open(name, OFP10_VERSION, &vconn, DSCP_DEFAULT);
         if (!retval) {
             if (n_switches >= MAX_SWITCHES) {
                 ovs_fatal(0, "max %d switch connections", n_switches);
@@ -124,7 +125,7 @@ main(int argc, char *argv[])
             continue;
         } else if (retval == EAFNOSUPPORT) {
             struct pvconn *pvconn;
-            retval = pvconn_open(name, &pvconn);
+            retval = pvconn_open(name, &pvconn, DSCP_DEFAULT);
             if (!retval) {
                 if (n_listeners >= MAX_LISTENERS) {
                     ovs_fatal(0, "max %d passive connections", n_listeners);
@@ -222,7 +223,7 @@ new_switch(struct switch_ *sw, struct vconn *vconn)
 {
     struct lswitch_config cfg;
 
-    sw->rconn = rconn_create(60, 0);
+    sw->rconn = rconn_create(60, 0, DSCP_DEFAULT);
     rconn_connect_unreliably(sw->rconn, vconn, NULL);
 
     cfg.mode = (action_normal ? LSW_NORMAL
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index 5b6976a..56203b9 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -222,6 +222,11 @@ static bool iface_is_synthetic(const struct iface *);
 static const char *get_interface_other_config(const struct ovsrec_interface *,
                                               const char *key,
                                               const char *default_value);
+static const char *controller_get_other_config(const struct ovsrec_controller *,
+                                               const char *key,
+                                               const char *default_value);
+static void controller_configure_dscp(const struct ovsrec_controller *c,
+                                      struct ofproto_controller *oc);
 
 static void shash_from_ovs_idl_map(char **keys, char **values, size_t n,
                                    struct shash *);
@@ -2350,6 +2355,7 @@ bridge_ofproto_controller_from_ovsrec(const struct ovsrec_controller *c,
                        ? *c->controller_burst_limit : 0);
     oc->enable_async_msgs = (!c->enable_async_messages
                              || *c->enable_async_messages);
+    controller_configure_dscp (c, oc);
 }
 
 /* Configures the IP stack for 'br''s local interface properly according to the
@@ -3261,6 +3267,34 @@ iface_is_synthetic(const struct iface *iface)
 {
     return ovsdb_idl_row_is_synthetic(&iface->cfg->header_);
 }
+
+/* Returns the user configured "other_config:key" value for controller. If no
+ * value is configured by the user, returns the default value. */
+static const char *
+controller_get_other_config(const struct ovsrec_controller *controller,
+                            const char *key,
+                            const char *default_value)
+{
+    const char *value;
+    value = get_ovsrec_key_value(controller->key_other_config,
+                                 controller->value_other_config,
+                                 controller->n_other_config, key);
+    return value ? value : default_value;
+}
+
+/* Extracts the dscp values for the controller. */
+static void
+controller_configure_dscp(const struct ovsrec_controller *c,
+                          struct ofproto_controller *oc)
+{
+    char default_value[5];
+
+    snprintf(default_value, sizeof(default_value), "%d", DSCP_DEFAULT);
+    oc->dscp  = atoi(controller_get_other_config(c,
+                                                 "dscp",
+                                                 default_value));
+}
+
 
 /* Port mirroring. */
 
diff --git a/vswitchd/vswitch.ovsschema b/vswitchd/vswitch.ovsschema
index c7aece7..a3847e7 100644
--- a/vswitchd/vswitch.ovsschema
+++ b/vswitchd/vswitch.ovsschema
@@ -1,6 +1,6 @@
 {"name": "Open_vSwitch",
  "version": "6.8.0",
- "cksum": "1404093776 16263",
+ "cksum": "4106006492 16485",
  "tables": {
    "Open_vSwitch": {
      "columns": {
@@ -390,6 +390,8 @@
          "type": {"key": {"type": "integer",
                           "minInteger": 25},
                   "min": 0, "max": 1}},
+       "other_config": {
+         "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}},
        "external_ids": {
          "type": {"key": "string", "value": "string",
                   "min": 0, "max": "unlimited"}},
@@ -418,6 +420,8 @@
          "type": {"key": {"type": "string",
                   "enum": ["set", ["in-band", "out-of-band"]]},
                   "min": 0, "max": 1}},
+       "other_config": {
+         "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}},
        "external_ids": {
          "type": {"key": "string", "value": "string",
                   "min": 0, "max": "unlimited"}},
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index 3e13682..21d0c70 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -2658,11 +2658,34 @@
       </column>
     </group>
 
+    <group title="Connection Parameters">
+      <p>
+        Additional configuration for a connection between the controller
+        and the Open vSwitch.
+      </p>
+
+      <column name="other_config" key="dscp"
+                type='{"type": "integer"}'>
+        The Differentiated Service Code Point (DSCP) is specified in the IP
+        header. They are specified using 6 bits in the Type of Service (TOS)
+        field in the IP header. DSCP provides a mechanism to classify the
+        network traffic and provide the Quality of Service (QoS) on IP
+        networks.
+        The DSCP value passed is used when establishing the connection between
+        the controller and the Open vSwitch.  The connection must be reset
+        for the new DSCP values to take effect.  If no value is
+        specified, a default value of 192 is chosen for connection
+        establishment.  Valid DSCP values must have their lower 2 bits set to 0.
+      </column>
+    </group>
+
+
     <group title="Common Columns">
       The overall purpose of these columns is described under <code>Common
       Columns</code> at the beginning of this document.
 
       <column name="external_ids"/>
+      <column name="other_config"/>
     </group>
   </table>
 
@@ -2882,11 +2905,33 @@
       </column>
     </group>
 
+    <group title="Connection Parameters">
+      <p>
+        Additional configuration for a connection between the manager
+        and the Open vSwitch Database.
+      </p>
+
+      <column name="other_config" key="dscp"
+                type='{"type": "integer"}'>
+        The Differentiated Service Code Point (DSCP) is specified in the IP
+        header. They are specified using 6 bits in the Type of Service (TOS)
+        field in the IP header. DSCP provides a mechanism to classify the
+        network traffic and provide the Quality of Service (QoS) on IP
+        networks.
+        The DSCP value passed when establishing the connection between
+        the manager and the Open vSwitch Database.  The connection must be
+        reset for the new DSCP values to take effect.  If no value is
+        specified, a default value of 192 is chosen for connection
+        establishment.  Valid DSCP values must have their lower 2 bits set to 0.
+      </column>
+    </group>
+
     <group title="Common Columns">
       The overall purpose of these columns is described under <code>Common
       Columns</code> at the beginning of this document.
 
       <column name="external_ids"/>
+      <column name="other_config"/>
     </group>
   </table>
 
-- 
1.7.2.5




More information about the dev mailing list