Merge branch 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[safe/jmp/linux-2.6] / net / sctp / associola.c
index 880dae2..99c93ee 100644 (file)
 static void sctp_assoc_bh_rcv(struct work_struct *work);
 static void sctp_assoc_free_asconf_acks(struct sctp_association *asoc);
 
+/* Keep track of the new idr low so that we don't re-use association id
+ * numbers too fast.  It is protected by they idr spin lock is in the
+ * range of 1 - INT_MAX.
+ */
+static u32 idr_low = 1;
+
 
 /* 1st Level Abstractions. */
 
@@ -167,7 +173,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
        asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0;
        asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay;
        asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] =
-               sp->autoclose * HZ;
+               (unsigned long)sp->autoclose * HZ;
 
        /* Initilizes the timers */
        for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i)
@@ -1188,8 +1194,10 @@ void sctp_assoc_update(struct sctp_association *asoc,
        /* Remove any peer addresses not present in the new association. */
        list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
                trans = list_entry(pos, struct sctp_transport, transports);
-               if (!sctp_assoc_lookup_paddr(new, &trans->ipaddr))
-                       sctp_assoc_del_peer(asoc, &trans->ipaddr);
+               if (!sctp_assoc_lookup_paddr(new, &trans->ipaddr)) {
+                       sctp_assoc_rm_peer(asoc, trans);
+                       continue;
+               }
 
                if (asoc->state >= SCTP_STATE_ESTABLISHED)
                        sctp_transport_reset(trans);
@@ -1553,7 +1561,12 @@ retry:
 
        spin_lock_bh(&sctp_assocs_id_lock);
        error = idr_get_new_above(&sctp_assocs_id, (void *)asoc,
-                                   1, &assoc_id);
+                                   idr_low, &assoc_id);
+       if (!error) {
+               idr_low = assoc_id + 1;
+               if (idr_low == INT_MAX)
+                       idr_low = 1;
+       }
        spin_unlock_bh(&sctp_assocs_id_lock);
        if (error == -EAGAIN)
                goto retry;