diff options
author | Chuck Lever <cel@netapp.com> | 2005-08-25 19:25:54 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-09-23 12:38:50 -0400 |
commit | 529b33c6db0120126b1381faa51406dc463acdc9 (patch) | |
tree | 4856a23687aa891f6a5d1c45db80190b90b0fc68 /net/sunrpc | |
parent | 555ee3af161b037865793bd4bebc06b58daafde6 (diff) |
[PATCH] RPC: allow RPC client's port range to be adjustable
Select an RPC client source port between 650 and 1023 instead of between
1 and 800. The old range conflicts with a number of network services.
Provide sysctls to allow admins to select a different port range.
Note that this doesn't affect user-level RPC library behavior, which
still uses 1 to 800.
Based on a suggestion by Olaf Kirch <okir@suse.de>.
Test-plan:
Repeated mount and unmount. Destructive testing. Idle timeouts.
Signed-off-by: Chuck Lever <cel@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/sysctl.c | 29 | ||||
-rw-r--r-- | net/sunrpc/xprtsock.c | 23 |
2 files changed, 37 insertions, 15 deletions
diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c index ef483262f17f..d0c9f460e411 100644 --- a/net/sunrpc/sysctl.c +++ b/net/sunrpc/sysctl.c | |||
@@ -121,9 +121,16 @@ done: | |||
121 | 121 | ||
122 | unsigned int xprt_udp_slot_table_entries = RPC_DEF_SLOT_TABLE; | 122 | unsigned int xprt_udp_slot_table_entries = RPC_DEF_SLOT_TABLE; |
123 | unsigned int xprt_tcp_slot_table_entries = RPC_DEF_SLOT_TABLE; | 123 | unsigned int xprt_tcp_slot_table_entries = RPC_DEF_SLOT_TABLE; |
124 | unsigned int xprt_min_resvport = RPC_DEF_MIN_RESVPORT; | ||
125 | EXPORT_SYMBOL(xprt_min_resvport); | ||
126 | unsigned int xprt_max_resvport = RPC_DEF_MAX_RESVPORT; | ||
127 | EXPORT_SYMBOL(xprt_max_resvport); | ||
128 | |||
124 | 129 | ||
125 | static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE; | 130 | static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE; |
126 | static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE; | 131 | static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE; |
132 | static unsigned int xprt_min_resvport_limit = RPC_MIN_RESVPORT; | ||
133 | static unsigned int xprt_max_resvport_limit = RPC_MAX_RESVPORT; | ||
127 | 134 | ||
128 | static ctl_table debug_table[] = { | 135 | static ctl_table debug_table[] = { |
129 | { | 136 | { |
@@ -180,6 +187,28 @@ static ctl_table debug_table[] = { | |||
180 | .extra1 = &min_slot_table_size, | 187 | .extra1 = &min_slot_table_size, |
181 | .extra2 = &max_slot_table_size | 188 | .extra2 = &max_slot_table_size |
182 | }, | 189 | }, |
190 | { | ||
191 | .ctl_name = CTL_MIN_RESVPORT, | ||
192 | .procname = "min_resvport", | ||
193 | .data = &xprt_min_resvport, | ||
194 | .maxlen = sizeof(unsigned int), | ||
195 | .mode = 0644, | ||
196 | .proc_handler = &proc_dointvec_minmax, | ||
197 | .strategy = &sysctl_intvec, | ||
198 | .extra1 = &xprt_min_resvport_limit, | ||
199 | .extra2 = &xprt_max_resvport_limit | ||
200 | }, | ||
201 | { | ||
202 | .ctl_name = CTL_MAX_RESVPORT, | ||
203 | .procname = "max_resvport", | ||
204 | .data = &xprt_max_resvport, | ||
205 | .maxlen = sizeof(unsigned int), | ||
206 | .mode = 0644, | ||
207 | .proc_handler = &proc_dointvec_minmax, | ||
208 | .strategy = &sysctl_intvec, | ||
209 | .extra1 = &xprt_min_resvport_limit, | ||
210 | .extra2 = &xprt_max_resvport_limit | ||
211 | }, | ||
183 | { .ctl_name = 0 } | 212 | { .ctl_name = 0 } |
184 | }; | 213 | }; |
185 | 214 | ||
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 26402c063f00..62c2e7caa345 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -36,11 +36,6 @@ | |||
36 | #include <net/tcp.h> | 36 | #include <net/tcp.h> |
37 | 37 | ||
38 | /* | 38 | /* |
39 | * Maximum port number to use when requesting a reserved port. | ||
40 | */ | ||
41 | #define XS_MAX_RESVPORT (800U) | ||
42 | |||
43 | /* | ||
44 | * How many times to try sending a request on a socket before waiting | 39 | * How many times to try sending a request on a socket before waiting |
45 | * for the socket buffer to clear. | 40 | * for the socket buffer to clear. |
46 | */ | 41 | */ |
@@ -873,10 +868,9 @@ static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock) | |||
873 | struct sockaddr_in myaddr = { | 868 | struct sockaddr_in myaddr = { |
874 | .sin_family = AF_INET, | 869 | .sin_family = AF_INET, |
875 | }; | 870 | }; |
876 | int err, port; | 871 | int err; |
872 | unsigned short port = xprt->port; | ||
877 | 873 | ||
878 | /* Were we already bound to a given port? Try to reuse it */ | ||
879 | port = xprt->port; | ||
880 | do { | 874 | do { |
881 | myaddr.sin_port = htons(port); | 875 | myaddr.sin_port = htons(port); |
882 | err = sock->ops->bind(sock, (struct sockaddr *) &myaddr, | 876 | err = sock->ops->bind(sock, (struct sockaddr *) &myaddr, |
@@ -887,8 +881,10 @@ static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock) | |||
887 | port); | 881 | port); |
888 | return 0; | 882 | return 0; |
889 | } | 883 | } |
890 | if (--port == 0) | 884 | if (port <= xprt_min_resvport) |
891 | port = XS_MAX_RESVPORT; | 885 | port = xprt_max_resvport; |
886 | else | ||
887 | port--; | ||
892 | } while (err == -EADDRINUSE && port != xprt->port); | 888 | } while (err == -EADDRINUSE && port != xprt->port); |
893 | 889 | ||
894 | dprintk("RPC: can't bind to reserved port (%d).\n", -err); | 890 | dprintk("RPC: can't bind to reserved port (%d).\n", -err); |
@@ -1075,9 +1071,6 @@ static struct rpc_xprt_ops xs_tcp_ops = { | |||
1075 | .destroy = xs_destroy, | 1071 | .destroy = xs_destroy, |
1076 | }; | 1072 | }; |
1077 | 1073 | ||
1078 | extern unsigned int xprt_udp_slot_table_entries; | ||
1079 | extern unsigned int xprt_tcp_slot_table_entries; | ||
1080 | |||
1081 | /** | 1074 | /** |
1082 | * xs_setup_udp - Set up transport to use a UDP socket | 1075 | * xs_setup_udp - Set up transport to use a UDP socket |
1083 | * @xprt: transport to set up | 1076 | * @xprt: transport to set up |
@@ -1098,7 +1091,7 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) | |||
1098 | memset(xprt->slot, 0, slot_table_size); | 1091 | memset(xprt->slot, 0, slot_table_size); |
1099 | 1092 | ||
1100 | xprt->prot = IPPROTO_UDP; | 1093 | xprt->prot = IPPROTO_UDP; |
1101 | xprt->port = XS_MAX_RESVPORT; | 1094 | xprt->port = xprt_max_resvport; |
1102 | xprt->tsh_size = 0; | 1095 | xprt->tsh_size = 0; |
1103 | xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0; | 1096 | xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0; |
1104 | /* XXX: header size can vary due to auth type, IPv6, etc. */ | 1097 | /* XXX: header size can vary due to auth type, IPv6, etc. */ |
@@ -1136,7 +1129,7 @@ int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to) | |||
1136 | memset(xprt->slot, 0, slot_table_size); | 1129 | memset(xprt->slot, 0, slot_table_size); |
1137 | 1130 | ||
1138 | xprt->prot = IPPROTO_TCP; | 1131 | xprt->prot = IPPROTO_TCP; |
1139 | xprt->port = XS_MAX_RESVPORT; | 1132 | xprt->port = xprt_max_resvport; |
1140 | xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); | 1133 | xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); |
1141 | xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0; | 1134 | xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0; |
1142 | xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; | 1135 | xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; |