]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
SUNRPC: Allow further customisation of RPC program registration
authorTrond Myklebust <trondmy@gmail.com>
Tue, 9 Apr 2019 15:46:17 +0000 (11:46 -0400)
committerJ. Bruce Fields <bfields@redhat.com>
Wed, 24 Apr 2019 13:46:35 +0000 (09:46 -0400)
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>
fs/lockd/svc.c
fs/nfs/callback.c
fs/nfsd/nfssvc.c
include/linux/sunrpc/svc.h
net/sunrpc/svc.c

index 75415b21efdae1416460bd2b9e7fb5da2df94164..96bb74c919f9a75a1494c836054e156995f19899 100644 (file)
@@ -809,4 +809,5 @@ static struct svc_program   nlmsvc_program = {
        .pg_stats               = &nlmsvc_stats,        /* stats table */
        .pg_authenticate        = &lockd_authenticate,  /* export authentication */
        .pg_init_request        = svc_generic_init_request,
+       .pg_rpcbind_set         = svc_generic_rpcbind_set,
 };
index a9510374bad71950d5a61a0d2a9cffac7ab3ca9a..15c9575e0e7a4e0b13461a78362fb63b2888b98f 100644 (file)
@@ -458,4 +458,5 @@ static struct svc_program nfs4_callback_program = {
        .pg_stats = &nfs4_callback_stats,
        .pg_authenticate = nfs_callback_authenticate,
        .pg_init_request = svc_generic_init_request,
+       .pg_rpcbind_set = svc_generic_rpcbind_set,
 };
index e26762e84798af467b6e826f490c2f3ec39b4b43..6a52400c85e059222cea3137dbbc7ba9f3c4efc7 100644 (file)
@@ -87,6 +87,7 @@ static struct svc_program     nfsd_acl_program = {
        .pg_stats               = &nfsd_acl_svcstats,
        .pg_authenticate        = &svc_set_client,
        .pg_init_request        = svc_generic_init_request,
+       .pg_rpcbind_set         = svc_generic_rpcbind_set,
 };
 
 static struct svc_stat nfsd_acl_svcstats = {
@@ -120,7 +121,7 @@ struct svc_program          nfsd_program = {
        .pg_stats               = &nfsd_svcstats,       /* version table */
        .pg_authenticate        = &svc_set_client,      /* export authentication */
        .pg_init_request        = svc_generic_init_request,
-
+       .pg_rpcbind_set         = svc_generic_rpcbind_set,
 };
 
 static bool nfsd_supported_minorversions[NFSD_SUPPORTED_MINOR_VERSION + 1] = {
index f43d5765acffa52d09c412be7d314b041170288f..1afe38eb33f7eab286c88f99ad969c5382952c3b 100644 (file)
@@ -410,6 +410,11 @@ struct svc_program {
        __be32                  (*pg_init_request)(struct svc_rqst *,
                                                   const struct svc_program *,
                                                   struct svc_process_info *);
+       int                     (*pg_rpcbind_set)(struct net *net,
+                                                 const struct svc_program *,
+                                                 u32 version, int family,
+                                                 unsigned short proto,
+                                                 unsigned short port);
 };
 
 /*
@@ -522,6 +527,16 @@ __be32                svc_return_autherr(struct svc_rqst *rqstp, __be32 auth_err);
 __be32            svc_generic_init_request(struct svc_rqst *rqstp,
                                            const struct svc_program *progp,
                                            struct svc_process_info *procinfo);
+int               svc_generic_rpcbind_set(struct net *net,
+                                          const struct svc_program *progp,
+                                          u32 version, int family,
+                                          unsigned short proto,
+                                          unsigned short port);
+int               svc_rpcbind_set_version(struct net *net,
+                                          const struct svc_program *progp,
+                                          u32 version, int family,
+                                          unsigned short proto,
+                                          unsigned short port);
 
 #define        RPC_MAX_ADDRBUFLEN      (63U)
 
index 791c8076793fee40ce588b3fe43fd91bf707cd0b..2be8278202471360192abe5661fc2ef016945f6d 100644 (file)
@@ -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",