Skip to contentSkip to conversation

kNFSd - 6 of 6 - Make sure nfsd replies from the address the request was sent to.

PATCH In review NeilBrown 2 participants 4 messages Sep 4, 2003 – Sep 7, 2003

Subsystems (3)
lore
Share & tools
lore

NeilBrown

author
#0 lore raw

PATCH 1/1 kNFSd - 6 of 6 - Make sure nfsd replies from the address the request was sent to.

This is important on multi-homes hosts.

include/linux/sunrpc/svc.h renamed from include/linux/sunrpc/svc.h~current~ +2 -0
diff ./include/linux/sunrpc/svc.h~current~ ./include/linux/sunrpc/svc.h
@@ -112,6 +112,8 @@ struct svc_rqst {
 				rq_secure  : 1,	/* secure port */
 				rq_auth    : 1;	/* check client */
 
+	__u32			rq_daddr;	/* dest addr of request - reply from here */
+
 	void *			rq_argp;	/* decoded arguments */
 	void *			rq_resp;	/* xdr'd results */
 
net/sunrpc/svcsock.c renamed from net/sunrpc/svcsock.c~current~ +16 -2
diff ./net/sunrpc/svcsock.c~current~ ./net/sunrpc/svcsock.c
@@ -317,6 +317,9 @@ svc_sendto(struct svc_rqst *rqstp, struc
 	struct svc_sock	*svsk = rqstp->rq_sock;
 	struct socket	*sock = svsk->sk_sock;
 	struct msghdr	msg;
+	struct { struct cmsghdr cmh;
+		struct in_pktinfo pki;
+	} cm;
 	int		i, buflen, len;
 
 	for (i = buflen = 0; i < nr; i++)
@@ -326,8 +329,18 @@ svc_sendto(struct svc_rqst *rqstp, struc
 	msg.msg_namelen = sizeof(rqstp->rq_addr);
 	msg.msg_iov     = iov;
 	msg.msg_iovlen  = nr;
-	msg.msg_control = NULL;
-	msg.msg_controllen = 0;
+	if (rqstp->rq_prot == IPPROTO_UDP) {
+		msg.msg_control = &cm;
+		msg.msg_controllen = sizeof(cm);
+		cm.cmh.cmsg_len = sizeof(cm);
+		cm.cmh.cmsg_level = SOL_IP;
+		cm.cmh.cmsg_type = IP_PKTINFO;
+		cm.pki.ipi_ifindex = 0;
+		cm.pki.ipi_spec_dst.s_addr = rqstp->rq_daddr;
+	} else {
+		msg.msg_control = NULL;
+		msg.msg_controllen = 0;
+	}
 
 	/* This was MSG_DONTWAIT, but I now want it to wait.
 	 * The only thing that it would wait for is memory and
@@ -531,6 +544,7 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
 	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;
 
 	if (serv->sv_stats)
 		serv->sv_stats->netudpcnt++;

-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

#1 lore raw

Hello,

the patch contains an alignment induced bug on 64-bit platforms:
sizeof(cm) becomes 32 bytes, instead of 16 + 12 = 28. This causes ip_cmsg_send to fail. See the attached fix.

Quoted 51 lines · NeilBrown

This is important on multi-homes hosts.

diff ./include/linux/sunrpc/svc.h~current~ ./include/linux/sunrpc/svc.h
-- ./include/linux/sunrpc/svc.h~current~ 2003-09-04 11:32:11.000000000 +1000
+++ ./include/linux/sunrpc/svc.h 2003-09-04 11:46:27.000000000 +1000

(quoted diff) +2 -0
@@ -112,6 +112,8 @@ struct svc_rqst {
 				rq_secure  : 1,	/* secure port */
 				rq_auth    : 1;	/* check client */
 
+	__u32			rq_daddr;	/* dest addr of request - reply from here */
+
 	void *			rq_argp;	/* decoded arguments */
 	void *			rq_resp;	/* xdr'd results */
 

diff ./net/sunrpc/svcsock.c~current~ ./net/sunrpc/svcsock.c
-- ./net/sunrpc/svcsock.c~current~ 2003-09-04 11:45:48.000000000 +1000
+++ ./net/sunrpc/svcsock.c 2003-09-04 11:46:27.000000000 +1000

(quoted diff) +15 -2
@@ -317,6 +317,9 @@ svc_sendto(struct svc_rqst *rqstp, struc
 	struct svc_sock	*svsk = rqstp->rq_sock;
 	struct socket	*sock = svsk->sk_sock;
 	struct msghdr	msg;
+	struct { struct cmsghdr cmh;
+		struct in_pktinfo pki;
+	} cm;
 	int		i, buflen, len;
 
 	for (i = buflen = 0; i < nr; i++)
@@ -326,8 +329,18 @@ svc_sendto(struct svc_rqst *rqstp, struc
 	msg.msg_namelen = sizeof(rqstp->rq_addr);
 	msg.msg_iov     = iov;
 	msg.msg_iovlen  = nr;
-	msg.msg_control = NULL;
-	msg.msg_controllen = 0;
+	if (rqstp->rq_prot == IPPROTO_UDP) {
+		msg.msg_control = &cm;
+		msg.msg_controllen = sizeof(cm);
+		cm.cmh.cmsg_len = sizeof(cm);
+		cm.cmh.cmsg_level = SOL_IP;
+		cm.cmh.cmsg_type = IP_PKTINFO;
+		cm.pki.ipi_ifindex = 0;
+		cm.pki.ipi_spec_dst.s_addr = rqstp->rq_daddr;
+	} else {
+		msg.msg_control = NULL;
+		msg.msg_controllen = 0;
+	}
 
 	/* This was MSG_DONTWAIT, but I now want it to wait.
 	 * The only thing that it would wait for is memory and

Review svc_udp_recvfrom(struct svc_rqst *rqstp) · line 550

Quoted 7 lines
(quoted diff) +1 -0
@@ -531,6 +544,7 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
 	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;
 
 	if (serv->sv_stats)
 		serv->sv_stats->netudpcnt++;

Cheers,

Signature · 2 lines
Andreas Gruenbacher <[email protected]>
SuSE Labs, SuSE Linux AG <http://www.suse.de/>
net/sunrpc/svcsock.c +2 -2
diff -u linux/net/sunrpc/svcsock.c linux/net/sunrpc/svcsock.c
@@ -331,8 +331,8 @@
 	msg.msg_iovlen  = nr;
 	if (rqstp->rq_prot == IPPROTO_UDP) {
 		msg.msg_control = &cm;
-		msg.msg_controllen = sizeof(cm);
-		cm.cmh.cmsg_len = sizeof(cm);
+		msg.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
+		cm.cmh.cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
 		cm.cmh.cmsg_level = SOL_IP;
 		cm.cmh.cmsg_type = IP_PKTINFO;
 		cm.pki.ipi_ifindex = 0;
#2 lore raw
Quoted 5 lines · Andreas Gruenbacher

Hello,

the patch contains an alignment induced bug on 64-bit platforms:
sizeof(cm) becomes 32 bytes, instead of 16 + 12 = 28. This causes ip_cmsg_send to fail. See the attached fix.

In addition, with the patch applied, I am seeing the following failure on ia64:

Sep  7 23:24:41 my kernel: Installing knfsd (copyright (C) 1996 [email protected]
Sep  7 23:24:45 my rpc.mountd: authenticated mount request from
localhost:891
Sep  7 23:24:45 my kernel: RPC request reserved -105422848 but used 20
Sep  7 23:24:45 my last message repeated 2 times
Sep  7 23:24:45 my kernel: nfs_get_root: getattr error = 13

If only this patch is removed, the problem disappears.

Cheers,

Signature · 12 lines
Andreas Gruenbacher <[email protected]>
SuSE Labs, SuSE Linux AG <http://www.suse.de/>



-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
NFS maillist  -  [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
#3 lore raw
Quoted 11 lines · Andreas Gruenbacher
Quoted 5 lines · Andreas Gruenbacher

Hello,

the patch contains an alignment induced bug on 64-bit platforms:
sizeof(cm) becomes 32 bytes, instead of 16 + 12 = 28. This causes ip_cmsg_send to fail. See the attached fix.

In addition, with the patch applied, I am seeing the following failure on ia64:

[...]

My mistake, no further problem. I had an old version of nfsd.o.

Cheers,

Signature · 12 lines
Andreas Gruenbacher <[email protected]>
SuSE Labs, SuSE Linux AG <http://www.suse.de/>



-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
NFS maillist  -  [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs