[ovs-dev] [PATCH] socket-util: Fix set_dscp for IPv6

YAMAMOTO Takashi yamamoto at valinux.co.jp
Mon Feb 24 02:46:59 UTC 2014


Try IPPROTO_IPV6/IPV6_TCLASS socket option as well as IPPROTO_IP/IP_TOS
so that this can work for IPv6 sockets.

IPPROTO_IP/IP_TOS socket option is, as it's SOL indicates, for IPv4.
What happens when it's used for IPv6 sockets?  On Linux, it seems to
be forwarded to IPv4 code and affects IPv4 part of the socket.
(e.g. non-V6ONLY case)  But it doesn't seem to be the intention of
this function.  On other platforms including NetBSD, it just fails
with ENOPROTOOPT.

Probably this function should take the address family but passing
it around lib/*stream*.c would be a bigger change.

Cc: Arun Sharma <arun.sharma at calsoftinc.com>
Signed-off-by: YAMAMOTO Takashi <yamamoto at valinux.co.jp>
---
 lib/socket-util.c         | 19 ++++++++++++++++++-
 python/ovs/socket_util.py | 15 ++++++++++++++-
 2 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/lib/socket-util.c b/lib/socket-util.c
index 810a142..760f3a6 100644
--- a/lib/socket-util.c
+++ b/lib/socket-util.c
@@ -108,14 +108,31 @@ int
 set_dscp(int fd, uint8_t dscp)
 {
     int val;
+    bool success;
 
     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)) {
-        return sock_errno();
+        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) {
+        return ENOPROTOOPT;
     }
 
     return 0;
diff --git a/python/ovs/socket_util.py b/python/ovs/socket_util.py
index be9fc95..8d34b71 100644
--- a/python/ovs/socket_util.py
+++ b/python/ovs/socket_util.py
@@ -295,5 +295,18 @@ def set_nonblocking(sock):
 def set_dscp(sock, dscp):
     if dscp > 63:
         raise ValueError("Invalid dscp %d" % dscp)
+
+    # Note: this function is used for both of IPv4 and IPv6 sockets
+    success = False
     val = dscp << 2
-    sock.setsockopt(socket.IPPROTO_IP, socket.IP_TOS, val)
+    try:
+        sock.setsockopt(socket.IPPROTO_IP, socket.IP_TOS, val)
+    except socket.error, e:
+        if e.errno != errno.ENOPROTOOPT:
+            raise
+    success = True
+    try:
+        sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_TCLASS, val)
+    except socket.error, e:
+        if e.errno != errno.ENOPROTOOPT or not success:
+            raise
-- 
1.8.3.1




More information about the dev mailing list