diff options
| -rw-r--r-- | net/sunrpc/xprtsock.c | 34 |
1 files changed, 18 insertions, 16 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 039444eb138f..9bb86cd3ee56 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
| @@ -129,7 +129,7 @@ static struct ctl_table xs_tunables_table[] = { | |||
| 129 | .mode = 0644, | 129 | .mode = 0644, |
| 130 | .proc_handler = proc_dointvec_minmax, | 130 | .proc_handler = proc_dointvec_minmax, |
| 131 | .extra1 = &xprt_min_resvport_limit, | 131 | .extra1 = &xprt_min_resvport_limit, |
| 132 | .extra2 = &xprt_max_resvport | 132 | .extra2 = &xprt_max_resvport_limit |
| 133 | }, | 133 | }, |
| 134 | { | 134 | { |
| 135 | .procname = "max_resvport", | 135 | .procname = "max_resvport", |
| @@ -137,7 +137,7 @@ static struct ctl_table xs_tunables_table[] = { | |||
| 137 | .maxlen = sizeof(unsigned int), | 137 | .maxlen = sizeof(unsigned int), |
| 138 | .mode = 0644, | 138 | .mode = 0644, |
| 139 | .proc_handler = proc_dointvec_minmax, | 139 | .proc_handler = proc_dointvec_minmax, |
| 140 | .extra1 = &xprt_min_resvport, | 140 | .extra1 = &xprt_min_resvport_limit, |
| 141 | .extra2 = &xprt_max_resvport_limit | 141 | .extra2 = &xprt_max_resvport_limit |
| 142 | }, | 142 | }, |
| 143 | { | 143 | { |
| @@ -1615,11 +1615,17 @@ static void xs_udp_timer(struct rpc_xprt *xprt, struct rpc_task *task) | |||
| 1615 | spin_unlock_bh(&xprt->transport_lock); | 1615 | spin_unlock_bh(&xprt->transport_lock); |
| 1616 | } | 1616 | } |
| 1617 | 1617 | ||
| 1618 | static unsigned short xs_get_random_port(void) | 1618 | static int xs_get_random_port(void) |
| 1619 | { | 1619 | { |
| 1620 | unsigned short range = xprt_max_resvport - xprt_min_resvport + 1; | 1620 | unsigned short min = xprt_min_resvport, max = xprt_max_resvport; |
| 1621 | unsigned short rand = (unsigned short) prandom_u32() % range; | 1621 | unsigned short range; |
| 1622 | return rand + xprt_min_resvport; | 1622 | unsigned short rand; |
| 1623 | |||
| 1624 | if (max < min) | ||
| 1625 | return -EADDRINUSE; | ||
| 1626 | range = max - min + 1; | ||
| 1627 | rand = (unsigned short) prandom_u32() % range; | ||
| 1628 | return rand + min; | ||
| 1623 | } | 1629 | } |
| 1624 | 1630 | ||
| 1625 | /** | 1631 | /** |
| @@ -1675,9 +1681,9 @@ static void xs_set_srcport(struct sock_xprt *transport, struct socket *sock) | |||
| 1675 | transport->srcport = xs_sock_getport(sock); | 1681 | transport->srcport = xs_sock_getport(sock); |
| 1676 | } | 1682 | } |
| 1677 | 1683 | ||
| 1678 | static unsigned short xs_get_srcport(struct sock_xprt *transport) | 1684 | static int xs_get_srcport(struct sock_xprt *transport) |
| 1679 | { | 1685 | { |
| 1680 | unsigned short port = transport->srcport; | 1686 | int port = transport->srcport; |
| 1681 | 1687 | ||
| 1682 | if (port == 0 && transport->xprt.resvport) | 1688 | if (port == 0 && transport->xprt.resvport) |
| 1683 | port = xs_get_random_port(); | 1689 | port = xs_get_random_port(); |
| @@ -1698,7 +1704,7 @@ static int xs_bind(struct sock_xprt *transport, struct socket *sock) | |||
| 1698 | { | 1704 | { |
| 1699 | struct sockaddr_storage myaddr; | 1705 | struct sockaddr_storage myaddr; |
| 1700 | int err, nloop = 0; | 1706 | int err, nloop = 0; |
| 1701 | unsigned short port = xs_get_srcport(transport); | 1707 | int port = xs_get_srcport(transport); |
| 1702 | unsigned short last; | 1708 | unsigned short last; |
| 1703 | 1709 | ||
| 1704 | /* | 1710 | /* |
| @@ -1716,8 +1722,8 @@ static int xs_bind(struct sock_xprt *transport, struct socket *sock) | |||
| 1716 | * transport->xprt.resvport == 1) xs_get_srcport above will | 1722 | * transport->xprt.resvport == 1) xs_get_srcport above will |
| 1717 | * ensure that port is non-zero and we will bind as needed. | 1723 | * ensure that port is non-zero and we will bind as needed. |
| 1718 | */ | 1724 | */ |
| 1719 | if (port == 0) | 1725 | if (port <= 0) |
| 1720 | return 0; | 1726 | return port; |
| 1721 | 1727 | ||
| 1722 | memcpy(&myaddr, &transport->srcaddr, transport->xprt.addrlen); | 1728 | memcpy(&myaddr, &transport->srcaddr, transport->xprt.addrlen); |
| 1723 | do { | 1729 | do { |
| @@ -3154,12 +3160,8 @@ static int param_set_uint_minmax(const char *val, | |||
| 3154 | 3160 | ||
| 3155 | static int param_set_portnr(const char *val, const struct kernel_param *kp) | 3161 | static int param_set_portnr(const char *val, const struct kernel_param *kp) |
| 3156 | { | 3162 | { |
| 3157 | if (kp->arg == &xprt_min_resvport) | ||
| 3158 | return param_set_uint_minmax(val, kp, | ||
| 3159 | RPC_MIN_RESVPORT, | ||
| 3160 | xprt_max_resvport); | ||
| 3161 | return param_set_uint_minmax(val, kp, | 3163 | return param_set_uint_minmax(val, kp, |
| 3162 | xprt_min_resvport, | 3164 | RPC_MIN_RESVPORT, |
| 3163 | RPC_MAX_RESVPORT); | 3165 | RPC_MAX_RESVPORT); |
| 3164 | } | 3166 | } |
| 3165 | 3167 | ||
