summaryrefslogtreecommitdiff
path: root/net/sunrpc/svc.c
diff options
context:
space:
mode:
authorTrond Myklebust <trondmy@gmail.com>2019-04-09 18:46:17 +0300
committerJ. Bruce Fields <bfields@redhat.com>2019-04-24 16:46:35 +0300
commit642ee6b209c2f4c20fe0a7ed36b429c470162eae (patch)
tree0d98fb1b5ddc6b9b8f670a8a745f84d17e879e24 /net/sunrpc/svc.c
parent4532608d71c8ed6049c949a667eeed719cb9291d (diff)
downloadlinux-642ee6b209c2f4c20fe0a7ed36b429c470162eae.tar.xz
SUNRPC: Allow further customisation of RPC program registration
Add a callback to allow customisation of the rpcbind registration. When clients have the ability to turn on and off version support, we want to allow them to also prevent registration of those versions with the rpc portmapper. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'net/sunrpc/svc.c')
-rw-r--r--net/sunrpc/svc.c85
1 files changed, 54 insertions, 31 deletions
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 791c8076793f..2be827820247 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -993,6 +993,58 @@ static int __svc_register(struct net *net, const char *progname,
return error;
}
+int svc_rpcbind_set_version(struct net *net,
+ const struct svc_program *progp,
+ u32 version, int family,
+ unsigned short proto,
+ unsigned short port)
+{
+ dprintk("svc: svc_register(%sv%d, %s, %u, %u)\n",
+ progp->pg_name, version,
+ proto == IPPROTO_UDP? "udp" : "tcp",
+ port, family);
+
+ return __svc_register(net, progp->pg_name, progp->pg_prog,
+ version, family, proto, port);
+
+}
+EXPORT_SYMBOL_GPL(svc_rpcbind_set_version);
+
+int svc_generic_rpcbind_set(struct net *net,
+ const struct svc_program *progp,
+ u32 version, int family,
+ unsigned short proto,
+ unsigned short port)
+{
+ const struct svc_version *vers = progp->pg_vers[version];
+ int error;
+
+ if (vers == NULL)
+ return 0;
+
+ if (vers->vs_hidden) {
+ dprintk("svc: svc_register(%sv%d, %s, %u, %u)"
+ " (but not telling portmap)\n",
+ progp->pg_name, version,
+ proto == IPPROTO_UDP? "udp" : "tcp",
+ port, family);
+ return 0;
+ }
+
+ /*
+ * Don't register a UDP port if we need congestion
+ * control.
+ */
+ if (vers->vs_need_cong_ctrl && proto == IPPROTO_UDP)
+ return 0;
+
+ error = svc_rpcbind_set_version(net, progp, version,
+ family, proto, port);
+
+ return (vers->vs_rpcb_optnl) ? 0 : error;
+}
+EXPORT_SYMBOL_GPL(svc_generic_rpcbind_set);
+
/**
* svc_register - register an RPC service with the local portmapper
* @serv: svc_serv struct for the service to register
@@ -1008,7 +1060,6 @@ int svc_register(const struct svc_serv *serv, struct net *net,
const unsigned short port)
{
struct svc_program *progp;
- const struct svc_version *vers;
unsigned int i;
int error = 0;
@@ -1018,37 +1069,9 @@ int svc_register(const struct svc_serv *serv, struct net *net,
for (progp = serv->sv_program; progp; progp = progp->pg_next) {
for (i = 0; i < progp->pg_nvers; i++) {
- vers = progp->pg_vers[i];
- if (vers == NULL)
- continue;
-
- dprintk("svc: svc_register(%sv%d, %s, %u, %u)%s\n",
- progp->pg_name,
- i,
- proto == IPPROTO_UDP? "udp" : "tcp",
- port,
- family,
- vers->vs_hidden ?
- " (but not telling portmap)" : "");
-
- if (vers->vs_hidden)
- continue;
-
- /*
- * Don't register a UDP port if we need congestion
- * control.
- */
- if (vers->vs_need_cong_ctrl && proto == IPPROTO_UDP)
- continue;
-
- error = __svc_register(net, progp->pg_name, progp->pg_prog,
- i, family, proto, port);
-
- if (vers->vs_rpcb_optnl) {
- error = 0;
- continue;
- }
+ error = progp->pg_rpcbind_set(net, progp, i,
+ family, proto, port);
if (error < 0) {
printk(KERN_WARNING "svc: failed to register "
"%sv%u RPC service (errno %d).\n",