summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Brown <neilb@cse.unsw.edu.au>2003-08-18 19:34:00 -0700
committerLinus Torvalds <torvalds@home.osdl.org>2003-08-18 19:34:00 -0700
commitb50ca02ac68265ffb102f7c9da13e429c7fb8f13 (patch)
tree047f7c62e32eb2a82a4bb5bd30e01279e9b9fb2a
parentebbbef610d7081e1820beb6ca375377c834b29c2 (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.h2
-rw-r--r--net/sunrpc/svcsock.c16
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;