summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trondmy@gmail.com>2019-04-09 11:46:17 -0400
committerJ. Bruce Fields <bfields@redhat.com>2019-04-24 09:46:35 -0400
commit642ee6b209c2f4c20fe0a7ed36b429c470162eae (patch)
tree0d98fb1b5ddc6b9b8f670a8a745f84d17e879e24
parent4532608d71c8ed6049c949a667eeed719cb9291d (diff)
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>
-rw-r--r--fs/lockd/svc.c1
-rw-r--r--fs/nfs/callback.c1
-rw-r--r--fs/nfsd/nfssvc.c3
-rw-r--r--include/linux/sunrpc/svc.h15
-rw-r--r--net/sunrpc/svc.c85
5 files changed, 73 insertions, 32 deletions
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 75415b21efda..96bb74c919f9 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -809,4 +809,5 @@ static struct svc_program nlmsvc_program = {
809 .pg_stats = &nlmsvc_stats, /* stats table */ 809 .pg_stats = &nlmsvc_stats, /* stats table */
810 .pg_authenticate = &lockd_authenticate, /* export authentication */ 810 .pg_authenticate = &lockd_authenticate, /* export authentication */
811 .pg_init_request = svc_generic_init_request, 811 .pg_init_request = svc_generic_init_request,
812 .pg_rpcbind_set = svc_generic_rpcbind_set,
812}; 813};
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index a9510374bad7..15c9575e0e7a 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -458,4 +458,5 @@ static struct svc_program nfs4_callback_program = {
458 .pg_stats = &nfs4_callback_stats, 458 .pg_stats = &nfs4_callback_stats,
459 .pg_authenticate = nfs_callback_authenticate, 459 .pg_authenticate = nfs_callback_authenticate,
460 .pg_init_request = svc_generic_init_request, 460 .pg_init_request = svc_generic_init_request,
461 .pg_rpcbind_set = svc_generic_rpcbind_set,
461}; 462};
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index e26762e84798..6a52400c85e0 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -87,6 +87,7 @@ static struct svc_program nfsd_acl_program = {
87 .pg_stats = &nfsd_acl_svcstats, 87 .pg_stats = &nfsd_acl_svcstats,
88 .pg_authenticate = &svc_set_client, 88 .pg_authenticate = &svc_set_client,
89 .pg_init_request = svc_generic_init_request, 89 .pg_init_request = svc_generic_init_request,
90 .pg_rpcbind_set = svc_generic_rpcbind_set,
90}; 91};
91 92
92static struct svc_stat nfsd_acl_svcstats = { 93static struct svc_stat nfsd_acl_svcstats = {
@@ -120,7 +121,7 @@ struct svc_program nfsd_program = {
120 .pg_stats = &nfsd_svcstats, /* version table */ 121 .pg_stats = &nfsd_svcstats, /* version table */
121 .pg_authenticate = &svc_set_client, /* export authentication */ 122 .pg_authenticate = &svc_set_client, /* export authentication */
122 .pg_init_request = svc_generic_init_request, 123 .pg_init_request = svc_generic_init_request,
123 124 .pg_rpcbind_set = svc_generic_rpcbind_set,
124}; 125};
125 126
126static bool nfsd_supported_minorversions[NFSD_SUPPORTED_MINOR_VERSION + 1] = { 127static bool nfsd_supported_minorversions[NFSD_SUPPORTED_MINOR_VERSION + 1] = {
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index f43d5765acff..1afe38eb33f7 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -410,6 +410,11 @@ struct svc_program {
410 __be32 (*pg_init_request)(struct svc_rqst *, 410 __be32 (*pg_init_request)(struct svc_rqst *,
411 const struct svc_program *, 411 const struct svc_program *,
412 struct svc_process_info *); 412 struct svc_process_info *);
413 int (*pg_rpcbind_set)(struct net *net,
414 const struct svc_program *,
415 u32 version, int family,
416 unsigned short proto,
417 unsigned short port);
413}; 418};
414 419
415/* 420/*
@@ -522,6 +527,16 @@ __be32 svc_return_autherr(struct svc_rqst *rqstp, __be32 auth_err);
522__be32 svc_generic_init_request(struct svc_rqst *rqstp, 527__be32 svc_generic_init_request(struct svc_rqst *rqstp,
523 const struct svc_program *progp, 528 const struct svc_program *progp,
524 struct svc_process_info *procinfo); 529 struct svc_process_info *procinfo);
530int svc_generic_rpcbind_set(struct net *net,
531 const struct svc_program *progp,
532 u32 version, int family,
533 unsigned short proto,
534 unsigned short port);
535int svc_rpcbind_set_version(struct net *net,
536 const struct svc_program *progp,
537 u32 version, int family,
538 unsigned short proto,
539 unsigned short port);
525 540
526#define RPC_MAX_ADDRBUFLEN (63U) 541#define RPC_MAX_ADDRBUFLEN (63U)
527 542
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,
993 return error; 993 return error;
994} 994}
995 995
996int svc_rpcbind_set_version(struct net *net,
997 const struct svc_program *progp,
998 u32 version, int family,
999 unsigned short proto,
1000 unsigned short port)
1001{
1002 dprintk("svc: svc_register(%sv%d, %s, %u, %u)\n",
1003 progp->pg_name, version,
1004 proto == IPPROTO_UDP? "udp" : "tcp",
1005 port, family);
1006
1007 return __svc_register(net, progp->pg_name, progp->pg_prog,
1008 version, family, proto, port);
1009
1010}
1011EXPORT_SYMBOL_GPL(svc_rpcbind_set_version);
1012
1013int svc_generic_rpcbind_set(struct net *net,
1014 const struct svc_program *progp,
1015 u32 version, int family,
1016 unsigned short proto,
1017 unsigned short port)
1018{
1019 const struct svc_version *vers = progp->pg_vers[version];
1020 int error;
1021
1022 if (vers == NULL)
1023 return 0;
1024
1025 if (vers->vs_hidden) {
1026 dprintk("svc: svc_register(%sv%d, %s, %u, %u)"
1027 " (but not telling portmap)\n",
1028 progp->pg_name, version,
1029 proto == IPPROTO_UDP? "udp" : "tcp",
1030 port, family);
1031 return 0;
1032 }
1033
1034 /*
1035 * Don't register a UDP port if we need congestion
1036 * control.
1037 */
1038 if (vers->vs_need_cong_ctrl && proto == IPPROTO_UDP)
1039 return 0;
1040
1041 error = svc_rpcbind_set_version(net, progp, version,
1042 family, proto, port);
1043
1044 return (vers->vs_rpcb_optnl) ? 0 : error;
1045}
1046EXPORT_SYMBOL_GPL(svc_generic_rpcbind_set);
1047
996/** 1048/**
997 * svc_register - register an RPC service with the local portmapper 1049 * svc_register - register an RPC service with the local portmapper
998 * @serv: svc_serv struct for the service to register 1050 * @serv: svc_serv struct for the service to register
@@ -1008,7 +1060,6 @@ int svc_register(const struct svc_serv *serv, struct net *net,
1008 const unsigned short port) 1060 const unsigned short port)
1009{ 1061{
1010 struct svc_program *progp; 1062 struct svc_program *progp;
1011 const struct svc_version *vers;
1012 unsigned int i; 1063 unsigned int i;
1013 int error = 0; 1064 int error = 0;
1014 1065
@@ -1018,37 +1069,9 @@ int svc_register(const struct svc_serv *serv, struct net *net,
1018 1069
1019 for (progp = serv->sv_program; progp; progp = progp->pg_next) { 1070 for (progp = serv->sv_program; progp; progp = progp->pg_next) {
1020 for (i = 0; i < progp->pg_nvers; i++) { 1071 for (i = 0; i < progp->pg_nvers; i++) {
1021 vers = progp->pg_vers[i];
1022 if (vers == NULL)
1023 continue;
1024
1025 dprintk("svc: svc_register(%sv%d, %s, %u, %u)%s\n",
1026 progp->pg_name,
1027 i,
1028 proto == IPPROTO_UDP? "udp" : "tcp",
1029 port,
1030 family,
1031 vers->vs_hidden ?
1032 " (but not telling portmap)" : "");
1033
1034 if (vers->vs_hidden)
1035 continue;
1036
1037 /*
1038 * Don't register a UDP port if we need congestion
1039 * control.
1040 */
1041 if (vers->vs_need_cong_ctrl && proto == IPPROTO_UDP)
1042 continue;
1043
1044 error = __svc_register(net, progp->pg_name, progp->pg_prog,
1045 i, family, proto, port);
1046
1047 if (vers->vs_rpcb_optnl) {
1048 error = 0;
1049 continue;
1050 }
1051 1072
1073 error = progp->pg_rpcbind_set(net, progp, i,
1074 family, proto, port);
1052 if (error < 0) { 1075 if (error < 0) {
1053 printk(KERN_WARNING "svc: failed to register " 1076 printk(KERN_WARNING "svc: failed to register "
1054 "%sv%u RPC service (errno %d).\n", 1077 "%sv%u RPC service (errno %d).\n",