An IP alias patch for sunrpc in kernel

From: H . J . Lu (hjl@valinux.com)
Date: Thu Feb 17 2000 - 19:39:43 EST


When you access an NFS server, which has IP aliases, through NAT over
UDP, sunrpc in kernel has to make sure to use its IP address, where
the client sent a UDP packet, when sending reply back to the client.
Otherwise, the reply may not go through NAT. This patch tries to fix
this problem.

-- 
H.J. Lu (hjl@gnu.org)
---
--- linux-2.2.14/include/linux/sunrpc/svc.h.alias	Thu Feb 17 12:17:42 2000
+++ linux-2.2.14/include/linux/sunrpc/svc.h	Thu Feb 17 13:05:04 2000
@@ -91,6 +91,8 @@ struct svc_rqst {
 	struct svc_rqst *	rq_next;
 	struct svc_sock *	rq_sock;	/* socket */
 	struct sockaddr_in	rq_addr;	/* peer address */
+	char			rq_mesg [sizeof (struct cmsghdr)
+					 + sizeof (struct in_pktinfo)];
 	int			rq_addrlen;
 
 	struct svc_serv *	rq_server;	/* RPC service definition */
--- linux-2.2.14/net/sunrpc/svcsock.c.alias	Thu Feb 17 12:24:17 2000
+++ linux-2.2.14/net/sunrpc/svcsock.c	Thu Feb 17 15:56:15 2000
@@ -249,8 +249,14 @@ 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 (sock->type == SOCK_DGRAM) {
+		msg.msg_control = &rqstp->rq_mesg [0];
+		msg.msg_controllen = sizeof (rqstp->rq_mesg);
+	}
+	else {
+		msg.msg_control = NULL;
+		msg.msg_controllen = 0;
+	}
 
 #if LINUX_VERSION_CODE >= 0x020100
 	msg.msg_flags	= MSG_DONTWAIT;
@@ -359,6 +365,9 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
 	struct sk_buff	*skb;
 	u32		*data;
 	int		err, len;
+	struct cmsghdr	*cm;
+	struct in_pktinfo *info;
+	struct rtable	*rt;
 
 	svsk->sk_data = 0;
 	while ((skb = skb_recv_datagram(svsk->sk_sk, 0, 1, &err)) == NULL) {
@@ -390,6 +399,24 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
 #else
 	rqstp->rq_addr.sin_addr.s_addr = skb->saddr;
 #endif
+
+	cm = (struct cmsghdr *) &rqstp->rq_mesg [0];
+	info = (struct in_pktinfo *)
+		&rqstp->rq_mesg [sizeof(struct cmsghdr)];
+	rt = (struct rtable *)skb->dst;
+
+	cm->cmsg_level = SOL_IP;
+	cm->cmsg_type = IP_PKTINFO;
+	cm->cmsg_len = CMSG_LEN (sizeof (struct in_pktinfo));
+	info->ipi_addr.s_addr = skb->nh.iph->daddr;
+	if (rt) {
+		info->ipi_ifindex = rt->rt_iif;
+		info->ipi_spec_dst.s_addr = rt->rt_spec_dst;
+	}
+	else {
+		info->ipi_ifindex = 0;
+		info->ipi_spec_dst.s_addr = 0;
+	}
 
 	if (serv->sv_stats)
 		serv->sv_stats->netudpcnt++;

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed Feb 23 2000 - 21:00:20 EST