]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/sctp/sm_sideeffect.c
net: Print the module name as part of the watchdog message
[linux-2.6-omap-h63xx.git] / net / sctp / sm_sideeffect.c
index 28eb38eb60833a7e339f2eed56ef47c8545f1985..9732c797e8edf06d73e69088d044b4af9ac3e236 100644 (file)
@@ -190,20 +190,28 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force,
         * unacknowledged DATA chunk. ...
         */
        if (!asoc->peer.sack_needed) {
-               /* We will need a SACK for the next packet.  */
-               asoc->peer.sack_needed = 1;
+               asoc->peer.sack_cnt++;
 
                /* Set the SACK delay timeout based on the
                 * SACK delay for the last transport
                 * data was received from, or the default
                 * for the association.
                 */
-               if (trans)
+               if (trans) {
+                       /* We will need a SACK for the next packet.  */
+                       if (asoc->peer.sack_cnt >= trans->sackfreq - 1)
+                               asoc->peer.sack_needed = 1;
+
                        asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] =
                                trans->sackdelay;
-               else
+               } else {
+                       /* We will need a SACK for the next packet.  */
+                       if (asoc->peer.sack_cnt >= asoc->sackfreq - 1)
+                               asoc->peer.sack_needed = 1;
+
                        asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] =
                                asoc->sackdelay;
+               }
 
                /* Restart the SACK timer. */
                sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
@@ -216,6 +224,7 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force,
                        goto nomem;
 
                asoc->peer.sack_needed = 0;
+               asoc->peer.sack_cnt = 0;
 
                sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(sack));
 
