Allow configuring DSCP on controller and manager connections.
authorMehak Mahajan <mmahajan@nicira.com>
Sat, 10 Mar 2012 23:58:10 +0000 (15:58 -0800)
committerMehak Mahajan <mmahajan@nicira.com>
Sat, 24 Mar 2012 01:13:08 +0000 (18:13 -0700)
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@nicira.com>
Signed-off-by: Mehak Mahajan <mmahajan@nicira.com>
37 files changed:
NEWS
include/sparse/netinet/in.h
lib/jsonrpc.c
lib/jsonrpc.h
lib/netdev-linux.c
lib/rconn.c
lib/rconn.h
lib/reconnect.c
lib/reconnect.h
lib/socket-util.c
lib/socket-util.h
lib/stream-provider.h
lib/stream-ssl.c
lib/stream-tcp.c
lib/stream-unix.c
lib/stream.c
lib/stream.h
lib/unixctl.c
lib/vconn-provider.h
lib/vconn-stream.c
lib/vconn.c
lib/vconn.h
ofproto/collectors.c
ofproto/connmgr.c
ofproto/ofproto.h
ovsdb/jsonrpc-server.c
ovsdb/jsonrpc-server.h
ovsdb/ovsdb-client.c
ovsdb/ovsdb-server.c
tests/test-jsonrpc.c
tests/test-netflow.c
tests/test-ovsdb.c
tests/test-vconn.c
utilities/ovs-controller.c
vswitchd/bridge.c
vswitchd/vswitch.ovsschema
vswitchd/vswitch.xml

diff --git a/NEWS b/NEWS
index b6e5dd188c2ff0c8d1c545c29b03d7f742db7163..a466f923f82122bbf09c0c07f22ce54802ece7a4 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,9 @@ post-v1.6.0
     - kernel modules are renamed. openvswitch_mod.ko is now
       openvswitch.ko and brcompat_mod.ko is now brcompat.ko.
     - Increased the number of NXM registers to 8.
+    - Added ability to configure dscp setting for manager and controller
+      connections.  By default, these connections have a DSCP value of
+      Internetwork Control (0xc0).
 
 
 v1.6.0 - xx xxx xxxx
index d86431ada496852c156c017402f76db9855fc4c0..ed31463addcd8599cb7abe1825ecefc3662137c1 100644 (file)
@@ -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
index 09b10711ff851fd8ca861cbb1af429df14b0f842..fa3362d17d8610dba45ca21f2bb47a135b936e2d 100644 (file)
@@ -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);
+}
index ff04a547e35e71fe66641f3d8fdaa986a4e43647..16131d333b21c5109fc58eb2fa319f0dc4170879 100644 (file)
@@ -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 */
index a5e6d3663e0840ba1a49f494c41eea10f57897ab..d2a5c7acc782b4ea921cabcc16e61d8dbaa22698 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/gen_stats.h>
 #include <linux/if_ether.h>
 #include <linux/if_tun.h>
-#include <linux/ip.h>
 #include <linux/types.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
index f6d85a7bdd43f74d35b224963ff6b92d7668e31e..56a7e19764069d28f6a849a375f7f4f045beaad2 100644 (file)
@@ -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;
 
@@ -218,6 +220,12 @@ 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;
+}
+
 void
 rconn_set_probe_interval(struct rconn *rc, int probe_interval)
 {
@@ -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);
index d0326e65a1843022be537cdee5e1e28ecb4d83e2..eea054f3739efe5939184d5e31e56a935d6b3973 100644 (file)
@@ -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);
index c169016236d9d3a33d65b5787341961aca4e648a..7737fcf7e7677f0bb83d658e24582bfddf74bcbf 100644 (file)
@@ -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
index 997a03f218d9806da0e07ca8a9e4e867fb757a32..9dfcfd7dfa276bc9b7b5920bdc3ccaeca88870e9 100644 (file)
@@ -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,
index 37f8c9ad48095fec9d2054428dc942dc2d7c4cf3..6554e972192b47a6310123345312d705f701e9f1 100644 (file)
@@ -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;
index 422cea9c35799d120a9247fadde8c0eb48e8124c..32c61e78913e8896383a56ba0899f20f2b2a3bef 100644 (file)
@@ -23,6 +23,7 @@
 #include <netinet/in.h>
 #include <stdbool.h>
 #include "openvswitch/types.h"
+#include <netinet/ip.h>
 
 int set_nonblocking(int fd);
 int get_max_fds(void);
