Bug reported by: Atanu Ghosh <at...@acm.org> I'll review + test this series soon~
On Fri, Feb 20, 2015 at 8:44 AM, Ben Pfaff <b...@nicira.com> wrote: > The set_dscp() function, until now, tried to set the DSCP as IPv4 and as > IPv6. This worked OK on Linux, where an ENOPROTOOPT error made it really > clear which one was wrong, but FreeBSD uses EINVAL instead, which has > multiple meanings and which it therefore seems somewhat risky to ignore. > Instead, this commit just tries to set the correct address family's DSCP > option. > > Signed-off-by: Ben Pfaff <b...@nicira.com> > --- > I'd like to credit whoever reported this bug, but I don't remember who it > is. Can someone remind me? > > lib/socket-util.c | 44 ++++++++++++++++++++------------------------ > lib/socket-util.h | 4 ++-- > 2 files changed, 22 insertions(+), 26 deletions(-) > > diff --git a/lib/socket-util.c b/lib/socket-util.c > index 8949da7..206e17b 100644 > --- a/lib/socket-util.c > +++ b/lib/socket-util.c > @@ -1,5 +1,5 @@ > /* > - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc. > + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, > Inc. > * > * Licensed under the Apache License, Version 2.0 (the "License"); > * you may not use this file except in compliance with the License. > @@ -101,11 +101,14 @@ setsockopt_tcp_nodelay(int fd) > } > } > > +/* Sets the DSCP value of socket 'fd' to 'dscp', which must be 63 or less. > + * 'family' must indicate the socket's address family (AF_INET or > AF_INET6, to > + * do anything useful). */ > int > -set_dscp(int fd, uint8_t dscp) > +set_dscp(int fd, int family, uint8_t dscp) > { > + int retval; > int val; > - bool success; > > #ifdef _WIN32 > /* XXX: Consider using QoS2 APIs for Windows to set dscp. */ > @@ -115,29 +118,22 @@ set_dscp(int fd, uint8_t dscp) > if (dscp > 63) { > return EINVAL; > } > - > - /* Note: this function is used for both of IPv4 and IPv6 sockets */ > - success = false; > val = dscp << 2; > - if (setsockopt(fd, IPPROTO_IP, IP_TOS, &val, sizeof val)) { > - if (sock_errno() != ENOPROTOOPT) { > - return sock_errno(); > - } > - } else { > - success = true; > - } > - if (setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &val, sizeof val)) { > - if (sock_errno() != ENOPROTOOPT) { > - return sock_errno(); > - } > - } else { > - success = true; > - } > - if (!success) { > + > + switch (family) { > + case AF_INET: > + retval = setsockopt(fd, IPPROTO_IP, IP_TOS, &val, sizeof val); > + break; > + > + case AF_INET6: > + retval = setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &val, sizeof > val); > + break; > + > + default: > return ENOPROTOOPT; > } > > - return 0; > + return retval ? sock_errno() : 0; > } > > /* Translates 'host_name', which must be a string representation of an IP > @@ -470,7 +466,7 @@ inet_open_active(int style, const char *target, > uint16_t default_port, > /* 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); > + error = set_dscp(fd, ss.ss_family, dscp); > if (error) { > VLOG_ERR("%s: set_dscp: %s", target, sock_strerror(error)); > goto exit; > @@ -611,7 +607,7 @@ inet_open_passive(int style, const char *target, int > default_port, > /* 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); > + error = set_dscp(fd, ss.ss_family, dscp); > if (error) { > VLOG_ERR("%s: set_dscp: %s", target, sock_strerror(error)); > goto error; > diff --git a/lib/socket-util.h b/lib/socket-util.h > index 5b94f20..1178fb8 100644 > --- a/lib/socket-util.h > +++ b/lib/socket-util.h > @@ -1,5 +1,5 @@ > /* > - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc. > + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, > Inc. > * > * Licensed under the Apache License, Version 2.0 (the "License"); > * you may not use this file except in compliance with the License. > @@ -30,7 +30,7 @@ > int set_nonblocking(int fd); > void xset_nonblocking(int fd); > void setsockopt_tcp_nodelay(int fd); > -int set_dscp(int fd, uint8_t dscp); > +int set_dscp(int fd, int family, uint8_t dscp); > > int lookup_ip(const char *host_name, struct in_addr *address); > int lookup_ipv6(const char *host_name, struct in6_addr *address); > -- > 2.1.3 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev