From: Olaf Kirch xprt_bindresvport would grab ports in the range 1-800, which can conflict with all sorts of network services. What we really want to do is select from a range N - 1023. The patch below changes xprt_bindresvport to select ports from 650-1023 by default (631 is cups, which we better avoid). It also adds syscontrols to allow the admin to use different port range. Signed-off-by: Olaf Kirch Signed-off-by: Andrew Morton --- include/linux/sunrpc/debug.h | 2 ++ include/linux/sunrpc/xprt.h | 3 +++ net/sunrpc/sysctl.c | 28 ++++++++++++++++++++++++++++ net/sunrpc/xprt.c | 9 +++++---- 4 files changed, 38 insertions(+), 4 deletions(-) diff -puN include/linux/sunrpc/debug.h~nfs-fix-xprt_bindresvport include/linux/sunrpc/debug.h --- 25/include/linux/sunrpc/debug.h~nfs-fix-xprt_bindresvport Mon Jul 11 16:01:21 2005 +++ 25-akpm/include/linux/sunrpc/debug.h Mon Jul 11 16:01:21 2005 @@ -94,6 +94,8 @@ enum { CTL_NLMDEBUG, CTL_SLOTTABLE_UDP, CTL_SLOTTABLE_TCP, + CTL_MIN_RESVPORT, + CTL_MAX_RESVPORT, }; #endif /* _LINUX_SUNRPC_DEBUG_H_ */ diff -puN include/linux/sunrpc/xprt.h~nfs-fix-xprt_bindresvport include/linux/sunrpc/xprt.h --- 25/include/linux/sunrpc/xprt.h~nfs-fix-xprt_bindresvport Mon Jul 11 16:01:21 2005 +++ 25-akpm/include/linux/sunrpc/xprt.h Mon Jul 11 16:01:21 2005 @@ -227,6 +227,9 @@ void xprt_sock_setbufsize(struct rpc_x (test_and_clear_bit(XPRT_CONNECT, &(xp)->sockstate)) #define xprt_clear_connected(xp) (clear_bit(XPRT_CONNECT, &(xp)->sockstate)) +extern unsigned int xprt_min_resvport; +extern unsigned int xprt_max_resvport; + #endif /* __KERNEL__*/ #endif /* _LINUX_SUNRPC_XPRT_H */ diff -puN net/sunrpc/sysctl.c~nfs-fix-xprt_bindresvport net/sunrpc/sysctl.c --- 25/net/sunrpc/sysctl.c~nfs-fix-xprt_bindresvport Mon Jul 11 16:01:21 2005 +++ 25-akpm/net/sunrpc/sysctl.c Mon Jul 11 16:01:21 2005 @@ -29,6 +29,10 @@ unsigned int nfs_debug; unsigned int nfsd_debug; unsigned int nlm_debug; +unsigned int xprt_min_resvport = 650; +unsigned int xprt_max_resvport = 1023; + + #ifdef RPC_DEBUG static struct ctl_table_header *sunrpc_table_header; @@ -121,6 +125,8 @@ done: static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE; static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE; +static unsigned int xprt_min_resvport_limit = 1; +static unsigned int xprt_max_resvport_limit = 65535; static ctl_table debug_table[] = { { @@ -156,6 +162,28 @@ static ctl_table debug_table[] = { .proc_handler = &proc_dodebug }, { + .ctl_name = CTL_MIN_RESVPORT, + .procname = "min_resvport", + .data = &xprt_min_resvport, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &xprt_min_resvport_limit, + .extra2 = &xprt_max_resvport_limit + }, + { + .ctl_name = CTL_MAX_RESVPORT, + .procname = "max_resvport", + .data = &xprt_max_resvport, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &xprt_min_resvport_limit, + .extra2 = &xprt_max_resvport_limit + }, + { .ctl_name = CTL_SLOTTABLE_UDP, .procname = "udp_slot_table_entries", .data = &xprt_udp_slot_table_entries, diff -puN net/sunrpc/xprt.c~nfs-fix-xprt_bindresvport net/sunrpc/xprt.c --- 25/net/sunrpc/xprt.c~nfs-fix-xprt_bindresvport Mon Jul 11 16:01:21 2005 +++ 25-akpm/net/sunrpc/xprt.c Mon Jul 11 16:01:21 2005 @@ -75,7 +75,6 @@ #define XPRT_MAX_BACKOFF (8) #define XPRT_IDLE_TIMEOUT (5*60*HZ) -#define XPRT_MAX_RESVPORT (800) /* * Local functions @@ -1515,7 +1514,7 @@ xprt_setup(int proto, struct sockaddr_in xprt->timer.function = xprt_init_autodisconnect; xprt->timer.data = (unsigned long) xprt; xprt->last_used = jiffies; - xprt->port = XPRT_MAX_RESVPORT; + xprt->port = xprt_max_resvport; /* Set timeout parameters */ if (to) { @@ -1563,8 +1562,10 @@ static inline int xprt_bindresvport(stru xprt->port = port; return 0; } - if (--port == 0) - port = XPRT_MAX_RESVPORT; + if (port < xprt_min_resvport) + port = xprt_max_resvport; + else + port--; } while (err == -EADDRINUSE && port != xprt->port); printk("RPC: Can't bind to reserved port (%d).\n", -err); _