@@ -243,7 +252,7 @@ void sctp_generate_t3_rtx_event(unsigned long peer)
 
        sctp_bh_lock_sock(asoc->base.sk);
        if (sock_owned_by_user(asoc->base.sk)) {
-               SCTP_DEBUG_PRINTK("%s:Sock is busy.\n", __FUNCTION__);
+               SCTP_DEBUG_PRINTK("%s:Sock is busy.\n", __func__);
 
                /* Try again later.  */
                if (!mod_timer(&transport->T3_rtx_timer, jiffies + (HZ/20)))
@@ -283,7 +292,7 @@ static void sctp_generate_timeout_event(struct sctp_association *asoc,
        sctp_bh_lock_sock(asoc->base.sk);
        if (sock_owned_by_user(asoc->base.sk)) {
                SCTP_DEBUG_PRINTK("%s:Sock is busy: timer %d\n",
-                                 __FUNCTION__,
+                                 __func__,
                                  timeout_type);
 
                /* Try again later.  */
@@ -361,7 +370,7 @@ void sctp_generate_heartbeat_event(unsigned long data)
 
        sctp_bh_lock_sock(asoc->base.sk);
        if (sock_owned_by_user(asoc->base.sk)) {
-               SCTP_DEBUG_PRINTK("%s:Sock is busy.\n", __FUNCTION__);
+               SCTP_DEBUG_PRINTK("%s:Sock is busy.\n", __func__);
 
                /* Try again later.  */
                if (!mod_timer(&transport->hb_timer, jiffies + (HZ/20)))
@@ -545,14 +554,12 @@ static void sctp_cmd_hb_timers_start(sctp_cmd_seq_t *cmds,
                                     struct sctp_association *asoc)
 {
        struct sctp_transport *t;
-       struct list_head *pos;
 
        /* Start a heartbeat timer for each transport on the association.
         * hold a reference on the transport to make sure none of
         * the needed data structures go away.
         */
-       list_for_each(pos, &asoc->peer.transport_addr_list) {
-               t = list_entry(pos, struct sctp_transport, transports);
+       list_for_each_entry(t, &asoc->peer.transport_addr_list, transports) {
 
                if (!mod_timer(&t->hb_timer, sctp_transport_timeout(t)))
                        sctp_transport_hold(t);
@@ -563,12 +570,11 @@ static void sctp_cmd_hb_timers_stop(sctp_cmd_seq_t *cmds,
                                    struct sctp_association *asoc)
 {
        struct sctp_transport *t;
-       struct list_head *pos;
 
        /* Stop all heartbeat timers. */
 
-       list_for_each(pos, &asoc->peer.transport_addr_list) {
-               t = list_entry(pos, struct sctp_transport, transports);
+       list_for_each_entry(t, &asoc->peer.transport_addr_list,
+                       transports) {
                if (del_timer(&t->hb_timer))
                        sctp_transport_put(t);
        }
@@ -579,10 +585,9 @@ static void sctp_cmd_t3_rtx_timers_stop(sctp_cmd_seq_t *cmds,
                                        struct sctp_association *asoc)
 {
        struct sctp_transport *t;
-       struct list_head *pos;
 
-       list_for_each(pos, &asoc->peer.transport_addr_list) {
-               t = list_entry(pos, struct sctp_transport, transports);
+       list_for_each_entry(t, &asoc->peer.transport_addr_list,
+                       transports) {
                if (timer_pending(&t->T3_rtx_timer) &&
                    del_timer(&t->T3_rtx_timer)) {
                        sctp_transport_put(t);
@@ -593,7 +598,6 @@ static void sctp_cmd_t3_rtx_timers_stop(sctp_cmd_seq_t *cmds,
 
 /* Helper function to update the heartbeat timer. */
 static void sctp_cmd_hb_timer_update(sctp_cmd_seq_t *cmds,
-                                    struct sctp_association *asoc,
                                     struct sctp_transport *t)
 {
        /* Update the heartbeat timer.  */
@@ -660,7 +664,7 @@ static int sctp_cmd_process_sack(sctp_cmd_seq_t *cmds,
                                 struct sctp_association *asoc,
                                 struct sctp_sackhdr *sackh)
 {
-       int err;
+       int err = 0;
 
        if (sctp_outq_sack(&asoc->outqueue, sackh)) {
                /* There are no more TSNs awaiting SACK.  */
@@ -668,11 +672,6 @@ static int sctp_cmd_process_sack(sctp_cmd_seq_t *cmds,
                                 SCTP_ST_OTHER(SCTP_EVENT_NO_PENDING_TSN),
                                 asoc->state, asoc->ep, asoc, NULL,
                                 GFP_ATOMIC);
-       } else {
-               /* Windows may have opened, so we need
-                * to check if we have DATA to transmit
-                */
-               err = sctp_outq_flush(&asoc->outqueue, 0);
        }
 
        return err;
@@ -1065,7 +1064,6 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
        struct sctp_chunk *new_obj;
        struct sctp_chunk *chunk = NULL;
        struct sctp_packet *packet;
-       struct list_head *pos;
        struct timer_list *timer;
        unsigned long timeout;
        struct sctp_transport *t;
@@ -1397,9 +1395,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                        /* If we've sent any data bundled with
                         * COOKIE-ECHO we need to resend.
                         */
-                       list_for_each(pos, &asoc->peer.transport_addr_list) {
-                               t = list_entry(pos, struct sctp_transport,
-                                              transports);
+                       list_for_each_entry(t, &asoc->peer.transport_addr_list,
+                                       transports) {
                                sctp_retransmit_mark(&asoc->outqueue, t,
                                            SCTP_RTXR_T1_RTX);
                        }
@@ -1457,7 +1454,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
 
                case SCTP_CMD_HB_TIMER_UPDATE:
                        t = cmd->obj.transport;
-                       sctp_cmd_hb_timer_update(commands, asoc, t);
+                       sctp_cmd_hb_timer_update(commands, t);
                        break;
 
                case SCTP_CMD_HB_TIMERS_STOP:
@@ -1479,8 +1476,15 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                        break;
 
                case SCTP_CMD_DISCARD_PACKET:
-                       /* We need to discard the whole packet.  */
+                       /* We need to discard the whole packet.
+                        * Uncork the queue since there might be
+                        * responses pending
+                        */
                        chunk->pdiscard = 1;
+                       if (asoc) {
+                               sctp_outq_uncork(&asoc->outqueue);
+                               local_cork = 0;
+                       }
                        break;
 
                case SCTP_CMD_RTO_PENDING:
@@ -1536,6 +1540,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                        error = sctp_auth_asoc_init_active_key(asoc,
                                                GFP_ATOMIC);
                        break;
+               case SCTP_CMD_UPDATE_INITTAG:
+                       asoc->peer.i.init_tag = cmd->obj.u32;
+                       break;
 
                default:
                        printk(KERN_WARNING "Impossible command: %u, %p\n",
@@ -1548,8 +1555,15 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
        }
 
 out:
-       if (local_cork)
-               sctp_outq_uncork(&asoc->outqueue);
+       /* If this is in response to a received chunk, wait until
+        * we are done with the packet to open the queue so that we don't
+        * send multiple packets in response to a single request.
+        */
+       if (asoc && SCTP_EVENT_T_CHUNK == event_type && chunk) {
+               if (chunk->end_of_packet || chunk->singleton)
+                       sctp_outq_uncork(&asoc->outqueue);
+       } else if (local_cork)
+                       sctp_outq_uncork(&asoc->outqueue);
        return error;
 nomem:
        error = -ENOMEM;