From: Chuck Lever <chuck.lever@oracle.com>
To: trond.myklebust@netapp.com, bfields@fieldses.org, steved@redhat.com
Cc: linux-nfs@vger.kernel.org
Subject: [PATCH 13/17] SUNRPC: Simplify kernel RPC service registration
Date: Tue, 03 Mar 2009 17:33:48 -0500 [thread overview]
Message-ID: <20090303223347.2933.32251.stgit@ingres.1015granger.net> (raw)
In-Reply-To: <20090303220539.2933.15015.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
The kernel registers RPC services with the local portmapper with an
rpcbind SET upcall to the local portmapper. Traditionally, this used
rpcbind v2, but registering RPC services that support IPv6 requires
rpcbind v3 or v4.
Since we now want separate PF_INET and PF_INET6 listeners for each
kernel RPC service, svc_register() will do only one of those
registrations at a time.
For PF_INET, it tries an rpcb v4 SET upcall first; if that fails, it
does a legacy portmap SET. This makes it entirely backwards
compatible with legacy user space, but allows a proper v4 SET to be
used if rpcbind is available.
For PF_INET6, it does an rpcb v4 SET upcall. If that fails, it fails
the registration, and thus the transport creation. This let's the
kernel detect if user space is able to support IPv6 RPC services.
This provides complete backwards compatibilty with legacy user space
that only supports rpcbind v2. The only down-side is that registering
a new kernel RPC service may take an extra exchange with the local
portmapper on legacy systems, but this is an infrequent operation, so
it shouldn't be consequential.
This patch is part of a series that addresses
http://bugzilla.kernel.org/show_bug.cgi?id=12256
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
net/sunrpc/svc.c | 79 +++++++++++++++++++++++-------------------------------
1 files changed, 34 insertions(+), 45 deletions(-)
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index f1e0ad8..949164d 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -718,8 +718,6 @@ svc_exit_thread(struct svc_rqst *rqstp)
}
EXPORT_SYMBOL_GPL(svc_exit_thread);
-#ifdef CONFIG_SUNRPC_REGISTER_V4
-
/*
* Register an "inet" protocol family netid with the local
* rpcbind daemon via an rpcbind v4 SET request.
@@ -734,12 +732,13 @@ static int __svc_rpcb_register4(const u32 program, const u32 version,
const unsigned short protocol,
const unsigned short port)
{
- struct sockaddr_in sin = {
+ const struct sockaddr_in sin = {
.sin_family = AF_INET,
.sin_addr.s_addr = htonl(INADDR_ANY),
.sin_port = htons(port),
};
- char *netid;
+ const char *netid;
+ int error;
switch (protocol) {
case IPPROTO_UDP:
@@ -752,10 +751,20 @@ static int __svc_rpcb_register4(const u32 program, const u32 version,
return -ENOPROTOOPT;
}
- return rpcb_v4_register(program, version,
- (struct sockaddr *)&sin, netid);
+ error = rpcb_v4_register(program, version,
+ (const struct sockaddr *)&sin, netid);
+
+ /*
+ * User space didn't support rpcbind v4, so retry this
+ * registration request with the legacy rpcbind v2 protocol.
+ */
+ if (error == -EPROTONOSUPPORT)
+ error = rpcb_register(program, version, protocol, port);
+
+ return error;
}
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
/*
* Register an "inet6" protocol family netid with the local
* rpcbind daemon via an rpcbind v4 SET request.
@@ -770,12 +779,13 @@ static int __svc_rpcb_register6(const u32 program, const u32 version,
const unsigned short protocol,
const unsigned short port)
{
- struct sockaddr_in6 sin6 = {
+ const struct sockaddr_in6 sin6 = {
.sin6_family = AF_INET6,
.sin6_addr = IN6ADDR_ANY_INIT,
.sin6_port = htons(port),
};
- char *netid;
+ const char *netid;
+ int error;
switch (protocol) {
case IPPROTO_UDP:
@@ -788,9 +798,19 @@ static int __svc_rpcb_register6(const u32 program, const u32 version,
return -ENOPROTOOPT;
}
- return rpcb_v4_register(program, version,
- (struct sockaddr *)&sin6, netid);
+ error = rpcb_v4_register(program, version,
+ (const struct sockaddr *)&sin6, netid);
+
+ /*
+ * User space didn't support rpcbind version 4, so we won't
+ * use a PF_INET6 listener.
+ */
+ if (error == -EPROTONOSUPPORT)
+ error = -EAFNOSUPPORT;
+
+ return error;
}
+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
/*
* Register a kernel RPC service via rpcbind version 4.
@@ -809,48 +829,17 @@ static int __svc_register(const u32 program, const u32 version,
case PF_INET:
return __svc_rpcb_register4(program, version,
protocol, port);
+ break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
case PF_INET6:
- error = __svc_rpcb_register6(program, version,
+ return__svc_rpcb_register6(program, version,
protocol, port);
- if (error < 0)
- return error;
-
- /*
- * Work around bug in some versions of Linux rpcbind
- * which don't allow registration of both inet and
- * inet6 netids.
- *
- * Error return ignored for now.
- */
- __svc_rpcb_register4(program, version,
- protocol, port);
- return 0;
+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
}
return -EAFNOSUPPORT;
}
-#else /* CONFIG_SUNRPC_REGISTER_V4 */
-
-/*
- * Register a kernel RPC service via rpcbind version 2.
- *
- * Returns zero on success; a negative errno value is returned
- * if any error occurs.
- */
-static int __svc_register(const u32 program, const u32 version,
- const int family,
- const unsigned short protocol,
- const unsigned short port)
-{
- if (family != PF_INET)
- return -EAFNOSUPPORT;
-
- return rpcb_register(program, version, protocol, port);
-}
-
-#endif /* CONFIG_SUNRPC_REGISTER_V4 */
-
/**
* svc_register - register an RPC service with the local portmapper
* @serv: svc_serv struct for the service to register
next prev parent reply other threads:[~2009-03-03 22:35 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-03-03 22:32 [PATCH 00/17] Proposed fix for blacklisted ipv6.ko Chuck Lever
[not found] ` <20090303220539.2933.15015.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2009-03-03 22:32 ` [PATCH 01/17] SUNRPC: Pass a family argument to svc_register() Chuck Lever
2009-03-03 22:32 ` [PATCH 02/17] SUNRPC: svc_setup_socket() gets protocol family from socket Chuck Lever
2009-03-03 22:32 ` [PATCH 03/17] SUNRPC: Change svc_create_xprt() to take a @family argument Chuck Lever
2009-03-03 22:32 ` [PATCH 04/17] SUNRPC: Remove @family argument from svc_create() and svc_create_pooled() Chuck Lever
2009-03-03 22:32 ` [PATCH 05/17] NFS: Revert creation of IPv6 listeners for lockd and NFSv4 callbacks Chuck Lever
2009-03-03 22:32 ` [PATCH 06/17] SUNRPC: Set IPV6ONLY flag on PF_INET6 RPC listener sockets Chuck Lever
[not found] ` <20090303223254.2933.70364.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2009-03-30 22:17 ` [PATCH 06/17] SUNRPC: Set IPV6ONLY flag on PF_INET6 RPC listenersockets Trond Myklebust
[not found] ` <1238451467.23512.11.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2009-03-30 22:28 ` Chuck Lever
2009-03-30 22:37 ` Trond Myklebust
[not found] ` <1238452665.23512.13.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2009-03-30 22:45 ` Chuck Lever
2009-03-31 12:19 ` Trond Myklebust
[not found] ` <1238501960.31172.1.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2009-03-31 15:32 ` Chuck Lever
2009-03-03 22:33 ` [PATCH 07/17] SUNRPC: Use IPv4 loopback for registering AF_INET6 kernel RPC services Chuck Lever
2009-03-03 22:33 ` [PATCH 08/17] SUNRPC: Don't return EPROTONOSUPPORT in svc_register()'s helpers Chuck Lever
[not found] ` <20090303223309.2933.51773.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2009-03-11 18:32 ` J. Bruce Fields
2009-03-03 22:33 ` [PATCH 09/17] SUNRPC: Clean up address type casts in rpcb_v4_register() Chuck Lever
2009-03-03 22:33 ` [PATCH 10/17] SUNRPC: Use "0" as r_owner Chuck Lever
[not found] ` <20090303223324.2933.57002.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2009-03-11 19:06 ` J. Bruce Fields
2009-03-11 19:57 ` Chuck Lever
2009-03-11 20:09 ` J. Bruce Fields
2009-03-11 20:18 ` Chuck Lever
2009-03-03 22:33 ` [PATCH 11/17] SUNRPC: Allow callers to pass rpcb_v4_register a NULL address Chuck Lever
2009-03-03 22:33 ` [PATCH 12/17] SUNRPC: Simplify svc_unregister() Chuck Lever
2009-03-03 22:33 ` Chuck Lever [this message]
2009-03-03 22:33 ` [PATCH 14/17] SUNRPC: rpcb_register() should handle errors silently Chuck Lever
2009-03-03 22:34 ` [PATCH 15/17] SUNRPC: Remove CONFIG_SUNRPC_REGISTER_V4 Chuck Lever
2009-03-03 22:34 ` [PATCH 16/17] lockd: Start PF_INET6 listener only if IPv6 support is available Chuck Lever
[not found] ` <20090303223410.2933.90223.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2009-03-30 22:06 ` [PATCH 16/17] lockd: Start PF_INET6 listener only if IPv6 support isavailable Trond Myklebust
2009-03-03 22:34 ` [PATCH 17/17] NFS: Start PF_INET6 callback listener only if IPv6 support is available Chuck Lever
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=20090303223347.2933.32251.stgit@ingres.1015granger.net \
--to=chuck.lever@oracle.com \
--cc=bfields@fieldses.org \
--cc=linux-nfs@vger.kernel.org \
--cc=steved@redhat.com \
--cc=trond.myklebust@netapp.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).