diff options
| author | Neil Brown <neilb@cse.unsw.edu.au> | 2003-08-18 19:34:00 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.osdl.org> | 2003-08-18 19:34:00 -0700 |
| commit | b50ca02ac68265ffb102f7c9da13e429c7fb8f13 (patch) | |
| tree | 047f7c62e32eb2a82a4bb5bd30e01279e9b9fb2a | |
| parent | ebbbef610d7081e1820beb6ca375377c834b29c2 (diff) | |
[PATCH] kNFSd: Make sure nfsd replies from the address the request was sent to.
This is important on multi-homes hosts.
| -rw-r--r-- | include/linux/sunrpc/svc.h | 2 | ||||
| -rw-r--r-- | net/sunrpc/svcsock.c | 16 |
2 files changed, 15 insertions, 3 deletions
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 71cd5d8daf23..8886ee64fe69 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -131,6 +131,8 @@ struct svc_rqst { rq_secure : 1; /* secure port */ + __u32 rq_daddr; /* dest addr of request - reply from here */ + void * rq_argp; /* decoded arguments */ void * rq_resp; /* xdr'd results */ diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index e5fe3ee84e1f..552fa2c31b39 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -353,6 +353,9 @@ svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr) struct svc_sock *svsk = rqstp->rq_sock; struct socket *sock = svsk->sk_sock; int slen; + struct { struct cmsghdr cmh; + struct in_pktinfo pki; + } cm; int len = 0; int result; int size; @@ -364,16 +367,22 @@ svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr) slen = xdr->len; if (rqstp->rq_prot == IPPROTO_UDP) { - /* set the destination */ + /* set the source and destination */ struct msghdr msg; msg.msg_name = &rqstp->rq_addr; msg.msg_namelen = sizeof(rqstp->rq_addr); msg.msg_iov = NULL; msg.msg_iovlen = 0; - msg.msg_control = NULL; - msg.msg_controllen = 0; msg.msg_flags = MSG_MORE; + 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; + if (sock_sendmsg(sock, &msg, 0) < 0) goto out; } @@ -594,6 +603,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; svsk->sk_sk->sk_stamp = skb->stamp; |
