Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7b9e8522 authored by Jeff Layton's avatar Jeff Layton Committed by J. Bruce Fields
Browse files

nfsd: fix IPv6 address handling in the DRC



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, and cast it to a sockaddr_in
as necessary. Also fix the comparitor to use the existing RPC
helpers for this.

Signed-off-by: default avatarJeff Layton <jlayton@redhat.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 885c91f7
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -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;
+5 −2
Original line number Diff line number Diff line
@@ -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;
+3 −1
Original line number Diff line number Diff line
@@ -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,