[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>
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 26402c0..62c2e7c 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -36,11 +36,6 @@
#include <net/tcp.h>
/*
- * Maximum port number to use when requesting a reserved port.
- */
-#define XS_MAX_RESVPORT (800U)
-
-/*
* How many times to try sending a request on a socket before waiting
* for the socket buffer to clear.
*/
@@ -873,10 +868,9 @@
struct sockaddr_in myaddr = {
.sin_family = AF_INET,
};
- int err, port;
+ int err;
+ unsigned short port = xprt->port;
- /* Were we already bound to a given port? Try to reuse it */
- port = xprt->port;
do {
myaddr.sin_port = htons(port);
err = sock->ops->bind(sock, (struct sockaddr *) &myaddr,
@@ -887,8 +881,10 @@
port);
return 0;
}
- if (--port == 0)
- port = XS_MAX_RESVPORT;
+ if (port <= xprt_min_resvport)
+ port = xprt_max_resvport;
+ else
+ port--;
} while (err == -EADDRINUSE && port != xprt->port);
dprintk("RPC: can't bind to reserved port (%d).\n", -err);
@@ -1075,9 +1071,6 @@
.destroy = xs_destroy,
};
-extern unsigned int xprt_udp_slot_table_entries;
-extern unsigned int xprt_tcp_slot_table_entries;
-
/**
* xs_setup_udp - Set up transport to use a UDP socket
* @xprt: transport to set up
@@ -1098,7 +1091,7 @@
memset(xprt->slot, 0, slot_table_size);
xprt->prot = IPPROTO_UDP;
- xprt->port = XS_MAX_RESVPORT;
+ xprt->port = xprt_max_resvport;
xprt->tsh_size = 0;
xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0;
/* XXX: header size can vary due to auth type, IPv6, etc. */
@@ -1136,7 +1129,7 @@
memset(xprt->slot, 0, slot_table_size);
xprt->prot = IPPROTO_TCP;
- xprt->port = XS_MAX_RESVPORT;
+ xprt->port = xprt_max_resvport;
xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32);
xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0;
xprt->max_payload = RPC_MAX_FRAGMENT_SIZE;