From: Stefan Hajnoczi <stefanha@redhat.com>
To: linux-nfs@vger.kernel.org
Cc: Abbas Naderi <abiusx@google.com>,
Anna Schumaker <anna.schumaker@netapp.com>,
Trond Myklebust <trond.myklebust@primarydata.com>,
"J. Bruce Fields" <bfields@fieldses.org>,
Jeff Layton <jlayton@redhat.com>,
Chuck Lever <chuck.lever@oracle.com>,
Stefan Hajnoczi <stefanha@redhat.com>
Subject: [PATCH v3 14/14] SUNRPC: add AF_VSOCK support to auth.unix.ip
Date: Fri, 30 Jun 2017 14:23:52 +0100 [thread overview]
Message-ID: <20170630132352.32133-15-stefanha@redhat.com> (raw)
In-Reply-To: <20170630132352.32133-1-stefanha@redhat.com>
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
next prev parent reply other threads:[~2017-06-30 13:24 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-30 13:23 [PATCH v3 00/14] NFS: add AF_VSOCK support Stefan Hajnoczi
2017-06-30 13:23 ` [PATCH v3 01/14] SUNRPC: add AF_VSOCK support to addr.[ch] Stefan Hajnoczi
2017-06-30 13:23 ` [PATCH v3 02/14] SUNRPC: rename "TCP" record parser to "stream" parser Stefan Hajnoczi
2017-06-30 13:23 ` [PATCH v3 03/14] SUNRPC: abstract tcp_read_sock() in record fragment parser Stefan Hajnoczi
2017-06-30 13:23 ` [PATCH v3 04/14] SUNRPC: extract xs_stream_reset_state() Stefan Hajnoczi
2017-06-30 13:23 ` [PATCH v3 05/14] VSOCK: add tcp_read_sock()-like vsock_read_sock() function Stefan Hajnoczi
2017-10-31 13:35 ` Jeff Layton
2017-11-07 13:32 ` Stefan Hajnoczi
2017-06-30 13:23 ` [PATCH v3 06/14] SUNRPC: add AF_VSOCK support to xprtsock.c Stefan Hajnoczi
2017-11-07 13:46 ` Jeff Layton
2017-11-14 16:45 ` Stefan Hajnoczi
2017-06-30 13:23 ` [PATCH v3 07/14] SUNRPC: drop unnecessary svc_bc_tcp_create() helper Stefan Hajnoczi
2017-10-31 13:55 ` Jeff Layton
2017-06-30 13:23 ` [PATCH v3 08/14] SUNRPC: add AF_VSOCK support to svc_xprt.c Stefan Hajnoczi
2017-10-31 14:10 ` Jeff Layton
2017-11-07 13:31 ` Stefan Hajnoczi
2017-11-07 14:01 ` Jeff Layton
2017-11-16 15:25 ` Stefan Hajnoczi
2017-11-16 20:53 ` Chuck Lever
2017-11-20 16:31 ` Stefan Hajnoczi
2017-11-26 11:58 ` Jeff Layton
2017-11-26 15:53 ` Chuck Lever
2017-11-27 16:46 ` Bruce Fields
2017-11-27 17:34 ` Jeff Layton
2017-11-27 17:37 ` Matt Benjamin
2017-06-30 13:23 ` [PATCH v3 09/14] SUNRPC: add AF_VSOCK backchannel support Stefan Hajnoczi
2017-06-30 13:23 ` [PATCH v3 10/14] NFS: add AF_VSOCK support to NFS client Stefan Hajnoczi
2017-06-30 13:23 ` [PATCH v3 11/14] nfsd: support vsock xprt creation Stefan Hajnoczi
2017-06-30 13:23 ` [PATCH v3 12/14] SUNRPC: add AF_VSOCK lock class Stefan Hajnoczi
2017-06-30 13:23 ` [PATCH v3 13/14] SUNRPC: vsock svcsock support Stefan Hajnoczi
2017-11-07 14:12 ` Jeff Layton
2017-11-14 14:20 ` Stefan Hajnoczi
2017-06-30 13:23 ` Stefan Hajnoczi [this message]
2017-07-06 18:46 ` [PATCH v3 14/14] SUNRPC: add AF_VSOCK support to auth.unix.ip Abbas Naderi
2017-07-10 18:05 ` Stefan Hajnoczi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170630132352.32133-15-stefanha@redhat.com \
--to=stefanha@redhat.com \
--cc=abiusx@google.com \
--cc=anna.schumaker@netapp.com \
--cc=bfields@fieldses.org \
--cc=chuck.lever@oracle.com \
--cc=jlayton@redhat.com \
--cc=linux-nfs@vger.kernel.org \
--cc=trond.myklebust@primarydata.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).