Changing the rq_daddr field of svc_rqst structure to become
transport-independant

Signed-off-by: Aurelien Charbon <aurelien.charbon@ext.bull.net>

 include/linux/sunrpc/svc.h |   10 +++++++++-
 net/sunrpc/svc.c           |    2 ++
 net/sunrpc/svcsock.c       |   15 ++++++++++++++-
 3 files changed, 25 insertions(+), 2 deletions(-)
--------
diff -Nru linux-2.6.11-06e/include/linux/sunrpc/svc.h linux-2.6.11-06f/include/linux/sunrpc/svc.h
--- linux-2.6.11-06e/include/linux/sunrpc/svc.h	2005-06-03 13:52:16.000000000 +0200
+++ linux-2.6.11-06f/include/linux/sunrpc/svc.h	2005-06-03 14:17:13.000000000 +0200
@@ -139,8 +139,12 @@
 	unsigned short
 				rq_secure  : 1;	/* secure port */
 
+	union {
+	    struct in_addr *	in_daddr;
+	    struct in6_addr *	in6_daddr;
+	    void *		daddr;
+	} rq_u_daddr;				/* dest addr of request - reply from here */
 
-	__u32			rq_daddr;	/* dest addr of request - reply from here */
 
 	void *			rq_argp;	/* decoded arguments */
 	void *			rq_resp;	/* xdr'd results */
@@ -164,6 +168,10 @@
 	wait_queue_head_t	rq_wait;	/* synchronization */
 };
 
+#define rq_in_daddr	rq_u_daddr.in_daddr
+#define rq_in6_daddr	rq_u_daddr.in6_daddr
+#define rq_daddr	rq_u_daddr.daddr
+
 /*
  * Check buffer bounds after decoding arguments
  */
diff -Nru linux-2.6.11-06e/net/sunrpc/svc.c linux-2.6.11-06f/net/sunrpc/svc.c
--- linux-2.6.11-06e/net/sunrpc/svc.c	2005-06-03 08:58:50.000000000 +0200
+++ linux-2.6.11-06f/net/sunrpc/svc.c	2005-06-03 14:19:35.000000000 +0200
@@ -194,6 +194,8 @@
 	struct svc_serv	*serv = rqstp->rq_server;
 
 	svc_release_buffer(rqstp);
+	if (rqstp->rq_daddr)
+		kfree(rqstp->rq_daddr);
 	if (rqstp->rq_resp)
 		kfree(rqstp->rq_resp);
 	if (rqstp->rq_argp)
diff -Nru linux-2.6.11-06e/net/sunrpc/svcsock.c linux-2.6.11-06f/net/sunrpc/svcsock.c
--- linux-2.6.11-06e/net/sunrpc/svcsock.c	2005-06-03 14:01:33.000000000 +0200
+++ linux-2.6.11-06f/net/sunrpc/svcsock.c	2005-06-06 11:42:06.000000000 +0200
@@ -610,6 +610,13 @@
 		sin->sin_family = AF_INET;
 		sin->sin_port = skb->h.uh->source;
 		sin->sin_addr.s_addr = skb->nh.iph->saddr;
+		if (rqstp->rq_in_daddr == NULL) {
+			skb_free_datagram(svsk->sk_sk, skb);
+			return 0;
+		}
+		rqstp->rq_in_daddr->s_addr = skb->nh.iph->daddr;
+		memcpy(&rqstp->rq_daddr, &skb->nh.iph->daddr,
+		       sizeof(struct in_addr));
 
 	} else if (*skb->nh.raw == IP6VERSION) {
 		struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&rqstp->rq_addr;
@@ -617,7 +624,13 @@
 		sin->sin6_port = skb->h.uh->source;
 		memcpy(&sin->sin6_addr, &skb->nh.ipv6h->saddr,
 		       sizeof(struct in6_addr));
-	
+		rqstp->rq_in6_daddr = (struct in6_addr *)kmalloc(sizeof(struct in6_addr), GFP_KERNEL);
+		if (rqstp->rq_in6_daddr == NULL) {
+			skb_free_datagram(svsk->sk_sk, skb);
+			return 0;
+		}
+		memcpy(rqstp->rq_in6_daddr, &skb->nh.ipv6h->daddr,
+		       sizeof(struct in6_addr));
 	} else {
 		skb_free_datagram(svsk->sk_sk, skb);
 		return 0;

