From patchwork Thu Jun 23 19:29:47 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Greear X-Patchwork-Id: 913492 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p5NJTvZb000782 for ; Thu, 23 Jun 2011 19:30:16 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933005Ab1FWTaO (ORCPT ); Thu, 23 Jun 2011 15:30:14 -0400 Received: from mail.candelatech.com ([208.74.158.172]:43995 "EHLO ns3.lanforge.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932729Ab1FWTaO (ORCPT ); Thu, 23 Jun 2011 15:30:14 -0400 Received: from localhost.localdomain (firewall.candelatech.com [70.89.124.249]) by ns3.lanforge.com (8.14.2/8.14.2) with ESMTP id p5NJTq5A001237 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 23 Jun 2011 12:29:55 -0700 From: greearb@candelatech.com To: linux-nfs@vger.kernel.org Cc: Ben Greear Subject: [PATCH v2 12/12] lockd: Support binding nlm client to specific address. Date: Thu, 23 Jun 2011 12:29:47 -0700 Message-Id: <1308857388-12243-14-git-send-email-greearb@candelatech.com> X-Mailer: git-send-email 1.7.3.4 In-Reply-To: <1308857388-12243-1-git-send-email-greearb@candelatech.com> References: <1308857388-12243-1-git-send-email-greearb@candelatech.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Thu, 23 Jun 2011 19:30:16 +0000 (UTC) From: Ben Greear This ensures that file locking messages use the proper source IP address if the file system has been mounted with a specified source IP address. Signed-off-by: Ben Greear --- :100644 100644 8d4ea83... e8dff8d... M fs/lockd/clntlock.c :100644 100644 b7c99bf... 140fccc... M fs/lockd/host.c :100644 100644 8b8766a... 39c7667... M fs/nfs/client.c :100644 100644 fbc48f8... 822bcc3... M include/linux/lockd/bind.h :100644 100644 ff9abff... b69ef3b... M include/linux/lockd/lockd.h :100644 100644 db7bcaf... adfe318... M include/linux/sunrpc/clnt.h fs/lockd/clntlock.c | 3 ++- fs/lockd/host.c | 17 ++++++++++++++++- fs/nfs/client.c | 1 + include/linux/lockd/bind.h | 1 + include/linux/lockd/lockd.h | 1 + include/linux/sunrpc/clnt.h | 2 ++ 6 files changed, 23 insertions(+), 2 deletions(-) diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index 8d4ea83..e8dff8d 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c @@ -60,7 +60,8 @@ struct nlm_host *nlmclnt_init(const struct nlmclnt_initdata *nlm_init) if (status < 0) return ERR_PTR(status); - host = nlmclnt_lookup_host(nlm_init->address, nlm_init->addrlen, + host = nlmclnt_lookup_host(nlm_init->address, nlm_init->srcaddr, + nlm_init->addrlen, nlm_init->protocol, nlm_version, nlm_init->hostname, nlm_init->noresvport); if (host == NULL) { diff --git a/fs/lockd/host.c b/fs/lockd/host.c index b7c99bf..140fccc 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c @@ -48,6 +48,7 @@ static void nlm_gc_hosts(void); struct nlm_lookup_host_info { const int server; /* search for server|client */ const struct sockaddr *sap; /* address to search for */ + const struct sockaddr *src_addr; /* source address */ const size_t salen; /* it's length */ const unsigned short protocol; /* transport to search for*/ const u32 version; /* NLM version to search for */ @@ -130,7 +131,12 @@ static struct nlm_host *nlm_alloc_host(struct nlm_lookup_host_info *ni, memcpy(nlm_addr(host), ni->sap, ni->salen); host->h_addrlen = ni->salen; rpc_set_port(nlm_addr(host), 0); - host->h_srcaddrlen = 0; + if (ni->src_addr && ni->src_addr->sa_family != AF_UNSPEC) { + memcpy(nlm_srcaddr(host), ni->src_addr, ni->salen); + host->h_srcaddrlen = ni->salen; + } else { + host->h_srcaddrlen = 0; + } host->h_rpcclnt = NULL; host->h_name = nsm->sm_name; @@ -202,6 +208,7 @@ static void nlm_destroy_host_locked(struct nlm_host *host) * created and returned. */ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, + const struct sockaddr *srcaddr, const size_t salen, const unsigned short protocol, const u32 version, @@ -216,6 +223,7 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, .version = version, .hostname = hostname, .hostname_len = strlen(hostname), + .src_addr = srcaddr, .noresvport = noresvport, }; struct hlist_head *chain; @@ -234,6 +242,13 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, if (!rpc_cmp_addr(nlm_addr(host), sap)) continue; + /* Check for local binding match only if user + * has specified the source-address. + */ + if (srcaddr && srcaddr->sa_family != AF_UNSPEC && + !rpc_cmp_addr(nlm_srcaddr(host), srcaddr)) + continue; + /* Same address. Share an NSM handle if we already have one */ if (nsm == NULL) nsm = host->h_nsmhandle; diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 8b8766a..39c7667 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -705,6 +705,7 @@ static int nfs_start_lockd(struct nfs_server *server) struct nlmclnt_initdata nlm_init = { .hostname = clp->cl_hostname, .address = (struct sockaddr *)&clp->cl_addr, + .srcaddr = (struct sockaddr *)&clp->srcaddr, .addrlen = clp->cl_addrlen, .nfs_version = clp->rpc_ops->version, .noresvport = server->flags & NFS_MOUNT_NORESVPORT ? diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h index fbc48f8..822bcc3 100644 --- a/include/linux/lockd/bind.h +++ b/include/linux/lockd/bind.h @@ -38,6 +38,7 @@ extern struct nlmsvc_binding * nlmsvc_ops; struct nlmclnt_initdata { const char *hostname; const struct sockaddr *address; + const struct sockaddr *srcaddr; size_t addrlen; unsigned short protocol; u32 nfs_version; diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index ff9abff..b69ef3b 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h @@ -218,6 +218,7 @@ void nlmclnt_next_cookie(struct nlm_cookie *); * Host cache */ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, + const struct sockaddr *bindaddr, const size_t salen, const unsigned short protocol, const u32 version, diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index db7bcaf..adfe318 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -262,6 +262,8 @@ static inline bool rpc_cmp_addr(const struct sockaddr *sap1, return __rpc_cmp_addr4(sap1, sap2); case AF_INET6: return __rpc_cmp_addr6(sap1, sap2); + case AF_UNSPEC: + return true; } } return false;