diff options
Diffstat (limited to 'net/ipv4/inet_connection_sock.c')
-rw-r--r-- | net/ipv4/inet_connection_sock.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index fbe7714f21d0..3cef12835c4b 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
@@ -33,6 +33,19 @@ EXPORT_SYMBOL(inet_csk_timer_bug_msg); | |||
33 | * This array holds the first and last local port number. | 33 | * This array holds the first and last local port number. |
34 | */ | 34 | */ |
35 | int sysctl_local_port_range[2] = { 32768, 61000 }; | 35 | int sysctl_local_port_range[2] = { 32768, 61000 }; |
36 | DEFINE_SEQLOCK(sysctl_port_range_lock); | ||
37 | |||
38 | void inet_get_local_port_range(int *low, int *high) | ||
39 | { | ||
40 | unsigned seq; | ||
41 | do { | ||
42 | seq = read_seqbegin(&sysctl_port_range_lock); | ||
43 | |||
44 | *low = sysctl_local_port_range[0]; | ||
45 | *high = sysctl_local_port_range[1]; | ||
46 | } while (read_seqretry(&sysctl_port_range_lock, seq)); | ||
47 | } | ||
48 | EXPORT_SYMBOL(inet_get_local_port_range); | ||
36 | 49 | ||
37 | int inet_csk_bind_conflict(const struct sock *sk, | 50 | int inet_csk_bind_conflict(const struct sock *sk, |
38 | const struct inet_bind_bucket *tb) | 51 | const struct inet_bind_bucket *tb) |
@@ -77,10 +90,11 @@ int inet_csk_get_port(struct inet_hashinfo *hashinfo, | |||
77 | 90 | ||
78 | local_bh_disable(); | 91 | local_bh_disable(); |
79 | if (!snum) { | 92 | if (!snum) { |
80 | int low = sysctl_local_port_range[0]; | 93 | int remaining, rover, low, high; |
81 | int high = sysctl_local_port_range[1]; | 94 | |
82 | int remaining = (high - low) + 1; | 95 | inet_get_local_port_range(&low, &high); |
83 | int rover = net_random() % (high - low) + low; | 96 | remaining = high - low; |
97 | rover = net_random() % remaining + low; | ||
84 | 98 | ||
85 | do { | 99 | do { |
86 | head = &hashinfo->bhash[inet_bhashfn(rover, hashinfo->bhash_size)]; | 100 | head = &hashinfo->bhash[inet_bhashfn(rover, hashinfo->bhash_size)]; |