X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fsocket-util.c;h=a9b3b1adcaec1a1cc83a7ad09acb8ade31898a90;hb=cb6e2b01787b71c39678e9ef98e3b9374a7db378;hp=aded01c35855acf760c820af5cd91f5a769c0324;hpb=a4efa3fc5dffb8c5011ac889aae83fb5e38fbd85;p=openvswitch diff --git a/lib/socket-util.c b/lib/socket-util.c index aded01c3..a9b3b1ad 100644 --- a/lib/socket-util.c +++ b/lib/socket-util.c @@ -17,6 +17,7 @@ #include #include "socket-util.h" #include +#include #include #include #include @@ -81,6 +82,21 @@ set_nonblocking(int fd) } } +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) { @@ -546,8 +562,9 @@ exit: * If 'sinp' is non-null, then on success the target address is stored into * '*sinp'. * - * 'dscp' If not DSCP_INVALID, its value 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) @@ -574,15 +591,13 @@ inet_open_active(int style, const char *target, uint16_t default_port, 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 (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; - } + /* 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; } /* Connect. */ @@ -672,8 +687,9 @@ exit: * If 'sinp' is non-null, then on success the bound address is stored into * '*sinp'. * - * 'dscp' If not DSCP_INVALID, its value 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) @@ -711,15 +727,13 @@ 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; - } + /* 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; } /* Listen. */