diff options
Diffstat (limited to 'net/sctp/associola.c')
-rw-r--r-- | net/sctp/associola.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 7eed77a39d0d..df5abbff63e2 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -63,6 +63,12 @@ | |||
63 | static void sctp_assoc_bh_rcv(struct work_struct *work); | 63 | static void sctp_assoc_bh_rcv(struct work_struct *work); |
64 | static void sctp_assoc_free_asconf_acks(struct sctp_association *asoc); | 64 | static void sctp_assoc_free_asconf_acks(struct sctp_association *asoc); |
65 | 65 | ||
66 | /* Keep track of the new idr low so that we don't re-use association id | ||
67 | * numbers too fast. It is protected by they idr spin lock is in the | ||
68 | * range of 1 - INT_MAX. | ||
69 | */ | ||
70 | static u32 idr_low = 1; | ||
71 | |||
66 | 72 | ||
67 | /* 1st Level Abstractions. */ | 73 | /* 1st Level Abstractions. */ |
68 | 74 | ||
@@ -167,7 +173,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
167 | asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0; | 173 | asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0; |
168 | asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay; | 174 | asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay; |
169 | asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = | 175 | asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = |
170 | sp->autoclose * HZ; | 176 | (unsigned long)sp->autoclose * HZ; |
171 | 177 | ||
172 | /* Initilizes the timers */ | 178 | /* Initilizes the timers */ |
173 | for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i) | 179 | for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i) |
@@ -512,7 +518,13 @@ void sctp_assoc_set_primary(struct sctp_association *asoc, | |||
512 | * to this destination address earlier. The sender MUST set | 518 | * to this destination address earlier. The sender MUST set |
513 | * CYCLING_CHANGEOVER to indicate that this switch is a | 519 | * CYCLING_CHANGEOVER to indicate that this switch is a |
514 | * double switch to the same destination address. | 520 | * double switch to the same destination address. |
521 | * | ||
522 | * Really, only bother is we have data queued or outstanding on | ||
523 | * the association. | ||
515 | */ | 524 | */ |
525 | if (!asoc->outqueue.outstanding_bytes && !asoc->outqueue.out_qlen) | ||
526 | return; | ||
527 | |||
516 | if (transport->cacc.changeover_active) | 528 | if (transport->cacc.changeover_active) |
517 | transport->cacc.cycling_changeover = changeover; | 529 | transport->cacc.cycling_changeover = changeover; |
518 | 530 | ||
@@ -732,6 +744,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc, | |||
732 | 744 | ||
733 | peer->partial_bytes_acked = 0; | 745 | peer->partial_bytes_acked = 0; |
734 | peer->flight_size = 0; | 746 | peer->flight_size = 0; |
747 | peer->burst_limited = 0; | ||
735 | 748 | ||
736 | /* Set the transport's RTO.initial value */ | 749 | /* Set the transport's RTO.initial value */ |
737 | peer->rto = asoc->rto_initial; | 750 | peer->rto = asoc->rto_initial; |
@@ -1377,8 +1390,9 @@ static inline int sctp_peer_needs_update(struct sctp_association *asoc) | |||
1377 | case SCTP_STATE_SHUTDOWN_RECEIVED: | 1390 | case SCTP_STATE_SHUTDOWN_RECEIVED: |
1378 | case SCTP_STATE_SHUTDOWN_SENT: | 1391 | case SCTP_STATE_SHUTDOWN_SENT: |
1379 | if ((asoc->rwnd > asoc->a_rwnd) && | 1392 | if ((asoc->rwnd > asoc->a_rwnd) && |
1380 | ((asoc->rwnd - asoc->a_rwnd) >= | 1393 | ((asoc->rwnd - asoc->a_rwnd) >= max_t(__u32, |
1381 | min_t(__u32, (asoc->base.sk->sk_rcvbuf >> 1), asoc->pathmtu))) | 1394 | (asoc->base.sk->sk_rcvbuf >> sctp_rwnd_upd_shift), |
1395 | asoc->pathmtu))) | ||
1382 | return 1; | 1396 | return 1; |
1383 | break; | 1397 | break; |
1384 | default: | 1398 | default: |
@@ -1545,7 +1559,12 @@ retry: | |||
1545 | 1559 | ||
1546 | spin_lock_bh(&sctp_assocs_id_lock); | 1560 | spin_lock_bh(&sctp_assocs_id_lock); |
1547 | error = idr_get_new_above(&sctp_assocs_id, (void *)asoc, | 1561 | error = idr_get_new_above(&sctp_assocs_id, (void *)asoc, |
1548 | 1, &assoc_id); | 1562 | idr_low, &assoc_id); |
1563 | if (!error) { | ||
1564 | idr_low = assoc_id + 1; | ||
1565 | if (idr_low == INT_MAX) | ||
1566 | idr_low = 1; | ||
1567 | } | ||
1549 | spin_unlock_bh(&sctp_assocs_id_lock); | 1568 | spin_unlock_bh(&sctp_assocs_id_lock); |
1550 | if (error == -EAGAIN) | 1569 | if (error == -EAGAIN) |
1551 | goto retry; | 1570 | goto retry; |