]> err.no Git - linux-2.6/commitdiff
SUNRPC: create an IPv6-savvy mechanism for binding to a reserved port
authorChuck Lever <chuck.lever@oracle.com>
Mon, 6 Aug 2007 15:57:33 +0000 (11:57 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 9 Oct 2007 21:16:10 +0000 (17:16 -0400)
Clone xs_bindresvport into two functions, one that can handle IPv4
addresses, and one that can handle IPv6 addresses.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Cc: Aurelien Charbon <aurelien.charbon@ext.bull.net>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
net/sunrpc/xprtsock.c

index cd7c18b24527cf674c83cf55c184d0644c3595cb..8295ae28391aa765718ded15b8418faa7b9ce52a 100644 (file)
@@ -1261,6 +1261,39 @@ static int xs_bind4(struct sock_xprt *transport, struct socket *sock)
        return err;
 }
 
+static int xs_bind6(struct sock_xprt *transport, struct socket *sock)
+{
+       struct sockaddr_in6 myaddr = {
+               .sin6_family = AF_INET6,
+       };
+       struct sockaddr_in6 *sa;
+       int err;
+       unsigned short port = transport->port;
+
+       if (!transport->xprt.resvport)
+               port = 0;
+       sa = (struct sockaddr_in6 *)&transport->addr;
+       myaddr.sin6_addr = sa->sin6_addr;
+       do {
+               myaddr.sin6_port = htons(port);
+               err = kernel_bind(sock, (struct sockaddr *) &myaddr,
+                                               sizeof(myaddr));
+               if (!transport->xprt.resvport)
+                       break;
+               if (err == 0) {
+                       transport->port = port;
+                       break;
+               }
+               if (port <= xprt_min_resvport)
+                       port = xprt_max_resvport;
+               else
+                       port--;
+       } while (err == -EADDRINUSE && port != transport->port);
+       dprintk("RPC:       xs_bind6 "NIP6_FMT":%u: %s (%d)\n",
+               NIP6(myaddr.sin6_addr), port, err ? "failed" : "ok", err);
+       return err;
+}
+
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 static struct lock_class_key xs_key[2];
 static struct lock_class_key xs_slock_key[2];