* [PATCH 0/7] nfs-utils: Support binding to source address.
@ 2011-06-10 18:09 greearb
2011-06-10 18:09 ` [PATCH 1/7] nfs-utils: Add structure for passing local binding info greearb
` (6 more replies)
0 siblings, 7 replies; 11+ messages in thread
From: greearb @ 2011-06-10 18:09 UTC (permalink / raw)
To: linux-nfs; +Cc: Ben Greear
From: Ben Greear <greearb@candelatech.com>
This lets one specify the source IP address for
sockets, allowing users to leverage routing rules
on multi-homed systems.
Kernel patches to RPC and NFS are needed to complete
full functionality.
v3: Break into smaller patches for easier review.
Remove srcaddr support from non-stropts API.
Ben Greear (7):
nfs-utils: Add structure for passing local binding info.
nfs-utils: Add patch to parse srcaddr= option.
nfs-utils: Implement srcaddr binding in rpc_socket
nfs-utils: Implement srcaddr binding in network.c
nfs-utils: Support srcaddr=n option for string mount.
nfs-utils: Implement srcaddr=n binding for unmount.
nfs-utils: Update man page for srcaddr= option.
support/include/nfsrpc.h | 23 +++++--
support/include/sockaddr.h | 6 ++
support/nfs/getport.c | 37 +++++++----
support/nfs/rpc_socket.c | 96 ++++++++++++++++++++--------
utils/gssd/gssd.h | 2 +
utils/gssd/gssd_proc.c | 33 ++++++----
utils/mount/network.c | 149 +++++++++++++++++++++++++++++++++----------
utils/mount/network.h | 20 ++++--
utils/mount/nfs.man | 7 ++
utils/mount/nfs4mount.c | 3 +-
utils/mount/nfsmount.c | 6 +-
utils/mount/nfsumount.c | 26 +++++++-
utils/mount/stropts.c | 35 +++++++++-
utils/mount/utils.c | 6 +-
utils/mount/utils.h | 4 +-
15 files changed, 335 insertions(+), 118 deletions(-)
--
1.7.3.4
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/7] nfs-utils: Add structure for passing local binding info.
2011-06-10 18:09 [PATCH 0/7] nfs-utils: Support binding to source address greearb
@ 2011-06-10 18:09 ` greearb
2011-06-10 18:09 ` [PATCH 2/7] nfs-utils: Add patch to parse srcaddr= option greearb
` (5 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: greearb @ 2011-06-10 18:09 UTC (permalink / raw)
To: linux-nfs; +Cc: Ben Greear
From: Ben Greear <greearb@candelatech.com>
Create a struct local_bind_info that will hold an IP
address to be used for binding to a local IP address.
Pass this down to the code that needs it.
There are no functional changes in this patch, just passing
around un-used variables which are always NULL. Future
patches will use this.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 d50fe94... d8ef257... M support/include/nfsrpc.h
:100644 100644 9af2543... b1089ce... M support/include/sockaddr.h
:100644 100644 d74400b... e8256ff... M support/nfs/getport.c
:100644 100644 c14efe8... 5652f6c... M support/nfs/rpc_socket.c
:100644 100644 b1b5793... ccd44a2... M utils/gssd/gssd.h
:100644 100644 41328c9... e584d20... M utils/gssd/gssd_proc.c
:100644 100644 d1f91dc... 6dc257b... M utils/mount/network.c
:100644 100644 81c6f22... 5732eb6... M utils/mount/network.h
:100644 100644 028e7cd... 80fab0d... M utils/mount/nfs4mount.c
:100644 100644 1298fe4... ff85bf5... M utils/mount/nfsmount.c
:100644 100644 f1aa503... 71417df... M utils/mount/stropts.c
:100644 100644 298db39... eb50074... M utils/mount/utils.c
support/include/nfsrpc.h | 23 ++++++++----
support/include/sockaddr.h | 6 +++
support/nfs/getport.c | 37 +++++++++++++-------
support/nfs/rpc_socket.c | 37 ++++++++++++--------
utils/gssd/gssd.h | 2 +
utils/gssd/gssd_proc.c | 33 ++++++++++-------
utils/mount/network.c | 83 +++++++++++++++++++++++++++-----------------
utils/mount/network.h | 18 ++++++----
utils/mount/nfs4mount.c | 3 +-
utils/mount/nfsmount.c | 6 ++--
utils/mount/stropts.c | 2 +-
utils/mount/utils.c | 2 +-
12 files changed, 158 insertions(+), 94 deletions(-)
diff --git a/support/include/nfsrpc.h b/support/include/nfsrpc.h
index d50fe94..d8ef257 100644
--- a/support/include/nfsrpc.h
+++ b/support/include/nfsrpc.h
@@ -55,6 +55,8 @@
#define NSMPROG ((rpcprog_t)100024)
#endif
+struct local_bind_info;
+
/**
* nfs_clear_rpc_createerr - zap all error reporting fields
*
@@ -75,7 +77,8 @@ extern rpcprog_t nfs_getrpcbyname(const rpcprog_t, const char *table[]);
extern CLIENT *nfs_get_rpcclient(const struct sockaddr *,
const socklen_t, const unsigned short,
const rpcprog_t, const rpcvers_t,
- struct timeval *);
+ struct timeval *,
+ struct local_bind_info *);
/*
* Acquire an RPC CLIENT * with a privileged source port
@@ -83,7 +86,8 @@ extern CLIENT *nfs_get_rpcclient(const struct sockaddr *,
extern CLIENT *nfs_get_priv_rpcclient( const struct sockaddr *,
const socklen_t, const unsigned short,
const rpcprog_t, const rpcvers_t,
- struct timeval *);
+ struct timeval *,
+ struct local_bind_info *);
/*
* Convert a netid to a protocol number and protocol family
@@ -116,7 +120,8 @@ extern int nfs_getport_ping(struct sockaddr *sap,
const socklen_t salen,
const rpcprog_t program,
const rpcvers_t version,
- const unsigned short protocol);
+ const unsigned short protocol,
+ struct local_bind_info *local_ip);
/*
* Generic function that maps an RPC service tuple to an IP port
@@ -124,14 +129,16 @@ extern int nfs_getport_ping(struct sockaddr *sap,
*/
extern unsigned short nfs_getport(const struct sockaddr *,
const socklen_t, const rpcprog_t,
- const rpcvers_t, const unsigned short);
+ const rpcvers_t, const unsigned short,
+ struct local_bind_info *local_ip);
/*
* Generic function that maps an RPC service tuple to an IP port
* number of the service on the local host
*/
extern unsigned short nfs_getlocalport(const rpcprot_t,
- const rpcvers_t, const unsigned short);
+ const rpcvers_t, const unsigned short,
+ struct local_bind_info *local_ip);
/*
* Function to invoke an rpcbind v3/v4 GETADDR request
@@ -153,7 +160,8 @@ extern unsigned long nfs_pmap_getport(const struct sockaddr_in *,
const unsigned long,
const unsigned long,
const unsigned long,
- const struct timeval *);
+ const struct timeval *,
+ struct local_bind_info *local_ip);
/*
* Contact a remote RPC service to discover whether it is responding
@@ -164,7 +172,8 @@ extern int nfs_rpc_ping(const struct sockaddr *sap,
const rpcprog_t program,
const rpcvers_t version,
const unsigned short protocol,
- const struct timeval *timeout);
+ const struct timeval *timeout,
+ struct local_bind_info *local_ip);
/* create AUTH_SYS handle with no supplemental groups */
extern AUTH * nfs_authsys_create(void);
diff --git a/support/include/sockaddr.h b/support/include/sockaddr.h
index 9af2543..b1089ce 100644
--- a/support/include/sockaddr.h
+++ b/support/include/sockaddr.h
@@ -46,6 +46,12 @@ union nfs_sockaddr {
struct sockaddr_in6 s6;
};
+struct local_bind_info {
+ union nfs_sockaddr addr;
+ socklen_t addrlen;
+ bool is_set;
+};
+
#if SIZEOF_SOCKLEN_T - 0 == 0
#define socklen_t unsigned int
#endif
diff --git a/support/nfs/getport.c b/support/nfs/getport.c
index d74400b..e8256ff 100644
--- a/support/nfs/getport.c
+++ b/support/nfs/getport.c
@@ -181,7 +181,8 @@ static CLIENT *nfs_gp_get_rpcbclient(struct sockaddr *sap,
const socklen_t salen,
const unsigned short transport,
const rpcvers_t version,
- struct timeval *timeout)
+ struct timeval *timeout,
+ struct local_bind_info *local_ip)
{
static const char *rpcb_pgmtbl[] = {
"rpcbind",
@@ -195,7 +196,7 @@ static CLIENT *nfs_gp_get_rpcbclient(struct sockaddr *sap,
nfs_set_port(sap, ntohs(nfs_gp_get_rpcb_port(transport)));
clnt = nfs_get_rpcclient(sap, salen, transport, rpcb_prog,
- version, timeout);
+ version, timeout, local_ip);
nfs_gp_map_tcp_errorcodes(transport);
return clnt;
}
@@ -729,7 +730,8 @@ static unsigned short nfs_gp_getport(CLIENT *client,
*/
int nfs_rpc_ping(const struct sockaddr *sap, const socklen_t salen,
const rpcprog_t program, const rpcvers_t version,
- const unsigned short protocol, const struct timeval *timeout)
+ const unsigned short protocol, const struct timeval *timeout,
+ struct local_bind_info *local_ip)
{
union nfs_sockaddr address;
struct sockaddr *saddr = &address.sa;
@@ -744,7 +746,7 @@ int nfs_rpc_ping(const struct sockaddr *sap, const socklen_t salen,
memcpy(saddr, sap, (size_t)salen);
client = nfs_get_rpcclient(saddr, salen, protocol,
- program, version, &tout);
+ program, version, &tout, local_ip);
if (client != NULL) {
result = nfs_gp_ping(client, tout);
nfs_gp_map_tcp_errorcodes(protocol);
@@ -798,7 +800,8 @@ unsigned short nfs_getport(const struct sockaddr *sap,
const socklen_t salen,
const rpcprog_t program,
const rpcvers_t version,
- const unsigned short protocol)
+ const unsigned short protocol,
+ struct local_bind_info *local_ip)
{
union nfs_sockaddr address;
struct sockaddr *saddr = &address.sa;
@@ -810,7 +813,8 @@ unsigned short nfs_getport(const struct sockaddr *sap,
memcpy(saddr, sap, (size_t)salen);
client = nfs_gp_get_rpcbclient(saddr, salen, protocol,
- default_rpcb_version, &timeout);
+ default_rpcb_version, &timeout,
+ local_ip);
if (client != NULL) {
port = nfs_gp_getport(client, saddr, program,
version, protocol, timeout);
@@ -840,7 +844,8 @@ unsigned short nfs_getport(const struct sockaddr *sap,
*/
int nfs_getport_ping(struct sockaddr *sap, const socklen_t salen,
const rpcprog_t program, const rpcvers_t version,
- const unsigned short protocol)
+ const unsigned short protocol,
+ struct local_bind_info *local_ip)
{
struct timeval timeout = { -1, 0 };
unsigned short port = 0;
@@ -850,7 +855,8 @@ int nfs_getport_ping(struct sockaddr *sap, const socklen_t salen,
nfs_clear_rpc_createerr();
client = nfs_gp_get_rpcbclient(sap, salen, protocol,
- default_rpcb_version, &timeout);
+ default_rpcb_version, &timeout,
+ local_ip);
if (client != NULL) {
port = nfs_gp_getport(client, sap, program,
version, protocol, timeout);
@@ -868,7 +874,8 @@ int nfs_getport_ping(struct sockaddr *sap, const socklen_t salen,
nfs_clear_rpc_createerr();
client = nfs_get_rpcclient(saddr, salen, protocol,
- program, version, &timeout);
+ program, version, &timeout,
+ local_ip);
if (client != NULL) {
result = nfs_gp_ping(client, timeout);
nfs_gp_map_tcp_errorcodes(protocol);
@@ -909,7 +916,8 @@ int nfs_getport_ping(struct sockaddr *sap, const socklen_t salen,
*/
unsigned short nfs_getlocalport(const rpcprot_t program,
const rpcvers_t version,
- const unsigned short protocol)
+ const unsigned short protocol,
+ struct local_bind_info *local_ip)
{
union nfs_sockaddr address;
struct sockaddr *lb_addr = &address.sa;
@@ -946,7 +954,8 @@ unsigned short nfs_getlocalport(const rpcprot_t program,
if (nfs_gp_loopback_address(lb_addr, &lb_len)) {
port = nfs_getport(lb_addr, lb_len,
- program, version, protocol);
+ program, version, protocol,
+ local_ip);
} else
rpc_createerr.cf_stat = RPC_UNKNOWNADDR;
}
@@ -1074,7 +1083,8 @@ unsigned long nfs_pmap_getport(const struct sockaddr_in *sin,
const unsigned long program,
const unsigned long version,
const unsigned long protocol,
- const struct timeval *timeout)
+ const struct timeval *timeout,
+ struct local_bind_info *local_ip)
{
struct sockaddr_in address;
struct sockaddr *saddr = (struct sockaddr *)&address;
@@ -1094,7 +1104,8 @@ unsigned long nfs_pmap_getport(const struct sockaddr_in *sin,
memcpy(saddr, sin, sizeof(address));
client = nfs_gp_get_rpcbclient(saddr, (socklen_t)sizeof(*sin),
- transport, PMAPVERS, &tout);
+ transport, PMAPVERS, &tout,
+ local_ip);
if (client != NULL) {
port = nfs_gp_pmap_getport(client, &parms, tout);
CLNT_DESTROY(client);
diff --git a/support/nfs/rpc_socket.c b/support/nfs/rpc_socket.c
index c14efe8..5652f6c 100644
--- a/support/nfs/rpc_socket.c
+++ b/support/nfs/rpc_socket.c
@@ -112,7 +112,8 @@ static CLIENT *nfs_get_localclient(const struct sockaddr *sap,
* Returns zero on success, or returns -1 on error. errno is
* set to reflect the nature of the error.
*/
-static int nfs_bind(const int sock, const sa_family_t family)
+static int nfs_bind(const int sock, const sa_family_t family,
+ struct local_bind_info *local_ip)
{
struct sockaddr_in sin = {
.sin_family = AF_INET,
@@ -144,7 +145,8 @@ static int nfs_bind(const int sock, const sa_family_t family)
* Returns zero on success, or returns -1 on error. errno is
* set to reflect the nature of the error.
*/
-static int nfs_bindresvport(const int sock, const sa_family_t family)
+static int nfs_bindresvport(const int sock, const sa_family_t family,
+ struct local_bind_info *local_ip)
{
struct sockaddr_in sin = {
.sin_family = AF_INET,
@@ -174,7 +176,8 @@ static int nfs_bindresvport(const int sock, const sa_family_t family)
* Returns zero on success, or returns -1 on error. errno is
* set to reflect the nature of the error.
*/
-static int nfs_bindresvport(const int sock, const sa_family_t family)
+static int nfs_bindresvport(const int sock, const sa_family_t family,
+ struct local_bind_info *local_ip)
{
if (family != AF_INET) {
errno = EAFNOSUPPORT;
@@ -273,7 +276,8 @@ static CLIENT *nfs_get_udpclient(const struct sockaddr *sap,
const rpcprog_t program,
const rpcvers_t version,
struct timeval *timeout,
- const int resvport)
+ const int resvport,
+ struct local_bind_info *local_ip)
{
CLIENT *client;
int ret, sock;
@@ -301,9 +305,9 @@ static CLIENT *nfs_get_udpclient(const struct sockaddr *sap,
}
if (resvport)
- ret = nfs_bindresvport(sock, sap->sa_family);
+ ret = nfs_bindresvport(sock, sap->sa_family, local_ip);
else
- ret = nfs_bind(sock, sap->sa_family);
+ ret = nfs_bind(sock, sap->sa_family, local_ip);
if (ret < 0) {
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
@@ -355,7 +359,8 @@ static CLIENT *nfs_get_tcpclient(const struct sockaddr *sap,
const rpcprog_t program,
const rpcvers_t version,
struct timeval *timeout,
- const int resvport)
+ const int resvport,
+ struct local_bind_info *local_ip)
{
CLIENT *client;
int ret, sock;
@@ -383,9 +388,9 @@ static CLIENT *nfs_get_tcpclient(const struct sockaddr *sap,
}
if (resvport)
- ret = nfs_bindresvport(sock, sap->sa_family);
+ ret = nfs_bindresvport(sock, sap->sa_family, local_ip);
else
- ret = nfs_bind(sock, sap->sa_family);
+ ret = nfs_bind(sock, sap->sa_family, local_ip);
if (ret < 0) {
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
@@ -442,7 +447,8 @@ CLIENT *nfs_get_rpcclient(const struct sockaddr *sap,
const unsigned short transport,
const rpcprog_t program,
const rpcvers_t version,
- struct timeval *timeout)
+ struct timeval *timeout,
+ struct local_bind_info *local_ip)
{
nfs_clear_rpc_createerr();
@@ -465,11 +471,11 @@ CLIENT *nfs_get_rpcclient(const struct sockaddr *sap,
switch (transport) {
case IPPROTO_TCP:
return nfs_get_tcpclient(sap, salen, program, version,
- timeout, 0);
+ timeout, 0, local_ip);
case 0:
case IPPROTO_UDP:
return nfs_get_udpclient(sap, salen, program, version,
- timeout, 0);
+ timeout, 0, local_ip);
}
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
@@ -499,7 +505,8 @@ CLIENT *nfs_get_priv_rpcclient(const struct sockaddr *sap,
const unsigned short transport,
const rpcprog_t program,
const rpcvers_t version,
- struct timeval *timeout)
+ struct timeval *timeout,
+ struct local_bind_info *local_ip)
{
nfs_clear_rpc_createerr();
@@ -522,11 +529,11 @@ CLIENT *nfs_get_priv_rpcclient(const struct sockaddr *sap,
switch (transport) {
case IPPROTO_TCP:
return nfs_get_tcpclient(sap, salen, program, version,
- timeout, 1);
+ timeout, 1, local_ip);
case 0:
case IPPROTO_UDP:
return nfs_get_udpclient(sap, salen, program, version,
- timeout, 1);
+ timeout, 1, local_ip);
}
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
diff --git a/utils/gssd/gssd.h b/utils/gssd/gssd.h
index b1b5793..ccd44a2 100644
--- a/utils/gssd/gssd.h
+++ b/utils/gssd/gssd.h
@@ -34,6 +34,7 @@
#include <sys/types.h>
#include <sys/queue.h>
#include <gssapi/gssapi.h>
+#include "sockaddr.h"
#define MAX_FILE_NAMELEN 32
#define FD_ALLOC_BLOCK 256
@@ -85,6 +86,7 @@ struct clnt_info {
int gssd_fd;
int gssd_poll_index;
struct sockaddr_storage addr;
+ struct local_bind_info local_ip;
};
TAILQ_HEAD(topdirs_list_head, topdirs_info) topdirs_list;
diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c
index 41328c9..e584d20 100644
--- a/utils/gssd/gssd_proc.c
+++ b/utils/gssd/gssd_proc.c
@@ -726,7 +726,8 @@ out_err:
static int
populate_port(struct sockaddr *sa, const socklen_t salen,
const rpcprog_t program, const rpcvers_t version,
- const unsigned short protocol)
+ const unsigned short protocol,
+ struct local_bind_info *local_ip)
{
struct sockaddr_in *s4 = (struct sockaddr_in *) sa;
#ifdef IPV6_SUPPORTED
@@ -774,7 +775,7 @@ populate_port(struct sockaddr *sa, const socklen_t salen,
goto set_port;
}
- port = nfs_getport(sa, salen, program, version, protocol);
+ port = nfs_getport(sa, salen, program, version, protocol, local_ip);
if (!port) {
printerr(0, "ERROR: unable to obtain port for prog %ld "
"vers %ld\n", program, version);
@@ -807,7 +808,8 @@ int create_auth_rpc_client(struct clnt_info *clp,
CLIENT **clnt_return,
AUTH **auth_return,
uid_t uid,
- int authtype)
+ int authtype,
+ struct local_bind_info *local_ip)
{
CLIENT *rpc_clnt = NULL;
struct rpc_gss_sec sec;
@@ -899,11 +901,12 @@ int create_auth_rpc_client(struct clnt_info *clp,
goto out_fail;
}
- if (!populate_port(addr, salen, clp->prog, clp->vers, protocol))
+ if (!populate_port(addr, salen, clp->prog, clp->vers,
+ protocol, local_ip))
goto out_fail;
rpc_clnt = nfs_get_rpcclient(addr, salen, protocol, clp->prog,
- clp->vers, &timeout);
+ clp->vers, &timeout, local_ip);
if (!rpc_clnt) {
snprintf(rpc_errmsg, sizeof(rpc_errmsg),
"WARNING: can't create %s rpc_clnt to server %s for "
@@ -955,7 +958,7 @@ int create_auth_rpc_client(struct clnt_info *clp,
*/
static void
process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
- char *service)
+ char *service, struct local_bind_info *local_ip)
{
CLIENT *rpc_clnt = NULL;
AUTH *auth = NULL;
@@ -1011,7 +1014,7 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
downcall_err = -EKEYEXPIRED;
else if (!err)
create_resp = create_auth_rpc_client(clp, &rpc_clnt, &auth, uid,
- AUTHTYPE_KRB5);
+ AUTHTYPE_KRB5, local_ip);
if (create_resp == 0)
break;
}
@@ -1038,7 +1041,8 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
gssd_setup_krb5_machine_gss_ccache(*ccname);
if ((create_auth_rpc_client(clp, &rpc_clnt,
&auth, uid,
- AUTHTYPE_KRB5)) == 0) {
+ AUTHTYPE_KRB5,
+ local_ip)) == 0) {
/* Success! */
success++;
break;
@@ -1108,7 +1112,8 @@ out_return_error:
* context on behalf of the kernel
*/
static void
-process_spkm3_upcall(struct clnt_info *clp, uid_t uid, int fd)
+process_spkm3_upcall(struct clnt_info *clp, uid_t uid, int fd,
+ struct local_bind_info *local_ip)
{
CLIENT *rpc_clnt = NULL;
AUTH *auth = NULL;
@@ -1120,7 +1125,7 @@ process_spkm3_upcall(struct clnt_info *clp, uid_t uid, int fd)
token.length = 0;
token.value = NULL;
- if (create_auth_rpc_client(clp, &rpc_clnt, &auth, uid, AUTHTYPE_SPKM3)) {
+ if (create_auth_rpc_client(clp, &rpc_clnt, &auth, uid, AUTHTYPE_SPKM3, local_ip)) {
printerr(0, "WARNING: Failed to create spkm3 context for "
"user with uid %d\n", uid);
goto out_return_error;
@@ -1167,7 +1172,7 @@ handle_krb5_upcall(struct clnt_info *clp)
return;
}
- return process_krb5_upcall(clp, uid, clp->krb5_fd, NULL, NULL);
+ process_krb5_upcall(clp, uid, clp->krb5_fd, NULL, NULL, &clp->local_ip);
}
void
@@ -1181,7 +1186,7 @@ handle_spkm3_upcall(struct clnt_info *clp)
return;
}
- return process_spkm3_upcall(clp, uid, clp->spkm3_fd);
+ process_spkm3_upcall(clp, uid, clp->spkm3_fd, &clp->local_ip);
}
void
@@ -1291,9 +1296,9 @@ handle_gssd_upcall(struct clnt_info *clp)
}
if (strcmp(mech, "krb5") == 0)
- process_krb5_upcall(clp, uid, clp->gssd_fd, target, service);
+ process_krb5_upcall(clp, uid, clp->gssd_fd, target, service, &clp->local_ip);
else if (strcmp(mech, "spkm3") == 0)
- process_spkm3_upcall(clp, uid, clp->gssd_fd);
+ process_spkm3_upcall(clp, uid, clp->gssd_fd, &clp->local_ip);
else
printerr(0, "WARNING: handle_gssd_upcall: "
"received unknown gss mech '%s'\n", mech);
diff --git a/utils/mount/network.c b/utils/mount/network.c
index d1f91dc..6dc257b 100644
--- a/utils/mount/network.c
+++ b/utils/mount/network.c
@@ -410,7 +410,8 @@ out:
* The caller should check rpc_createerr to determine the cause of any error.
*/
static int get_socket(struct sockaddr_in *saddr, unsigned int p_prot,
- unsigned int timeout, int resvp, int conn)
+ unsigned int timeout, int resvp, int conn,
+ struct local_bind_info *local_ip)
{
int so, cc, type;
struct sockaddr_in laddr;
@@ -537,7 +538,8 @@ static void nfs_pp_debug2(const char *str)
*/
static int nfs_probe_port(const struct sockaddr *sap, const socklen_t salen,
struct pmap *pmap, const unsigned long *versions,
- const unsigned int *protos)
+ const unsigned int *protos,
+ struct local_bind_info *local_ip)
{
union nfs_sockaddr address;
struct sockaddr *saddr = &address.sa;
@@ -555,14 +557,16 @@ static int nfs_probe_port(const struct sockaddr *sap, const socklen_t salen,
if (verbose)
printf(_("%s: prog %lu, trying vers=%lu, prot=%u\n"),
progname, prog, *p_vers, *p_prot);
- p_port = nfs_getport(saddr, salen, prog, *p_vers, *p_prot);
+ p_port = nfs_getport(saddr, salen, prog, *p_vers, *p_prot,
+ local_ip);
if (p_port) {
if (!port || port == p_port) {
nfs_set_port(saddr, p_port);
nfs_pp_debug(saddr, salen, prog, *p_vers,
*p_prot, p_port);
if (nfs_rpc_ping(saddr, salen, prog,
- *p_vers, *p_prot, NULL))
+ *p_vers, *p_prot, NULL,
+ local_ip))
goto out_ok;
} else
rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
@@ -615,7 +619,8 @@ out_ok:
* returned; rpccreateerr.cf_stat is set to reflect the nature of the error.
*/
static int nfs_probe_nfsport(const struct sockaddr *sap, const socklen_t salen,
- struct pmap *pmap)
+ struct pmap *pmap,
+ struct local_bind_info *local_ip)
{
if (pmap->pm_vers && pmap->pm_prot && pmap->pm_port)
return 1;
@@ -626,10 +631,12 @@ static int nfs_probe_nfsport(const struct sockaddr *sap, const socklen_t salen,
probe_proto = nfs_default_proto();
return nfs_probe_port(sap, salen, pmap,
- probe_nfs3_first, probe_proto);
+ probe_nfs3_first, probe_proto,
+ local_ip);
} else
return nfs_probe_port(sap, salen, pmap,
- probe_nfs2_only, probe_udp_only);
+ probe_nfs2_only, probe_udp_only,
+ local_ip);
}
/*
@@ -646,17 +653,20 @@ static int nfs_probe_nfsport(const struct sockaddr *sap, const socklen_t salen,
* returned; rpccreateerr.cf_stat is set to reflect the nature of the error.
*/
static int nfs_probe_mntport(const struct sockaddr *sap, const socklen_t salen,
- struct pmap *pmap)
+ struct pmap *pmap,
+ struct local_bind_info *local_ip)
{
if (pmap->pm_vers && pmap->pm_prot && pmap->pm_port)
return 1;
if (nfs_mount_data_version >= 4)
return nfs_probe_port(sap, salen, pmap,
- probe_mnt3_first, probe_udp_first);
+ probe_mnt3_first, probe_udp_first,
+ local_ip);
else
return nfs_probe_port(sap, salen, pmap,
- probe_mnt1_first, probe_udp_only);
+ probe_mnt1_first, probe_udp_only,
+ local_ip);
}
/*
@@ -673,11 +683,12 @@ static int nfs_probe_version_fixed(const struct sockaddr *mnt_saddr,
struct pmap *mnt_pmap,
const struct sockaddr *nfs_saddr,
const socklen_t nfs_salen,
- struct pmap *nfs_pmap)
+ struct pmap *nfs_pmap,
+ struct local_bind_info *local_ip)
{
- if (!nfs_probe_nfsport(nfs_saddr, nfs_salen, nfs_pmap))
+ if (!nfs_probe_nfsport(nfs_saddr, nfs_salen, nfs_pmap, local_ip))
return 0;
- return nfs_probe_mntport(mnt_saddr, mnt_salen, mnt_pmap);
+ return nfs_probe_mntport(mnt_saddr, mnt_salen, mnt_pmap, local_ip);
}
/**
@@ -700,7 +711,8 @@ int nfs_probe_bothports(const struct sockaddr *mnt_saddr,
struct pmap *mnt_pmap,
const struct sockaddr *nfs_saddr,
const socklen_t nfs_salen,
- struct pmap *nfs_pmap)
+ struct pmap *nfs_pmap,
+ struct local_bind_info *local_ip)
{
struct pmap save_nfs, save_mnt;
const unsigned long *probe_vers;
@@ -712,7 +724,8 @@ int nfs_probe_bothports(const struct sockaddr *mnt_saddr,
if (nfs_pmap->pm_vers)
return nfs_probe_version_fixed(mnt_saddr, mnt_salen, mnt_pmap,
- nfs_saddr, nfs_salen, nfs_pmap);
+ nfs_saddr, nfs_salen, nfs_pmap,
+ local_ip);
memcpy(&save_nfs, nfs_pmap, sizeof(save_nfs));
memcpy(&save_mnt, mnt_pmap, sizeof(save_mnt));
@@ -721,9 +734,9 @@ int nfs_probe_bothports(const struct sockaddr *mnt_saddr,
for (; *probe_vers; probe_vers++) {
nfs_pmap->pm_vers = mntvers_to_nfs(*probe_vers);
- if (nfs_probe_nfsport(nfs_saddr, nfs_salen, nfs_pmap) != 0) {
+ if (nfs_probe_nfsport(nfs_saddr, nfs_salen, nfs_pmap, local_ip) != 0) {
mnt_pmap->pm_vers = *probe_vers;
- if (nfs_probe_mntport(mnt_saddr, mnt_salen, mnt_pmap) != 0)
+ if (nfs_probe_mntport(mnt_saddr, mnt_salen, mnt_pmap, local_ip) != 0)
return 1;
memcpy(mnt_pmap, &save_mnt, sizeof(*mnt_pmap));
}
@@ -753,7 +766,8 @@ int nfs_probe_bothports(const struct sockaddr *mnt_saddr,
* Otherwise zero is returned; rpccreateerr.cf_stat is set to reflect
* the nature of the error.
*/
-int probe_bothports(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server)
+int probe_bothports(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server,
+ struct local_bind_info *local_ip)
{
struct sockaddr *mnt_addr = SAFE_SOCKADDR(&mnt_server->saddr);
struct sockaddr *nfs_addr = SAFE_SOCKADDR(&nfs_server->saddr);
@@ -761,7 +775,7 @@ int probe_bothports(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server)
return nfs_probe_bothports(mnt_addr, sizeof(mnt_server->saddr),
&mnt_server->pmap,
nfs_addr, sizeof(nfs_server->saddr),
- &nfs_server->pmap);
+ &nfs_server->pmap, local_ip);
}
static int nfs_probe_statd(void)
@@ -773,7 +787,8 @@ static int nfs_probe_statd(void)
rpcprog_t program = nfs_getrpcbyname(NSMPROG, nfs_ns_pgmtbl);
return nfs_getport_ping(SAFE_SOCKADDR(&addr), sizeof(addr),
- program, (rpcvers_t)1, IPPROTO_UDP);
+ program, (rpcvers_t)1, IPPROTO_UDP,
+ NULL);
}
/**
@@ -829,7 +844,8 @@ int start_statd(void)
* We use a fast timeout since this call is advisory only.
*/
int nfs_advise_umount(const struct sockaddr *sap, const socklen_t salen,
- const struct pmap *pmap, const dirpath *argp)
+ const struct pmap *pmap, const dirpath *argp,
+ struct local_bind_info *local_ip)
{
union nfs_sockaddr address;
struct sockaddr *saddr = &address.sa;
@@ -841,7 +857,7 @@ int nfs_advise_umount(const struct sockaddr *sap, const socklen_t salen,
enum clnt_stat res = 0;
memcpy(saddr, sap, salen);
- if (nfs_probe_mntport(saddr, salen, &mnt_pmap) == 0) {
+ if (nfs_probe_mntport(saddr, salen, &mnt_pmap, local_ip) == 0) {
if (verbose)
nfs_error(_("%s: Failed to discover mountd port%s"),
progname, clnt_spcreateerror(""));
@@ -851,7 +867,7 @@ int nfs_advise_umount(const struct sockaddr *sap, const socklen_t salen,
client = nfs_get_priv_rpcclient(saddr, salen, mnt_pmap.pm_prot,
mnt_pmap.pm_prog, mnt_pmap.pm_vers,
- &timeout);
+ &timeout, local_ip);
if (client == NULL) {
if (verbose)
nfs_error(_("%s: Failed to create RPC client%s"),
@@ -899,7 +915,8 @@ int nfs_advise_umount(const struct sockaddr *sap, const socklen_t salen,
* Note that a side effect of calling this function is that rpccreateerr
* is set.
*/
-int nfs_call_umount(clnt_addr_t *mnt_server, dirpath *argp)
+int nfs_call_umount(clnt_addr_t *mnt_server, dirpath *argp,
+ struct local_bind_info *local_ip)
{
struct sockaddr *sap = SAFE_SOCKADDR(&mnt_server->saddr);
socklen_t salen = sizeof(mnt_server->saddr);
@@ -908,9 +925,9 @@ int nfs_call_umount(clnt_addr_t *mnt_server, dirpath *argp)
enum clnt_stat res = 0;
int msock;
- if (!nfs_probe_mntport(sap, salen, pmap))
+ if (!nfs_probe_mntport(sap, salen, pmap, local_ip))
return 0;
- clnt = mnt_openclnt(mnt_server, &msock);
+ clnt = mnt_openclnt(mnt_server, &msock, local_ip);
if (!clnt)
return 0;
res = clnt_call(clnt, MOUNTPROC_UMNT,
@@ -931,7 +948,8 @@ int nfs_call_umount(clnt_addr_t *mnt_server, dirpath *argp)
*
* Returns an active handle for the remote's mountd service
*/
-CLIENT *mnt_openclnt(clnt_addr_t *mnt_server, int *msock)
+CLIENT *mnt_openclnt(clnt_addr_t *mnt_server, int *msock,
+ struct local_bind_info *local_ip)
{
struct sockaddr_in *mnt_saddr = &mnt_server->saddr;
struct pmap *mnt_pmap = &mnt_server->pmap;
@@ -939,7 +957,7 @@ CLIENT *mnt_openclnt(clnt_addr_t *mnt_server, int *msock)
mnt_saddr->sin_port = htons((u_short)mnt_pmap->pm_port);
*msock = get_socket(mnt_saddr, mnt_pmap->pm_prot, MOUNT_TIMEOUT,
- TRUE, FALSE);
+ TRUE, FALSE, local_ip);
if (*msock == RPC_ANYSOCK) {
if (rpc_createerr.cf_error.re_errno == EADDRINUSE)
/*
@@ -1008,7 +1026,7 @@ void mnt_closeclnt(CLIENT *clnt, int msock)
*/
int clnt_ping(struct sockaddr_in *saddr, const unsigned long prog,
const unsigned long vers, const unsigned int prot,
- struct sockaddr_in *caddr)
+ struct sockaddr_in *caddr, struct local_bind_info *local_ip)
{
CLIENT *clnt = NULL;
int sock, status;
@@ -1016,7 +1034,7 @@ int clnt_ping(struct sockaddr_in *saddr, const unsigned long prog,
struct sockaddr dissolve;
rpc_createerr.cf_stat = status = 0;
- sock = get_socket(saddr, prot, CONNECT_TIMEOUT, FALSE, TRUE);
+ sock = get_socket(saddr, prot, CONNECT_TIMEOUT, FALSE, TRUE, local_ip);
if (sock == RPC_ANYSOCK) {
if (rpc_createerr.cf_error.re_errno == ETIMEDOUT) {
/*
@@ -1659,7 +1677,8 @@ out:
* parsed successfully; otherwise EX_FAIL.
*/
int nfs_umount_do_umnt(struct mount_options *options,
- char **hostname, char **dirname)
+ char **hostname, char **dirname,
+ struct local_bind_info *local_ip)
{
union nfs_sockaddr address;
struct sockaddr *sap = &address.sa;
@@ -1686,7 +1705,7 @@ int nfs_umount_do_umnt(struct mount_options *options,
/* nfs_lookup reports any errors */
return EX_FAIL;
- if (nfs_advise_umount(sap, salen, &mnt_pmap, dirname) == 0)
+ if (nfs_advise_umount(sap, salen, &mnt_pmap, dirname, local_ip) == 0)
/* nfs_advise_umount reports any errors */
return EX_FAIL;
diff --git a/utils/mount/network.h b/utils/mount/network.h
index 81c6f22..5732eb6 100644
--- a/utils/mount/network.h
+++ b/utils/mount/network.h
@@ -25,6 +25,7 @@
#define _NFS_UTILS_MOUNT_NETWORK_H
#include <rpc/pmap_prot.h>
+#include "sockaddr.h"
#define MNT_SENDBUFSIZE (2048U)
#define MNT_RECVBUFSIZE (1024U)
@@ -39,10 +40,11 @@ typedef struct {
static const struct timeval TIMEOUT = { 20, 0 };
static const struct timeval RETRY_TIMEOUT = { 3, 0 };
-int probe_bothports(clnt_addr_t *, clnt_addr_t *);
+int probe_bothports(clnt_addr_t *, clnt_addr_t *, struct local_bind_info *);
int nfs_probe_bothports(const struct sockaddr *, const socklen_t,
struct pmap *, const struct sockaddr *,
- const socklen_t, struct pmap *);
+ const socklen_t, struct pmap *,
+ struct local_bind_info *);
int nfs_gethostbyname(const char *, struct sockaddr_in *);
int nfs_lookup(const char *hostname, const sa_family_t family,
struct sockaddr *sap, socklen_t *salen);
@@ -53,7 +55,7 @@ int nfs_callback_address(const struct sockaddr *, const socklen_t,
struct sockaddr *, socklen_t *);
int clnt_ping(struct sockaddr_in *, const unsigned long,
const unsigned long, const unsigned int,
- struct sockaddr_in *);
+ struct sockaddr_in *, struct local_bind_info *);
struct mount_options;
@@ -69,13 +71,15 @@ int start_statd(void);
unsigned long nfsvers_to_mnt(const unsigned long);
-int nfs_call_umount(clnt_addr_t *, dirpath *);
+int nfs_call_umount(clnt_addr_t *, dirpath *, struct local_bind_info *);
int nfs_advise_umount(const struct sockaddr *, const socklen_t,
- const struct pmap *, const dirpath *);
-CLIENT *mnt_openclnt(clnt_addr_t *, int *);
+ const struct pmap *, const dirpath *,
+ struct local_bind_info *);
+CLIENT *mnt_openclnt(clnt_addr_t *, int *, struct local_bind_info *);
void mnt_closeclnt(CLIENT *, int);
int nfs_umount_do_umnt(struct mount_options *options,
- char **hostname, char **dirname);
+ char **hostname, char **dirname,
+ struct local_bind_info *local_ip);
#endif /* _NFS_UTILS_MOUNT_NETWORK_H */
diff --git a/utils/mount/nfs4mount.c b/utils/mount/nfs4mount.c
index 028e7cd..80fab0d 100644
--- a/utils/mount/nfs4mount.c
+++ b/utils/mount/nfs4mount.c
@@ -425,7 +425,8 @@ int nfs4mount(const char *spec, const char *node, int flags,
}
client_addr.sin_family = 0;
client_addr.sin_addr.s_addr = 0;
- clnt_ping(&server_addr, NFS_PROGRAM, 4, data.proto, &client_addr);
+ clnt_ping(&server_addr, NFS_PROGRAM, 4, data.proto,
+ &client_addr, NULL);
if (rpc_createerr.cf_stat == RPC_SUCCESS) {
if (!ip_addr_in_opts &&
client_addr.sin_family != 0 &&
diff --git a/utils/mount/nfsmount.c b/utils/mount/nfsmount.c
index 1298fe4..ff85bf5 100644
--- a/utils/mount/nfsmount.c
+++ b/utils/mount/nfsmount.c
@@ -129,10 +129,10 @@ nfs_call_mount(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server,
enum clnt_stat stat;
int msock;
- if (!probe_bothports(mnt_server, nfs_server))
+ if (!probe_bothports(mnt_server, nfs_server, NULL))
goto out_bad;
- clnt = mnt_openclnt(mnt_server, &msock);
+ clnt = mnt_openclnt(mnt_server, &msock, NULL);
if (!clnt)
goto out_bad;
/* make pointers in xdr_mountres3 NULL so
@@ -779,7 +779,7 @@ nfsmount(const char *spec, const char *node, int flags,
"not supported"),
progname, hostname, dirname);
/* server has registered us in rmtab, send umount */
- nfs_call_umount(&mnt_server, &dirname);
+ nfs_call_umount(&mnt_server, &dirname, NULL);
goto fail;
}
noauth_flavors:
diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c
index f1aa503..71417df 100644
--- a/utils/mount/stropts.c
+++ b/utils/mount/stropts.c
@@ -534,7 +534,7 @@ nfs_rewrite_pmap_mount_options(struct mount_options *options)
* negotiate. Bail now if we can't contact it.
*/
if (!nfs_probe_bothports(mnt_saddr, mnt_salen, &mnt_pmap,
- nfs_saddr, nfs_salen, &nfs_pmap)) {
+ nfs_saddr, nfs_salen, &nfs_pmap, NULL)) {
errno = ESPIPE;
if (rpc_createerr.cf_stat == RPC_PROGNOTREGISTERED)
errno = EOPNOTSUPP;
diff --git a/utils/mount/utils.c b/utils/mount/utils.c
index 298db39..eb50074 100644
--- a/utils/mount/utils.c
+++ b/utils/mount/utils.c
@@ -164,7 +164,7 @@ int nfs_umount23(const char *devname, char *string)
options = po_split(string);
if (options) {
- result = nfs_umount_do_umnt(options, &hostname, &dirname);
+ result = nfs_umount_do_umnt(options, &hostname, &dirname, NULL);
po_destroy(options);
} else
nfs_error(_("%s: option parsing error"), progname);
--
1.7.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/7] nfs-utils: Add patch to parse srcaddr= option.
2011-06-10 18:09 [PATCH 0/7] nfs-utils: Support binding to source address greearb
2011-06-10 18:09 ` [PATCH 1/7] nfs-utils: Add structure for passing local binding info greearb
@ 2011-06-10 18:09 ` greearb
2011-06-10 18:09 ` [PATCH 3/7] nfs-utils: Implement srcaddr binding in rpc_socket greearb
` (4 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: greearb @ 2011-06-10 18:09 UTC (permalink / raw)
To: linux-nfs; +Cc: Ben Greear
From: Ben Greear <greearb@candelatech.com>
This will be used to parse the IP address used for
binding to a particular local IP address.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 6dc257b... 36c2e94... M utils/mount/network.c
:100644 100644 5732eb6... 4af8fd1... M utils/mount/network.h
utils/mount/network.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
utils/mount/network.h | 2 ++
2 files changed, 47 insertions(+), 0 deletions(-)
diff --git a/utils/mount/network.c b/utils/mount/network.c
index 6dc257b..36c2e94 100644
--- a/utils/mount/network.c
+++ b/utils/mount/network.c
@@ -405,6 +405,51 @@ out:
}
/*
+ * node should be an IPv4 or IPv6 address numeric notation.
+ * The value will be parsed in placed into laddr.
+ */
+void
+parse_local_bind(struct local_bind_info *laddr, const char* node) {
+ /* str is an IP address. */
+ int aiErr;
+ struct addrinfo *aiHead;
+ struct addrinfo hints;
+
+ laddr->is_set = 0;
+
+ memset(&hints, 0, sizeof(hints));
+
+ hints.ai_flags = AI_NUMERICSERV;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+ hints.ai_family = PF_INET;
+
+ aiErr = getaddrinfo(node, NULL, &hints, &aiHead);
+
+ /* If we tried PF_INET and it failed, try IPv6 instead
+ * to see if it resolves properly.
+ */
+ if (aiErr != 0) {
+ hints.ai_family = PF_INET6;
+ aiErr = getaddrinfo(node, NULL, &hints, &aiHead);
+ }
+
+ if (aiErr != 0) {
+ nfs_error(_("%s: parse srcaddr failed, "
+ "node: %s aiErr: %i %s\n"),
+ progname, node, aiErr, gai_strerror(aiErr));
+ } else {
+ if (aiHead) {
+ memcpy(&laddr->addr, aiHead->ai_addr,
+ aiHead->ai_addrlen);
+ laddr->addrlen = aiHead->ai_addrlen;
+ laddr->is_set = true;
+ freeaddrinfo(aiHead);
+ }
+ }
+}
+
+/*
* Create a socket that is locally bound to a reserved or non-reserved port.
*
* The caller should check rpc_createerr to determine the cause of any error.
diff --git a/utils/mount/network.h b/utils/mount/network.h
index 5732eb6..4af8fd1 100644
--- a/utils/mount/network.h
+++ b/utils/mount/network.h
@@ -36,6 +36,8 @@ typedef struct {
struct pmap pmap;
} clnt_addr_t;
+void parse_local_bind(struct local_bind_info *laddr, const char* str);
+
/* RPC call timeout values */
static const struct timeval TIMEOUT = { 20, 0 };
static const struct timeval RETRY_TIMEOUT = { 3, 0 };
--
1.7.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 3/7] nfs-utils: Implement srcaddr binding in rpc_socket
2011-06-10 18:09 [PATCH 0/7] nfs-utils: Support binding to source address greearb
2011-06-10 18:09 ` [PATCH 1/7] nfs-utils: Add structure for passing local binding info greearb
2011-06-10 18:09 ` [PATCH 2/7] nfs-utils: Add patch to parse srcaddr= option greearb
@ 2011-06-10 18:09 ` greearb
2011-06-10 18:09 ` [PATCH 4/7] nfs-utils: Implement srcaddr binding in network.c greearb
` (3 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: greearb @ 2011-06-10 18:09 UTC (permalink / raw)
To: linux-nfs; +Cc: Ben Greear
From: Ben Greear <greearb@candelatech.com>
This implements the actual binding, if we are passed
a non-null local_ip structure.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 5652f6c... 4bcbdf0... M support/nfs/rpc_socket.c
support/nfs/rpc_socket.c | 59 +++++++++++++++++++++++++++++++++++----------
1 files changed, 46 insertions(+), 13 deletions(-)
diff --git a/support/nfs/rpc_socket.c b/support/nfs/rpc_socket.c
index 5652f6c..4bcbdf0 100644
--- a/support/nfs/rpc_socket.c
+++ b/support/nfs/rpc_socket.c
@@ -115,6 +115,8 @@ static CLIENT *nfs_get_localclient(const struct sockaddr *sap,
static int nfs_bind(const int sock, const sa_family_t family,
struct local_bind_info *local_ip)
{
+ struct sockaddr *sa = NULL;
+ socklen_t salen = 0;
struct sockaddr_in sin = {
.sin_family = AF_INET,
.sin_addr.s_addr = htonl(INADDR_ANY),
@@ -124,15 +126,26 @@ static int nfs_bind(const int sock, const sa_family_t family,
.sin6_addr = IN6ADDR_ANY_INIT,
};
- switch (family) {
- case AF_INET:
- return bind(sock, (struct sockaddr *)(char *)&sin,
- (socklen_t)sizeof(sin));
- case AF_INET6:
- return bind(sock, (struct sockaddr *)(char *)&sin6,
- (socklen_t)sizeof(sin6));
+ if (local_ip && local_ip->is_set) {
+ sa = &local_ip->addr.sa;
+ salen = local_ip->addrlen;
+ } else {
+ switch (family) {
+ case AF_INET:
+ sa = (struct sockaddr *)&sin;
+ salen = sizeof(sin);
+ break;
+ case AF_INET6:
+ sa = (struct sockaddr *)&sin6;
+ salen = sizeof(sin6);
+ default:
+ break;
+ }
}
+ if (sa)
+ return bind(sock, sa, salen);
+
errno = EAFNOSUPPORT;
return -1;
}
@@ -148,6 +161,7 @@ static int nfs_bind(const int sock, const sa_family_t family,
static int nfs_bindresvport(const int sock, const sa_family_t family,
struct local_bind_info *local_ip)
{
+ struct sockaddr *sa = NULL;
struct sockaddr_in sin = {
.sin_family = AF_INET,
.sin_addr.s_addr = htonl(INADDR_ANY),
@@ -157,13 +171,23 @@ static int nfs_bindresvport(const int sock, const sa_family_t family,
.sin6_addr = IN6ADDR_ANY_INIT,
};
- switch (family) {
- case AF_INET:
- return bindresvport_sa(sock, (struct sockaddr *)(char *)&sin);
- case AF_INET6:
- return bindresvport_sa(sock, (struct sockaddr *)(char *)&sin6);
+ if (local_ip && local_ip->is_set) {
+ sa = &local_ip->addr.sa;
+ } else {
+ switch (family) {
+ case AF_INET:
+ sa = (struct sockaddr *)&sin;
+ break;
+ case AF_INET6:
+ sa = (struct sockaddr *)&sin6;
+ default:
+ break;
+ }
}
+ if (sa)
+ return bindresvport_sa(sock, sa);
+
errno = EAFNOSUPPORT;
return -1;
}
@@ -179,12 +203,21 @@ static int nfs_bindresvport(const int sock, const sa_family_t family,
static int nfs_bindresvport(const int sock, const sa_family_t family,
struct local_bind_info *local_ip)
{
+ struct sockaddr_in laddr;
if (family != AF_INET) {
errno = EAFNOSUPPORT;
return -1;
}
- return bindresvport(sock, NULL);
+ laddr.sin_family = family;
+ laddr.sin_port = 0;
+ if (local_ip && local_ip->is_set) {
+ struct sockaddr_in *si = &local_ip->addr.s4;
+ laddr.sin_addr.s_addr = si->sin_addr.s_addr;
+ } else {
+ laddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ }
+ return bindresvport(sock, &laddr);
}
#endif /* !HAVE_LIBTIRPC */
--
1.7.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 4/7] nfs-utils: Implement srcaddr binding in network.c
2011-06-10 18:09 [PATCH 0/7] nfs-utils: Support binding to source address greearb
` (2 preceding siblings ...)
2011-06-10 18:09 ` [PATCH 3/7] nfs-utils: Implement srcaddr binding in rpc_socket greearb
@ 2011-06-10 18:09 ` greearb
2011-06-10 18:29 ` Chuck Lever
2011-06-10 18:09 ` [PATCH 5/7] nfs-utils: Support srcaddr=n option for string mount greearb
` (2 subsequent siblings)
6 siblings, 1 reply; 11+ messages in thread
From: greearb @ 2011-06-10 18:09 UTC (permalink / raw)
To: linux-nfs; +Cc: Ben Greear
From: Ben Greear <greearb@candelatech.com>
Implement binding logic in get_socket() if local_ip
argument is not NULL.
Note that this method had issues with supporting IPv6 before
this patch, and this patch does NOT resolve them.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 36c2e94... 5419c5d... M utils/mount/network.c
utils/mount/network.c | 21 ++++++++++++++++++---
1 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/utils/mount/network.c b/utils/mount/network.c
index 36c2e94..5419c5d 100644
--- a/utils/mount/network.c
+++ b/utils/mount/network.c
@@ -461,19 +461,34 @@ static int get_socket(struct sockaddr_in *saddr, unsigned int p_prot,
int so, cc, type;
struct sockaddr_in laddr;
socklen_t namelen = sizeof(laddr);
+ int f = AF_INET;
+
+ if (local_ip && local_ip->is_set)
+ f = local_ip->addr.sa.sa_family;
type = (p_prot == IPPROTO_UDP ? SOCK_DGRAM : SOCK_STREAM);
- if ((so = socket (AF_INET, type, p_prot)) < 0)
+
+ so = socket(f, type, p_prot);
+ if (so < 0)
goto err_socket;
- laddr.sin_family = AF_INET;
+ laddr.sin_family = f;
laddr.sin_port = 0;
laddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (resvp) {
+ /* TODO: Support IPv6 */
+ if (local_ip && local_ip->is_set
+ && local_ip->addr.sa.sa_family == AF_INET) {
+ struct sockaddr_in *si = &local_ip->addr.s4;
+ laddr.sin_addr.s_addr = si->sin_addr.s_addr;
+ }
if (bindresvport(so, &laddr) < 0)
goto err_bindresvport;
} else {
- cc = bind(so, SAFE_SOCKADDR(&laddr), namelen);
+ if (local_ip && local_ip->is_set)
+ cc = bind(so, &local_ip->addr.sa, local_ip->addrlen);
+ else
+ cc = bind(so, SAFE_SOCKADDR(&laddr), namelen);
if (cc < 0)
goto err_bind;
}
--
1.7.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 5/7] nfs-utils: Support srcaddr=n option for string mount.
2011-06-10 18:09 [PATCH 0/7] nfs-utils: Support binding to source address greearb
` (3 preceding siblings ...)
2011-06-10 18:09 ` [PATCH 4/7] nfs-utils: Implement srcaddr binding in network.c greearb
@ 2011-06-10 18:09 ` greearb
2011-06-10 18:39 ` Chuck Lever
2011-06-10 18:09 ` [PATCH 6/7] nfs-utils: Implement srcaddr=n binding for unmount greearb
2011-06-10 18:09 ` [PATCH 7/7] nfs-utils: Update man page for srcaddr= option greearb
6 siblings, 1 reply; 11+ messages in thread
From: greearb @ 2011-06-10 18:09 UTC (permalink / raw)
To: linux-nfs; +Cc: Ben Greear
From: Ben Greear <greearb@candelatech.com>
Look for and parse the srcaddr=n argument. If parsing
succeeds, pass this down the call chain. This fully
implements binding to a specified source address when
mounting.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 71417df... b02a469... M utils/mount/stropts.c
utils/mount/stropts.c | 35 +++++++++++++++++++++++++++++++----
1 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c
index 71417df..b02a469 100644
--- a/utils/mount/stropts.c
+++ b/utils/mount/stropts.c
@@ -92,6 +92,7 @@ struct nfsmount_info {
int flags, /* MS_ flags */
fake, /* actually do the mount? */
child; /* forked bg child? */
+ struct local_bind_info *local_ip; /* Local IP binding info */
};
#ifdef MOUNT_CONFIG
@@ -484,7 +485,8 @@ static int nfs_construct_new_options(struct mount_options *options,
* FALSE is returned if some failure occurred.
*/
static int
-nfs_rewrite_pmap_mount_options(struct mount_options *options)
+nfs_rewrite_pmap_mount_options(struct mount_options *options,
+ struct local_bind_info *local_ip)
{
union nfs_sockaddr nfs_address;
struct sockaddr *nfs_saddr = &nfs_address.sa;
@@ -534,7 +536,8 @@ nfs_rewrite_pmap_mount_options(struct mount_options *options)
* negotiate. Bail now if we can't contact it.
*/
if (!nfs_probe_bothports(mnt_saddr, mnt_salen, &mnt_pmap,
- nfs_saddr, nfs_salen, &nfs_pmap, NULL)) {
+ nfs_saddr, nfs_salen, &nfs_pmap,
+ local_ip)) {
errno = ESPIPE;
if (rpc_createerr.cf_stat == RPC_PROGNOTREGISTERED)
errno = EOPNOTSUPP;
@@ -589,7 +592,7 @@ static int nfs_sys_mount(struct nfsmount_info *mi, struct mount_options *opts)
}
static int nfs_do_mount_v3v2(struct nfsmount_info *mi,
- struct sockaddr *sap, socklen_t salen)
+ struct sockaddr *sap, socklen_t salen)
{
struct mount_options *options = po_dup(mi->options);
int result = 0;
@@ -631,7 +634,7 @@ static int nfs_do_mount_v3v2(struct nfsmount_info *mi,
printf(_("%s: trying text-based options '%s'\n"),
progname, *mi->extra_opts);
- if (!nfs_rewrite_pmap_mount_options(options))
+ if (!nfs_rewrite_pmap_mount_options(options, mi->local_ip))
goto out_fail;
result = nfs_sys_mount(mi, options);
@@ -1039,8 +1042,31 @@ int nfsmount_string(const char *spec, const char *node, const char *type,
.flags = flags,
.fake = fake,
.child = child,
+ .local_ip = NULL,
};
int retval = EX_FAIL;
+ char *opt = strstr(*extra_opts, "srcaddr=");
+ struct local_bind_info local_ip;
+ memset(&local_ip, 0, sizeof(local_ip));
+
+ if (opt) {
+ char *tmp = xstrdup(opt);
+ unsigned int i;
+ int olen = strlen("srcaddr=");
+ for (i = olen; i < strlen(tmp); i++) {
+ if (tmp[i] == ',') {
+ tmp[i] = 0;
+ break;
+ }
+ }
+ parse_local_bind(&local_ip, tmp + olen);
+ free(tmp);
+ if (!local_ip.is_set)
+ goto fail;
+ }
+
+ if (local_ip.is_set)
+ mi.local_ip = &local_ip;
mi.options = po_split(*extra_opts);
if (mi.options) {
@@ -1049,6 +1075,7 @@ int nfsmount_string(const char *spec, const char *node, const char *type,
} else
nfs_error(_("%s: internal option parsing error"), progname);
+fail:
freeaddrinfo(mi.address);
free(mi.hostname);
return retval;
--
1.7.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 6/7] nfs-utils: Implement srcaddr=n binding for unmount.
2011-06-10 18:09 [PATCH 0/7] nfs-utils: Support binding to source address greearb
` (4 preceding siblings ...)
2011-06-10 18:09 ` [PATCH 5/7] nfs-utils: Support srcaddr=n option for string mount greearb
@ 2011-06-10 18:09 ` greearb
2011-06-10 18:09 ` [PATCH 7/7] nfs-utils: Update man page for srcaddr= option greearb
6 siblings, 0 replies; 11+ messages in thread
From: greearb @ 2011-06-10 18:09 UTC (permalink / raw)
To: linux-nfs; +Cc: Ben Greear
From: Ben Greear <greearb@candelatech.com>
This fully implements binding to a local IP address when
attempting to un-mount.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 8cd2852... ef5ec17... M utils/mount/nfsumount.c
:100644 100644 eb50074... c3d3467... M utils/mount/utils.c
:100644 100644 3fcd504... ef71814... M utils/mount/utils.h
utils/mount/nfsumount.c | 26 +++++++++++++++++++++++---
utils/mount/utils.c | 6 ++++--
utils/mount/utils.h | 4 +++-
3 files changed, 30 insertions(+), 6 deletions(-)
diff --git a/utils/mount/nfsumount.c b/utils/mount/nfsumount.c
index 8cd2852..ef5ec17 100644
--- a/utils/mount/nfsumount.c
+++ b/utils/mount/nfsumount.c
@@ -239,6 +239,9 @@ int nfsumount(int argc, char *argv[])
int c, ret;
char *spec;
struct mntentchn *mc;
+ char *opt;
+ struct local_bind_info local_ip;
+ memset(&local_ip, 0, sizeof(local_ip));
if (argc < 2) {
umount_usage();
@@ -314,7 +317,7 @@ int nfsumount(int argc, char *argv[])
return EX_USAGE;
}
if (hasmntopt(&mc->m, "users") == NULL) {
- char *opt = hasmntopt(&mc->m, "user");
+ opt = hasmntopt(&mc->m, "user");
struct passwd *pw;
char *comma;
size_t len;
@@ -334,6 +337,22 @@ int nfsumount(int argc, char *argv[])
}
}
+ if (mc) {
+ opt = hasmntopt(&mc->m, "srcaddr");
+ if ((opt != NULL) && strlen(opt) > strlen("srcaddr=")) {
+ char *sa = xstrdup(opt + strlen("srcaddr="));
+ unsigned int z;
+ for (z = 0; z < strlen(sa); z++) {
+ if (sa[z] == ',') {
+ sa[z] = 0;
+ break;
+ }
+ }
+ parse_local_bind(&local_ip, sa);
+ free(sa);
+ }
+ }
+
ret = EX_SUCCESS;
if (mc) {
if (!lazy) {
@@ -344,7 +363,8 @@ int nfsumount(int argc, char *argv[])
* we don't want to signal an error, as that
* could cause /sbin/mount to retry!
*/
- nfs_umount23(mc->m.mnt_fsname, mc->m.mnt_opts);
+ nfs_umount23(mc->m.mnt_fsname, mc->m.mnt_opts,
+ &local_ip);
break;
case 1:
break;
@@ -355,7 +375,7 @@ int nfsumount(int argc, char *argv[])
ret = del_mtab(mc->m.mnt_fsname, mc->m.mnt_dir);
} else if (*spec != '/') {
if (!lazy)
- ret = nfs_umount23(spec, "tcp,v3");
+ ret = nfs_umount23(spec, "tcp,v3", &local_ip);
} else
ret = del_mtab(NULL, spec);
diff --git a/utils/mount/utils.c b/utils/mount/utils.c
index eb50074..c3d3467 100644
--- a/utils/mount/utils.c
+++ b/utils/mount/utils.c
@@ -153,7 +153,8 @@ int chk_mountpoint(const char *mount_point)
* pmap tuple. If the GETPORT call later fails to disambiguate them,
* then we fail.
*/
-int nfs_umount23(const char *devname, char *string)
+int nfs_umount23(const char *devname, char *string,
+ struct local_bind_info *local_ip)
{
char *hostname = NULL, *dirname = NULL;
struct mount_options *options;
@@ -164,7 +165,8 @@ int nfs_umount23(const char *devname, char *string)
options = po_split(string);
if (options) {
- result = nfs_umount_do_umnt(options, &hostname, &dirname, NULL);
+ result = nfs_umount_do_umnt(options, &hostname, &dirname,
+ local_ip);
po_destroy(options);
} else
nfs_error(_("%s: option parsing error"), progname);
diff --git a/utils/mount/utils.h b/utils/mount/utils.h
index 3fcd504..ef71814 100644
--- a/utils/mount/utils.h
+++ b/utils/mount/utils.h
@@ -31,6 +31,8 @@ void mount_usage(void);
void umount_usage(void);
int chk_mountpoint(const char *mount_point);
-int nfs_umount23(const char *devname, char *string);
+struct local_bind_info;
+int nfs_umount23(const char *devname, char *string,
+ struct local_bind_info *local_ip);
#endif /* !_NFS_UTILS_MOUNT_UTILS_H */
--
1.7.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 7/7] nfs-utils: Update man page for srcaddr= option.
2011-06-10 18:09 [PATCH 0/7] nfs-utils: Support binding to source address greearb
` (5 preceding siblings ...)
2011-06-10 18:09 ` [PATCH 6/7] nfs-utils: Implement srcaddr=n binding for unmount greearb
@ 2011-06-10 18:09 ` greearb
6 siblings, 0 replies; 11+ messages in thread
From: greearb @ 2011-06-10 18:09 UTC (permalink / raw)
To: linux-nfs; +Cc: Ben Greear
From: Ben Greear <greearb@candelatech.com>
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 be91a25... 622d7cb... M utils/mount/nfs.man
utils/mount/nfs.man | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/utils/mount/nfs.man b/utils/mount/nfs.man
index be91a25..622d7cb 100644
--- a/utils/mount/nfs.man
+++ b/utils/mount/nfs.man
@@ -463,6 +463,13 @@ by other clients, but can impact application and server performance.
.IP
The DATA AND METADATA COHERENCE section contains a
detailed discussion of these trade-offs.
+.TP 1.5i
+.BI srcaddr= n
+Specifies a single IPv4 or IPv6 address
+to which the NFS client will bind its sockets.
+This can help force NFS to use a particular IP
+address on a multi-homed machine. This option is not required
+in most cases.
.SS "Options for NFS versions 2 and 3 only"
Use these options, along with the options in the above subsection,
for NFS versions 2 and 3 only.
--
1.7.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 4/7] nfs-utils: Implement srcaddr binding in network.c
2011-06-10 18:09 ` [PATCH 4/7] nfs-utils: Implement srcaddr binding in network.c greearb
@ 2011-06-10 18:29 ` Chuck Lever
2011-06-10 18:40 ` Ben Greear
0 siblings, 1 reply; 11+ messages in thread
From: Chuck Lever @ 2011-06-10 18:29 UTC (permalink / raw)
To: greearb; +Cc: linux-nfs
On Jun 10, 2011, at 2:09 PM, greearb@candelatech.com wrote:
> From: Ben Greear <greearb@candelatech.com>
>
> Implement binding logic in get_socket() if local_ip
> argument is not NULL.
>
> Note that this method had issues with supporting IPv6 before
> this patch, and this patch does NOT resolve them.
If get_socket() doesn't support IPv6, then I doubt it's used for string-based mounts. You may not need any changes here.
> Signed-off-by: Ben Greear <greearb@candelatech.com>
> ---
> :100644 100644 36c2e94... 5419c5d... M utils/mount/network.c
> utils/mount/network.c | 21 ++++++++++++++++++---
> 1 files changed, 18 insertions(+), 3 deletions(-)
>
> diff --git a/utils/mount/network.c b/utils/mount/network.c
> index 36c2e94..5419c5d 100644
> --- a/utils/mount/network.c
> +++ b/utils/mount/network.c
> @@ -461,19 +461,34 @@ static int get_socket(struct sockaddr_in *saddr, unsigned int p_prot,
> int so, cc, type;
> struct sockaddr_in laddr;
> socklen_t namelen = sizeof(laddr);
> + int f = AF_INET;
> +
> + if (local_ip && local_ip->is_set)
> + f = local_ip->addr.sa.sa_family;
>
> type = (p_prot == IPPROTO_UDP ? SOCK_DGRAM : SOCK_STREAM);
> - if ((so = socket (AF_INET, type, p_prot)) < 0)
> +
> + so = socket(f, type, p_prot);
> + if (so < 0)
> goto err_socket;
>
> - laddr.sin_family = AF_INET;
> + laddr.sin_family = f;
> laddr.sin_port = 0;
> laddr.sin_addr.s_addr = htonl(INADDR_ANY);
> if (resvp) {
> + /* TODO: Support IPv6 */
> + if (local_ip && local_ip->is_set
> + && local_ip->addr.sa.sa_family == AF_INET) {
> + struct sockaddr_in *si = &local_ip->addr.s4;
> + laddr.sin_addr.s_addr = si->sin_addr.s_addr;
> + }
> if (bindresvport(so, &laddr) < 0)
> goto err_bindresvport;
> } else {
> - cc = bind(so, SAFE_SOCKADDR(&laddr), namelen);
> + if (local_ip && local_ip->is_set)
> + cc = bind(so, &local_ip->addr.sa, local_ip->addrlen);
> + else
> + cc = bind(so, SAFE_SOCKADDR(&laddr), namelen);
> if (cc < 0)
> goto err_bind;
> }
> --
> 1.7.3.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Chuck Lever
chuck[dot]lever[at]oracle[dot]com
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 5/7] nfs-utils: Support srcaddr=n option for string mount.
2011-06-10 18:09 ` [PATCH 5/7] nfs-utils: Support srcaddr=n option for string mount greearb
@ 2011-06-10 18:39 ` Chuck Lever
0 siblings, 0 replies; 11+ messages in thread
From: Chuck Lever @ 2011-06-10 18:39 UTC (permalink / raw)
To: greearb; +Cc: linux-nfs
On Jun 10, 2011, at 2:09 PM, greearb@candelatech.com wrote:
> From: Ben Greear <greearb@candelatech.com>
>
> Look for and parse the srcaddr=n argument. If parsing
> succeeds, pass this down the call chain. This fully
> implements binding to a specified source address when
> mounting.
>
> Signed-off-by: Ben Greear <greearb@candelatech.com>
> ---
> :100644 100644 71417df... b02a469... M utils/mount/stropts.c
> utils/mount/stropts.c | 35 +++++++++++++++++++++++++++++++----
> 1 files changed, 31 insertions(+), 4 deletions(-)
>
> diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c
> index 71417df..b02a469 100644
> --- a/utils/mount/stropts.c
> +++ b/utils/mount/stropts.c
> @@ -92,6 +92,7 @@ struct nfsmount_info {
> int flags, /* MS_ flags */
> fake, /* actually do the mount? */
> child; /* forked bg child? */
> + struct local_bind_info *local_ip; /* Local IP binding info */
> };
>
> #ifdef MOUNT_CONFIG
> @@ -484,7 +485,8 @@ static int nfs_construct_new_options(struct mount_options *options,
> * FALSE is returned if some failure occurred.
> */
> static int
> -nfs_rewrite_pmap_mount_options(struct mount_options *options)
> +nfs_rewrite_pmap_mount_options(struct mount_options *options,
> + struct local_bind_info *local_ip)
> {
> union nfs_sockaddr nfs_address;
> struct sockaddr *nfs_saddr = &nfs_address.sa;
> @@ -534,7 +536,8 @@ nfs_rewrite_pmap_mount_options(struct mount_options *options)
> * negotiate. Bail now if we can't contact it.
> */
> if (!nfs_probe_bothports(mnt_saddr, mnt_salen, &mnt_pmap,
> - nfs_saddr, nfs_salen, &nfs_pmap, NULL)) {
> + nfs_saddr, nfs_salen, &nfs_pmap,
> + local_ip)) {
> errno = ESPIPE;
> if (rpc_createerr.cf_stat == RPC_PROGNOTREGISTERED)
> errno = EOPNOTSUPP;
> @@ -589,7 +592,7 @@ static int nfs_sys_mount(struct nfsmount_info *mi, struct mount_options *opts)
> }
>
> static int nfs_do_mount_v3v2(struct nfsmount_info *mi,
> - struct sockaddr *sap, socklen_t salen)
> + struct sockaddr *sap, socklen_t salen)
> {
> struct mount_options *options = po_dup(mi->options);
> int result = 0;
> @@ -631,7 +634,7 @@ static int nfs_do_mount_v3v2(struct nfsmount_info *mi,
> printf(_("%s: trying text-based options '%s'\n"),
> progname, *mi->extra_opts);
>
> - if (!nfs_rewrite_pmap_mount_options(options))
> + if (!nfs_rewrite_pmap_mount_options(options, mi->local_ip))
> goto out_fail;
>
> result = nfs_sys_mount(mi, options);
> @@ -1039,8 +1042,31 @@ int nfsmount_string(const char *spec, const char *node, const char *type,
> .flags = flags,
> .fake = fake,
> .child = child,
> + .local_ip = NULL,
> };
> int retval = EX_FAIL;
> + char *opt = strstr(*extra_opts, "srcaddr=");
> + struct local_bind_info local_ip;
> + memset(&local_ip, 0, sizeof(local_ip));
> +
> + if (opt) {
> + char *tmp = xstrdup(opt);
> + unsigned int i;
> + int olen = strlen("srcaddr=");
> + for (i = olen; i < strlen(tmp); i++) {
> + if (tmp[i] == ',') {
> + tmp[i] = 0;
> + break;
> + }
> + }
> + parse_local_bind(&local_ip, tmp + olen);
> + free(tmp);
> + if (!local_ip.is_set)
> + goto fail;
> + }
> +
> + if (local_ip.is_set)
> + mi.local_ip = &local_ip;
This doesn't belong here; it probably goes in nfs_validate_options().
Use the parsing tools that are available for string-based mount options. Open-coding checks for srcaddr= and dealing with the comma yourself is unnecessary. For instance, after the po_split() is done, you can just do a po_get(options, "srcaddr") to extract the value of the srcaddr mount option if it exists.
> mi.options = po_split(*extra_opts);
> if (mi.options) {
> @@ -1049,6 +1075,7 @@ int nfsmount_string(const char *spec, const char *node, const char *type,
> } else
> nfs_error(_("%s: internal option parsing error"), progname);
>
> +fail:
> freeaddrinfo(mi.address);
> free(mi.hostname);
> return retval;
> --
> 1.7.3.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Chuck Lever
chuck[dot]lever[at]oracle[dot]com
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 4/7] nfs-utils: Implement srcaddr binding in network.c
2011-06-10 18:29 ` Chuck Lever
@ 2011-06-10 18:40 ` Ben Greear
0 siblings, 0 replies; 11+ messages in thread
From: Ben Greear @ 2011-06-10 18:40 UTC (permalink / raw)
To: Chuck Lever; +Cc: linux-nfs
On 06/10/2011 11:29 AM, Chuck Lever wrote:
>
> On Jun 10, 2011, at 2:09 PM, greearb@candelatech.com wrote:
>
>> From: Ben Greear<greearb@candelatech.com>
>>
>> Implement binding logic in get_socket() if local_ip
>> argument is not NULL.
>>
>> Note that this method had issues with supporting IPv6 before
>> this patch, and this patch does NOT resolve them.
>
> If get_socket() doesn't support IPv6, then I doubt it's used for string-based mounts. You may not need any changes here.
Looks like you are correct. I added printf to that method and
see nothing while doing mount/unmount. I'll respin the patches
to remove that...should make things a good bit smaller.
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2011-06-10 18:40 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-06-10 18:09 [PATCH 0/7] nfs-utils: Support binding to source address greearb
2011-06-10 18:09 ` [PATCH 1/7] nfs-utils: Add structure for passing local binding info greearb
2011-06-10 18:09 ` [PATCH 2/7] nfs-utils: Add patch to parse srcaddr= option greearb
2011-06-10 18:09 ` [PATCH 3/7] nfs-utils: Implement srcaddr binding in rpc_socket greearb
2011-06-10 18:09 ` [PATCH 4/7] nfs-utils: Implement srcaddr binding in network.c greearb
2011-06-10 18:29 ` Chuck Lever
2011-06-10 18:40 ` Ben Greear
2011-06-10 18:09 ` [PATCH 5/7] nfs-utils: Support srcaddr=n option for string mount greearb
2011-06-10 18:39 ` Chuck Lever
2011-06-10 18:09 ` [PATCH 6/7] nfs-utils: Implement srcaddr=n binding for unmount greearb
2011-06-10 18:09 ` [PATCH 7/7] nfs-utils: Update man page for srcaddr= option greearb
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).