public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 000 of 14] knfsd: Assorted nfsd patches for 2.6.20 - prepare for IPv6 and more
@ 2006-12-12 23:58 NeilBrown
  2006-12-12 23:58 ` [PATCH 001 of 14] knfsd: SUNRPC: update internal API: separate pmap register and temp sockets NeilBrown
                   ` (14 more replies)
  0 siblings, 15 replies; 21+ messages in thread
From: NeilBrown @ 2006-12-12 23:58 UTC (permalink / raw)
  To: Andrew Morton; +Cc: nfs, linux-kernel

Following are 14 patches for knfsd that are suitable for inclusion in 2.6.20.
First 13 are from Chuck Lever and make preparations for IPv6 support (I think we've
get them right this time).

Last is from Peter Staubach and fixes and issue with exclusive create
interacting badly with some ACLs.

Thanks,
NeilBrown


 [PATCH 001 of 14] knfsd: SUNRPC: update internal API: separate pmap register and temp sockets
 [PATCH 002 of 14] knfsd: SUNRPC: allow creating an RPC service without registering with portmapper
 [PATCH 003 of 14] knfsd: SUNRPC: Cache remote peer's address in svc_sock.
 [PATCH 004 of 14] knfsd: SUNRPC: Don't set msg_name and msg_namelen when calling sock_recvmsg
 [PATCH 005 of 14] knfsd: SUNRPC: Use sockaddr_storage to store address in svc_deferred_req
 [PATCH 006 of 14] knfsd: SUNRPC: Add a function to format the address in an svc_rqst for printing
 [PATCH 007 of 14] knfsd: SUNRPC: Provide room in svc_rqst for larger addresses
 [PATCH 008 of 14] knfsd: SUNRPC: Make rq_daddr field address-version independent
 [PATCH 009 of 14] knfsd: SUNRPC: teach svc_sendto() to deal with IPv6 addresses
 [PATCH 010 of 14] knfsd: SUNRPC: add a "generic" function to see if the peer uses a secure port
 [PATCH 011 of 14] knfsd: SUNRPC: Support IPv6 addresses in svc_tcp_accept
 [PATCH 012 of 14] knfsd: SUNRPC: support IPv6 addresses in RPC server's UDP receive path
 [PATCH 013 of 14] knfsd: SUNRPC: fix up svc_create_socket() to take a sockaddr struct + length
 [PATCH 014 of 14] knfsd: Don't mess with the 'mode' when storing a exclusive-create cookie.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 001 of 14] knfsd: SUNRPC: update internal API: separate pmap register and temp sockets
  2006-12-12 23:58 [PATCH 000 of 14] knfsd: Assorted nfsd patches for 2.6.20 - prepare for IPv6 and more NeilBrown
@ 2006-12-12 23:58 ` NeilBrown
  2006-12-12 23:58 ` [PATCH 002 of 14] knfsd: SUNRPC: allow creating an RPC service without registering with portmapper NeilBrown
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 21+ messages in thread
From: NeilBrown @ 2006-12-12 23:58 UTC (permalink / raw)
  To: Andrew Morton; +Cc: nfs, linux-kernel


From: Chuck Lever <chuck.lever@oracle.com>
Currently in the RPC server, registering with the local portmapper and
creating "permanent" sockets are tied together.  Expand the internal APIs
to allow these two socket characteristics to be separately specified.

This will be externalized in the next patch.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Cc: Aurelien Charbon <aurelien.charbon@ext.bull.net>
Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./include/linux/sunrpc/svcsock.h |    7 +++++
 ./net/sunrpc/svcsock.c           |   47 ++++++++++++++++++++++-----------------
 2 files changed, 34 insertions(+), 20 deletions(-)

diff .prev/include/linux/sunrpc/svcsock.h ./include/linux/sunrpc/svcsock.h
--- .prev/include/linux/sunrpc/svcsock.h	2006-12-13 10:28:53.000000000 +1100
+++ ./include/linux/sunrpc/svcsock.h	2006-12-13 10:28:59.000000000 +1100
@@ -74,4 +74,11 @@ int		svc_addsock(struct svc_serv *serv,
 			    char *name_return,
 			    int *proto);
 
+/*
+ * svc_makesock socket characteristics
+ */
+#define SVC_SOCK_DEFAULTS	(0U)
+#define SVC_SOCK_ANONYMOUS	(1U << 0)	/* don't register with pmap */
+#define SVC_SOCK_TEMPORARY	(1U << 1)	/* flag socket as temporary */
+
 #endif /* SUNRPC_SVCSOCK_H */

diff .prev/net/sunrpc/svcsock.c ./net/sunrpc/svcsock.c
--- .prev/net/sunrpc/svcsock.c	2006-12-13 10:28:53.000000000 +1100
+++ ./net/sunrpc/svcsock.c	2006-12-13 10:28:59.000000000 +1100
@@ -69,7 +69,7 @@
 
 
 static struct svc_sock *svc_setup_socket(struct svc_serv *, struct socket *,
-					 int *errp, int pmap_reg);
+					 int *, int);
 static void		svc_udp_data_ready(struct sock *, int);
 static int		svc_udp_recvfrom(struct svc_rqst *);
 static int		svc_udp_sendto(struct svc_rqst *);
@@ -922,7 +922,8 @@ svc_tcp_accept(struct svc_sock *svsk)
 	 */
 	newsock->sk->sk_sndtimeo = HZ*30;
 
-	if (!(newsvsk = svc_setup_socket(serv, newsock, &err, 0)))
+	if (!(newsvsk = svc_setup_socket(serv, newsock, &err,
+				 (SVC_SOCK_ANONYMOUS | SVC_SOCK_TEMPORARY))))
 		goto failed;
 
 
