diff options
author | Frank van Maarseveen <frankvm@frankvm.com> | 2007-07-09 16:25:29 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-07-10 23:40:49 -0400 |
commit | c98451bdb2f3e6d6cc1e03adad641e9497512b49 (patch) | |
tree | e5e2aa60dd308fc5fa2b641d84798e6b93376949 | |
parent | d3bc9a1deb8964d774af8535814cb91bf8f6def0 (diff) |
NLM: fix source address of callback to client
Use the destination address of the original NLM request as the
source address in callbacks to the client.
Signed-off-by: Frank van Maarseveen <frankvm@frankvm.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/lockd/host.c | 27 | ||||
-rw-r--r-- | include/linux/lockd/lockd.h | 1 |
2 files changed, 20 insertions, 8 deletions
diff --git a/fs/lockd/host.c b/fs/lockd/host.c index c252a1c95857..572601e98dcd 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c | |||
@@ -44,9 +44,8 @@ static struct nsm_handle * nsm_find(const struct sockaddr_in *sin, | |||
44 | */ | 44 | */ |
45 | static struct nlm_host * | 45 | static struct nlm_host * |
46 | nlm_lookup_host(int server, const struct sockaddr_in *sin, | 46 | nlm_lookup_host(int server, const struct sockaddr_in *sin, |
47 | int proto, int version, | 47 | int proto, int version, const char *hostname, |
48 | const char *hostname, | 48 | int hostname_len, const struct sockaddr_in *ssin) |
49 | int hostname_len) | ||
50 | { | 49 | { |
51 | struct hlist_head *chain; | 50 | struct hlist_head *chain; |
52 | struct hlist_node *pos; | 51 | struct hlist_node *pos; |
@@ -54,7 +53,9 @@ nlm_lookup_host(int server, const struct sockaddr_in *sin, | |||
54 | struct nsm_handle *nsm = NULL; | 53 | struct nsm_handle *nsm = NULL; |
55 | int hash; | 54 | int hash; |
56 | 55 | ||
57 | dprintk("lockd: nlm_lookup_host(%u.%u.%u.%u, p=%d, v=%d, my role=%s, name=%.*s)\n", | 56 | dprintk("lockd: nlm_lookup_host("NIPQUAD_FMT"->"NIPQUAD_FMT |
57 | ", p=%d, v=%d, my role=%s, name=%.*s)\n", | ||
58 | NIPQUAD(ssin->sin_addr.s_addr), | ||
58 | NIPQUAD(sin->sin_addr.s_addr), proto, version, | 59 | NIPQUAD(sin->sin_addr.s_addr), proto, version, |
59 | server? "server" : "client", | 60 | server? "server" : "client", |
60 | hostname_len, | 61 | hostname_len, |
@@ -91,6 +92,8 @@ nlm_lookup_host(int server, const struct sockaddr_in *sin, | |||
91 | continue; | 92 | continue; |
92 | if (host->h_server != server) | 93 | if (host->h_server != server) |
93 | continue; | 94 | continue; |
95 | if (!nlm_cmp_addr(&host->h_saddr, ssin)) | ||
96 | continue; | ||
94 | 97 | ||
95 | /* Move to head of hash chain. */ | 98 | /* Move to head of hash chain. */ |
96 | hlist_del(&host->h_hash); | 99 | hlist_del(&host->h_hash); |
@@ -118,6 +121,7 @@ nlm_lookup_host(int server, const struct sockaddr_in *sin, | |||
118 | host->h_name = nsm->sm_name; | 121 | host->h_name = nsm->sm_name; |
119 | host->h_addr = *sin; | 122 | host->h_addr = *sin; |
120 | host->h_addr.sin_port = 0; /* ouch! */ | 123 | host->h_addr.sin_port = 0; /* ouch! */ |
124 | host->h_saddr = *ssin; | ||
121 | host->h_version = version; | 125 | host->h_version = version; |
122 | host->h_proto = proto; | 126 | host->h_proto = proto; |
123 | host->h_rpcclnt = NULL; | 127 | host->h_rpcclnt = NULL; |
@@ -174,8 +178,10 @@ struct nlm_host * | |||
174 | nlmclnt_lookup_host(const struct sockaddr_in *sin, int proto, int version, | 178 | nlmclnt_lookup_host(const struct sockaddr_in *sin, int proto, int version, |
175 | const char *hostname, int hostname_len) | 179 | const char *hostname, int hostname_len) |
176 | { | 180 | { |
181 | struct sockaddr_in ssin = {0}; | ||
182 | |||
177 | return nlm_lookup_host(0, sin, proto, version, | 183 | return nlm_lookup_host(0, sin, proto, version, |
178 | hostname, hostname_len); | 184 | hostname, hostname_len, &ssin); |
179 | } | 185 | } |
180 | 186 | ||
181 | /* | 187 | /* |
@@ -185,9 +191,12 @@ struct nlm_host * | |||
185 | nlmsvc_lookup_host(struct svc_rqst *rqstp, | 191 | nlmsvc_lookup_host(struct svc_rqst *rqstp, |
186 | const char *hostname, int hostname_len) | 192 | const char *hostname, int hostname_len) |
187 | { | 193 | { |
194 | struct sockaddr_in ssin = {0}; | ||
195 | |||
196 | ssin.sin_addr = rqstp->rq_daddr.addr; | ||
188 | return nlm_lookup_host(1, svc_addr_in(rqstp), | 197 | return nlm_lookup_host(1, svc_addr_in(rqstp), |
189 | rqstp->rq_prot, rqstp->rq_vers, | 198 | rqstp->rq_prot, rqstp->rq_vers, |
190 | hostname, hostname_len); | 199 | hostname, hostname_len, &ssin); |
191 | } | 200 | } |
192 | 201 | ||
193 | /* | 202 | /* |
@@ -198,8 +207,9 @@ nlm_bind_host(struct nlm_host *host) | |||
198 | { | 207 | { |
199 | struct rpc_clnt *clnt; | 208 | struct rpc_clnt *clnt; |
200 | 209 | ||
201 | dprintk("lockd: nlm_bind_host(%08x)\n", | 210 | dprintk("lockd: nlm_bind_host("NIPQUAD_FMT"->"NIPQUAD_FMT")\n", |
202 | (unsigned)ntohl(host->h_addr.sin_addr.s_addr)); | 211 | NIPQUAD(host->h_saddr.sin_addr), |
212 | NIPQUAD(host->h_addr.sin_addr)); | ||
203 | 213 | ||
204 | /* Lock host handle */ | 214 | /* Lock host handle */ |
205 | mutex_lock(&host->h_mutex); | 215 | mutex_lock(&host->h_mutex); |
@@ -226,6 +236,7 @@ nlm_bind_host(struct nlm_host *host) | |||
226 | .protocol = host->h_proto, | 236 | .protocol = host->h_proto, |
227 | .address = (struct sockaddr *)&host->h_addr, | 237 | .address = (struct sockaddr *)&host->h_addr, |
228 | .addrsize = sizeof(host->h_addr), | 238 | .addrsize = sizeof(host->h_addr), |
239 | .saddress = (struct sockaddr *)&host->h_saddr, | ||
229 | .timeout = &timeparms, | 240 | .timeout = &timeparms, |
230 | .servername = host->h_name, | 241 | .servername = host->h_name, |
231 | .program = &nlm_program, | 242 | .program = &nlm_program, |
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index 05707e2fccae..e2d1ce36b367 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h | |||
@@ -39,6 +39,7 @@ | |||
39 | struct nlm_host { | 39 | struct nlm_host { |
40 | struct hlist_node h_hash; /* doubly linked list */ | 40 | struct hlist_node h_hash; /* doubly linked list */ |
41 | struct sockaddr_in h_addr; /* peer address */ | 41 | struct sockaddr_in h_addr; /* peer address */ |
42 | struct sockaddr_in h_saddr; /* our address (optional) */ | ||
42 | struct rpc_clnt * h_rpcclnt; /* RPC client to talk to peer */ | 43 | struct rpc_clnt * h_rpcclnt; /* RPC client to talk to peer */ |
43 | char * h_name; /* remote hostname */ | 44 | char * h_name; /* remote hostname */ |
44 | u32 h_version; /* interface version */ | 45 | u32 h_version; /* interface version */ |