#include <config.h>
#include "socket-util.h"
#include <arpa/inet.h>
+#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <net/if.h>
}
}
+static int
+set_dscp(int fd, uint8_t dscp)
+{
+ if (dscp > 63) {
+ return EINVAL;
+ }
+
+ dscp = dscp << 2;
+ if (setsockopt(fd, IPPROTO_IP, IP_TOS, &dscp, sizeof dscp)) {
+ return errno;
+ }
+
+ return 0;
+}
+
static bool
rlim_is_finite(rlim_t limit)
{
* If 'sinp' is non-null, then on success the target address is stored into
* '*sinp'.
*
- * 'dscp' becomes the DSCP bits in the IP headers for the new connection. */
+ * 'dscp' becomes the DSCP bits in the IP headers for the new connection. It
+ * should be in the range [0, 63] and will automatically be shifted to the
+ * appropriately place in the IP tos field. */
int
inet_open_active(int style, const char *target, uint16_t default_port,
struct sockaddr_in *sinp, int *fdp, uint8_t dscp)
goto exit;
}
- /* 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 (setsockopt(fd, IPPROTO_IP, IP_TOS, &dscp, sizeof dscp)) {
- VLOG_ERR("%s: socket: %s", target, strerror(errno));
- error = errno;
+ /* The dscp bits must be configured before connect() to ensure that the TOS
+ * field is set during the connection establishment. If set after
+ * connect(), the handshake SYN frames will be sent with a TOS of 0. */
+ error = set_dscp(fd, dscp);
+ if (error) {
+ VLOG_ERR("%s: socket: %s", target, strerror(error));
goto exit;
}
* If 'sinp' is non-null, then on success the bound address is stored into
* '*sinp'.
*
- * 'dscp' becomes the DSCP bits in the IP headers for the new connection. */
+ * 'dscp' becomes the DSCP bits in the IP headers for the new connection. It
+ * should be in the range [0, 63] and will automatically be shifted to the
+ * appropriately place in the IP tos field. */
int
inet_open_passive(int style, const char *target, int default_port,
struct sockaddr_in *sinp, uint8_t dscp)
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 (setsockopt(fd, IPPROTO_IP, IP_TOS, &dscp, sizeof dscp)) {
- VLOG_ERR("%s: socket: %s", target, strerror(errno));
- error = errno;
+ /* The dscp bits must be configured before connect() to ensure that the TOS
+ * field is set during the connection establishment. If set after
+ * connect(), the handshake SYN frames will be sent with a TOS of 0. */
+ error = set_dscp(fd, dscp);
+ if (error) {
+ VLOG_ERR("%s: socket: %s", target, strerror(error));
goto error;
}
/* 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
+ * in <netinet/ip.h> is used. */
+#define DSCP_DEFAULT (IPTOS_PREC_INTERNETCONTROL >> 2)
#endif /* socket-util.h */
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 string-string key-values from a map. Returns the value associated with
+ * 'key', if found, or NULL */
+static const char *
read_map_string_column(const struct ovsdb_row *row, const char *column_name,
- const char **stringp, const char *key)
+ const char *key)
{
const struct ovsdb_datum *datum;
union ovsdb_atom *atom_key = NULL, *atom_value = NULL;
OVSDB_TYPE_STRING, UINT_MAX);
if (!datum) {
- *stringp = NULL;
- return false;
+ return NULL;
}
for (i = 0; i < datum->n; i++) {
}
}
- *stringp = atom_value ? atom_value->string : NULL;
- return atom_value != NULL;
+ return atom_value ? atom_value->string : NULL;
}
static const union ovsdb_atom *
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
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
struct ovsdb_jsonrpc_options *options;
long long int max_backoff, probe_interval;
- const char *target;
+ const char *target, *dscp_string;
if (!read_string_column(row, "target", &target) || !target) {
VLOG_INFO_RL(&rl, "Table `%s' has missing or invalid `target' column",
options->probe_interval = probe_interval;
}
- manager_get_other_config(row, options);
+ options->dscp = DSCP_DEFAULT;
+ dscp_string = read_map_string_column(row, "other_config", "dscp");
+ if (dscp_string) {
+ int dscp = atoi(dscp_string);
+ if (dscp >= 0 && dscp <= 63) {
+ options->dscp = dscp;
+ }
+ }
}
static void
oc->enable_async_msgs = (!c->enable_async_messages
|| *c->enable_async_messages);
config_str = ovsrec_controller_get_other_config_value(c, "dscp", NULL);
+
+ oc->dscp = DSCP_DEFAULT;
if (config_str) {
- oc->dscp = atoi(config_str);
- } else {
- oc->dscp = DSCP_DEFAULT;
+ int dscp = atoi(config_str);
+
+ if (dscp >= 0 && dscp <= 63) {
+ oc->dscp = dscp;
+ }
}
}
{"name": "Open_vSwitch",
- "version": "6.9.0",
- "cksum": "617116616 16682",
+ "version": "6.9.1",
+ "cksum": "3226481229 16682",
"tables": {
"Open_vSwitch": {
"columns": {
<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.
+ The Differentiated Service Code Point (DSCP) is 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 Quality of
+ Service (QoS) on IP networks.
+
+ The DSCP value specified here 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 48 is chosen. Valid DSCP values must be
+ in the range 0 to 63.
</column>
</group>
<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
+ The Differentiated Service Code Point (DSCP) is 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 Quality of
+ Service (QoS) on IP networks.
+
+ The DSCP value specified here is used when establishing the connection
+ between the manager 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.
+ specified, a default value of 48 is chosen. Valid DSCP values must be
+ in the range 0 to 63.
</column>
</group>