@@ -1456,12 +1457,14 @@ svc_age_temp_sockets(unsigned long closu
  * Initialize socket for RPC use and create svc_sock struct
  * XXX: May want to setsockopt SO_SNDBUF and SO_RCVBUF.
  */
-static struct svc_sock *
-svc_setup_socket(struct svc_serv *serv, struct socket *sock,
-					int *errp, int pmap_register)
+static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
+						struct socket *sock,
+						int *errp, int flags)
 {
 	struct svc_sock	*svsk;
 	struct sock	*inet;
+	int		pmap_register = !(flags & SVC_SOCK_ANONYMOUS);
+	int		is_temporary = flags & SVC_SOCK_TEMPORARY;
 
 	dprintk("svc: svc_setup_socket %p\n", sock);
 	if (!(svsk = kzalloc(sizeof(*svsk), GFP_KERNEL))) {
@@ -1503,7 +1506,7 @@ svc_setup_socket(struct svc_serv *serv, 
 		svc_tcp_init(svsk);
 
 	spin_lock_bh(&serv->sv_lock);
-	if (!pmap_register) {
+	if (is_temporary) {
 		set_bit(SK_TEMP, &svsk->sk_flags);
 		list_add(&svsk->sk_list, &serv->sv_tempsocks);
 		serv->sv_tmpcnt++;
@@ -1547,7 +1550,7 @@ int svc_addsock(struct svc_serv *serv,
 	else if (so->state > SS_UNCONNECTED)
 		err = -EISCONN;
 	else {
-		svsk = svc_setup_socket(serv, so, &err, 1);
+		svsk = svc_setup_socket(serv, so, &err, SVC_SOCK_DEFAULTS);
 		if (svsk)
 			err = 0;
 	}
@@ -1563,8 +1566,8 @@ EXPORT_SYMBOL_GPL(svc_addsock);
 /*
  * Create socket for RPC service.
  */
-static int
-svc_create_socket(struct svc_serv *serv, int protocol, struct sockaddr_in *sin)
+static int svc_create_socket(struct svc_serv *serv, int protocol,
+				struct sockaddr_in *sin, int flags)
 {
 	struct svc_sock	*svsk;
 	struct socket	*sock;
@@ -1600,8 +1603,8 @@ svc_create_socket(struct svc_serv *serv,
 			goto bummer;
 	}
 
-	if ((svsk = svc_setup_socket(serv, sock, &error, 1)) != NULL)
-		return 0;
+	if ((svsk = svc_setup_socket(serv, sock, &error, flags)) != NULL)
+		return ntohs(inet_sk(svsk->sk_sk)->sport);
 
 bummer:
 	dprintk("svc: svc_create_socket error = %d\n", -error);
@@ -1651,19 +1654,23 @@ svc_delete_socket(struct svc_sock *svsk)
 	svc_sock_put(svsk);
 }
 
-/*
- * Make a socket for nfsd and lockd
+/**
+ * svc_makesock - Make a socket for nfsd and lockd
+ * @serv: RPC server structure
+ * @protocol: transport protocol to use
+ * @port: port to use
+ *
  */
-int
-svc_makesock(struct svc_serv *serv, int protocol, unsigned short port)
+int svc_makesock(struct svc_serv *serv, int protocol, unsigned short port)
 {
-	struct sockaddr_in	sin;
+	struct sockaddr_in sin = {
+		.sin_family		= AF_INET,
+		.sin_addr.s_addr	= INADDR_ANY,
+		.sin_port		= htons(port),
+	};
 
 	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);
+	return svc_create_socket(serv, protocol, &sin, SVC_SOCK_DEFAULTS);
 }
 
 /*

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 002 of 14] knfsd: SUNRPC: allow creating an RPC service without registering with portmapper
  2006-12-12 23:58 [PATCH 000 of 14] knfsd: Assorted nfsd patches for 2.6.20 - prepare for IPv6 and more NeilBrown
  2006-12-12 23:58 ` [PATCH 001 of 14] knfsd: SUNRPC: update internal API: separate pmap register and temp sockets NeilBrown
@ 2006-12-12 23:58 ` NeilBrown
  2006-12-12 23:58 ` [PATCH 003 of 14] knfsd: SUNRPC: Cache remote peer's address in svc_sock NeilBrown
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 21+ messages in thread
From: NeilBrown @ 2006-12-12 23:58 UTC (permalink / raw)
  To: Andrew Morton; +Cc: nfs, linux-kernel


From: Chuck Lever <chuck.lever@oracle.com>
Sometimes we need to create an RPC service but not register it with the
local portmapper.  NFSv4 delegation callback, for example.

Change the svc_makesock() API to allow optionally creating temporary or
permanent sockets, optionally registering with the local portmapper, and
make it return the ephemeral port of the new socket.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Cc: Aurelien Charbon <aurelien.charbon@ext.bull.net>
Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./fs/lockd/svc.c                 |   26 ++++++++++++++++----------
 ./fs/nfs/callback.c              |   20 +++++++++-----------
 ./fs/nfsd/nfssvc.c               |    6 ++++--
 ./include/linux/sunrpc/svcsock.h |    2 +-
 ./net/sunrpc/svcsock.c           |    6 ++++--
 5 files changed, 34 insertions(+), 26 deletions(-)

diff .prev/fs/lockd/svc.c ./fs/lockd/svc.c
--- .prev/fs/lockd/svc.c	2006-12-13 10:28:52.000000000 +1100
+++ ./fs/lockd/svc.c	2006-12-13 10:29:09.000000000 +1100
@@ -223,23 +223,29 @@ static int find_socket(struct svc_serv *
 	return found;
 }
 
+/*
+ * Make any sockets that are needed but not present.
+ * If nlm_udpport or nlm_tcpport were set as module
+ * options, make those sockets unconditionally
+ */
 static int make_socks(struct svc_serv *serv, int proto)
 {
-	/* Make any sockets that are needed but not present.
-	 * If nlm_udpport or nlm_tcpport were set as module
-	 * options, make those sockets unconditionally
-	 */
-	static int		warned;
+	static int warned;
 	int err = 0;
+
 	if (proto == IPPROTO_UDP || nlm_udpport)
 		if (!find_socket(serv, IPPROTO_UDP))
-			err = svc_makesock(serv, IPPROTO_UDP, nlm_udpport);
-	if (err == 0 && (proto == IPPROTO_TCP || nlm_tcpport))
+			err = svc_makesock(serv, IPPROTO_UDP, nlm_udpport,
+						SVC_SOCK_DEFAULTS);
+	if (err >= 0 && (proto == IPPROTO_TCP || nlm_tcpport))
 		if (!find_socket(serv, IPPROTO_TCP))
-			err= svc_makesock(serv, IPPROTO_TCP, nlm_tcpport);
-	if (!err)
+			err = svc_makesock(serv, IPPROTO_TCP, nlm_tcpport,
+						SVC_SOCK_DEFAULTS);
+
+	if (err >= 0) {
 		warned = 0;
-	else if (warned++ == 0)
+		err = 0;
+	} else if (warned++ == 0)
 		printk(KERN_WARNING
 		       "lockd_up: makesock failed, error=%d\n", err);
 	return err;

diff .prev/fs/nfs/callback.c ./fs/nfs/callback.c
--- .prev/fs/nfs/callback.c	2006-12-13 10:28:52.000000000 +1100
+++ ./fs/nfs/callback.c	2006-12-13 10:29:09.000000000 +1100
@@ -106,7 +106,6 @@ static void nfs_callback_svc(struct svc_
 int nfs_callback_up(void)
 {
 	struct svc_serv *serv;
-	struct svc_sock *svsk;
 	int ret = 0;
 
 	lock_kernel();
@@ -119,17 +118,14 @@ int nfs_callback_up(void)
 	ret = -ENOMEM;
 	if (!serv)
 		goto out_err;
-	/* FIXME: We don't want to register this socket with the portmapper */
-	ret = svc_makesock(serv, IPPROTO_TCP, nfs_callback_set_tcpport);
-	if (ret < 0)
+
+	ret = svc_makesock(serv, IPPROTO_TCP, nfs_callback_set_tcpport,
+							SVC_SOCK_ANONYMOUS);
+	if (ret <= 0)
 		goto out_destroy;
-	if (!list_empty(&serv->sv_permsocks)) {
-		svsk = list_entry(serv->sv_permsocks.next,
-				struct svc_sock, sk_list);
-		nfs_callback_tcpport = ntohs(inet_sk(svsk->sk_sk)->sport);
-		dprintk ("Callback port = 0x%x\n", nfs_callback_tcpport);
-	} else
-		BUG();
+	nfs_callback_tcpport = ret;
+	dprintk("Callback port = 0x%x\n", nfs_callback_tcpport);
+
 	ret = svc_create_thread(nfs_callback_svc, serv);
 	if (ret < 0)
 		goto out_destroy;
@@ -140,6 +136,8 @@ out:
 	unlock_kernel();
 	return ret;
 out_destroy:
+	dprintk("Couldn't create callback socket or server thread; err = %d\n",
+		ret);
 	svc_destroy(serv);
 out_err:
 	nfs_callback_info.users--;

diff .prev/fs/nfsd/nfssvc.c ./fs/nfsd/nfssvc.c
--- .prev/fs/nfsd/nfssvc.c	2006-12-13 10:28:52.000000000 +1100
+++ ./fs/nfsd/nfssvc.c	2006-12-13 10:29:09.000000000 +1100
@@ -235,7 +235,8 @@ static int nfsd_init_socks(int port)
 
 	error = lockd_up(IPPROTO_UDP);
 	if (error >= 0) {
-		error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
+		error = svc_makesock(nfsd_serv, IPPROTO_UDP, port,
+					SVC_SOCK_DEFAULTS);
 		if (error < 0)
 			lockd_down();
 	}
@@ -245,7 +246,8 @@ static int nfsd_init_socks(int port)
 #ifdef CONFIG_NFSD_TCP
 	error = lockd_up(IPPROTO_TCP);
 	if (error >= 0) {
-		error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
+		error = svc_makesock(nfsd_serv, IPPROTO_TCP, port,
+					SVC_SOCK_DEFAULTS);
 		if (error < 0)
 			lockd_down();
 	}

diff .prev/include/linux/sunrpc/svcsock.h ./include/linux/sunrpc/svcsock.h
--- .prev/include/linux/sunrpc/svcsock.h	2006-12-13 10:28:59.000000000 +1100
+++ ./include/linux/sunrpc/svcsock.h	2006-12-13 10:29:09.000000000 +1100
@@ -62,7 +62,7 @@ struct svc_sock {
 /*
  * Function prototypes.
  */
-int		svc_makesock(struct svc_serv *, int, unsigned short);
+int		svc_makesock(struct svc_serv *, int, unsigned short, int flags);
 void		svc_delete_socket(struct svc_sock *);
 int		svc_recv(struct svc_rqst *, long);
 int		svc_send(struct svc_rqst *);

diff .prev/net/sunrpc/svcsock.c ./net/sunrpc/svcsock.c
--- .prev/net/sunrpc/svcsock.c	2006-12-13 10:28:59.000000000 +1100
+++ ./net/sunrpc/svcsock.c	2006-12-13 10:29:09.000000000 +1100
@@ -1659,9 +1659,11 @@ svc_delete_socket(struct svc_sock *svsk)
  * @serv: RPC server structure
  * @protocol: transport protocol to use
  * @port: port to use
+ * @flags: requested socket characteristics
  *
  */
-int svc_makesock(struct svc_serv *serv, int protocol, unsigned short port)
+int svc_makesock(struct svc_serv *serv, int protocol, unsigned short port,
+			int flags)
 {
 	struct sockaddr_in sin = {
 		.sin_family		= AF_INET,
@@ -1670,7 +1672,7 @@ int svc_makesock(struct svc_serv *serv, 
 	};
 
 	dprintk("svc: creating socket proto = %d\n", protocol);
-	return svc_create_socket(serv, protocol, &sin, SVC_SOCK_DEFAULTS);
+	return svc_create_socket(serv, protocol, &sin, flags);
 }
 
 /*

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 003 of 14] knfsd: SUNRPC: Cache remote peer's address in svc_sock.
  2006-12-12 23:58 [PATCH 000 of 14] knfsd: Assorted nfsd patches for 2.6.20 - prepare for IPv6 and more NeilBrown
  2006-12-12 23:58 ` [PATCH 001 of 14] knfsd: SUNRPC: update internal API: separate pmap register and temp sockets NeilBrown
  2006-12-12 23:58 ` [PATCH 002 of 14] knfsd: SUNRPC: allow creating an RPC service without registering with portmapper NeilBrown
@ 2006-12-12 23:58 ` NeilBrown
  2006-12-12 23:58 ` [PATCH 004 of 14] knfsd: SUNRPC: Don't set msg_name and msg_namelen when calling sock_recvmsg NeilBrown
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 21+ messages in thread
From: NeilBrown @ 2006-12-12 23:58 UTC (permalink / raw)
  To: Andrew Morton; +Cc: nfs, linux-kernel


From: Chuck Lever <chuck.lever@oracle.com>
The remote peer's address won't change after the socket has been
accepted.  We don't need to call ->getname on every incoming request.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Cc: Aurelien Charbon <aurelien.charbon@ext.bull.net>
Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./include/linux/sunrpc/svcsock.h |    3 +++
 ./net/sunrpc/svcsock.c           |   11 +++++------
 2 files changed, 8 insertions(+), 6 deletions(-)

diff .prev/include/linux/sunrpc/svcsock.h ./include/linux/sunrpc/svcsock.h
--- .prev/include/linux/sunrpc/svcsock.h	2006-12-13 10:29:09.000000000 +1100
+++ ./include/linux/sunrpc/svcsock.h	2006-12-13 10:29:13.000000000 +1100
@@ -57,6 +57,9 @@ struct svc_sock {
 
 	/* cache of various info for TCP sockets */
 	void			*sk_info_authunix;
+
+	struct sockaddr_storage	sk_remote;	/* remote peer's address */
+	int			sk_remotelen;	/* length of address */
 };
 
 /*

diff .prev/net/sunrpc/svcsock.c ./net/sunrpc/svcsock.c
--- .prev/net/sunrpc/svcsock.c	2006-12-13 10:29:09.000000000 +1100
+++ ./net/sunrpc/svcsock.c	2006-12-13 10:29:13.000000000 +1100
@@ -577,11 +577,9 @@ svc_recvfrom(struct svc_rqst *rqstp, str
 	len = kernel_recvmsg(sock, &msg, iov, nr, buflen, MSG_DONTWAIT);
 
 	/* sock_recvmsg doesn't fill in the name/namelen, so we must..
-	 * possibly we should cache this in the svc_sock structure
-	 * at accept time. FIXME
 	 */
-	alen = sizeof(rqstp->rq_addr);
-	kernel_getpeername(sock, (struct sockaddr *)&rqstp->rq_addr, &alen);
+	memcpy(&rqstp->rq_addr, &svsk->sk_remote, svsk->sk_remotelen);
+	rqstp->rq_addrlen = svsk->sk_remotelen;
 
 	dprintk("svc: socket %p recvfrom(%p, %Zu) = %d\n",
 		rqstp->rq_sock, iov[0].iov_base, iov[0].iov_len, len);
@@ -873,7 +871,7 @@ svc_tcp_accept(struct svc_sock *svsk)
 	struct socket	*sock = svsk->sk_sock;
 	struct socket	*newsock;
 	struct svc_sock	*newsvsk;
-	int		err, slen;
+	int		err, slen = 0;
 
 	dprintk("svc: tcp_accept %p sock %p\n", svsk, sock);
 	if (!sock)
@@ -925,7 +923,8 @@ svc_tcp_accept(struct svc_sock *svsk)
 	if (!(newsvsk = svc_setup_socket(serv, newsock, &err,
 				 (SVC_SOCK_ANONYMOUS | SVC_SOCK_TEMPORARY))))
 		goto failed;
-
+	memcpy(&newsvsk->sk_remote, &sin, slen);
+	newsvsk->sk_remotelen = slen;
 
 	/* make sure that we don't have too many active connections.
 	 * If we have, something must be dropped.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 004 of 14] knfsd: SUNRPC: Don't set msg_name and msg_namelen when calling sock_recvmsg
  2006-12-12 23:58 [PATCH 000 of 14] knfsd: Assorted nfsd patches for 2.6.20 - prepare for IPv6 and more NeilBrown
                   ` (2 preceding siblings ...)
  2006-12-12 23:58 ` [PATCH 003 of 14] knfsd: SUNRPC: Cache remote peer's address in svc_sock NeilBrown
@ 2006-12-12 23:58 ` NeilBrown
  2006-12-12 23:58 ` [PATCH 005 of 14] knfsd: SUNRPC: Use sockaddr_storage to store address in svc_deferred_req NeilBrown
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 21+ messages in thread
From: NeilBrown @ 2006-12-12 23:58 UTC (permalink / raw)
  To: Andrew Morton; +Cc: nfs, linux-kernel


From: Chuck Lever <chuck.lever@oracle.com>
Clean-up: msg_name and msg_namelen are not used by sock_recvmsg, so
don't bother to set them in svc_recvfrom.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./net/sunrpc/svcsock.c |   23 ++++++++---------------
 1 file changed, 8 insertions(+), 15 deletions(-)

diff .prev/net/sunrpc/svcsock.c ./net/sunrpc/svcsock.c
--- .prev/net/sunrpc/svcsock.c	2006-12-13 10:29:13.000000000 +1100
+++ ./net/sunrpc/svcsock.c	2006-12-13 10:29:15.000000000 +1100
@@ -560,21 +560,14 @@ svc_recv_available(struct svc_sock *svsk
 static int
 svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr, int buflen)
 {
-	struct msghdr	msg;
-	struct socket	*sock;
-	int		len, alen;
-
-	rqstp->rq_addrlen = sizeof(rqstp->rq_addr);
-	sock = rqstp->rq_sock->sk_sock;
-
-	msg.msg_name    = &rqstp->rq_addr;
-	msg.msg_namelen = sizeof(rqstp->rq_addr);
-	msg.msg_control = NULL;
-	msg.msg_controllen = 0;
-
-	msg.msg_flags	= MSG_DONTWAIT;
+	struct svc_sock	*svsk = rqstp->rq_sock;
+	struct msghdr msg = {
+		.msg_flags	= MSG_DONTWAIT,
+	};
+	int len;
 
-	len = kernel_recvmsg(sock, &msg, iov, nr, buflen, MSG_DONTWAIT);
+	len = kernel_recvmsg(svsk->sk_sock, &msg, iov, nr, buflen,
+				msg.msg_flags);
 
 	/* sock_recvmsg doesn't fill in the name/namelen, so we must..
 	 */
@@ -582,7 +575,7 @@ svc_recvfrom(struct svc_rqst *rqstp, str
 	rqstp->rq_addrlen = svsk->sk_remotelen;
 
 	dprintk("svc: socket %p recvfrom(%p, %Zu) = %d\n",
-		rqstp->rq_sock, iov[0].iov_base, iov[0].iov_len, len);
+		svsk, iov[0].iov_base, iov[0].iov_len, len);
 
 	return len;
 }

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 005 of 14] knfsd: SUNRPC: Use sockaddr_storage to store address in svc_deferred_req
  2006-12-12 23:58 [PATCH 000 of 14] knfsd: Assorted nfsd patches for 2.6.20 - prepare for IPv6 and more NeilBrown
                   ` (3 preceding siblings ...)
  2006-12-12 23:58 ` [PATCH 004 of 14] knfsd: SUNRPC: Don't set msg_name and msg_namelen when calling sock_recvmsg NeilBrown
@ 2006-12-12 23:58 ` NeilBrown
  2006-12-12 23:59 ` [PATCH 006 of 14] knfsd: SUNRPC: Add a function to format the address in an svc_rqst for printing NeilBrown
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 21+ messages in thread
From: NeilBrown @ 2006-12-12 23:58 UTC (permalink / raw)
  To: Andrew Morton; +Cc: nfs, linux-kernel


From: Chuck Lever <chuck.lever@oracle.com>
Sockaddr_storage will allow us to store arbitrary socket addresses in
the svc_deferred_req struct.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Cc: Aurelien Charbon <aurelien.charbon@ext.bull.net>
Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./include/linux/sunrpc/svc.h |    3 ++-
 ./net/sunrpc/svcsock.c       |    6 ++++--
 2 files changed, 6 insertions(+), 3 deletions(-)

diff .prev/include/linux/sunrpc/svc.h ./include/linux/sunrpc/svc.h
--- .prev/include/linux/sunrpc/svc.h	2006-12-13 10:28:52.000000000 +1100
+++ ./include/linux/sunrpc/svc.h	2006-12-13 10:29:18.000000000 +1100
@@ -289,7 +289,8 @@ static inline void svc_free_res_pages(st
 
 struct svc_deferred_req {
 	u32			prot;	/* protocol (UDP or TCP) */
-	struct sockaddr_in	addr;
+	struct sockaddr_storage	addr;
+	int			addrlen;
 	struct svc_sock		*svsk;	/* where reply must go */
 	__be32			daddr;	/* where reply must come from */
 	struct cache_deferred_req handle;

diff .prev/net/sunrpc/svcsock.c ./net/sunrpc/svcsock.c
--- .prev/net/sunrpc/svcsock.c	2006-12-13 10:29:15.000000000 +1100
+++ ./net/sunrpc/svcsock.c	2006-12-13 10:29:18.000000000 +1100
@@ -1713,7 +1713,8 @@ svc_defer(struct cache_req *req)
 
 		dr->handle.owner = rqstp->rq_server;
 		dr->prot = rqstp->rq_prot;
-		dr->addr = rqstp->rq_addr;
+		memcpy(&dr->addr, &rqstp->rq_addr, rqstp->rq_addrlen);
+		dr->addrlen = rqstp->rq_addrlen;
 		dr->daddr = rqstp->rq_daddr;
 		dr->argslen = rqstp->rq_arg.len >> 2;
 		memcpy(dr->args, rqstp->rq_arg.head[0].iov_base-skip, dr->argslen<<2);
@@ -1737,7 +1738,8 @@ static int svc_deferred_recv(struct svc_
 	rqstp->rq_arg.page_len = 0;
 	rqstp->rq_arg.len = dr->argslen<<2;
 	rqstp->rq_prot        = dr->prot;
-	rqstp->rq_addr        = dr->addr;
+	memcpy(&rqstp->rq_addr, &dr->addr, dr->addrlen);
+	rqstp->rq_addrlen     = dr->addrlen;
 	rqstp->rq_daddr       = dr->daddr;
 	rqstp->rq_respages    = rqstp->rq_pages;
 	return dr->argslen<<2;

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 006 of 14] knfsd: SUNRPC: Add a function to format the address in an svc_rqst for printing
  2006-12-12 23:58 [PATCH 000 of 14] knfsd: Assorted nfsd patches for 2.6.20 - prepare for IPv6 and more NeilBrown
                   ` (4 preceding siblings ...)
  2006-12-12 23:58 ` [PATCH 005 of 14] knfsd: SUNRPC: Use sockaddr_storage to store address in svc_deferred_req NeilBrown
@ 2006-12-12 23:59 ` NeilBrown
  2006-12-12 23:59 ` [PATCH 007 of 14] knfsd: SUNRPC: Provide room in svc_rqst for larger addresses NeilBrown
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 21+ messages in thread
From: NeilBrown @ 2006-12-12 23:59 UTC (permalink / raw)
  To: Andrew Morton; +Cc: nfs, linux-kernel


From: Chuck Lever <chuck.lever@oracle.com>
There are loads of places where the RPC server assumes that the rq_addr
fields contains an IPv4 address.  Top among these are error and debugging
messages that display the server's IP address.

Let's refactor the address printing into a separate function that's smart
enough to figure out the difference between IPv4 and IPv6 addresses.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Cc: Aurelien Charbon <aurelien.charbon@ext.bull.net>
Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./fs/lockd/svc.c             |    6 +--
 ./fs/lockd/svc4proc.c        |    7 +--
 ./fs/lockd/svcproc.c         |    7 +--
 ./fs/nfs/callback.c          |   12 +++++-
 ./fs/nfsd/nfsfh.c            |    7 ++-
 ./fs/nfsd/nfsproc.c          |    7 ++-
 ./include/linux/sunrpc/svc.h |    3 +
 ./net/sunrpc/svcsock.c       |   76 +++++++++++++++++++++++++++++++------------
 8 files changed, 85 insertions(+), 40 deletions(-)

diff .prev/fs/lockd/svc4proc.c ./fs/lockd/svc4proc.c
--- .prev/fs/lockd/svc4proc.c	2006-12-13 10:28:51.000000000 +1100
+++ ./fs/lockd/svc4proc.c	2006-12-13 10:29:44.000000000 +1100
@@ -426,10 +426,9 @@ nlm4svc_proc_sm_notify(struct svc_rqst *
 	dprintk("lockd: SM_NOTIFY     called\n");
 	if (saddr.sin_addr.s_addr != htonl(INADDR_LOOPBACK)
 	 || ntohs(saddr.sin_port) >= 1024) {
-		printk(KERN_WARNING
-			"lockd: rejected NSM callback from %08x:%d\n",
-			ntohl(rqstp->rq_addr.sin_addr.s_addr),
-			ntohs(rqstp->rq_addr.sin_port));
+		char buf[RPC_MAX_ADDRBUFLEN];
+		printk(KERN_WARNING "lockd: rejected NSM callback from %s\n",
+				svc_print_addr(rqstp, buf, sizeof(buf)));
 		return rpc_system_err;
 	}
 

diff .prev/fs/lockd/svc.c ./fs/lockd/svc.c
--- .prev/fs/lockd/svc.c	2006-12-13 10:29:09.000000000 +1100
+++ ./fs/lockd/svc.c	2006-12-13 10:30:01.000000000 +1100
@@ -141,6 +141,7 @@ lockd(struct svc_rqst *rqstp)
 	 */
 	while ((nlmsvc_users || !signalled()) && nlmsvc_pid == current->pid) {
 		long timeout = MAX_SCHEDULE_TIMEOUT;
+		char buf[RPC_MAX_ADDRBUFLEN];
 
 		if (signalled()) {
 			flush_signals(current);
@@ -175,11 +176,10 @@ lockd(struct svc_rqst *rqstp)
 			break;
 		}
 
-		dprintk("lockd: request from %08x\n",
-			(unsigned)ntohl(rqstp->rq_addr.sin_addr.s_addr));
+		dprintk("lockd: request from %s\n",
+				svc_print_addr(rqstp, buf, sizeof(buf)));
 
 		svc_process(rqstp);
-
 	}
 
 	flush_signals(current);

diff .prev/fs/lockd/svcproc.c ./fs/lockd/svcproc.c
--- .prev/fs/lockd/svcproc.c	2006-12-13 10:28:51.000000000 +1100
+++ ./fs/lockd/svcproc.c	2006-12-13 10:29:21.000000000 +1100
@@ -457,10 +457,9 @@ nlmsvc_proc_sm_notify(struct svc_rqst *r
 	dprintk("lockd: SM_NOTIFY     called\n");
 	if (saddr.sin_addr.s_addr != htonl(INADDR_LOOPBACK)
 	 || ntohs(saddr.sin_port) >= 1024) {
-		printk(KERN_WARNING
-			"lockd: rejected NSM callback from %08x:%d\n",
-			ntohl(rqstp->rq_addr.sin_addr.s_addr),
-			ntohs(rqstp->rq_addr.sin_port));
+		char buf[RPC_MAX_ADDRBUFLEN];
+		printk(KERN_WARNING "lockd: rejected NSM callback from %s\n",
+				svc_print_addr(rqstp, buf, sizeof(buf)));
 		return rpc_system_err;
 	}
 

diff .prev/fs/nfs/callback.c ./fs/nfs/callback.c
--- .prev/fs/nfs/callback.c	2006-12-13 10:29:09.000000000 +1100
+++ ./fs/nfs/callback.c	2006-12-13 10:29:21.000000000 +1100
@@ -71,6 +71,8 @@ static void nfs_callback_svc(struct svc_
 	complete(&nfs_callback_info.started);
 
 	for(;;) {
+		char buf[RPC_MAX_ADDRBUFLEN];
+
 		if (signalled()) {
 			if (nfs_callback_info.users == 0)
 				break;
@@ -88,8 +90,8 @@ static void nfs_callback_svc(struct svc_
 					__FUNCTION__, -err);
 			break;
 		}
-		dprintk("%s: request from %u.%u.%u.%u\n", __FUNCTION__,
-				NIPQUAD(rqstp->rq_addr.sin_addr.s_addr));
+		dprintk("%s: request from %s\n", __FUNCTION__,
+				svc_print_addr(rqstp, buf, sizeof(buf)));
 		svc_process(rqstp);
 	}
 
@@ -166,13 +168,17 @@ static int nfs_callback_authenticate(str
 {
 	struct sockaddr_in *addr = &rqstp->rq_addr;
 	struct nfs_client *clp;
+	char buf[RPC_MAX_ADDRBUFLEN];
 
 	/* Don't talk to strangers */
 	clp = nfs_find_client(addr, 4);
 	if (clp == NULL)
 		return SVC_DROP;
-	dprintk("%s: %u.%u.%u.%u NFSv4 callback!\n", __FUNCTION__, NIPQUAD(addr->sin_addr));
+
+	dprintk("%s: %s NFSv4 callback!\n", __FUNCTION__,
+			svc_print_addr(rqstp, buf, sizeof(buf)));
 	nfs_put_client(clp);
+
 	switch (rqstp->rq_authop->flavour) {
 		case RPC_AUTH_NULL:
 			if (rqstp->rq_proc != CB_NULL)

diff .prev/fs/nfsd/nfsfh.c ./fs/nfsd/nfsfh.c
--- .prev/fs/nfsd/nfsfh.c	2006-12-13 10:28:51.000000000 +1100
+++ ./fs/nfsd/nfsfh.c	2006-12-13 10:30:26.000000000 +1100
@@ -20,6 +20,7 @@
 #include <linux/mount.h>
 #include <asm/pgtable.h>
 
+#include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/nfsd/nfsd.h>
 
@@ -182,10 +183,10 @@ fh_verify(struct svc_rqst *rqstp, struct
 		/* Check if the request originated from a secure port. */
 		error = nfserr_perm;
 		if (!rqstp->rq_secure && EX_SECURE(exp)) {
+			char buf[RPC_MAX_ADDRBUFLEN];
 			printk(KERN_WARNING
-			       "nfsd: request from insecure port (%u.%u.%u.%u:%d)!\n",
-			       NIPQUAD(rqstp->rq_addr.sin_addr.s_addr),
-			       ntohs(rqstp->rq_addr.sin_port));
+			       "nfsd: request from insecure port %s!\n",
+			       svc_print_addr(rqstp, buf, sizeof(buf)));
 			goto out;
 		}
 

diff .prev/fs/nfsd/nfsproc.c ./fs/nfsd/nfsproc.c
--- .prev/fs/nfsd/nfsproc.c	2006-12-13 10:28:51.000000000 +1100
+++ ./fs/nfsd/nfsproc.c	2006-12-13 10:29:21.000000000 +1100
@@ -19,6 +19,7 @@
 #include <linux/unistd.h>
 #include <linux/slab.h>
 
+#include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/nfsd/nfsd.h>
 #include <linux/nfsd/cache.h>
@@ -147,10 +148,10 @@ nfsd_proc_read(struct svc_rqst *rqstp, s
 	 */
 
 	if (NFSSVC_MAXBLKSIZE_V2 < argp->count) {
+		char buf[RPC_MAX_ADDRBUFLEN];
 		printk(KERN_NOTICE
-			"oversized read request from %u.%u.%u.%u:%d (%d bytes)\n",
-				NIPQUAD(rqstp->rq_addr.sin_addr.s_addr),
-				ntohs(rqstp->rq_addr.sin_port),
+			"oversized read request from %s (%d bytes)\n",
+				svc_print_addr(rqstp, buf, sizeof(buf)),
 				argp->count);
 		argp->count = NFSSVC_MAXBLKSIZE_V2;
 	}

diff .prev/include/linux/sunrpc/svc.h ./include/linux/sunrpc/svc.h
--- .prev/include/linux/sunrpc/svc.h	2006-12-13 10:29:18.000000000 +1100
+++ ./include/linux/sunrpc/svc.h	2006-12-13 10:29:21.000000000 +1100
@@ -366,5 +366,8 @@ int		   svc_register(struct svc_serv *, 
 void		   svc_wake_up(struct svc_serv *);
 void		   svc_reserve(struct svc_rqst *rqstp, int space);
 struct svc_pool *  svc_pool_for_cpu(struct svc_serv *serv, int cpu);
+char *		   svc_print_addr(struct svc_rqst *, char *, size_t);
+
+#define	RPC_MAX_ADDRBUFLEN	(63U)
 
 #endif /* SUNRPC_SVC_H */

diff .prev/net/sunrpc/svcsock.c ./net/sunrpc/svcsock.c
--- .prev/net/sunrpc/svcsock.c	2006-12-13 10:29:18.000000000 +1100
+++ ./net/sunrpc/svcsock.c	2006-12-13 10:31:31.000000000 +1100
@@ -41,6 +41,7 @@
 #include <asm/ioctls.h>
 
 #include <linux/sunrpc/types.h>
+#include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/xdr.h>
 #include <linux/sunrpc/svcsock.h>
 #include <linux/sunrpc/stats.h>
@@ -114,6 +115,41 @@ static inline void svc_reclassify_socket
 }
 #endif
 
+static char *__svc_print_addr(struct sockaddr *addr, char *buf, size_t len)
+{
+	switch (addr->sa_family) {
+	case AF_INET:
+		snprintf(buf, len, "%u.%u.%u.%u, port=%u",
+			NIPQUAD(((struct sockaddr_in *) addr)->sin_addr),
+			htons(((struct sockaddr_in *) addr)->sin_port));
+		break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	case AF_INET6:
+		snprintf(buf, len, "%x:%x:%x:%x:%x:%x:%x:%x, port=%u",
+			NIP6(((struct sockaddr_in6 *) addr)->sin6_addr),
+			htons(((struct sockaddr_in6 *) addr)->sin6_port));
+		break;
+#endif
+	default:
+		snprintf(buf, len, "unknown address type");
+		break;
+	}
+	return buf;
+}
+
+/**
+ * svc_print_addr - Format rq_addr field for printing
+ * @rqstp: svc_rqst struct containing address to print
+ * @buf: target buffer for formatted address
+ * @len: length of target buffer
+ *
+ */
+char *svc_print_addr(struct svc_rqst *rqstp, char *buf, size_t len)
+{
+	return __svc_print_addr((struct sockaddr *) &rqstp->rq_addr, buf, len);
+}
+EXPORT_SYMBOL_GPL(svc_print_addr);
+
 /*
  * Queue up an idle server thread.  Must have pool->sp_lock held.
  * Note: this is really a stack rather than a queue, so that we only
@@ -421,6 +457,7 @@ svc_sendto(struct svc_rqst *rqstp, struc
 	size_t		base = xdr->page_base;
 	unsigned int	pglen = xdr->page_len;
 	unsigned int	flags = MSG_MORE;
+	char		buf[RPC_MAX_ADDRBUFLEN];
 
 	slen = xdr->len;
 
@@ -483,9 +520,9 @@ svc_sendto(struct svc_rqst *rqstp, struc
 			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 %s)\n",
+		rqstp->rq_sock, xdr->head[0].iov_base, xdr->head[0].iov_len,
+		xdr->len, len, svc_print_addr(rqstp, buf, sizeof(buf)));
 
 	return len;
 }
@@ -865,6 +902,7 @@ svc_tcp_accept(struct svc_sock *svsk)
 	struct socket	*newsock;
 	struct svc_sock	*newsvsk;
 	int		err, slen = 0;
+	char		buf[RPC_MAX_ADDRBUFLEN];
 
 	dprintk("svc: tcp_accept %p sock %p\n", svsk, sock);
 	if (!sock)
@@ -895,18 +933,17 @@ svc_tcp_accept(struct svc_sock *svsk)
 	}
 
 	/* Ideally, we would want to reject connections from unauthorized
-	 * hosts here, but when we get encription, the IP of the host won't
-	 * tell us anything. For now just warn about unpriv connections.
+	 * hosts here, but when we get encryption, the IP of the host won't
+	 * tell us anything.  For now just warn about unpriv connections.
 	 */
 	if (ntohs(sin.sin_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: %s\n",
+			serv->sv_name,
+			__svc_print_addr((struct sockaddr *) &sin, buf,
+								sizeof(buf)));
 	}
-
-	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 %s\n", serv->sv_name, buf);
 
 	/* make sure that a write doesn't block forever when
 	 * low on memory
@@ -940,11 +977,9 @@ svc_tcp_accept(struct svc_sock *svsk)
 					"sockets, consider increasing the "
 					"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));
+				printk(KERN_NOTICE
+				       "%s: last TCP connect from %s\n",
+				       serv->sv_name, buf);
 			}
 			/*
 			 * Always select the oldest socket. It's not fair,
@@ -1565,11 +1600,12 @@ static int svc_create_socket(struct svc_
 	struct socket	*sock;
 	int		error;
 	int		type;
+	char		buf[RPC_MAX_ADDRBUFLEN];
 
-	dprintk("svc: svc_create_socket(%s, %d, %u.%u.%u.%u:%d)\n",
-				serv->sv_program->pg_name, protocol,
-				NIPQUAD(sin->sin_addr.s_addr),
-				ntohs(sin->sin_port));
+	dprintk("svc: svc_create_socket(%s, %d, %s)\n",
+			serv->sv_program->pg_name, protocol,
+			__svc_print_addr((struct sockaddr *) sin, buf,
+								sizeof(buf)));
 
 	if (protocol != IPPROTO_UDP && protocol != IPPROTO_TCP) {
 		printk(KERN_WARNING "svc: only UDP and TCP "

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 007 of 14] knfsd: SUNRPC: Provide room in svc_rqst for larger addresses
  2006-12-12 23:58 [PATCH 000 of 14] knfsd: Assorted nfsd patches for 2.6.20 - prepare for IPv6 and more NeilBrown
                   ` (5 preceding siblings ...)
  2006-12-12 23:59 ` [PATCH 006 of 14] knfsd: SUNRPC: Add a function to format the address in an svc_rqst for printing NeilBrown
@ 2006-12-12 23:59 ` NeilBrown
  2006-12-15  4:30   ` Andrew Morton
  2006-12-12 23:59 ` [PATCH 008 of 14] knfsd: SUNRPC: Make rq_daddr field address-version independent NeilBrown
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 21+ messages in thread
From: NeilBrown @ 2006-12-12 23:59 UTC (permalink / raw)
  To: Andrew Morton; +Cc: nfs, linux-kernel


From: Chuck Lever <chuck.lever@oracle.com>
Expand the rq_addr field to allow it to contain larger addresses.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Cc: Aurelien Charbon <aurelien.charbon@ext.bull.net>
Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./fs/lockd/host.c            |    2 +-
 ./fs/lockd/svc4proc.c        |    6 ++++--
 ./fs/lockd/svcproc.c         |    6 ++++--
 ./fs/nfs/callback.c          |    2 +-
 ./fs/nfs/callback_xdr.c      |    4 ++--
 ./fs/nfsd/nfs4state.c        |   18 +++++++++---------
 ./fs/nfsd/nfscache.c         |    2 +-
 ./include/linux/sunrpc/svc.h |   15 ++++++++++++++-
 ./net/sunrpc/svcauth_unix.c  |    3 ++-
 ./net/sunrpc/svcsock.c       |   16 +++++++++-------
 10 files changed, 47 insertions(+), 27 deletions(-)

diff .prev/fs/lockd/host.c ./fs/lockd/host.c
--- .prev/fs/lockd/host.c	2006-12-13 10:28:51.000000000 +1100
+++ ./fs/lockd/host.c	2006-12-13 10:31:37.000000000 +1100
@@ -192,7 +192,7 @@ struct nlm_host *
 nlmsvc_lookup_host(struct svc_rqst *rqstp,
 			const char *hostname, int hostname_len)
 {
-	return nlm_lookup_host(1, &rqstp->rq_addr,
+	return nlm_lookup_host(1, svc_addr_in(rqstp),
 			       rqstp->rq_prot, rqstp->rq_vers,
 			       hostname, hostname_len);
 }

diff .prev/fs/lockd/svc4proc.c ./fs/lockd/svc4proc.c
--- .prev/fs/lockd/svc4proc.c	2006-12-13 10:29:44.000000000 +1100
+++ ./fs/lockd/svc4proc.c	2006-12-13 10:31:37.000000000 +1100
@@ -224,7 +224,7 @@ nlm4svc_proc_granted(struct svc_rqst *rq
 	resp->cookie = argp->cookie;
 
 	dprintk("lockd: GRANTED       called\n");
-	resp->status = nlmclnt_grant(&rqstp->rq_addr, &argp->lock);
+	resp->status = nlmclnt_grant(svc_addr_in(rqstp), &argp->lock);
 	dprintk("lockd: GRANTED       status %d\n", ntohl(resp->status));
 	return rpc_success;
 }
@@ -421,7 +421,9 @@ static __be32
 nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
 					      void	        *resp)
 {
-	struct sockaddr_in	saddr = rqstp->rq_addr;
+	struct sockaddr_in	saddr;
+
+	memcpy(&saddr, svc_addr_in(rqstp), sizeof(saddr));
 
 	dprintk("lockd: SM_NOTIFY     called\n");
 	if (saddr.sin_addr.s_addr != htonl(INADDR_LOOPBACK)

diff .prev/fs/lockd/svcproc.c ./fs/lockd/svcproc.c
--- .prev/fs/lockd/svcproc.c	2006-12-13 10:29:21.000000000 +1100
+++ ./fs/lockd/svcproc.c	2006-12-13 10:31:37.000000000 +1100
@@ -253,7 +253,7 @@ nlmsvc_proc_granted(struct svc_rqst *rqs
 	resp->cookie = argp->cookie;
 
 	dprintk("lockd: GRANTED       called\n");
-	resp->status = nlmclnt_grant(&rqstp->rq_addr, &argp->lock);
+	resp->status = nlmclnt_grant(svc_addr_in(rqstp), &argp->lock);
 	dprintk("lockd: GRANTED       status %d\n", ntohl(resp->status));
 	return rpc_success;
 }
@@ -452,7 +452,9 @@ static __be32
 nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
 					      void	        *resp)
 {
-	struct sockaddr_in	saddr = rqstp->rq_addr;
+	struct sockaddr_in	saddr;
+
+	memcpy(&saddr, svc_addr_in(rqstp), sizeof(saddr));
 
 	dprintk("lockd: SM_NOTIFY     called\n");
 	if (saddr.sin_addr.s_addr != htonl(INADDR_LOOPBACK)

diff .prev/fs/nfs/callback.c ./fs/nfs/callback.c
--- .prev/fs/nfs/callback.c	2006-12-13 10:29:21.000000000 +1100
+++ ./fs/nfs/callback.c	2006-12-13 10:31:37.000000000 +1100
@@ -166,7 +166,7 @@ void nfs_callback_down(void)
 
 static int nfs_callback_authenticate(struct svc_rqst *rqstp)
 {
-	struct sockaddr_in *addr = &rqstp->rq_addr;
+	struct sockaddr_in *addr = svc_addr_in(rqstp);
 	struct nfs_client *clp;
 	char buf[RPC_MAX_ADDRBUFLEN];
 

diff .prev/fs/nfs/callback_xdr.c ./fs/nfs/callback_xdr.c
--- .prev/fs/nfs/callback_xdr.c	2006-12-13 10:28:51.000000000 +1100
+++ ./fs/nfs/callback_xdr.c	2006-12-13 10:31:37.000000000 +1100
@@ -176,7 +176,7 @@ static __be32 decode_getattr_args(struct
 	status = decode_fh(xdr, &args->fh);
 	if (unlikely(status != 0))
 		goto out;
-	args->addr = &rqstp->rq_addr;
+	args->addr = svc_addr_in(rqstp);
 	status = decode_bitmap(xdr, args->bitmap);
 out:
 	dprintk("%s: exit with status = %d\n", __FUNCTION__, status);
@@ -188,7 +188,7 @@ static __be32 decode_recall_args(struct 
 	__be32 *p;
 	__be32 status;
 
-	args->addr = &rqstp->rq_addr;
+	args->addr = svc_addr_in(rqstp);
 	status = decode_stateid(xdr, &args->stateid);
 	if (unlikely(status != 0))
 		goto out;

diff .prev/fs/nfsd/nfs4state.c ./fs/nfsd/nfs4state.c
--- .prev/fs/nfsd/nfs4state.c	2006-12-13 10:28:51.000000000 +1100
+++ ./fs/nfsd/nfs4state.c	2006-12-13 10:31:37.000000000 +1100
@@ -714,7 +714,7 @@ __be32
 nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 		  struct nfsd4_setclientid *setclid)
 {
-	__be32 			ip_addr = rqstp->rq_addr.sin_addr.s_addr;
+	struct sockaddr_in	*sin = svc_addr_in(rqstp);
 	struct xdr_netobj 	clname = { 
 		.len = setclid->se_namelen,
 		.data = setclid->se_name,
@@ -749,7 +749,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp
 		 */
 		status = nfserr_clid_inuse;
 		if (!cmp_creds(&conf->cl_cred, &rqstp->rq_cred)
-				|| conf->cl_addr != ip_addr) {
+				|| conf->cl_addr != sin->sin_addr.s_addr) {
 			printk("NFSD: setclientid: string in use by client"
 			"(clientid %08x/%08x)\n",
 			conf->cl_clientid.cl_boot, conf->cl_clientid.cl_id);
@@ -769,7 +769,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp
 		if (new == NULL)
 			goto out;
 		copy_verf(new, &clverifier);
-		new->cl_addr = ip_addr;
+		new->cl_addr = sin->sin_addr.s_addr;
 		copy_cred(&new->cl_cred,&rqstp->rq_cred);
 		gen_clid(new);
 		gen_confirm(new);
@@ -801,7 +801,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp
 		if (new == NULL)
 			goto out;
 		copy_verf(new,&conf->cl_verifier);
-		new->cl_addr = ip_addr;
+		new->cl_addr = sin->sin_addr.s_addr;
 		copy_cred(&new->cl_cred,&rqstp->rq_cred);
 		copy_clid(new, conf);
 		gen_confirm(new);
@@ -820,7 +820,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp
 		if (new == NULL)
 			goto out;
 		copy_verf(new,&clverifier);
-		new->cl_addr = ip_addr;
+		new->cl_addr = sin->sin_addr.s_addr;
 		copy_cred(&new->cl_cred,&rqstp->rq_cred);
 		gen_clid(new);
 		gen_confirm(new);
@@ -847,7 +847,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp
 		if (new == NULL)
 			goto out;
 		copy_verf(new,&clverifier);
-		new->cl_addr = ip_addr;
+		new->cl_addr = sin->sin_addr.s_addr;
 		copy_cred(&new->cl_cred,&rqstp->rq_cred);
 		gen_clid(new);
 		gen_confirm(new);
@@ -881,7 +881,7 @@ nfsd4_setclientid_confirm(struct svc_rqs
 			 struct nfsd4_compound_state *cstate,
 			 struct nfsd4_setclientid_confirm *setclientid_confirm)
 {
-	__be32 ip_addr = rqstp->rq_addr.sin_addr.s_addr;
+	struct sockaddr_in *sin = svc_addr_in(rqstp);
 	struct nfs4_client *conf, *unconf;
 	nfs4_verifier confirm = setclientid_confirm->sc_confirm; 
 	clientid_t * clid = &setclientid_confirm->sc_clientid;
@@ -900,9 +900,9 @@ nfsd4_setclientid_confirm(struct svc_rqs
 	unconf = find_unconfirmed_client(clid);
 
 	status = nfserr_clid_inuse;
-	if (conf && conf->cl_addr != ip_addr)
+	if (conf && conf->cl_addr != sin->sin_addr.s_addr)
 		goto out;
-	if (unconf && unconf->cl_addr != ip_addr)
+	if (unconf && unconf->cl_addr != sin->sin_addr.s_addr)
 		goto out;
 
 	if ((conf && unconf) && 

diff .prev/fs/nfsd/nfscache.c ./fs/nfsd/nfscache.c
--- .prev/fs/nfsd/nfscache.c	2006-12-13 10:28:51.000000000 +1100
+++ ./fs/nfsd/nfscache.c	2006-12-13 10:31:37.000000000 +1100
@@ -186,7 +186,7 @@ nfsd_cache_lookup(struct svc_rqst *rqstp
 	rp->c_state = RC_INPROG;
 	rp->c_xid = xid;
 	rp->c_proc = proc;
-	rp->c_addr = rqstp->rq_addr;
+	memcpy(&rp->c_addr, svc_addr_in(rqstp), sizeof(rp->c_addr));
 	rp->c_prot = proto;
 	rp->c_vers = vers;
 	rp->c_timestamp = jiffies;

diff .prev/include/linux/sunrpc/svc.h ./include/linux/sunrpc/svc.h
--- .prev/include/linux/sunrpc/svc.h	2006-12-13 10:29:21.000000000 +1100
+++ ./include/linux/sunrpc/svc.h	2006-12-13 10:31:37.000000000 +1100
@@ -197,7 +197,7 @@ struct svc_rqst {
 	struct list_head	rq_list;	/* idle list */
 	struct list_head	rq_all;		/* all threads list */
 	struct svc_sock *	rq_sock;	/* socket */
-	struct sockaddr_in	rq_addr;	/* peer address */
+	struct sockaddr_storage	rq_addr;	/* peer address */
 	int			rq_addrlen;
 
 	struct svc_serv *	rq_server;	/* RPC service definition */
@@ -253,6 +253,19 @@ struct svc_rqst {
 };
 
 /*
+ * Rigorous type checking on sockaddr type conversions
+ */
+static inline struct sockaddr_in *svc_addr_in(struct svc_rqst *rqst)
+{
+	return (struct sockaddr_in *) &rqst->rq_addr;
+}
+
+static inline struct sockaddr *svc_addr(struct svc_rqst *rqst)
+{
+	return (struct sockaddr *) &rqst->rq_addr;
+}
+
+/*
  * Check buffer bounds after decoding arguments
  */
 static inline int

diff .prev/net/sunrpc/svcauth_unix.c ./net/sunrpc/svcauth_unix.c
--- .prev/net/sunrpc/svcauth_unix.c	2006-12-13 10:28:51.000000000 +1100
+++ ./net/sunrpc/svcauth_unix.c	2006-12-13 10:31:37.000000000 +1100
@@ -421,6 +421,7 @@ svcauth_unix_info_release(void *info)
 static int
 svcauth_unix_set_client(struct svc_rqst *rqstp)
 {
+	struct sockaddr_in *sin = svc_addr_in(rqstp);
 	struct ip_map *ipm;
 
 	rqstp->rq_client = NULL;
@@ -430,7 +431,7 @@ svcauth_unix_set_client(struct svc_rqst 
 	ipm = ip_map_cached_get(rqstp);
 	if (ipm == NULL)
 		ipm = ip_map_lookup(rqstp->rq_server->sv_program->pg_class,
-				    rqstp->rq_addr.sin_addr);
+				    sin->sin_addr);
 
 	if (ipm == NULL)
 		return SVC_DENIED;

diff .prev/net/sunrpc/svcsock.c ./net/sunrpc/svcsock.c
--- .prev/net/sunrpc/svcsock.c	2006-12-13 10:31:31.000000000 +1100
+++ ./net/sunrpc/svcsock.c	2006-12-13 10:31:37.000000000 +1100
@@ -146,7 +146,7 @@ static char *__svc_print_addr(struct soc
  */
 char *svc_print_addr(struct svc_rqst *rqstp, char *buf, size_t len)
 {
-	return __svc_print_addr((struct sockaddr *) &rqstp->rq_addr, buf, len);
+	return __svc_print_addr(svc_addr(rqstp), buf, len);
 }
 EXPORT_SYMBOL_GPL(svc_print_addr);
 
@@ -465,7 +465,7 @@ svc_sendto(struct svc_rqst *rqstp, struc
 		/* set the source and destination */
 		struct msghdr	msg;
 		msg.msg_name    = &rqstp->rq_addr;
-		msg.msg_namelen = sizeof(rqstp->rq_addr);
+		msg.msg_namelen = rqstp->rq_addrlen;
 		msg.msg_iov     = NULL;
 		msg.msg_iovlen  = 0;
 		msg.msg_flags	= MSG_MORE;
@@ -688,6 +688,7 @@ svc_write_space(struct sock *sk)
 static int
 svc_udp_recvfrom(struct svc_rqst *rqstp)
 {
+	struct sockaddr_in *sin = svc_addr_in(rqstp);
 	struct svc_sock	*svsk = rqstp->rq_sock;
 	struct svc_serv	*serv = svsk->sk_server;
 	struct sk_buff	*skb;
@@ -743,9 +744,9 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
 	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;
+	sin->sin_family = AF_INET;
+	sin->sin_port = skb->h.uh->source;
+	sin->sin_addr.s_addr = skb->nh.iph->saddr;
 	rqstp->rq_daddr = skb->nh.iph->daddr;
 
 	if (skb_is_nonlinear(skb)) {
@@ -1276,7 +1277,8 @@ svc_sock_update_bufs(struct svc_serv *se
 int
 svc_recv(struct svc_rqst *rqstp, long timeout)
 {
-	struct svc_sock		*svsk =NULL;
+	struct svc_sock		*svsk = NULL;
+	struct sockaddr_in	*sin = svc_addr_in(rqstp);
 	struct svc_serv		*serv = rqstp->rq_server;
 	struct svc_pool		*pool = rqstp->rq_pool;
 	int			len, i;
@@ -1371,7 +1373,7 @@ svc_recv(struct svc_rqst *rqstp, long ti
 	svsk->sk_lastrecv = get_seconds();
 	clear_bit(SK_OLD, &svsk->sk_flags);
 
-	rqstp->rq_secure  = ntohs(rqstp->rq_addr.sin_port) < 1024;
+	rqstp->rq_secure = ntohs(sin->sin_port) < 1024;
 	rqstp->rq_chandle.defer = svc_defer;
 
 	if (serv->sv_stats)

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 008 of 14] knfsd: SUNRPC: Make rq_daddr field address-version independent
  2006-12-12 23:58 [PATCH 000 of 14] knfsd: Assorted nfsd patches for 2.6.20 - prepare for IPv6 and more NeilBrown
                   ` (6 preceding siblings ...)
  2006-12-12 23:59 ` [PATCH 007 of 14] knfsd: SUNRPC: Provide room in svc_rqst for larger addresses NeilBrown
@ 2006-12-12 23:59 ` NeilBrown
  2006-12-12 23:59 ` [PATCH 009 of 14] knfsd: SUNRPC: teach svc_sendto() to deal with IPv6 addresses NeilBrown
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 21+ messages in thread
From: NeilBrown @ 2006-12-12 23:59 UTC (permalink / raw)
  To: Andrew Morton; +Cc: nfs, linux-kernel


From: Chuck Lever <chuck.lever@oracle.com>
The rq_daddr field must support larger addresses.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Cc: Aurelien Charbon <aurelien.charbon@ext.bull.net>
Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./include/linux/sunrpc/svc.h |   15 +++++++++++----
 ./net/sunrpc/svcsock.c       |    4 ++--
 2 files changed, 13 insertions(+), 6 deletions(-)

diff .prev/include/linux/sunrpc/svc.h ./include/linux/sunrpc/svc.h
--- .prev/include/linux/sunrpc/svc.h	2006-12-13 10:31:37.000000000 +1100
+++ ./include/linux/sunrpc/svc.h	2006-12-13 10:32:10.000000000 +1100
@@ -11,6 +11,7 @@
 #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/auth.h>
@@ -188,7 +189,13 @@ static inline void svc_putu32(struct kve
 	iov->iov_len += sizeof(__be32);
 }
 
-	
+union svc_addr_u {
+    struct in_addr	addr;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+    struct in6_addr	addr6;
+#endif
+};
+
 /*
  * The context of a single thread, including the request currently being
  * processed.
@@ -224,8 +231,8 @@ struct svc_rqst {
 	unsigned short
 				rq_secure  : 1;	/* secure port */
 
-
-	__be32			rq_daddr;	/* dest addr of request - reply from here */
+	union svc_addr_u	rq_daddr;	/* dest addr of request -
+						 * reply from here */
 
 	void *			rq_argp;	/* decoded arguments */
 	void *			rq_resp;	/* xdr'd results */
@@ -305,7 +312,7 @@ struct svc_deferred_req {
 	struct sockaddr_storage	addr;
 	int			addrlen;
 	struct svc_sock		*svsk;	/* where reply must go */
-	__be32			daddr;	/* where reply must come from */
+	union svc_addr_u	daddr;	/* where reply must come from */
 	struct cache_deferred_req handle;
 	int			argslen;
 	__be32			args[0];

diff .prev/net/sunrpc/svcsock.c ./net/sunrpc/svcsock.c
--- .prev/net/sunrpc/svcsock.c	2006-12-13 10:31:37.000000000 +1100
+++ ./net/sunrpc/svcsock.c	2006-12-13 10:31:39.000000000 +1100
@@ -476,7 +476,7 @@ svc_sendto(struct svc_rqst *rqstp, struc
 		cmh->cmsg_level = SOL_IP;
 		cmh->cmsg_type = IP_PKTINFO;
 		pki->ipi_ifindex = 0;
-		pki->ipi_spec_dst.s_addr = rqstp->rq_daddr;
+		pki->ipi_spec_dst.s_addr = rqstp->rq_daddr.addr.s_addr;
 
 		if (sock_sendmsg(sock, &msg, 0) < 0)
 			goto out;
@@ -747,7 +747,7 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
 	sin->sin_family = AF_INET;
 	sin->sin_port = skb->h.uh->source;
 	sin->sin_addr.s_addr = skb->nh.iph->saddr;
-	rqstp->rq_daddr = skb->nh.iph->daddr;
+	rqstp->rq_daddr.addr.s_addr = skb->nh.iph->daddr;
 
 	if (skb_is_nonlinear(skb)) {
 		/* we have to copy */

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 009 of 14] knfsd: SUNRPC: teach svc_sendto() to deal with IPv6 addresses
  2006-12-12 23:58 [PATCH 000 of 14] knfsd: Assorted nfsd patches for 2.6.20 - prepare for IPv6 and more NeilBrown
                   ` (7 preceding siblings ...)
  2006-12-12 23:59 ` [PATCH 008 of 14] knfsd: SUNRPC: Make rq_daddr field address-version independent NeilBrown
@ 2006-12-12 23:59 ` NeilBrown
  2006-12-17 15:15   ` Ingo Oeser
  2006-12-12 23:59 ` [PATCH 010 of 14] knfsd: SUNRPC: add a "generic" function to see if the peer uses a secure port NeilBrown
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 21+ messages in thread
From: NeilBrown @ 2006-12-12 23:59 UTC (permalink / raw)
  To: Andrew Morton; +Cc: nfs, linux-kernel


From: Chuck Lever <chuck.lever@oracle.com>
CMSG_DATA comes in different sizes, depending on address family.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Cc: Aurelien Charbon <aurelien.charbon@ext.bull.net>
Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./net/sunrpc/svcsock.c |   69 ++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 52 insertions(+), 17 deletions(-)

diff .prev/net/sunrpc/svcsock.c ./net/sunrpc/svcsock.c
--- .prev/net/sunrpc/svcsock.c	2006-12-13 10:31:39.000000000 +1100
+++ ./net/sunrpc/svcsock.c	2006-12-13 10:32:15.000000000 +1100
@@ -36,6 +36,7 @@
 #include <net/sock.h>
 #include <net/checksum.h>
 #include <net/ip.h>
+#include <net/ipv6.h>
 #include <net/tcp_states.h>
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
@@ -438,6 +439,47 @@ svc_wake_up(struct svc_serv *serv)
 	}
 }
 
+union svc_pktinfo_u {
+	struct in_pktinfo pkti;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	struct in6_pktinfo pkti6;
+#endif
+};
+
+static void svc_set_cmsg_data(struct svc_rqst *rqstp, struct cmsghdr *cmh)
+{
+	switch (rqstp->rq_sock->sk_sk->sk_family) {
+	case AF_INET:
+		do {
+			struct in_pktinfo *pki =
+					(struct in_pktinfo *) CMSG_DATA(cmh);
+
+			cmh->cmsg_level = SOL_IP;
+			cmh->cmsg_type = IP_PKTINFO;
+			pki->ipi_ifindex = 0;
+			pki->ipi_spec_dst.s_addr = rqstp->rq_daddr.addr.s_addr;
+			cmh->cmsg_len = CMSG_LEN(sizeof(*pki));
+		} while (0);
+		break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	case AF_INET6:
+		do {
+			struct in6_pktinfo *pki =
+					(struct in6_pktinfo *) CMSG_DATA(cmh);
+
+			cmh->cmsg_level = SOL_IPV6;
+			cmh->cmsg_type = IPV6_PKTINFO;
+			pki->ipi6_ifindex = 0;
+			ipv6_addr_copy(&pki->ipi6_addr,
+					&rqstp->rq_daddr.addr6);
+			cmh->cmsg_len = CMSG_LEN(sizeof(*pki));
+		} while (0);
+		break;
+#endif
+	}
+	return;
+}
+
 /*
  * Generic sendto routine
  */
@@ -447,9 +489,8 @@ svc_sendto(struct svc_rqst *rqstp, struc
 	struct svc_sock	*svsk = rqstp->rq_sock;
 	struct socket	*sock = svsk->sk_sock;
 	int		slen;
-	char 		buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
+	char 		buffer[CMSG_SPACE(sizeof(union svc_pktinfo_u))];
 	struct cmsghdr *cmh = (struct cmsghdr *)buffer;
-	struct in_pktinfo *pki = (struct in_pktinfo *)CMSG_DATA(cmh);
 	int		len = 0;
 	int		result;
 	int		size;
@@ -462,21 +503,15 @@ svc_sendto(struct svc_rqst *rqstp, struc
 	slen = xdr->len;
 
 	if (rqstp->rq_prot == IPPROTO_UDP) {
-		/* set the source and destination */
-		struct msghdr	msg;
-		msg.msg_name    = &rqstp->rq_addr;
-		msg.msg_namelen = rqstp->rq_addrlen;
-		msg.msg_iov     = NULL;
-		msg.msg_iovlen  = 0;
-		msg.msg_flags	= MSG_MORE;
-
-		msg.msg_control = cmh;
-		msg.msg_controllen = sizeof(buffer);
-		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.addr.s_addr;
+		struct msghdr msg = {
+			.msg_name	= &rqstp->rq_addr,
+			.msg_namelen	= rqstp->rq_addrlen,
+			.msg_control	= cmh,
+			.msg_controllen	= sizeof(buffer),
+			.msg_flags	= MSG_MORE,
+		};
+
+		svc_set_cmsg_data(rqstp, cmh);
 
 		if (sock_sendmsg(sock, &msg, 0) < 0)
 			goto out;

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 010 of 14] knfsd: SUNRPC: add a "generic" function to see if the peer uses a secure port
  2006-12-12 23:58 [PATCH 000 of 14] knfsd: Assorted nfsd patches for 2.6.20 - prepare for IPv6 and more NeilBrown
                   ` (8 preceding siblings ...)
  2006-12-12 23:59 ` [PATCH 009 of 14] knfsd: SUNRPC: teach svc_sendto() to deal with IPv6 addresses NeilBrown
@ 2006-12-12 23:59 ` NeilBrown
  2006-12-13  1:42   ` Andrew Morton
  2006-12-12 23:59 ` [PATCH 011 of 14] knfsd: SUNRPC: Support IPv6 addresses in svc_tcp_accept NeilBrown
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 21+ messages in thread
From: NeilBrown @ 2006-12-12 23:59 UTC (permalink / raw)
  To: Andrew Morton; +Cc: nfs, linux-kernel


From: Chuck Lever <chuck.lever@oracle.com>
The only reason svcsock.c looks at a sockaddr's port is to check whether
the remote peer is connecting from a privileged port.  Refactor this check
to hide processing that is specific to address format.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Cc: Aurelien Charbon <aurelien.charbon@ext.bull.net>
Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./net/sunrpc/svcsock.c |   20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff .prev/net/sunrpc/svcsock.c ./net/sunrpc/svcsock.c
--- .prev/net/sunrpc/svcsock.c	2006-12-13 10:32:15.000000000 +1100
+++ ./net/sunrpc/svcsock.c	2006-12-13 10:32:17.000000000 +1100
@@ -926,6 +926,20 @@ svc_tcp_data_ready(struct sock *sk, int 
 		wake_up_interruptible(sk->sk_sleep);
 }
 
+static inline int svc_port_is_privileged(struct sockaddr *sin)
+{
+	switch (sin->sa_family) {
+	case AF_INET:
+		return ntohs(((struct sockaddr_in *)sin)->sin_port) < 1024;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	case AF_INET6:
+		return ntohs(((struct sockaddr_in6 *)sin)->sin6_port) < 1024;
+#endif
+	default:
+		return 0;
+	}
+}
+
 /*
  * Accept a TCP connection
  */
@@ -972,7 +986,7 @@ svc_tcp_accept(struct svc_sock *svsk)
 	 * hosts here, but when we get encryption, the IP of the host won't
 	 * tell us anything.  For now just warn about unpriv connections.
 	 */
-	if (ntohs(sin.sin_port) >= 1024) {
+	if (!svc_port_is_privileged((struct sockaddr *) &sin)) {
 		dprintk(KERN_WARNING
 			"%s: connect from unprivileged port: %s\n",
 			serv->sv_name,
@@ -1313,7 +1327,6 @@ int
 svc_recv(struct svc_rqst *rqstp, long timeout)
 {
 	struct svc_sock		*svsk = NULL;
-	struct sockaddr_in	*sin = svc_addr_in(rqstp);
 	struct svc_serv		*serv = rqstp->rq_server;
 	struct svc_pool		*pool = rqstp->rq_pool;
 	int			len, i;
@@ -1408,7 +1421,8 @@ svc_recv(struct svc_rqst *rqstp, long ti
 	svsk->sk_lastrecv = get_seconds();
 	clear_bit(SK_OLD, &svsk->sk_flags);
 
-	rqstp->rq_secure = ntohs(sin->sin_port) < 1024;
+	rqstp->rq_secure =
+		svc_port_is_privileged(svc_addr(rqstp));
 	rqstp->rq_chandle.defer = svc_defer;
 
 	if (serv->sv_stats)

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 011 of 14] knfsd: SUNRPC: Support IPv6 addresses in svc_tcp_accept
  2006-12-12 23:58 [PATCH 000 of 14] knfsd: Assorted nfsd patches for 2.6.20 - prepare for IPv6 and more NeilBrown
                   ` (9 preceding siblings ...)
  2006-12-12 23:59 ` [PATCH 010 of 14] knfsd: SUNRPC: add a "generic" function to see if the peer uses a secure port NeilBrown
@ 2006-12-12 23:59 ` NeilBrown
  2006-12-12 23:59 ` [PATCH 012 of 14] knfsd: SUNRPC: support IPv6 addresses in RPC server's UDP receive path NeilBrown
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 21+ messages in thread
From: NeilBrown @ 2006-12-12 23:59 UTC (permalink / raw)
  To: Andrew Morton; +Cc: nfs, linux-kernel


From: Chuck Lever <chuck.lever@oracle.com>
Modify svc_tcp_accept to support connecting on IPv6 sockets.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Cc: Aurelien Charbon <aurelien.charbon@ext.bull.net>
Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./net/sunrpc/svcsock.c |   11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff .prev/net/sunrpc/svcsock.c ./net/sunrpc/svcsock.c
--- .prev/net/sunrpc/svcsock.c	2006-12-13 10:32:17.000000000 +1100
+++ ./net/sunrpc/svcsock.c	2006-12-13 10:32:19.000000000 +1100
@@ -946,7 +946,8 @@ static inline int svc_port_is_privileged
 static void
 svc_tcp_accept(struct svc_sock *svsk)
 {
-	struct sockaddr_in sin;
+	struct sockaddr_storage addr;
+	struct sockaddr	*sin = (struct sockaddr *) &addr;
 	struct svc_serv	*serv = svsk->sk_server;
 	struct socket	*sock = svsk->sk_sock;
 	struct socket	*newsock;
@@ -973,8 +974,7 @@ svc_tcp_accept(struct svc_sock *svsk)
 	set_bit(SK_CONN, &svsk->sk_flags);
 	svc_sock_enqueue(svsk);
 
-	slen = sizeof(sin);
-	err = kernel_getpeername(newsock, (struct sockaddr *) &sin, &slen);
+	err = kernel_getpeername(newsock, sin, &slen);
 	if (err < 0) {
 		if (net_ratelimit())
 			printk(KERN_WARNING "%s: peername failed (err %d)!\n",
@@ -986,12 +986,11 @@ svc_tcp_accept(struct svc_sock *svsk)
 	 * hosts here, but when we get encryption, the IP of the host won't
 	 * tell us anything.  For now just warn about unpriv connections.
 	 */
-	if (!svc_port_is_privileged((struct sockaddr *) &sin)) {
+	if (!svc_port_is_privileged(sin)) {
 		dprintk(KERN_WARNING
 			"%s: connect from unprivileged port: %s\n",
 			serv->sv_name,
-			__svc_print_addr((struct sockaddr *) &sin, buf,
-								sizeof(buf)));
+			__svc_print_addr(sin, buf, sizeof(buf)));
 	}
 	dprintk("%s: connect from %s\n", serv->sv_name, buf);
 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 012 of 14] knfsd: SUNRPC: support IPv6 addresses in RPC server's UDP receive path
  2006-12-12 23:58 [PATCH 000 of 14] knfsd: Assorted nfsd patches for 2.6.20 - prepare for IPv6 and more NeilBrown
                   ` (10 preceding siblings ...)
  2006-12-12 23:59 ` [PATCH 011 of 14] knfsd: SUNRPC: Support IPv6 addresses in svc_tcp_accept NeilBrown
@ 2006-12-12 23:59 ` NeilBrown
  2006-12-12 23:59 ` [PATCH 013 of 14] knfsd: SUNRPC: fix up svc_create_socket() to take a sockaddr struct + length NeilBrown
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 21+ messages in thread
From: NeilBrown @ 2006-12-12 23:59 UTC (permalink / raw)
  To: Andrew Morton; +Cc: nfs, linux-kernel


From: Chuck Lever <chuck.lever@oracle.com>
Add support for IPv6 addresses in the RPC server's UDP receive path.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Cc: Aurelien Charbon <aurelien.charbon@ext.bull.net>
Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./include/linux/sunrpc/svc.h |    5 ++++
 ./net/sunrpc/svcsock.c       |   49 +++++++++++++++++++++++++++++++++++--------
 2 files changed, 46 insertions(+), 8 deletions(-)

diff .prev/include/linux/sunrpc/svc.h ./include/linux/sunrpc/svc.h
--- .prev/include/linux/sunrpc/svc.h	2006-12-13 10:32:10.000000000 +1100
+++ ./include/linux/sunrpc/svc.h	2006-12-13 10:32:20.000000000 +1100
@@ -267,6 +267,11 @@ static inline struct sockaddr_in *svc_ad
 	return (struct sockaddr_in *) &rqst->rq_addr;
 }
 
+static inline struct sockaddr_in6 *svc_addr_in6(struct svc_rqst *rqst)
+{
+	return (struct sockaddr_in6 *) &rqst->rq_addr;
+}
+
 static inline struct sockaddr *svc_addr(struct svc_rqst *rqst)
 {
 	return (struct sockaddr *) &rqst->rq_addr;

diff .prev/net/sunrpc/svcsock.c ./net/sunrpc/svcsock.c
--- .prev/net/sunrpc/svcsock.c	2006-12-13 10:32:19.000000000 +1100
+++ ./net/sunrpc/svcsock.c	2006-12-13 10:32:20.000000000 +1100
@@ -717,13 +717,51 @@ svc_write_space(struct sock *sk)
 	}
 }
 
+static void svc_udp_get_sender_address(struct svc_rqst *rqstp,
+					struct sk_buff *skb)
+{
+	switch (rqstp->rq_sock->sk_sk->sk_family) {
+	case AF_INET:
+		/* this seems to come from net/ipv4/udp.c:udp_recvmsg */
+		do {
+			struct sockaddr_in *sin = svc_addr_in(rqstp);
+
+			sin->sin_family = AF_INET;
+			sin->sin_port = skb->h.uh->source;
+			sin->sin_addr.s_addr = skb->nh.iph->saddr;
+			rqstp->rq_daddr.addr.s_addr = skb->nh.iph->daddr;
+		} while (0);
+		break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	case AF_INET6:
+		/* this is derived from net/ipv6/udp.c:udpv6_recvmesg */
+		do {
+			struct sockaddr_in6 *sin6 = svc_addr_in6(rqstp);
+
+			sin6->sin6_family = AF_INET6;
+			sin6->sin6_port = skb->h.uh->source;
+			sin6->sin6_flowinfo = 0;
+			sin6->sin6_scope_id = 0;
+			if (ipv6_addr_type(&sin6->sin6_addr) &
+							IPV6_ADDR_LINKLOCAL)
+				sin6->sin6_scope_id = IP6CB(skb)->iif;
+			ipv6_addr_copy(&sin6->sin6_addr,
+							&skb->nh.ipv6h->saddr);
+			ipv6_addr_copy(&rqstp->rq_daddr.addr6,
+							&skb->nh.ipv6h->saddr);
+		} while (0);
+		break;
+#endif
+	}
+	return;
+}
+
 /*
  * Receive a datagram from a UDP socket.
  */
 static int
 svc_udp_recvfrom(struct svc_rqst *rqstp)
 {
-	struct sockaddr_in *sin = svc_addr_in(rqstp);
 	struct svc_sock	*svsk = rqstp->rq_sock;
 	struct svc_serv	*serv = svsk->sk_server;
 	struct sk_buff	*skb;
@@ -775,14 +813,9 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
 
 	len  = skb->len - sizeof(struct udphdr);
 	rqstp->rq_arg.len = len;
+	rqstp->rq_prot = IPPROTO_UDP;
 
-	rqstp->rq_prot        = IPPROTO_UDP;
-
-	/* Get sender address */
-	sin->sin_family = AF_INET;
-	sin->sin_port = skb->h.uh->source;
-	sin->sin_addr.s_addr = skb->nh.iph->saddr;
-	rqstp->rq_daddr.addr.s_addr = skb->nh.iph->daddr;
+	svc_udp_get_sender_address(rqstp, skb);
 
 	if (skb_is_nonlinear(skb)) {
 		/* we have to copy */

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 013 of 14] knfsd: SUNRPC: fix up svc_create_socket() to take a sockaddr struct + length
  2006-12-12 23:58 [PATCH 000 of 14] knfsd: Assorted nfsd patches for 2.6.20 - prepare for IPv6 and more NeilBrown
                   ` (11 preceding siblings ...)
  2006-12-12 23:59 ` [PATCH 012 of 14] knfsd: SUNRPC: support IPv6 addresses in RPC server's UDP receive path NeilBrown
@ 2006-12-12 23:59 ` NeilBrown
  2006-12-12 23:59 ` [PATCH 014 of 14] knfsd: Don't mess with the 'mode' when storing a exclusive-create cookie NeilBrown
  2006-12-13  5:40 ` [PATCH 000 of 14] knfsd: Assorted nfsd patches for 2.6.20 - prepare for IPv6 and more Jeff Garzik
  14 siblings, 0 replies; 21+ messages in thread
From: NeilBrown @ 2006-12-12 23:59 UTC (permalink / raw)
  To: Andrew Morton; +Cc: nfs, linux-kernel


From: Chuck Lever <chuck.lever@oracle.com>
Replace existing svc_create_socket() API to allow callers to pass addresses
larger than a sockaddr_in.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Cc: Aurelien Charbon <aurelien.charbon@ext.bull.net>
Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./net/sunrpc/svcsock.c |   16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff .prev/net/sunrpc/svcsock.c ./net/sunrpc/svcsock.c
--- .prev/net/sunrpc/svcsock.c	2006-12-13 10:32:20.000000000 +1100
+++ ./net/sunrpc/svcsock.c	2006-12-13 10:32:50.000000000 +1100
@@ -1677,7 +1677,7 @@ EXPORT_SYMBOL_GPL(svc_addsock);
  * Create socket for RPC service.
  */
 static int svc_create_socket(struct svc_serv *serv, int protocol,
-				struct sockaddr_in *sin, int flags)
+				struct sockaddr *sin, int len, int flags)
 {
 	struct svc_sock	*svsk;
 	struct socket	*sock;
@@ -1687,8 +1687,7 @@ static int svc_create_socket(struct svc_
 
 	dprintk("svc: svc_create_socket(%s, %d, %s)\n",
 			serv->sv_program->pg_name, protocol,
-			__svc_print_addr((struct sockaddr *) sin, buf,
-								sizeof(buf)));
+			__svc_print_addr(sin, buf, sizeof(buf)));
 
 	if (protocol != IPPROTO_UDP && protocol != IPPROTO_TCP) {
 		printk(KERN_WARNING "svc: only UDP and TCP "
@@ -1697,15 +1696,15 @@ static int svc_create_socket(struct svc_
 	}
 	type = (protocol == IPPROTO_UDP)? SOCK_DGRAM : SOCK_STREAM;
 
-	if ((error = sock_create_kern(PF_INET, type, protocol, &sock)) < 0)
+	error = sock_create_kern(sin->sa_family, type, protocol, &sock);
+	if (error < 0)
 		return error;
 
 	svc_reclassify_socket(sock);
 
 	if (type == SOCK_STREAM)
-		sock->sk->sk_reuse = 1; /* allow address reuse */
-	error = kernel_bind(sock, (struct sockaddr *) sin,
-					sizeof(*sin));
+		sock->sk->sk_reuse = 1;		/* allow address reuse */
+	error = kernel_bind(sock, sin, len);
 	if (error < 0)
 		goto bummer;
 
@@ -1783,7 +1782,8 @@ int svc_makesock(struct svc_serv *serv, 
 	};
 
 	dprintk("svc: creating socket proto = %d\n", protocol);
-	return svc_create_socket(serv, protocol, &sin, flags);
+	return svc_create_socket(serv, protocol, (struct sockaddr *) &sin,
+							sizeof(sin), flags);
 }
 
 /*

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 014 of 14] knfsd: Don't mess with the 'mode' when storing a exclusive-create cookie.
  2006-12-12 23:58 [PATCH 000 of 14] knfsd: Assorted nfsd patches for 2.6.20 - prepare for IPv6 and more NeilBrown
                   ` (12 preceding siblings ...)
  2006-12-12 23:59 ` [PATCH 013 of 14] knfsd: SUNRPC: fix up svc_create_socket() to take a sockaddr struct + length NeilBrown
@ 2006-12-12 23:59 ` NeilBrown
  2006-12-13  5:40 ` [PATCH 000 of 14] knfsd: Assorted nfsd patches for 2.6.20 - prepare for IPv6 and more Jeff Garzik
  14 siblings, 0 replies; 21+ messages in thread
From: NeilBrown @ 2006-12-12 23:59 UTC (permalink / raw)
  To: Andrew Morton; +Cc: nfs, linux-kernel


From: Peter Staubach <staubach@redhat.com>

NFS V3 (and V4) support exclusive create by passing a 'cookie' which
can get stored with the file.  If the file exists but has exactly the
right cookie stored, then we assume this is a retransmit and the
exclusive create was successful.

The cookie is 64bits and is traditionally stored in the mtime and
atime fields.  This causes a problem with Solaris7 as negative mtime
or atime confuse it.  So we moved two bits into the mode word instead.

But inherited ACLs sometimes overwrite the mode word on create, so
this is a problem.

So we give up and just store 62 of the 64 bits and assume that is
close enough.

Signed-off-by: Neil Brown <neilb@suse.de>

### Diffstat output
 ./fs/nfsd/vfs.c |   21 +++++----------------
 1 file changed, 5 insertions(+), 16 deletions(-)

diff .prev/fs/nfsd/vfs.c ./fs/nfsd/vfs.c
--- .prev/fs/nfsd/vfs.c	2006-12-08 12:08:37.000000000 +1100
+++ ./fs/nfsd/vfs.c	2006-12-13 10:44:55.000000000 +1100
@@ -1248,7 +1248,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
 	__be32		err;
 	int		host_err;
 	__u32		v_mtime=0, v_atime=0;
-	int		v_mode=0;
 
 	err = nfserr_perm;
 	if (!flen)
@@ -1285,16 +1284,11 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
 		goto out;
 
 	if (createmode == NFS3_CREATE_EXCLUSIVE) {
-		/* while the verifier would fit in mtime+atime,
-		 * solaris7 gets confused (bugid 4218508) if these have
-		 * the high bit set, so we use the mode as well
+		/* solaris7 gets confused (bugid 4218508) if these have
+		 * the high bit set, so just clear the high bits.
 		 */
 		v_mtime = verifier[0]&0x7fffffff;
 		v_atime = verifier[1]&0x7fffffff;
-		v_mode  = S_IFREG
-			| ((verifier[0]&0x80000000) >> (32-7)) /* u+x */
-			| ((verifier[1]&0x80000000) >> (32-9)) /* u+r */
-			;
 	}
 	
 	if (dchild->d_inode) {
@@ -1322,7 +1316,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
 		case NFS3_CREATE_EXCLUSIVE:
 			if (   dchild->d_inode->i_mtime.tv_sec == v_mtime
 			    && dchild->d_inode->i_atime.tv_sec == v_atime
-			    && dchild->d_inode->i_mode  == v_mode
 			    && dchild->d_inode->i_size  == 0 )
 				break;
 			 /* fallthru */
@@ -1344,26 +1337,22 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
 	}
 
 	if (createmode == NFS3_CREATE_EXCLUSIVE) {
-		/* Cram the verifier into atime/mtime/mode */
+		/* Cram the verifier into atime/mtime */
 		iap->ia_valid = ATTR_MTIME|ATTR_ATIME
-			| ATTR_MTIME_SET|ATTR_ATIME_SET
-			| ATTR_MODE;
+			| ATTR_MTIME_SET|ATTR_ATIME_SET;
 		/* XXX someone who knows this better please fix it for nsec */ 
 		iap->ia_mtime.tv_sec = v_mtime;
 		iap->ia_atime.tv_sec = v_atime;
 		iap->ia_mtime.tv_nsec = 0;
 		iap->ia_atime.tv_nsec = 0;
-		iap->ia_mode  = v_mode;
 	}
 
 	/* Set file attributes.
-	 * Mode has already been set but we might need to reset it
-	 * for CREATE_EXCLUSIVE
 	 * Irix appears to send along the gid when it tries to
 	 * implement setgid directories via NFS. Clear out all that cruft.
 	 */
  set_attr:
-	if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID)) != 0) {
+	if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) {
  		__be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
 		if (err2)
 			err = err2;

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 010 of 14] knfsd: SUNRPC: add a "generic" function to see if the peer uses a secure port
  2006-12-12 23:59 ` [PATCH 010 of 14] knfsd: SUNRPC: add a "generic" function to see if the peer uses a secure port NeilBrown
@ 2006-12-13  1:42   ` Andrew Morton
  2006-12-13 20:26     ` [NFS] " Chuck Lever
  0 siblings, 1 reply; 21+ messages in thread
From: Andrew Morton @ 2006-12-13  1:42 UTC (permalink / raw)
  To: NeilBrown; +Cc: nfs, linux-kernel

On Wed, 13 Dec 2006 10:59:27 +1100
NeilBrown <neilb@suse.de> wrote:

> From: Chuck Lever <chuck.lever@oracle.com>
> The only reason svcsock.c looks at a sockaddr's port is to check whether
> the remote peer is connecting from a privileged port.  Refactor this check
> to hide processing that is specific to address format.
> 
> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
> Cc: Aurelien Charbon <aurelien.charbon@ext.bull.net>
> Signed-off-by: Neil Brown <neilb@suse.de>
> 
> ### Diffstat output
>  ./net/sunrpc/svcsock.c |   20 +++++++++++++++++---
>  1 file changed, 17 insertions(+), 3 deletions(-)
> 
> diff .prev/net/sunrpc/svcsock.c ./net/sunrpc/svcsock.c
> --- .prev/net/sunrpc/svcsock.c	2006-12-13 10:32:15.000000000 +1100
> +++ ./net/sunrpc/svcsock.c	2006-12-13 10:32:17.000000000 +1100
> @@ -926,6 +926,20 @@ svc_tcp_data_ready(struct sock *sk, int 
>  		wake_up_interruptible(sk->sk_sleep);
>  }
>  
> +static inline int svc_port_is_privileged(struct sockaddr *sin)
> +{
> +	switch (sin->sa_family) {
> +	case AF_INET:
> +		return ntohs(((struct sockaddr_in *)sin)->sin_port) < 1024;
> +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
> +	case AF_INET6:
> +		return ntohs(((struct sockaddr_in6 *)sin)->sin6_port) < 1024;
> +#endif
> +	default:
> +		return 0;
> +	}
> +}

I'm a bit surprised to see this test implemented in sunrpc - it's the sort
of thing which core networking should implement?

And should that "1024" be PROT_SOCK?

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 000 of 14] knfsd: Assorted nfsd patches for 2.6.20 - prepare for IPv6 and more
  2006-12-12 23:58 [PATCH 000 of 14] knfsd: Assorted nfsd patches for 2.6.20 - prepare for IPv6 and more NeilBrown
                   ` (13 preceding siblings ...)
  2006-12-12 23:59 ` [PATCH 014 of 14] knfsd: Don't mess with the 'mode' when storing a exclusive-create cookie NeilBrown
@ 2006-12-13  5:40 ` Jeff Garzik
  2006-12-13 11:13   ` Neil Brown
  14 siblings, 1 reply; 21+ messages in thread
From: Jeff Garzik @ 2006-12-13  5:40 UTC (permalink / raw)
  To: NeilBrown; +Cc: Andrew Morton, nfs, linux-kernel

NeilBrown wrote:
> Following are 14 patches for knfsd that are suitable for inclusion in 2.6.20.
> First 13 are from Chuck Lever and make preparations for IPv6 support (I think we've
> get them right this time).
> 
> Last is from Peter Staubach and fixes and issue with exclusive create
> interacting badly with some ACLs.


Any word on this 2.6.19 oops?

http://lkml.org/lkml/2006/12/8/110

	Jeff



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 000 of 14] knfsd: Assorted nfsd patches for 2.6.20 - prepare for IPv6 and more
  2006-12-13  5:40 ` [PATCH 000 of 14] knfsd: Assorted nfsd patches for 2.6.20 - prepare for IPv6 and more Jeff Garzik
@ 2006-12-13 11:13   ` Neil Brown
  0 siblings, 0 replies; 21+ messages in thread
From: Neil Brown @ 2006-12-13 11:13 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Andrew Morton, nfs, linux-kernel

On Wednesday December 13, jeff@garzik.org wrote:
> NeilBrown wrote:
> > Following are 14 patches for knfsd that are suitable for inclusion in 2.6.20.
> > First 13 are from Chuck Lever and make preparations for IPv6 support (I think we've
> > get them right this time).
> > 
> > Last is from Peter Staubach and fixes and issue with exclusive create
> > interacting badly with some ACLs.
> 
> 
> Any word on this 2.6.19 oops?
> 
> http://lkml.org/lkml/2006/12/8/110

Not yet... I've been spending my spare time looking for an md oops :-)

A quick look suggests that it cannot possibly happen ...

cancel_rearming_delayed_workqueue appears to be being called with a
bad "struct workqueue_struct *".  But that really must have been
initialised when the first nfsd thread started...

It looks like cwq in flush_cpu_workqueue is 0x0000040000000100.  Is
that the sort of address you would expect?  Where do alloc_percpu 
data structures live?  The '4' wouldn't be a single-bit memory error,
would it? (that would be too easy).

So: no, no real progress.   Is it repeatable?

NeilBrown

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [NFS] [PATCH 010 of 14] knfsd: SUNRPC: add a "generic" function to see if the peer uses a secure port
  2006-12-13  1:42   ` Andrew Morton
@ 2006-12-13 20:26     ` Chuck Lever
  0 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2006-12-13 20:26 UTC (permalink / raw)
  To: Andrew Morton; +Cc: NeilBrown, nfs, linux-kernel

On 12/12/06, Andrew Morton <akpm@osdl.org> wrote:
> On Wed, 13 Dec 2006 10:59:27 +1100
> NeilBrown <neilb@suse.de> wrote:
>
> > From: Chuck Lever <chuck.lever@oracle.com>
> > The only reason svcsock.c looks at a sockaddr's port is to check whether
> > the remote peer is connecting from a privileged port.  Refactor this check
> > to hide processing that is specific to address format.
> >
> > Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
> > Cc: Aurelien Charbon <aurelien.charbon@ext.bull.net>
> > Signed-off-by: Neil Brown <neilb@suse.de>
> >
> > ### Diffstat output
> >  ./net/sunrpc/svcsock.c |   20 +++++++++++++++++---
> >  1 file changed, 17 insertions(+), 3 deletions(-)
> >
> > diff .prev/net/sunrpc/svcsock.c ./net/sunrpc/svcsock.c
> > --- .prev/net/sunrpc/svcsock.c        2006-12-13 10:32:15.000000000 +1100
> > +++ ./net/sunrpc/svcsock.c    2006-12-13 10:32:17.000000000 +1100
> > @@ -926,6 +926,20 @@ svc_tcp_data_ready(struct sock *sk, int
> >               wake_up_interruptible(sk->sk_sleep);
> >  }
> >
> > +static inline int svc_port_is_privileged(struct sockaddr *sin)
> > +{
> > +     switch (sin->sa_family) {
> > +     case AF_INET:
> > +             return ntohs(((struct sockaddr_in *)sin)->sin_port) < 1024;
> > +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
> > +     case AF_INET6:
> > +             return ntohs(((struct sockaddr_in6 *)sin)->sin6_port) < 1024;
> > +#endif
> > +     default:
> > +             return 0;
> > +     }
> > +}
>
> I'm a bit surprised to see this test implemented in sunrpc - it's the sort
> of thing which core networking should implement?

The check is open-coded in each socket type's bind callout, and
includes a capability check which I believe the NFS server doesn't
require.

> And should that "1024" be PROT_SOCK?

All I can say is.... "Doh!"  I'll send Neil a replacement with this fixed.

-- 
"We who cut mere stones must always be envisioning cathedrals"
   -- Quarry worker's creed

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 007 of 14] knfsd: SUNRPC: Provide room in svc_rqst for larger addresses
  2006-12-12 23:59 ` [PATCH 007 of 14] knfsd: SUNRPC: Provide room in svc_rqst for larger addresses NeilBrown
@ 2006-12-15  4:30   ` Andrew Morton
  0 siblings, 0 replies; 21+ messages in thread
From: Andrew Morton @ 2006-12-15  4:30 UTC (permalink / raw)
  To: NeilBrown; +Cc: nfs, linux-kernel, Chuck Lever

On Wed, 13 Dec 2006 10:59:11 +1100
NeilBrown <neilb@suse.de> wrote:

> From: Chuck Lever <chuck.lever@oracle.com>
> Expand the rq_addr field to allow it to contain larger addresses.

This patch breaks the NFS server on my heroically modern RH FC1 machine.

There's a mysterious 30-second pause when initscripts are bringing up
mountd.

showmount (from a FC5 client) works:

box:/usr/src/25> 0 showmount -e vmm
Export list for vmm:
/         *
/mnt/hda5 *

But things get really exciting when we try to mount it:


box:/usr/src/25> 0 mount vmm:/mnt/hda5 /mnt         
*** buffer overflow detected ***: mount terminated
======= Backtrace: =========
/lib64/libc.so.6(__chk_fail+0x2f)[0x32adbdfaef]
mount[0x40bcf8]
mount[0x4044c5]
mount[0x405850]
mount[0x406388]
/lib64/libc.so.6(__libc_start_main+0xf4)[0x32adb1ce54]
mount[0x4034a9]
======= Memory map: ========
00400000-00414000 r-xp 00000000 08:01 3041513                            /bin/mount
00513000-00514000 rw-p 00013000 08:01 3041513                            /bin/mount
00514000-00516000 rw-p 00514000 00:00 0 
00613000-00615000 rw-p 00013000 08:01 3041513                            /bin/mount
00615000-00636000 rw-p 00615000 00:00 0                                  [heap]
32ad900000-32ad91a000 r-xp 00000000 08:01 1619031                        /lib64/ld-2.4.so
32ada19000-32ada1a000 r--p 00019000 08:01 1619031                        /lib64/ld-2.4.so
32ada1a000-32ada1b000 rw-p 0001a000 08:01 1619031                        /lib64/ld-2.4.so
32adb00000-32adc3f000 r-xp 00000000 08:01 1619091                        /lib64/libc-2.4.so
32adc3f000-32add3f000 ---p 0013f000 08:01 1619091                        /lib64/libc-2.4.so
32add3f000-32add43000 r--p 0013f000 08:01 1619091                        /lib64/libc-2.4.so
32add43000-32add44000 rw-p 00143000 08:01 1619091                        /lib64/libc-2.4.so
32add44000-32add49000 rw-p 32add44000 00:00 0 
32ade00000-32ade02000 r-xp 00000000 08:01 1619011                        /lib64/libuuid.so.1.2
32ade02000-32adf02000 ---p 00002000 08:01 1619011                        /lib64/libuuid.so.1.2
32adf02000-32adf03000 rw-p 00002000 08:01 1619011                        /lib64/libuuid.so.1.2
32ae000000-32ae002000 r-xp 00000000 08:01 1619095                        /lib64/libdl-2.4.so
32ae002000-32ae102000 ---p 00002000 08:01 1619095                        /lib64/libdl-2.4.so
32ae102000-32ae103000 r--p 00002000 08:01 1619095                        /lib64/libdl-2.4.so
32ae103000-32ae104000 rw-p 00003000 08:01 1619095                        /lib64/libdl-2.4.so
32ae200000-32ae20e000 r-xp 00000000 08:01 1619005                        /lib64/libdevmapper.so.1.02
32ae20e000-32ae30e000 ---p 0000e000 08:01 1619005                        /lib64/libdevmapper.so.1.02
32ae30e000-32ae310000 rw-p 0000e000 08:01 1619005                        /lib64/libdevmapper.so.1.02
32ae400000-32ae408000 r-xp 00000000 08:01 1619066                        /lib64/libblkid.so.1.0
32ae408000-32ae508000 ---p 00008000 08:01 1619066                        /lib64/libblkid.so.1.0
32ae508000-32ae509000 rw-p 00008000 08:01 1619066                        /lib64/libblkid.so.1.0
32b0600000-32b060d000 r-xp 00000000 08:01 1619093                        /lib64/libgcc_s-4.1.1-20060525.so.1
32b060d000-32b070d000 ---p 0000d000 08:01 1619093                        /lib64/libgcc_s-4.1.1-20060525.so.1
32b070d000-32b070e000 rw-p 0000d000 08:01 1619093                        /lib64/libgcc_s-4.1.1-20060525.so.1
32b2800000-32b2814000 r-xp 00000000 08:01 1619102                        /lib64/libselinux.so.1
32b2814000-32b2913000 ---p 00014000 08:01 1619102                        /lib64/libselinux.so.1
32b2913000-32b2915000 rw-p 00013000 08:01 1619102                        /lib64/libselinux.so.1
32b2915000-32b2916000 rw-p 32b2915000 00:00 0 
32b2a00000-32b2a38000 r-xp 00000000 08:01 1619101                        /lib64/libsepol.so.1
32b2a38000-32b2b37000 ---p 00038000 08:01 1619101                        /lib64/libsepol.so.1
32b2b37000-32b2b38000 rw-p 00037000 08:01 1619101                        /lib64/libsepol.so.1
32b2b38000-32b2b42000 rw-p 32b2b38000 00:00 0 
2b9eea00c000-2b9eea00d000 rw-p 2b9eea00c000 00:00 0 
2b9eea032000-2b9eea036000 rw-p 2b9eea032000 00:00 0 
2b9eea036000-2b9eea039000 r-xp 00000000 08:01 1618858                    /lib64/libsetrans.so.0
2b9eea039000-2b9eea138000 ---p 00003000 08:01 1618858                    /lib64/libsetrans.so.0
2b9eea138000-2b9eea139000 rw-p 00002000 08:01 1618858                    /lib64/libsetrans.so.0
2b9eea139000-2b9eea143000 r-xp 00000000 08:01 1619053                    /lib64/libnss_files-2.4.so
2b9eea143000-2b9eea242000 ---p 0000a000 08:01 1619053                    /lib64/libnss_files-2.4.so
2b9eea242000-2b9eea243000 r--p 00009000 08:01 1619053                    /lib64/libnss_files-2.4.so
2b9eea243000-2b9eea244000 rw-p 0000a000 08:01 1619053                    /lib64/libnss_files-2.4.so
7fffc0a88000-7fffc0a9e000 rw-p 7fffc0a88000 00:00 0                      [stack]
ffffffffff600000-ffffffffffe00000 ---p 00000000 00:00 0                  [vdso]
zsh: abort      0 mount vmm:/mnt/hda5 /mnt


btw, knfsd-sunrpc-cache-remote-peers-address-in-svc_sock.patch breaks the build:

net/sunrpc/svcsock.c: In function 'svc_recvfrom':
net/sunrpc/svcsock.c:581: error: 'svsk' undeclared (first use in this function)
net/sunrpc/svcsock.c:581: error: (Each undeclared identifier is reported only once

but the next patch
(knfsd-sunrpc-dont-set-msg_name-and-msg_namelen-when-calling-sock_recvmsg.patch)
fixes that.



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 009 of 14] knfsd: SUNRPC: teach svc_sendto() to deal with IPv6 addresses
  2006-12-12 23:59 ` [PATCH 009 of 14] knfsd: SUNRPC: teach svc_sendto() to deal with IPv6 addresses NeilBrown
@ 2006-12-17 15:15   ` Ingo Oeser
  0 siblings, 0 replies; 21+ messages in thread
From: Ingo Oeser @ 2006-12-17 15:15 UTC (permalink / raw)
  To: NeilBrown; +Cc: Andrew Morton, nfs, linux-kernel

On Wednesday, 13. December 2006 00:59, NeilBrown wrote:
> diff .prev/net/sunrpc/svcsock.c ./net/sunrpc/svcsock.c
> --- .prev/net/sunrpc/svcsock.c	2006-12-13 10:31:39.000000000 +1100
> +++ ./net/sunrpc/svcsock.c	2006-12-13 10:32:15.000000000 +1100
> @@ -438,6 +439,47 @@ svc_wake_up(struct svc_serv *serv)
>  	}
>  }
>  
> +union svc_pktinfo_u {
> +	struct in_pktinfo pkti;
> +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
> +	struct in6_pktinfo pkti6;
> +#endif
> +};
> +
> +static void svc_set_cmsg_data(struct svc_rqst *rqstp, struct cmsghdr *cmh)
> +{
> +	switch (rqstp->rq_sock->sk_sk->sk_family) {
> +	case AF_INET:
> +		do {
> +			struct in_pktinfo *pki =
> +					(struct in_pktinfo *) CMSG_DATA(cmh);

			struct in_pktinfo *pki = CMSG_DATA(cmh);

Ugly casting not needed here, since CMSG_DATA should return "void *",
which can be casted to any pointer.

> +
> +			cmh->cmsg_level = SOL_IP;
> +			cmh->cmsg_type = IP_PKTINFO;
> +			pki->ipi_ifindex = 0;
> +			pki->ipi_spec_dst.s_addr = rqstp->rq_daddr.addr.s_addr;
> +			cmh->cmsg_len = CMSG_LEN(sizeof(*pki));
> +		} while (0);
> +		break;
> +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
> +	case AF_INET6:
> +		do {
> +			struct in6_pktinfo *pki =
> +					(struct in6_pktinfo *) CMSG_DATA(cmh);
> +

No casting needed, so:

			struct in6_pktinfo *pki = CMSG_DATA(cmh);


Regards

Ingo Oeser

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2006-12-17 15:15 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-12-12 23:58 [PATCH 000 of 14] knfsd: Assorted nfsd patches for 2.6.20 - prepare for IPv6 and more NeilBrown
2006-12-12 23:58 ` [PATCH 001 of 14] knfsd: SUNRPC: update internal API: separate pmap register and temp sockets NeilBrown
2006-12-12 23:58 ` [PATCH 002 of 14] knfsd: SUNRPC: allow creating an RPC service without registering with portmapper NeilBrown
2006-12-12 23:58 ` [PATCH 003 of 14] knfsd: SUNRPC: Cache remote peer's address in svc_sock NeilBrown
2006-12-12 23:58 ` [PATCH 004 of 14] knfsd: SUNRPC: Don't set msg_name and msg_namelen when calling sock_recvmsg NeilBrown
2006-12-12 23:58 ` [PATCH 005 of 14] knfsd: SUNRPC: Use sockaddr_storage to store address in svc_deferred_req NeilBrown
2006-12-12 23:59 ` [PATCH 006 of 14] knfsd: SUNRPC: Add a function to format the address in an svc_rqst for printing NeilBrown
2006-12-12 23:59 ` [PATCH 007 of 14] knfsd: SUNRPC: Provide room in svc_rqst for larger addresses NeilBrown
2006-12-15  4:30   ` Andrew Morton
2006-12-12 23:59 ` [PATCH 008 of 14] knfsd: SUNRPC: Make rq_daddr field address-version independent NeilBrown
2006-12-12 23:59 ` [PATCH 009 of 14] knfsd: SUNRPC: teach svc_sendto() to deal with IPv6 addresses NeilBrown
2006-12-17 15:15   ` Ingo Oeser
2006-12-12 23:59 ` [PATCH 010 of 14] knfsd: SUNRPC: add a "generic" function to see if the peer uses a secure port NeilBrown
2006-12-13  1:42   ` Andrew Morton
2006-12-13 20:26     ` [NFS] " Chuck Lever
2006-12-12 23:59 ` [PATCH 011 of 14] knfsd: SUNRPC: Support IPv6 addresses in svc_tcp_accept NeilBrown
2006-12-12 23:59 ` [PATCH 012 of 14] knfsd: SUNRPC: support IPv6 addresses in RPC server's UDP receive path NeilBrown
2006-12-12 23:59 ` [PATCH 013 of 14] knfsd: SUNRPC: fix up svc_create_socket() to take a sockaddr struct + length NeilBrown
2006-12-12 23:59 ` [PATCH 014 of 14] knfsd: Don't mess with the 'mode' when storing a exclusive-create cookie NeilBrown
2006-12-13  5:40 ` [PATCH 000 of 14] knfsd: Assorted nfsd patches for 2.6.20 - prepare for IPv6 and more Jeff Garzik
2006-12-13 11:13   ` Neil Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox