aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-10-10 20:30:18 -0400
committerDavid S. Miller <davem@davemloft.net>2007-10-10 20:30:18 -0400
commit06393009000779b00a558fd2f280882cc7dc2008 (patch)
tree0cd2e1f4cedd58c3c8056018bb6148dddd21d6ab
parent3c0cfc135829b98f7a4894938652f9ef78e24237 (diff)
[SCTP]: port randomization
Add port randomization rather than a simple fixed rover for use with SCTP. This makes it act similar to TCP, UDP, DCCP when allocating ports. No longer need port_alloc_lock as well (suggestion by Brian Haley). Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/sctp/structs.h2
-rw-r--r--net/sctp/protocol.c3
-rw-r--r--net/sctp/socket.c21
3 files changed, 5 insertions, 21 deletions
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 448f713a0205..ef892e00c833 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -197,8 +197,6 @@ extern struct sctp_globals {
197 197
198 /* This is the sctp port control hash. */ 198 /* This is the sctp port control hash. */
199 int port_hashsize; 199 int port_hashsize;
200 int port_rover;
201 spinlock_t port_alloc_lock; /* Protects port_rover. */
202 struct sctp_bind_hashbucket *port_hashtable; 200 struct sctp_bind_hashbucket *port_hashtable;
203 201
204 /* This is the global local address list. 202 /* This is the global local address list.
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 4e6b59e8b695..81b26c5ffd4b 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -1172,9 +1172,6 @@ SCTP_STATIC __init int sctp_init(void)
1172 sctp_port_hashtable[i].chain = NULL; 1172 sctp_port_hashtable[i].chain = NULL;
1173 } 1173 }
1174 1174
1175 spin_lock_init(&sctp_port_alloc_lock);
1176 sctp_port_rover = sysctl_local_port_range[0] - 1;
1177
1178 printk(KERN_INFO "SCTP: Hash tables configured " 1175 printk(KERN_INFO "SCTP: Hash tables configured "
1179 "(established %d bind %d)\n", 1176 "(established %d bind %d)\n",
1180 sctp_assoc_hashsize, sctp_port_hashsize); 1177 sctp_assoc_hashsize, sctp_port_hashsize);
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index f3e1a9c811ad..7cd58ef84eda 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -5314,22 +5314,13 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
5314 sctp_local_bh_disable(); 5314 sctp_local_bh_disable();
5315 5315
5316 if (snum == 0) { 5316 if (snum == 0) {
5317 /* Search for an available port. 5317 /* Search for an available port. */
5318 * 5318 unsigned int low = sysctl_local_port_range[0];
5319 * 'sctp_port_rover' was the last port assigned, so 5319 unsigned int high = sysctl_local_port_range[1];
5320 * we start to search from 'sctp_port_rover + 5320 unsigned int remaining = (high - low) + 1;
5321 * 1'. What we do is first check if port 'rover' is 5321 unsigned int rover = net_random() % remaining + low;
5322 * already in the hash table; if not, we use that; if
5323 * it is, we try next.
5324 */
5325 int low = sysctl_local_port_range[0];
5326 int high = sysctl_local_port_range[1];
5327 int remaining = (high - low) + 1;
5328 int rover;
5329 int index; 5322 int index;
5330 5323
5331 sctp_spin_lock(&sctp_port_alloc_lock);
5332 rover = sctp_port_rover;
5333 do { 5324 do {
5334 rover++; 5325 rover++;
5335 if ((rover < low) || (rover > high)) 5326 if ((rover < low) || (rover > high))
@@ -5344,8 +5335,6 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
5344 next: 5335 next:
5345 sctp_spin_unlock(&head->lock); 5336 sctp_spin_unlock(&head->lock);
5346 } while (--remaining > 0); 5337 } while (--remaining > 0);
5347 sctp_port_rover = rover;
5348 sctp_spin_unlock(&sctp_port_alloc_lock);
5349 5338
5350 /* Exhausted local port range during search? */ 5339 /* Exhausted local port range during search? */
5351 ret = 1; 5340 ret = 1;