diff mbox

[v3,14/14] SUNRPC: add AF_VSOCK support to auth.unix.ip

Message ID 20170630132352.32133-15-stefanha@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Stefan Hajnoczi June 30, 2017, 1:23 p.m. UTC
The ip_map currently supports AF_INET and AF_INET6.  It actually
converts IPv4 to IPv6 addresses.  We can't do that for AF_VSOCK but a
union will allow both IPv6 and vsock sockaddr structs to be used.

The cache userspace interface now supports 'vsock:CID' syntax for
AF_VSOCK addresses.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 net/sunrpc/svcauth_unix.c | 146 ++++++++++++++++++++++++++++++++++++----------
 1 file changed, 115 insertions(+), 31 deletions(-)

Comments

Abbas Naderi July 6, 2017, 6:46 p.m. UTC | #1
Without CONFIG_SUNRPC_BACKCHANNEL, many things such as “svc_vsock_bc_class” are undefined, and then used throughout the code.
Most of the “CONFIG_SUNRPC_XPRT_VSOCK” guards in sunrpc/svcsock.c should also be guarded by CONFIG_SUNRPC_BACKCHANNEL.

-A

> On Jun 30, 2017, at 6:23 AM, Stefan Hajnoczi <stefanha@redhat.com> wrote:
> 
> The ip_map currently supports AF_INET and AF_INET6.  It actually
> converts IPv4 to IPv6 addresses.  We can't do that for AF_VSOCK but a
> union will allow both IPv6 and vsock sockaddr structs to be used.
> 
> The cache userspace interface now supports 'vsock:CID' syntax for
> AF_VSOCK addresses.
> 
> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> ---
> net/sunrpc/svcauth_unix.c | 146 ++++++++++++++++++++++++++++++++++++----------
> 1 file changed, 115 insertions(+), 31 deletions(-)
> 
> diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
> index f81eaa8..b33ea0b 100644
> --- a/net/sunrpc/svcauth_unix.c
> +++ b/net/sunrpc/svcauth_unix.c
> @@ -89,7 +89,15 @@ EXPORT_SYMBOL_GPL(unix_domain_find);
> struct ip_map {
> 	struct cache_head	h;
> 	char			m_class[8]; /* e.g. "nfsd" */
> -	struct in6_addr		m_addr;
> +	union {
> +		struct sockaddr		m_sa;
> +
> +		/* For AF_INET6 and AF_INET (we map to IPv6) */
> +		struct sockaddr_in6	m_sin6;
> +
> +		/* For AF_VSOCK */
> +		struct sockaddr_vm	m_svm;
> +	};
> 	struct unix_domain	*m_client;
> };
> 
> @@ -112,8 +120,22 @@ static int ip_map_match(struct cache_head *corig, struct cache_head *cnew)
> {
> 	struct ip_map *orig = container_of(corig, struct ip_map, h);
> 	struct ip_map *new = container_of(cnew, struct ip_map, h);
> -	return strcmp(orig->m_class, new->m_class) == 0 &&
> -	       ipv6_addr_equal(&orig->m_addr, &new->m_addr);
> +
> +	if (strcmp(orig->m_class, new->m_class) != 0)
> +		return 0;
> +
> +	if (orig->m_sa.sa_family != new->m_sa.sa_family)
> +		return 0;
> +
> +	switch (orig->m_sa.sa_family) {
> +	case AF_INET6:
> +		return ipv6_addr_equal(&orig->m_sin6.sin6_addr,
> +				       &new->m_sin6.sin6_addr);
> +
> +	case AF_VSOCK:
> +		return orig->m_svm.svm_cid == new->m_svm.svm_cid;
> +	}
> +	return 0;
> }
> static void ip_map_init(struct cache_head *cnew, struct cache_head *citem)
> {
> @@ -121,7 +143,14 @@ static void ip_map_init(struct cache_head *cnew, struct cache_head *citem)
> 	struct ip_map *item = container_of(citem, struct ip_map, h);
> 
> 	strcpy(new->m_class, item->m_class);
> -	new->m_addr = item->m_addr;
> +	switch (item->m_sa.sa_family) {
> +	case AF_INET6:
> +		new->m_sin6 = item->m_sin6;
> +		break;
> +	case AF_VSOCK:
> +		new->m_svm = item->m_svm;
> +		break;
> +	}
> }
> static void update(struct cache_head *cnew, struct cache_head *citem)
> {
> @@ -145,19 +174,30 @@ static void ip_map_request(struct cache_detail *cd,
> 				  char **bpp, int *blen)
> {
> 	char text_addr[40];
> +	struct in6_addr *addr;
> 	struct ip_map *im = container_of(h, struct ip_map, h);
> 
> -	if (ipv6_addr_v4mapped(&(im->m_addr))) {
> -		snprintf(text_addr, 20, "%pI4", &im->m_addr.s6_addr32[3]);
> -	} else {
> -		snprintf(text_addr, 40, "%pI6", &im->m_addr);
> +	switch (im->m_sa.sa_family) {
> +	case AF_INET6:
> +		addr = &im->m_sin6.sin6_addr;
> +		if (ipv6_addr_v4mapped(addr)) {
> +			snprintf(text_addr, 20, "%pI4", &addr->s6_addr32[3]);
> +		} else {
> +			snprintf(text_addr, 40, "%pI6", addr);
> +		}
> +		break;
> +
> +	case AF_VSOCK:
> +		snprintf(text_addr, 10, "vsock:%u", im->m_svm.svm_cid);
> +		break;
> 	}
> +
> 	qword_add(bpp, blen, im->m_class);
> 	qword_add(bpp, blen, text_addr);
> 	(*bpp)[-1] = '\n';
> }
> 
> -static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class, struct in6_addr *addr);
> +static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class, struct sockaddr *sap);
> static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, struct unix_domain *udom, time_t expiry);
> 
> static int ip_map_parse(struct cache_detail *cd,
> @@ -173,6 +213,7 @@ static int ip_map_parse(struct cache_detail *cd,
> 		struct sockaddr		sa;
> 		struct sockaddr_in	s4;
> 		struct sockaddr_in6	s6;
> +		struct sockaddr_vm	svm;
> 	} address;
> 	struct sockaddr_in6 sin6;
> 	int err;
> @@ -201,11 +242,15 @@ static int ip_map_parse(struct cache_detail *cd,
> 		sin6.sin6_family = AF_INET6;
> 		ipv6_addr_set_v4mapped(address.s4.sin_addr.s_addr,
> 				&sin6.sin6_addr);
> +		address.s6 = sin6;
> 		break;
> #if IS_ENABLED(CONFIG_IPV6)
> 	case AF_INET6:
> -		memcpy(&sin6, &address.s6, sizeof(sin6));
> -		break;
> +		break; /* Do nothing */
> +#endif
> +#ifdef CONFIG_SUNRPC_XPRT_VSOCK
> +	case AF_VSOCK:
> +		break; /* Do nothing */
> #endif
> 	default:
> 		return -EINVAL;
> @@ -227,7 +272,7 @@ static int ip_map_parse(struct cache_detail *cd,
> 		dom = NULL;
> 
> 	/* IPv6 scope IDs are ignored for now */
> -	ipmp = __ip_map_lookup(cd, class, &sin6.sin6_addr);
> +	ipmp = __ip_map_lookup(cd, class, &address.sa);
> 	if (ipmp) {
> 		err = __ip_map_update(cd, ipmp,
> 			     container_of(dom, struct unix_domain, h),
> @@ -247,7 +292,7 @@ static int ip_map_show(struct seq_file *m,
> 		       struct cache_head *h)
> {
> 	struct ip_map *im;
> -	struct in6_addr addr;
> +	struct in6_addr *addr;
> 	char *dom = "-no-domain-";
> 
> 	if (h == NULL) {
> @@ -256,33 +301,67 @@ static int ip_map_show(struct seq_file *m,
> 	}
> 	im = container_of(h, struct ip_map, h);
> 	/* class addr domain */
> -	addr = im->m_addr;
> -
> +	addr = &im->m_sin6.sin6_addr;
> 	if (test_bit(CACHE_VALID, &h->flags) &&
> 	    !test_bit(CACHE_NEGATIVE, &h->flags))
> 		dom = im->m_client->h.name;
> 
> -	if (ipv6_addr_v4mapped(&addr)) {
> -		seq_printf(m, "%s %pI4 %s\n",
> -			im->m_class, &addr.s6_addr32[3], dom);
> -	} else {
> -		seq_printf(m, "%s %pI6 %s\n", im->m_class, &addr, dom);
> +	switch (im->m_sa.sa_family) {
> +	case AF_INET6:
> +		if (ipv6_addr_v4mapped(addr)) {
> +			seq_printf(m, "%s %pI4 %s\n",
> +				im->m_class,
> +				&addr->s6_addr32[3],
> +				dom);
> +		} else {
> +			seq_printf(m, "%s %pI6 %s\n", im->m_class, addr, dom);
> +		}
> +		break;
> +
> +	case AF_VSOCK:
> +		seq_printf(m, "%s %u %s\n",
> +			im->m_class, im->m_svm.svm_cid, dom);
> +		break;
> 	}
> 	return 0;
> }
> 
> +static int __ip_map_hash(struct ip_map *ipm)
> +{
> +	int hash;
> +
> +	switch (ipm->m_sa.sa_family) {
> +	case AF_INET6:
> +		hash = hash_ip6(&ipm->m_sin6.sin6_addr);
> +		break;
> +	case AF_VSOCK:
> +		hash = hash_32(ipm->m_svm.svm_cid, IP_HASHBITS);
> +		break;
> +	default:
> +		BUG();
> +	}
> +
> +	return hash_str(ipm->m_class, IP_HASHBITS) ^ hash;
> +}
> 
> static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class,
> -		struct in6_addr *addr)
> +		struct sockaddr *sap)
> {
> 	struct ip_map ip;
> 	struct cache_head *ch;
> 
> 	strcpy(ip.m_class, class);
> -	ip.m_addr = *addr;
> -	ch = sunrpc_cache_lookup(cd, &ip.h,
> -				 hash_str(class, IP_HASHBITS) ^
> -				 hash_ip6(addr));
> +	switch (sap->sa_family) {
> +	case AF_INET6:
> +		ip.m_sin6 = *(struct sockaddr_in6 *)sap;
> +		break;
> +	case AF_VSOCK:
> +		ip.m_svm = *(struct sockaddr_vm *)sap;
> +		break;
> +	default:
> +		return NULL;
> +	}
> +	ch = sunrpc_cache_lookup(cd, &ip.h, __ip_map_hash(&ip));
> 
> 	if (ch)
> 		return container_of(ch, struct ip_map, h);
> @@ -291,12 +370,12 @@ static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class,
> }
> 
> static inline struct ip_map *ip_map_lookup(struct net *net, char *class,
> -		struct in6_addr *addr)
> +		struct sockaddr *sap)
> {
> 	struct sunrpc_net *sn;
> 
> 	sn = net_generic(net, sunrpc_net_id);
> -	return __ip_map_lookup(sn->ip_map_cache, class, addr);
> +	return __ip_map_lookup(sn->ip_map_cache, class, sap);
> }
> 
> static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm,
> @@ -311,8 +390,7 @@ static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm,
> 		set_bit(CACHE_NEGATIVE, &ip.h.flags);
> 	ip.h.expiry_time = expiry;
> 	ch = sunrpc_cache_update(cd, &ip.h, &ipm->h,
> -				 hash_str(ipm->m_class, IP_HASHBITS) ^
> -				 hash_ip6(&ipm->m_addr));
> +				 __ip_map_hash(ipm));
> 	if (!ch)
> 		return -ENOMEM;
> 	cache_put(ch, cd);
> @@ -654,6 +732,7 @@ static struct group_info *unix_gid_find(kuid_t uid, struct svc_rqst *rqstp)
> int
> svcauth_unix_set_client(struct svc_rqst *rqstp)
> {
> +	struct sockaddr *sap;
> 	struct sockaddr_in *sin;
> 	struct sockaddr_in6 *sin6, sin6_storage;
> 	struct ip_map *ipm;
> @@ -667,10 +746,15 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
> 	case AF_INET:
> 		sin = svc_addr_in(rqstp);
> 		sin6 = &sin6_storage;
> +		sin6->sin6_family = AF_INET6;
> 		ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &sin6->sin6_addr);
> +		sap = (struct sockaddr *)sin6;
> 		break;
> 	case AF_INET6:
> -		sin6 = svc_addr_in6(rqstp);
> +		sap = svc_addr(rqstp);
> +		break;
> +	case AF_VSOCK:
> +		sap = svc_addr(rqstp);
> 		break;
> 	default:
> 		BUG();
> @@ -683,7 +767,7 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
> 	ipm = ip_map_cached_get(xprt);
> 	if (ipm == NULL)
> 		ipm = __ip_map_lookup(sn->ip_map_cache, rqstp->rq_server->sv_program->pg_class,
> -				    &sin6->sin6_addr);
> +				    sap);
> 
> 	if (ipm == NULL)
> 		return SVC_DENIED;
> -- 
> 2.9.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
Stefan Hajnoczi July 10, 2017, 6:05 p.m. UTC | #2
On Thu, Jul 06, 2017 at 11:46:05AM -0700, Abbas Naderi wrote:
> Without CONFIG_SUNRPC_BACKCHANNEL, many things such as “svc_vsock_bc_class” are undefined, and then used throughout the code.
> Most of the “CONFIG_SUNRPC_XPRT_VSOCK” guards in sunrpc/svcsock.c should also be guarded by CONFIG_SUNRPC_BACKCHANNEL.

Thanks, Abbas!  Will fix in v4.

Stefan
diff mbox

Patch

diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index f81eaa8..b33ea0b 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -89,7 +89,15 @@  EXPORT_SYMBOL_GPL(unix_domain_find);
 struct ip_map {
 	struct cache_head	h;
 	char			m_class[8]; /* e.g. "nfsd" */
-	struct in6_addr		m_addr;
+	union {
+		struct sockaddr		m_sa;
+
+		/* For AF_INET6 and AF_INET (we map to IPv6) */
+		struct sockaddr_in6	m_sin6;
+
+		/* For AF_VSOCK */
+		struct sockaddr_vm	m_svm;
+	};
 	struct unix_domain	*m_client;
 };
 
@@ -112,8 +120,22 @@  static int ip_map_match(struct cache_head *corig, struct cache_head *cnew)
 {
 	struct ip_map *orig = container_of(corig, struct ip_map, h);
 	struct ip_map *new = container_of(cnew, struct ip_map, h);
-	return strcmp(orig->m_class, new->m_class) == 0 &&
-	       ipv6_addr_equal(&orig->m_addr, &new->m_addr);
+
+	if (strcmp(orig->m_class, new->m_class) != 0)
+		return 0;
+
+	if (orig->m_sa.sa_family != new->m_sa.sa_family)
+		return 0;
+
+	switch (orig->m_sa.sa_family) {
+	case AF_INET6:
+		return ipv6_addr_equal(&orig->m_sin6.sin6_addr,
+				       &new->m_sin6.sin6_addr);
+
+	case AF_VSOCK:
+		return orig->m_svm.svm_cid == new->m_svm.svm_cid;
+	}
+	return 0;
 }
 static void ip_map_init(struct cache_head *cnew, struct cache_head *citem)
 {
@@ -121,7 +143,14 @@  static void ip_map_init(struct cache_head *cnew, struct cache_head *citem)
 	struct ip_map *item = container_of(citem, struct ip_map, h);
 
 	strcpy(new->m_class, item->m_class);
-	new->m_addr = item->m_addr;
+	switch (item->m_sa.sa_family) {
+	case AF_INET6:
+		new->m_sin6 = item->m_sin6;
+		break;
+	case AF_VSOCK:
+		new->m_svm = item->m_svm;
+		break;
+	}
 }
 static void update(struct cache_head *cnew, struct cache_head *citem)
 {
@@ -145,19 +174,30 @@  static void ip_map_request(struct cache_detail *cd,
 				  char **bpp, int *blen)
 {
 	char text_addr[40];
+	struct in6_addr *addr;
 	struct ip_map *im = container_of(h, struct ip_map, h);
 
-	if (ipv6_addr_v4mapped(&(im->m_addr))) {
-		snprintf(text_addr, 20, "%pI4", &im->m_addr.s6_addr32[3]);
-	} else {
-		snprintf(text_addr, 40, "%pI6", &im->m_addr);
+	switch (im->m_sa.sa_family) {
+	case AF_INET6:
+		addr = &im->m_sin6.sin6_addr;
+		if (ipv6_addr_v4mapped(addr)) {
+			snprintf(text_addr, 20, "%pI4", &addr->s6_addr32[3]);
+		} else {
+			snprintf(text_addr, 40, "%pI6", addr);
+		}
+		break;
+
+	case AF_VSOCK:
+		snprintf(text_addr, 10, "vsock:%u", im->m_svm.svm_cid);
+		break;
 	}
+
 	qword_add(bpp, blen, im->m_class);
 	qword_add(bpp, blen, text_addr);
 	(*bpp)[-1] = '\n';
 }
 
-static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class, struct in6_addr *addr);
+static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class, struct sockaddr *sap);
 static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, struct unix_domain *udom, time_t expiry);
 
 static int ip_map_parse(struct cache_detail *cd,
@@ -173,6 +213,7 @@  static int ip_map_parse(struct cache_detail *cd,
 		struct sockaddr		sa;
 		struct sockaddr_in	s4;
 		struct sockaddr_in6	s6;
+		struct sockaddr_vm	svm;
 	} address;
 	struct sockaddr_in6 sin6;
 	int err;
@@ -201,11 +242,15 @@  static int ip_map_parse(struct cache_detail *cd,
 		sin6.sin6_family = AF_INET6;
 		ipv6_addr_set_v4mapped(address.s4.sin_addr.s_addr,
 				&sin6.sin6_addr);
+		address.s6 = sin6;
 		break;
 #if IS_ENABLED(CONFIG_IPV6)
 	case AF_INET6:
-		memcpy(&sin6, &address.s6, sizeof(sin6));
-		break;
+		break; /* Do nothing */
+#endif
+#ifdef CONFIG_SUNRPC_XPRT_VSOCK
+	case AF_VSOCK:
+		break; /* Do nothing */
 #endif
 	default:
 		return -EINVAL;
@@ -227,7 +272,7 @@  static int ip_map_parse(struct cache_detail *cd,
 		dom = NULL;
 
 	/* IPv6 scope IDs are ignored for now */
-	ipmp = __ip_map_lookup(cd, class, &sin6.sin6_addr);
+	ipmp = __ip_map_lookup(cd, class, &address.sa);
 	if (ipmp) {
 		err = __ip_map_update(cd, ipmp,
 			     container_of(dom, struct unix_domain, h),
@@ -247,7 +292,7 @@  static int ip_map_show(struct seq_file *m,
 		       struct cache_head *h)
 {
 	struct ip_map *im;
-	struct in6_addr addr;
+	struct in6_addr *addr;
 	char *dom = "-no-domain-";
 
 	if (h == NULL) {
@@ -256,33 +301,67 @@  static int ip_map_show(struct seq_file *m,
 	}
 	im = container_of(h, struct ip_map, h);
 	/* class addr domain */
-	addr = im->m_addr;
-
+	addr = &im->m_sin6.sin6_addr;
 	if (test_bit(CACHE_VALID, &h->flags) &&
 	    !test_bit(CACHE_NEGATIVE, &h->flags))
 		dom = im->m_client->h.name;
 
-	if (ipv6_addr_v4mapped(&addr)) {
-		seq_printf(m, "%s %pI4 %s\n",
-			im->m_class, &addr.s6_addr32[3], dom);
-	} else {
-		seq_printf(m, "%s %pI6 %s\n", im->m_class, &addr, dom);
+	switch (im->m_sa.sa_family) {
+	case AF_INET6:
+		if (ipv6_addr_v4mapped(addr)) {
+			seq_printf(m, "%s %pI4 %s\n",
+				im->m_class,
+				&addr->s6_addr32[3],
+				dom);
+		} else {
+			seq_printf(m, "%s %pI6 %s\n", im->m_class, addr, dom);
+		}
+		break;
+
+	case AF_VSOCK:
+		seq_printf(m, "%s %u %s\n",
+			im->m_class, im->m_svm.svm_cid, dom);
+		break;
 	}
 	return 0;
 }
 
+static int __ip_map_hash(struct ip_map *ipm)
+{
+	int hash;
+
+	switch (ipm->m_sa.sa_family) {
+	case AF_INET6:
+		hash = hash_ip6(&ipm->m_sin6.sin6_addr);
+		break;
+	case AF_VSOCK:
+		hash = hash_32(ipm->m_svm.svm_cid, IP_HASHBITS);
+		break;
+	default:
+		BUG();
+	}
+
+	return hash_str(ipm->m_class, IP_HASHBITS) ^ hash;
+}
 
 static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class,
-		struct in6_addr *addr)
+		struct sockaddr *sap)
 {
 	struct ip_map ip;
 	struct cache_head *ch;
 
 	strcpy(ip.m_class, class);
-	ip.m_addr = *addr;
-	ch = sunrpc_cache_lookup(cd, &ip.h,
-				 hash_str(class, IP_HASHBITS) ^
-				 hash_ip6(addr));
+	switch (sap->sa_family) {
+	case AF_INET6:
+		ip.m_sin6 = *(struct sockaddr_in6 *)sap;
+		break;
+	case AF_VSOCK:
+		ip.m_svm = *(struct sockaddr_vm *)sap;
+		break;
+	default:
+		return NULL;
+	}
+	ch = sunrpc_cache_lookup(cd, &ip.h, __ip_map_hash(&ip));
 
 	if (ch)
 		return container_of(ch, struct ip_map, h);
@@ -291,12 +370,12 @@  static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class,
 }
 
 static inline struct ip_map *ip_map_lookup(struct net *net, char *class,
-		struct in6_addr *addr)
+		struct sockaddr *sap)
 {
 	struct sunrpc_net *sn;
 
 	sn = net_generic(net, sunrpc_net_id);
-	return __ip_map_lookup(sn->ip_map_cache, class, addr);
+	return __ip_map_lookup(sn->ip_map_cache, class, sap);
 }
 
 static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm,
@@ -311,8 +390,7 @@  static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm,
 		set_bit(CACHE_NEGATIVE, &ip.h.flags);
 	ip.h.expiry_time = expiry;
 	ch = sunrpc_cache_update(cd, &ip.h, &ipm->h,
-				 hash_str(ipm->m_class, IP_HASHBITS) ^
-				 hash_ip6(&ipm->m_addr));
+				 __ip_map_hash(ipm));
 	if (!ch)
 		return -ENOMEM;
 	cache_put(ch, cd);
@@ -654,6 +732,7 @@  static struct group_info *unix_gid_find(kuid_t uid, struct svc_rqst *rqstp)
 int
 svcauth_unix_set_client(struct svc_rqst *rqstp)
 {
+	struct sockaddr *sap;
 	struct sockaddr_in *sin;
 	struct sockaddr_in6 *sin6, sin6_storage;
 	struct ip_map *ipm;
@@ -667,10 +746,15 @@  svcauth_unix_set_client(struct svc_rqst *rqstp)
 	case AF_INET:
 		sin = svc_addr_in(rqstp);
 		sin6 = &sin6_storage;
+		sin6->sin6_family = AF_INET6;
 		ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &sin6->sin6_addr);
+		sap = (struct sockaddr *)sin6;
 		break;
 	case AF_INET6:
-		sin6 = svc_addr_in6(rqstp);
+		sap = svc_addr(rqstp);
+		break;
+	case AF_VSOCK:
+		sap = svc_addr(rqstp);
 		break;
 	default:
 		BUG();
@@ -683,7 +767,7 @@  svcauth_unix_set_client(struct svc_rqst *rqstp)
 	ipm = ip_map_cached_get(xprt);
 	if (ipm == NULL)
 		ipm = __ip_map_lookup(sn->ip_map_cache, rqstp->rq_server->sv_program->pg_class,
-				    &sin6->sin6_addr);
+				    sap);
 
 	if (ipm == NULL)
 		return SVC_DENIED;