@@ -46,12 +47,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 +64,14 @@ void xpipe(int fds[2]);
 
 char *describe_fd(int fd);
 
+/* Default value of dscp bits for connection between controller and manager.
+ * Value of IPTOS_PREC_INTERNETCONTROL = 0xc0 which is defined
+ * in <netinet/ip.h> is used.  */
+#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 */
index 03bf777b60865b791463a3e8199551e9bf62359d..77d0a10601c25c50d80d4db478a51df978631229 100644 (file)
@@ -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);
index 22d4c99aeb223ad3d4cb1cd0dbae595a4a20d524..5463388ea5159e5cc987feb223ee52f02f02060f 100644 (file)
@@ -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
index 052ad8cb54c6a8a7bd4d2f77352c22152379d135..c7a2ee2e8dcf6dc2fbacdc694a7515da55a60814 100644 (file)
@@ -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;
     }
index d2e8e82382ab2b3bd6bcb8cd929a5d511688868f..a9d76f2572050a56a9857909485c68f4df20e8ba 100644 (file)
@@ -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;
 
index 066de4e8772488697e8b87509f99c268df03ab8d..2f418c42ae22b36f160ba0d59d2ded3ee246bc77 100644 (file)
@@ -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;
index 5c111f999e3de4423481d036d9d5302abb68467e..c1f3adb6b33ddbdc38ff26dadbd2f0a662d8d418 100644 (file)
@@ -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,
index d8974c9e44503ac0d93d779b50853b019a75fec7..e40f17314cf6eace1deda098debed874344bd169 100644 (file)
@@ -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);
     if (error) {
         ovs_error(error, "could not initialize control socket %s", punix_path);
         goto exit;
@@ -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);
 
index 682a593c899158fe7535746f6d194cdb066d8aa6..43d2072e261f9b7d7ab92cbaa4a93258dcac153c 100644 (file)
@@ -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);
index a9890b594b30231c0f739df8982f29a1deb8f660..03e588185bf8cad7f0777714e0c2371206e8118d 100644 (file)
@@ -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;
     }
index f0be46a3da9cccd27241dd2f5abe0de9ef1cd837..4d04c8338243bb3dcc19895a50abb4a98bb03ae4 100644 (file)
@@ -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;
index 516e2d3a844563de52510f48ad75094ea5106a09..59713275edb56314ee11f1b8068107001d86da9d 100644 (file)
@@ -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 **);
index bd3e89b19ac21a751eb092486e6420f823e7836f..b41e8e64c255704f4f9b5de115fa96e2d3344b05 100644 (file)
@@ -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 {
index ed1aac2e98e8454bd5888abf44855a2d5245b3f3..2e05adb8bbaf6ad85bf83207f45325f1292869d7 100644 (file)
@@ -122,11 +122,12 @@ struct ofservice {
     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? */
+    uint8_t dscp;               /* DSCP Value for controller connection */
 };
 
 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 +281,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, ofservice->dscp);
             name = ofconn_make_name(mgr, vconn_get_name(vconn));
             rconn_connect_unreliably(rconn, vconn, name);
             free(name);
