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 /fs/lockd | |
| 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>
Diffstat (limited to 'fs/lockd')
| -rw-r--r-- | fs/lockd/host.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/fs/lockd/host.c b/fs/lockd/host.c index c252a1c958..572601e98d 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, |
