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