have NFSv4 nfs sockets bind to the callback address
Subsystems (2)
PATCH 1/1 have NFSv4 nfs sockets bind to the callback address
It's been pointed out to me that some clients have complicated routing, or have HA requirements that require that they prefer particular source addresses for their NFS sockets. Here's one such scheme that was described to me:
-------[snip]--------
- two interfaces, each on different subnets (say eth0 and eth1)
- an lo:foo virtual interface with a /32 bit netmask (in a different IP range than the above two).
- multiple, equal cost, default routes out each of the two real interfaces
- advertise the /32 lo:foo IP simultaneously, VIA RIPv2, out bot eth0 and eth1 or
- add equal cost static routes, on the router, to the lo:foo IP via eth0 and eth1
- you would need something to monitor the routers and remove the route on the host if one of them goes down.
without any patch, when you mount, the above configured NFS client will use one of the eth0/1 IPs, never the lo:foo IP as the src. Then if the router out the int it chose to use goes down, it will never recover cause the NFS server only knows it via that addr. but if you mounted the NFS volume using the src addr of lo:foo, it will "just work" -------[snip]--------
After looking at some different ways to handle this, I think the best scheme would be to expand the scope of the NFSv4 "clientaddr=" option so that the nfs socket is also bound to the same local address.
Now that Frank V.M. has done the heavy lifting to allow client side sockets to bind to a specified address, this patch is fairly simple to implement for NFSv4. If this is acceptable we might consider doing the same for v2/3, but I'd prefer to wait until Chuck's string-based options patch is fully in place rather than having to change the nfs_mount_options struct.
Thoughts?
fs/nfs/client.c +11 -1
@@ -372,6 +372,7 @@ static int nfs_create_rpc_client(struct nfs_client *clp, int proto, {struct rpc_timeout timeparms;struct rpc_clnt *clnt =NULL ; +struct sockaddr_in sin_client;struct rpc_create_args args = { .protocol = proto, .address = (struct sockaddr *)&clp->cl_addr,
@@ -387,6 +388,14 @@ static int nfs_create_rpc_client(struct nfs_client *clp, int proto,if (!IS_ERR (clp->cl_rpcclient))return 0 ; +/* if cl_ipaddr is set then set the src address to be the same */ +if (clp->cl_ipaddr[0 ] !='\0' &&in4_pton (clp->cl_ipaddr,-1 , + (u8 *) &sin_client.sin_addr.s_addr,0 ,NULL )) { + sin_client.sin_family =AF_INET ; + sin_client.sin_port =0 ; + args.saddress = (struct sockaddr *) &sin_client; + } +nfs_init_timeout_values (&timeparms, proto, timeo, retrans); clp->retrans_timeo = timeparms.to_initval; clp->retrans_count = timeparms.to_retries;
@@ -844,11 +853,12 @@ static int nfs4_init_client(struct nfs_client *clp,/* Check NFS protocol revision and initialize RPC op vector */ clp->rpc_ops = &nfs_v4_clientops; +memcpy (clp->cl_ipaddr, ip_addr,sizeof (clp->cl_ipaddr)); + error =nfs_create_rpc_client (clp, proto, timeo, retrans, authflavour,RPC_CLNT_CREATE_DISCRTRY );if (error <0 ) goto error; -memcpy (clp->cl_ipaddr, ip_addr,sizeof (clp->cl_ipaddr)); error =nfs_idmap_new (clp);if (error <0 ) {
Quoted 29 lines · Jeff Layton
It's been pointed out to me that some clients have complicated routing, or have HA requirements that require that they prefer particular source addresses for their NFS sockets. Here's one such scheme that was described to me:
-------[snip]--------
(quoted diff) +0
-6- two interfaces, each on different subnets (say eth0 and eth1) - an lo:foo virtual interface with a /32 bit netmask (in a different IP range than the above two). - multiple, equal cost, default routes out each of the two real interfaces - advertise the /32 lo:foo IP simultaneously, VIA RIPv2, out bot eth0 and eth1 or - add equal cost static routes, on the router, to the lo:foo IP via eth0 and eth1 - you would need something to monitor the routers and remove the route on the host if one of them goes down.without any patch, when you mount, the above configured NFS client will use one of the eth0/1 IPs, never the lo:foo IP as the src. Then if the router out the int it chose to use goes down, it will never recover cause the NFS server only knows it via that addr. but if you mounted the NFS volume using the src addr of lo:foo, it will "just work" -------[snip]--------
After looking at some different ways to handle this, I think the best scheme would be to expand the scope of the NFSv4 "clientaddr=" option so that the nfs socket is also bound to the same local address.
Quoted 8 lines
Now that Frank V.M. has done the heavy lifting to allow client side sockets to bind to a specified address, this patch is fairly simple to implement for NFSv4. If this is acceptable we might consider doing the same for v2/3, but I'd prefer to wait until Chuck's string-based options patch is fully in place rather than having to change the
nfs_mount_optionsstruct.Thoughts?
No. "clientaddr" is supposed to advertise the _callback_ address for NFSv4. i.e. it advertises the address on which the callback server is listening.
Consider a NAT setup, say, on which you have set up an incoming tunnel and need to advertise that to the server. It should be clear that this address (being on the outside of the NAT) has absolutely nothing to do with the address on which you want to bind the outgoing connections.
Trond
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs