Commit b50ca02a authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[PATCH] kNFSd: Make sure nfsd replies from the address the request was sent to.

This is important on multi-homes hosts.
parent ebbbef61
...@@ -131,6 +131,8 @@ struct svc_rqst { ...@@ -131,6 +131,8 @@ struct svc_rqst {
rq_secure : 1; /* secure port */ rq_secure : 1; /* secure port */
__u32 rq_daddr; /* dest addr of request - reply from here */
void * rq_argp; /* decoded arguments */ void * rq_argp; /* decoded arguments */
void * rq_resp; /* xdr'd results */ void * rq_resp; /* xdr'd results */
......
...@@ -353,6 +353,9 @@ svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr) ...@@ -353,6 +353,9 @@ svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr)
struct svc_sock *svsk = rqstp->rq_sock; struct svc_sock *svsk = rqstp->rq_sock;
struct socket *sock = svsk->sk_sock; struct socket *sock = svsk->sk_sock;
int slen; int slen;
struct { struct cmsghdr cmh;
struct in_pktinfo pki;
} cm;
int len = 0; int len = 0;
int result; int result;
int size; int size;
...@@ -364,16 +367,22 @@ svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr) ...@@ -364,16 +367,22 @@ svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr)
slen = xdr->len; slen = xdr->len;
if (rqstp->rq_prot == IPPROTO_UDP) { if (rqstp->rq_prot == IPPROTO_UDP) {
/* set the destination */ /* set the source and destination */
struct msghdr msg; struct msghdr msg;
msg.msg_name = &rqstp->rq_addr; msg.msg_name = &rqstp->rq_addr;
msg.msg_namelen = sizeof(rqstp->rq_addr); msg.msg_namelen = sizeof(rqstp->rq_addr);
msg.msg_iov = NULL; msg.msg_iov = NULL;
msg.msg_iovlen = 0; msg.msg_iovlen = 0;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_flags = MSG_MORE; 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) if (sock_sendmsg(sock, &msg, 0) < 0)
goto out; goto out;
} }
...@@ -594,6 +603,7 @@ svc_udp_recvfrom(struct svc_rqst *rqstp) ...@@ -594,6 +603,7 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
rqstp->rq_addr.sin_family = AF_INET; rqstp->rq_addr.sin_family = AF_INET;
rqstp->rq_addr.sin_port = skb->h.uh->source; rqstp->rq_addr.sin_port = skb->h.uh->source;
rqstp->rq_addr.sin_addr.s_addr = skb->nh.iph->saddr; 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; svsk->sk_sk->sk_stamp = skb->stamp;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment