Add the support of IPv6 in the sunrpc (authentication changes done in next patch).

Signed-off-by: Gilles Quillard <gilles.quillard@bull.net>
---

diff -Nru linux-2.6.9-cel5/include/linux/sunrpc/svc.h linux-2.6.9-cel5-gq-01/include/linux/sunrpc/svc.h
--- linux-2.6.9-cel5/include/linux/sunrpc/svc.h	2004-12-13 14:36:31.000000000 +0100
+++ linux-2.6.9-cel5-gq-01/include/linux/sunrpc/svc.h	2005-01-21 17:04:43.000000000 +0100
@@ -10,7 +10,7 @@
 #ifndef SUNRPC_SVC_H
 #define SUNRPC_SVC_H
 
-#include <linux/in.h>
+#include <linux/in6.h>
 #include <linux/sunrpc/types.h>
 #include <linux/sunrpc/xdr.h>
 #include <linux/sunrpc/svcauth.h>
@@ -111,7 +111,7 @@
 struct svc_rqst {
 	struct list_head	rq_list;	/* idle list */
 	struct svc_sock *	rq_sock;	/* socket */
-	struct sockaddr_in	rq_addr;	/* peer address */
+	struct sockaddr_in6	rq_addr;	/* peer address */
 	int			rq_addrlen;
 
 	struct svc_serv *	rq_server;	/* RPC service definition */
@@ -139,7 +139,7 @@
 				rq_secure  : 1;	/* secure port */
 
 
-	__u32			rq_daddr;	/* dest addr of request - reply from here */
+	struct in6_addr	       	rq_daddr;	/* dest addr of request - reply from here */
 
 	void *			rq_argp;	/* decoded arguments */
 	void *			rq_resp;	/* xdr'd results */
@@ -232,7 +232,7 @@
 
 struct svc_deferred_req {
 	u32			prot;	/* protocol (UDP or TCP) */
-	struct sockaddr_in	addr;
+	struct sockaddr_in6	addr;
 	struct svc_sock		*svsk;	/* where reply must go */
 	struct cache_deferred_req handle;
 	int			argslen;
diff -Nru linux-2.6.9-cel5/include/linux/sunrpc/xprt.h linux-2.6.9-cel5-gq-01/include/linux/sunrpc/xprt.h
--- linux-2.6.9-cel5/include/linux/sunrpc/xprt.h	2005-01-21 17:09:06.000000000 +0100
+++ linux-2.6.9-cel5-gq-01/include/linux/sunrpc/xprt.h	2005-01-21 17:04:43.000000000 +0100
@@ -204,6 +204,8 @@
 struct rpc_xprt *	xprt_create_transport(int proto,
 					struct sockaddr *addr, size_t size,
 					struct rpc_timeout *toparms);
+struct rpc_xprt *	xprt_create_proto2(int proto, struct sockaddr *addr,
+					struct rpc_timeout *toparms);
 void			xprt_disconnect(struct rpc_xprt *);
 int			xprt_destroy(struct rpc_xprt *);
 void			xprt_set_timeout(struct rpc_timeout *, unsigned int,
@@ -266,6 +268,21 @@
 	return test_and_clear_bit(XPRT_CONNECTED, &xprt->state);
 }
 
+static inline void map_ipaddr_4to6(struct in_addr *addr, struct in6_addr *addr6)
+{
+	addr6->s6_addr32[0] = 0;
+	addr6->s6_addr32[1] = 0;
+	addr6->s6_addr32[2] = htonl(0xffff);
+	addr6->s6_addr32[3] = *(uint32_t *)addr;
+}
+
+static inline void map_sockaddr_4to6(struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
+{
+	sin6->sin6_family = AF_INET6;
+	sin6->sin6_port = sin->sin_port;
+	map_ipaddr_4to6(&sin->sin_addr, &sin6->sin6_addr);
+}
+
 #endif /* __KERNEL__*/
 
 #endif /* _LINUX_SUNRPC_XPRT_H */
diff -Nru linux-2.6.9-cel5/net/sunrpc/pmap_clnt.c linux-2.6.9-cel5-gq-01/net/sunrpc/pmap_clnt.c
--- linux-2.6.9-cel5/net/sunrpc/pmap_clnt.c	2005-01-21 17:09:06.000000000 +0100
+++ linux-2.6.9-cel5-gq-01/net/sunrpc/pmap_clnt.c	2005-01-21 17:04:43.000000000 +0100
@@ -174,8 +174,7 @@
 	dprintk("RPC:       rpc_getport_external(%u.%u.%u.%u, %u, %u, %d)\n",
 			NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot);
 
-	sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(sin->sin_addr.s_addr));
-	pmap_clnt = pmap_create(hostname, sin, prot);
+	pmap_clnt = pmap_create(hostname, &sin, prot);
 	if (IS_ERR(pmap_clnt))
 		return PTR_ERR(pmap_clnt);
 
diff -Nru linux-2.6.9-cel5/net/sunrpc/rpc_pipe.c linux-2.6.9-cel5-gq-01/net/sunrpc/rpc_pipe.c
--- linux-2.6.9-cel5/net/sunrpc/rpc_pipe.c	2004-12-13 14:36:38.000000000 +0100
+++ linux-2.6.9-cel5-gq-01/net/sunrpc/rpc_pipe.c	2005-01-21 17:04:43.000000000 +0100
@@ -23,6 +23,7 @@
 #include <linux/poll.h>
 #include <linux/wait.h>
 #include <linux/seq_file.h>
+#include <linux/in.h>
 
 #include <linux/sunrpc/clnt.h>
 #include <linux/workqueue.h>
@@ -296,14 +297,14 @@
 rpc_show_info(struct seq_file *m, void *v)
 {
 	struct rpc_clnt *clnt = m->private;
-	struct sockaddr_in addr;
+	struct sockaddr_in6 addr;
 
 	seq_printf(m, "RPC server: %s\n", clnt->cl_server);
 	seq_printf(m, "service: %s (%d) version %d\n", clnt->cl_protname,
 			clnt->cl_prog, clnt->cl_vers);
 	rpc_peeraddr(clnt, &addr, sizeof(addr));
-	seq_printf(m, "address: %u.%u.%u.%u\n",
-			NIPQUAD(addr.sin_addr.s_addr));
+	seq_printf(m, "address: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
+		   NIP6(addr.sin6_addr));
 	seq_printf(m, "protocol: %s\n",
 			clnt->cl_xprt->prot == IPPROTO_UDP ? "udp" : "tcp");
 	return 0;
diff -Nru linux-2.6.9-cel5/net/sunrpc/svcsock.c linux-2.6.9-cel5-gq-01/net/sunrpc/svcsock.c
--- linux-2.6.9-cel5/net/sunrpc/svcsock.c	2004-12-13 14:36:38.000000000 +0100
+++ linux-2.6.9-cel5-gq-01/net/sunrpc/svcsock.c	2005-01-21 17:04:43.000000000 +0100
@@ -24,6 +24,7 @@
 #include <linux/fcntl.h>
 #include <linux/net.h>
 #include <linux/in.h>
+#include <linux/ipv6.h>
 #include <linux/inet.h>
 #include <linux/udp.h>
 #include <linux/tcp.h>
@@ -354,7 +355,7 @@
 	int		slen;
 	char 		buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
 	struct cmsghdr *cmh = (struct cmsghdr *)buffer;
-	struct in_pktinfo *pki = (struct in_pktinfo *)CMSG_DATA(cmh);
+	struct in6_pktinfo *pki = (struct in6_pktinfo *)CMSG_DATA(cmh);
 	int		len = 0;
 	int		result;
 	int		size;
@@ -379,8 +380,8 @@
 		cmh->cmsg_len = CMSG_LEN(sizeof(*pki));
 		cmh->cmsg_level = SOL_IP;
 		cmh->cmsg_type = IP_PKTINFO;
-		pki->ipi_ifindex = 0;
-		pki->ipi_spec_dst.s_addr = rqstp->rq_daddr;
+		pki->ipi6_ifindex = 0;
+		memcpy(&pki->ipi6_addr, &rqstp->rq_daddr, sizeof(struct in6_addr));
 
 		if (sock_sendmsg(sock, &msg, 0) < 0)
 			goto out;
@@ -422,9 +423,9 @@
 			len += result;
 	}
 out:
-	dprintk("svc: socket %p sendto([%p %Zu... ], %d) = %d (addr %x)\n",
-			rqstp->rq_sock, xdr->head[0].iov_base, xdr->head[0].iov_len, xdr->len, len,
-		rqstp->rq_addr.sin_addr.s_addr);
+	dprintk("svc: socket %p sendto([%p %Zu... ], %d) = %d (addr %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x)\n",
+	       	rqstp->rq_sock, xdr->head[0].iov_base, xdr->head[0].iov_len, xdr->len, len,
+		NIP6(rqstp->rq_addr.sin6_addr));
 
 	return len;
 }
@@ -602,10 +603,10 @@
 	rqstp->rq_prot        = IPPROTO_UDP;
 
 	/* Get sender address */
-	rqstp->rq_addr.sin_family = AF_INET;
-	rqstp->rq_addr.sin_port = skb->h.uh->source;
-	rqstp->rq_addr.sin_addr.s_addr = skb->nh.iph->saddr;
-	rqstp->rq_daddr = skb->nh.iph->daddr;
+	rqstp->rq_addr.sin6_family = AF_INET6;
+	rqstp->rq_addr.sin6_port = skb->h.uh->source;
+	memcpy(&rqstp->rq_addr.sin6_addr, &skb->nh.ipv6h->saddr, sizeof(struct in6_addr));
+	memcpy(&rqstp->rq_daddr, &skb->nh.ipv6h->daddr, sizeof(struct in6_addr));
 
 	if (skb_is_nonlinear(skb)) {
 		/* we have to copy */
@@ -760,7 +761,7 @@
 static void
 svc_tcp_accept(struct svc_sock *svsk)
 {
-	struct sockaddr_in sin;
+	struct sockaddr_in6 sin;
 	struct svc_serv	*serv = svsk->sk_server;
 	struct socket	*sock = svsk->sk_sock;
 	struct socket	*newsock;
@@ -772,7 +773,7 @@
 	if (!sock)
 		return;
 
-	err = sock_create_lite(PF_INET, SOCK_STREAM, IPPROTO_TCP, &newsock);
+	err = sock_create_lite(PF_INET6, SOCK_STREAM, IPPROTO_TCP, &newsock);
 	if (err) {
 		if (err == -ENOMEM)
 			printk(KERN_WARNING "%s: no more sockets!\n",
@@ -806,15 +807,16 @@
 	 * hosts here, but when we get encription, the IP of the host won't
 	 * tell us anything. For now just warn about unpriv connections.
 	 */
-	if (ntohs(sin.sin_port) >= 1024) {
+	if (ntohs(sin.sin6_port) >= 1024) {
 		dprintk(KERN_WARNING
-			"%s: connect from unprivileged port: %u.%u.%u.%u:%d\n",
-			serv->sv_name, 
-			NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port));
+			"%s: connect from unprivileged port: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x, port %d (0x%x)\n",
+			serv->sv_name, NIP6(sin.sin6_addr),
+			ntohs(sin.sin6_port), ntohs(sin.sin6_port));
 	}
 
-	dprintk("%s: connect from %u.%u.%u.%u:%04x\n", serv->sv_name,
-			NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port));
+	dprintk("%s: connect from %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x, port %d (0x%x)\n",
+		serv->sv_name, NIP6(sin.sin6_addr),
+	       	ntohs(sin.sin6_port), ntohs(sin.sin6_port));
 
 	/* make sure that a write doesn't block forever when
 	 * low on memory
@@ -847,10 +849,9 @@
 					"number of nfsd threads\n",
 						   serv->sv_name);
 				printk(KERN_NOTICE "%s: last TCP connect from "
-					"%u.%u.%u.%u:%d\n",
-					serv->sv_name,
-					NIPQUAD(sin.sin_addr.s_addr),
-					ntohs(sin.sin_port));
+					"%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x, port %d (0x%x)\n",
+					serv->sv_name, NIP6(sin.sin6_addr),
+					ntohs(sin.sin6_port), ntohs(sin.sin6_port));
 			}
 			/*
 			 * Always select the oldest socket. It's not fair,
@@ -1259,7 +1260,7 @@
 		spin_unlock_bh(&serv->sv_lock);
 	}
 
-	rqstp->rq_secure  = ntohs(rqstp->rq_addr.sin_port) < 1024;
+	rqstp->rq_secure  = ntohs(rqstp->rq_addr.sin6_port) < 1024;
 	rqstp->rq_chandle.defer = svc_defer;
 
 	if (serv->sv_stats)
@@ -1388,17 +1389,17 @@
  * Create socket for RPC service.
  */
 static int
-svc_create_socket(struct svc_serv *serv, int protocol, struct sockaddr_in *sin)
+svc_create_socket(struct svc_serv *serv, int protocol, struct sockaddr_in6 *sin)
 {
 	struct svc_sock	*svsk;
 	struct socket	*sock;
 	int		error;
 	int		type;
 
-	dprintk("svc: svc_create_socket(%s, %d, %u.%u.%u.%u:%d)\n",
+	dprintk("svc: svc_create_socket(%s, %d, %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%d)\n",
 				serv->sv_program->pg_name, protocol,
-				NIPQUAD(sin->sin_addr.s_addr),
-				ntohs(sin->sin_port));
+				NIP6(sin->sin6_addr),
+				ntohs(sin->sin6_port));
 
 	if (protocol != IPPROTO_UDP && protocol != IPPROTO_TCP) {
 		printk(KERN_WARNING "svc: only UDP and TCP "
@@ -1407,7 +1408,7 @@
 	}
 	type = (protocol == IPPROTO_UDP)? SOCK_DGRAM : SOCK_STREAM;
 
-	if ((error = sock_create_kern(PF_INET, type, protocol, &sock)) < 0)
+	if ((error = sock_create_kern(PF_INET6, type, protocol, &sock)) < 0)
 		return error;
 
 	if (sin != NULL) {
@@ -1476,13 +1477,13 @@
 int
 svc_makesock(struct svc_serv *serv, int protocol, unsigned short port)
 {
-	struct sockaddr_in	sin;
+    struct sockaddr_in6	sin;
 
-	dprintk("svc: creating socket proto = %d\n", protocol);
-	sin.sin_family      = AF_INET;
-	sin.sin_addr.s_addr = INADDR_ANY;
-	sin.sin_port        = htons(port);
-	return svc_create_socket(serv, protocol, &sin);
+    dprintk("svc: creating socket proto = %d\n", protocol);
+    sin.sin6_family      = AF_INET6;
+    memset(&sin.sin6_addr, 0, sizeof(struct in6_addr));
+    sin.sin6_port        = htons(port);
+    return svc_create_socket(serv, protocol, &sin);
 }
 
 /*
diff -Nru linux-2.6.9-cel5/net/sunrpc/xprtsock.c linux-2.6.9-cel5-gq-01/net/sunrpc/xprtsock.c
--- linux-2.6.9-cel5/net/sunrpc/xprtsock.c	2005-01-21 17:09:06.000000000 +0100
+++ linux-2.6.9-cel5-gq-01/net/sunrpc/xprtsock.c	2005-01-21 17:04:43.000000000 +0100
@@ -1196,15 +1196,15 @@
  */
 static int xs_bindresvport(struct xs_private *priv, struct socket *sock)
 {
-	struct sockaddr_in myaddr = {
-		.sin_family = AF_INET,
+	struct sockaddr_in6 myaddr = {
+		.sin6_family = AF_INET6,
 	};
 	int		err, port;
 
 	/* Were we already bound to a given port? Try to reuse it */
 	port = priv->port;
 	do {
-		myaddr.sin_port = htons(port);
+		myaddr.sin6_port = htons(port);
 		err = sock->ops->bind(sock, (struct sockaddr *) &myaddr,
 						sizeof(myaddr));
 		if (err == 0) {
@@ -1271,7 +1271,7 @@
 	/* Start by resetting any existing state */
 	xs_close(xprt);
 
-	if ((err = sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock)) < 0) {
+	if ((err = sock_create(PF_INET6, SOCK_DGRAM, IPPROTO_UDP, &sock)) < 0) {
 		printk(KERN_ERR "RPC: can't create socket (%d).\n", -err);
 		goto out;
 	}
@@ -1403,7 +1403,7 @@
 	/* Start by resetting any existing state */
 	xs_close(xprt);
 
-	if ((err = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) {
+	if ((err = sock_create(PF_INET6, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) {
 		printk(KERN_ERR "RPC: can't create socket (%d).\n", -err);
 		goto out;
 	}
@@ -1660,7 +1660,7 @@
 {
 	struct xs_private *priv;
 
-	dprintk("RPC:       setting up udp-ipv4 transport...\n");
+	dprintk("RPC:       setting up udp transport...\n");
 
 	xprt->max_reqs = xprt_udp_slot_table_entries;
 
@@ -1760,7 +1760,7 @@
 {
 	struct xs_private *priv;
 
-	dprintk("RPC:       setting up tcp-ipv4 transport...\n");
+	dprintk("RPC:       setting up tcp transport...\n");
 
 	xprt->max_reqs = xprt_tcp_slot_table_entries;
 

