aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMehak Mahajan <mmahajan@nicira.com>2012-03-10 15:58:10 -0800
committerMehak Mahajan <mmahajan@nicira.com>2012-03-23 18:13:08 -0700
commitf125905cdd3dc0339ad968c0a70128807884b400 (patch)
treeab389d41b625f2d9e5c820bdac80ec2df825ff8a
parent11460e2316b88f0bd0ea0005d94338d800ea16bd (diff)
Allow configuring DSCP on controller and manager connections.
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>
-rw-r--r--NEWS3
-rw-r--r--include/sparse/netinet/in.h21
-rw-r--r--lib/jsonrpc.c22
-rw-r--r--lib/jsonrpc.h7
-rw-r--r--lib/netdev-linux.c1
-rw-r--r--lib/rconn.c12
-rw-r--r--lib/rconn.h5
-rw-r--r--lib/reconnect.c18
-rw-r--r--lib/reconnect.h3
-rw-r--r--lib/socket-util.c36
-rw-r--r--lib/socket-util.h15
-rw-r--r--lib/stream-provider.h15
-rw-r--r--lib/stream-ssl.c16
-rw-r--r--lib/stream-tcp.c11
-rw-r--r--lib/stream-unix.c5
-rw-r--r--lib/stream.c18
-rw-r--r--lib/stream.h10
-rw-r--r--lib/unixctl.c5
-rw-r--r--lib/vconn-provider.h14
-rw-r--r--lib/vconn-stream.c8
-rw-r--r--lib/vconn.c12
-rw-r--r--lib/vconn.h5
-rw-r--r--ofproto/collectors.c3
-rw-r--r--ofproto/connmgr.c23
-rw-r--r--ofproto/ofproto.h2
-rw-r--r--ovsdb/jsonrpc-server.c12
-rw-r--r--ovsdb/jsonrpc-server.h1
-rw-r--r--ovsdb/ovsdb-client.c5
-rw-r--r--ovsdb/ovsdb-server.c51
-rw-r--r--tests/test-jsonrpc.c8
-rw-r--r--tests/test-netflow.c2
-rw-r--r--tests/test-ovsdb.c4
-rw-r--r--tests/test-vconn.c17
-rw-r--r--utilities/ovs-controller.c7
-rw-r--r--vswitchd/bridge.c10
-rw-r--r--vswitchd/vswitch.ovsschema6
-rw-r--r--vswitchd/vswitch.xml45
37 files changed, 361 insertions, 97 deletions
diff --git a/NEWS b/NEWS
index b6e5dd18..a466f923 100644
--- 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
diff --git a/include/sparse/netinet/in.h b/include/sparse/netinet/in.h
index d86431ad..ed31463a 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 09b10711..fa3362d1 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 ff04a547..16131d33 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/netdev-linux.c b/lib/netdev-linux.c
index a5e6d366..d2a5c7ac 100644
--- a/lib/netdev-linux.c
+++ b/lib/netdev-linux.c
@@ -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>
diff --git a/lib/rconn.c b/lib/rconn.c
index f6d85a7b..56a7e197 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 d0326e65..eea054f3 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 c1690162..7737fcf7 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 997a03f2..9dfcfd7d 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 37f8c9ad..6554e972 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 422cea9c..32c61e78 100644
--- a/lib/socket-util.h
+++ b/lib/socket-util.h
@@ -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 */
diff --git a/lib/stream-provider.h b/lib/stream-provider.h
index 03bf777b..77d0a106 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 22d4c99a..5463388e 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 052ad8cb..c7a2ee2e 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 d2e8e823..a9d76f25 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 066de4e8..2f418c42 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 5c111f99..c1f3adb6 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 d8974c9e..e40f1731 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);
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);
diff --git a/lib/vconn-provider.h b/lib/vconn-provider.h
index 682a593c..43d2072e 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 a9890b59..03e58818 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 f0be46a3..4d04c833 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 516e2d3a..59713275 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 bd3e89b1..b41e8e64 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 ed1aac2e..2e05adb8 100644
--- a/ofproto/connmgr.c
+++ b/ofproto/connmgr.c
@@ -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)
/* 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
diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h
index 538c2c6e..6172f291 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."
diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c
index 147dadc7..9e6ed257 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 78ddb82d..c5ea6faf 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 8562fc9a..53da6ae2 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 9e0636e9..776bbb25 100644
--- a/ovsdb/ovsdb-server.c
+++ b/ovsdb/ovsdb-server.c
@@ -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
diff --git a/tests/test-jsonrpc.c b/tests/test-jsonrpc.c
index f431f868..9c585aa6 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 8b474ea9..49cab495 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 893532cc..65d6e5f7 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 8dfc1e43..8aa5a8d8 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 da9b17d0..fa60f8f6 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 2ea146cf..17782270 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -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_);
}
+
/* Port mirroring. */
diff --git a/vswitchd/vswitch.ovsschema b/vswitchd/vswitch.ovsschema
index c7aece70..a3847e77 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 e3e2a48b..f3ea3387 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -2659,11 +2659,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>
@@ -2883,11 +2906,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>