Re: [PATCH v1 01/16] nfsd: fix IPv6 address handling in the DRC

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Jan 28, 2013, at 2:41 PM, Jeff Layton <jlayton@xxxxxxxxxx> wrote:

> Currently, it only stores the first 16 bytes of any address. struct
> sockaddr_in6 is 28 bytes however, so we're currently ignoring the last
> 12 bytes of the address.
> 
> Expand the c_addr field to a sockaddr_in6,

What do you do about link-local addresses?

> and cast it to a sockaddr_in
> as necessary. Also fix the comparitor to use the existing RPC
> helpers for this.
> 
> Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
> ---
> fs/nfsd/cache.h             | 6 +++++-
> fs/nfsd/nfscache.c          | 7 +++++--
> include/linux/sunrpc/clnt.h | 4 +++-
> 3 files changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/nfsd/cache.h b/fs/nfsd/cache.h
> index 93cc9d3..2cac76c 100644
> --- a/fs/nfsd/cache.h
> +++ b/fs/nfsd/cache.h
> @@ -12,6 +12,10 @@
> 
> /*
>  * Representation of a reply cache entry.
> + *
> + * Note that we use a sockaddr_in6 to hold the address instead of the more
> + * typical sockaddr_storage. This is for space reasons, since sockaddr_storage
> + * is much larger than a sockaddr_in6.
>  */
> struct svc_cacherep {
> 	struct hlist_node	c_hash;
> @@ -20,7 +24,7 @@ struct svc_cacherep {
> 	unsigned char		c_state,	/* unused, inprog, done */
> 				c_type,		/* status, buffer */
> 				c_secure : 1;	/* req came from port < 1024 */
> -	struct sockaddr_in	c_addr;
> +	struct sockaddr_in6	c_addr;
> 	__be32			c_xid;
> 	u32			c_prot;
> 	u32			c_proc;
> diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c
> index 2cbac34..5dd9ec2 100644
> --- a/fs/nfsd/nfscache.c
> +++ b/fs/nfsd/nfscache.c
> @@ -9,6 +9,7 @@
>  */
> 
> #include <linux/slab.h>
> +#include <linux/sunrpc/clnt.h>
> 
> #include "nfsd.h"
> #include "cache.h"
> @@ -146,7 +147,8 @@ nfsd_cache_lookup(struct svc_rqst *rqstp)
> 		    xid == rp->c_xid && proc == rp->c_proc &&
> 		    proto == rp->c_prot && vers == rp->c_vers &&
> 		    time_before(jiffies, rp->c_timestamp + 120*HZ) &&
> -		    memcmp((char*)&rqstp->rq_addr, (char*)&rp->c_addr, sizeof(rp->c_addr))==0) {
> +		    rpc_cmp_addr(svc_addr(rqstp), (struct sockaddr *)&rp->c_addr) &&
> +		    rpc_get_port(svc_addr(rqstp)) == rpc_get_port((struct sockaddr *)&rp->c_addr)) {
> 			nfsdstats.rchits++;
> 			goto found_entry;
> 		}
> @@ -183,7 +185,8 @@ nfsd_cache_lookup(struct svc_rqst *rqstp)
> 	rp->c_state = RC_INPROG;
> 	rp->c_xid = xid;
> 	rp->c_proc = proc;
> -	memcpy(&rp->c_addr, svc_addr_in(rqstp), sizeof(rp->c_addr));
> +	rpc_copy_addr((struct sockaddr *)&rp->c_addr, svc_addr(rqstp));
> +	rpc_set_port((struct sockaddr *)&rp->c_addr, rpc_get_port(svc_addr(rqstp)));
> 	rp->c_prot = proto;
> 	rp->c_vers = vers;
> 	rp->c_timestamp = jiffies;
> diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
> index 34206b8..47354a2 100644
> --- a/include/linux/sunrpc/clnt.h
> +++ b/include/linux/sunrpc/clnt.h
> @@ -263,7 +263,9 @@ static inline bool __rpc_copy_addr6(struct sockaddr *dst,
>  * @sap1: first sockaddr
>  * @sap2: second sockaddr
>  *
> - * Just compares the family and address portion. Ignores port, scope, etc.
> + * Just compares the family and address portion. Ignores port, but
> + * compares the scope if it's a link-local address.
> + *
>  * Returns true if the addrs are equal, false if they aren't.
>  */
> static inline bool rpc_cmp_addr(const struct sockaddr *sap1,
> -- 
> 1.7.11.7
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Chuck Lever
chuck[dot]lever[at]oracle[dot]com




--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux