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