From: Mehak Mahajan Date: Sat, 10 Mar 2012 23:58:10 +0000 (-0800) Subject: Allow configuring DSCP on controller and manager connections. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f125905cdd3dc0339ad968c0a70128807884b400;p=openvswitch 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 Signed-off-by: Mehak Mahajan --- 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 #include +#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 #include #include -#include #include #include #include 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; @@ -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); 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 +#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 #include #include "openvswitch/types.h" +#include 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 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 @@ + +

+ Additional configuration for a connection between the controller + and the Open vSwitch. +

+ + + 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. + +
+ + The overall purpose of these columns is described under Common Columns at the beginning of this document. + @@ -2883,11 +2906,33 @@ + +

+ Additional configuration for a connection between the manager + and the Open vSwitch Database. +

+ + + 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. + +
+ The overall purpose of these columns is described under Common Columns at the beginning of this document. +