@@ -358,7 +360,7 @@ connmgr_retry(struct connmgr *mgr)
 \f
 /* 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 +467,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 +561,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 +674,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, DSCP_INVALID);
         if (!error) {
             pvconns[n_pvconns++] = pvconn;
         } else {
@@ -1551,13 +1553,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;
     }
@@ -1585,6 +1587,7 @@ ofservice_reconfigure(struct ofservice *ofservice,
     ofservice->rate_limit = c->rate_limit;
     ofservice->burst_limit = c->burst_limit;
     ofservice->enable_async_msgs = c->enable_async_msgs;
+    ofservice->dscp = c->dscp;
 }
 
 /* Finds and returns the ofservice within 'mgr' that has the given
index 538c2c6e063a6cfe64aad81870b212616a526ea3..6172f291f22f542e3685eb00340597ed307c98e0 100644 (file)
@@ -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."
index 147dadc7edbd14d33389cd1e3ff11ba45da1eeab..9e6ed257a662108da7d2f89346565388399010fc 100644 (file)
@@ -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
index 78ddb82dcd3b8ab397e250adc77edf19ceaa51ae..c5ea6faf2f021eb10691b837193ad31e619769c2 100644 (file)
@@ -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);
 
index 8562fc9af6df63ab3fce3338f4ef76a79e46ee2f..53da6ae27fe75d72aecfce2fabef8b3480867333 100644 (file)
@@ -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);
         }
index 9e0636e9c0136f69cf63076f54164a1909b5075a..776bbb258ba1c60a31078fd399e56a61f96d9ac1 100644 (file)
@@ -319,13 +319,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 true if the 'key' is found and returns the "value"  associated
+ * with the 'key' in 'stringp', else returns false. */
+static bool
+read_map_string_column(const struct ovsdb_row *row, const char *column_name,
+                       const char **stringp, const char *key)
+{
+    const struct ovsdb_datum *datum;
+    union ovsdb_atom *atom_key = NULL, *atom_value = NULL;
+    size_t i;
+
+    datum = get_datum((struct ovsdb_row *) row, column_name, OVSDB_TYPE_STRING,
+                      OVSDB_TYPE_STRING, UINT_MAX);
+
+    if (!datum) {
+        *stringp = NULL;
+        return false;
+    }
+
+    for (i = 0; i < datum->n; i++) {
+        atom_key = &datum->keys[i];
+        if (!strcmp(atom_key->string, key)){
+            atom_value = &datum->values[i];
+            break;
+        }
+    }
+
+    *stringp = atom_value ? atom_value->string : NULL;
+    return atom_value != NULL;
+}
+
 static const union ovsdb_atom *
 read_column(const struct ovsdb_row *row, const char *column_name,
             enum ovsdb_atomic_type type)
 {
     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 +427,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 +465,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
index f431f8685a48a06c442a64b14304c23f1caf0c03..9c585aa66eff79372ce183d45e442b13d324b274 100644 (file)
@@ -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]);
     }
index 8b474ea91fd853c05e52972c05ca7b70a4849210..49cab495d09d10d1d94f2736b2fc9c4e3861d451 100644 (file)
@@ -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));
     }
index 893532cca26ac0cec7abd6eee0aae1d5bd90794c..65d6e5f71f878e3c1bb07509bf168eb96ad572d8 100644 (file)
@@ -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]);
         }
index 8dfc1e43708e3421d7b5f72f0f0b57a3c9304305..8aa5a8d8d516578593786b488168be8089f857c9 100644 (file)
@@ -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);
index da9b17d00f86354bb7b3d25fab781d1e5038c433..fa60f8f68f53b6e5b757d0d68385a0f08632df9b 100644 (file)
@@ -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
index 2ea146cfaf15becd4ebe571e8622eb56f95cbf82..1778227021a068b43d535a1beb824a5ffca265d3 100644 (file)
@@ -215,7 +215,6 @@ static void iface_refresh_cfm_stats(struct iface *);
 static void iface_refresh_stats(struct iface *);
 static void iface_refresh_status(struct iface *);
 static bool iface_is_synthetic(const struct iface *);
-
 static void shash_from_ovs_idl_map(char **keys, char **values, size_t n,
                                    struct shash *);
 static void shash_to_ovs_idl_map(struct shash *,
@@ -2337,6 +2336,8 @@ static void
 bridge_ofproto_controller_from_ovsrec(const struct ovsrec_controller *c,
                                       struct ofproto_controller *oc)
 {
+    const char *config_str;
+
     oc->target = c->target;
     oc->max_backoff = c->max_backoff ? *c->max_backoff / 1000 : 8;
     oc->probe_interval = c->inactivity_probe ? *c->inactivity_probe / 1000 : 5;
@@ -2347,6 +2348,12 @@ 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);
+    config_str = ovsrec_controller_get_other_config_value(c, "dscp", NULL);
+    if (config_str) {
+        oc->dscp = atoi(config_str);
+    } else {
+        oc->dscp = DSCP_DEFAULT;
+    }
 }
 
 /* Configures the IP stack for 'br''s local interface properly according to the
@@ -3273,6 +3280,7 @@ iface_is_synthetic(const struct iface *iface)
 {
     return ovsdb_idl_row_is_synthetic(&iface->cfg->header_);
 }
+
 \f
 /* Port mirroring. */
 
index c7aece7047cf61758a8fc4b45939f266c53d070d..a3847e777ba1e2ff34dc66f3be7eba26ec19badb 100644 (file)
@@ -1,6 +1,6 @@
 {"name": "Open_vSwitch",
  "version": "6.8.0",
- "cksum": "1404093776 16263",
+ "cksum": "4106006492 16485",
  "tables": {
    "Open_vSwitch": {
      "columns": {
          "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"}},
          "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"}},
index e3e2a48b45d954590689fd34045b9855ee615116..f3ea33871ba2bf456c90e0b8fac33951b7677e6e 100644 (file)
       </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>
 
       </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>