ide: use DIV_ROUND_UP
[safe/jmp/linux-2.6] / net / sctp / sm_sideeffect.c
index e4c43a3..23a9f1a 100644 (file)
@@ -1,21 +1,21 @@
-/* SCTP kernel reference Implementation
+/* SCTP kernel implementation
  * (C) Copyright IBM Corp. 2001, 2004
  * Copyright (c) 1999 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
  *
- * This file is part of the SCTP kernel reference Implementation
+ * This file is part of the SCTP kernel implementation
  *
  * These functions work with the state functions in sctp_sm_statefuns.c
  * to implement that state operations.  These functions implement the
  * steps which require modifying existing data structures.
  *
- * The SCTP reference implementation is free software;
+ * This SCTP implementation is free software;
  * you can redistribute it and/or modify it under the terms of
  * the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
  * any later version.
  *
- * The SCTP reference implementation is distributed in the hope that it
+ * This SCTP implementation is distributed in the hope that it
  * will be useful, but WITHOUT ANY WARRANTY; without even the implied
  *                 ************************
  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
@@ -61,7 +61,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                                struct sctp_endpoint *ep,
                                struct sctp_association *asoc,
                                void *event_arg,
-                               sctp_disposition_t status,
+                               sctp_disposition_t status,
                                sctp_cmd_seq_t *commands,
                                gfp_t gfp);
 static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
@@ -78,7 +78,7 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
  ********************************************************************/
 
 /* A helper function for delayed processing of INET ECN CE bit. */
-static void sctp_do_ecn_ce_work(struct sctp_association *asoc, 
+static void sctp_do_ecn_ce_work(struct sctp_association *asoc,
                                __u32 lowest_tsn)
 {
        /* Save the TSN away for comparison when we receive CWR */
@@ -160,7 +160,7 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force,
        struct sctp_transport *trans = asoc->peer.last_data_from;
        int error = 0;
 
-       if (force || 
+       if (force ||
            (!trans && (asoc->param_flags & SPP_SACKDELAY_DISABLE)) ||
            (trans && (trans->param_flags & SPP_SACKDELAY_DISABLE)))
                asoc->peer.sack_needed = 1;
@@ -178,7 +178,7 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force,
         * [This is actually not mentioned in Section 6, but we
         * implement it here anyway. --piggy]
         */
-        if (max_tsn_seen != ctsn)
+       if (max_tsn_seen != ctsn)
                asoc->peer.sack_needed = 1;
 
        /* From 6.2  Acknowledgement on Reception of DATA Chunks:
@@ -199,10 +199,10 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force,
                 * for the association.
                 */
                if (trans)
-                       asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = 
+                       asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] =
                                trans->sackdelay;
                else
-                       asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = 
+                       asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] =
                                asoc->sackdelay;
 
                /* Restart the SACK timer. */
@@ -217,7 +217,7 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force,
 
                asoc->peer.sack_needed = 0;
 
-               error = sctp_outq_tail(&asoc->outqueue, sack);
+               sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(sack));
 
                /* Stop the SACK timer.  */
                sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
@@ -243,7 +243,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 +283,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.  */
@@ -338,8 +338,8 @@ static void sctp_generate_t4_rto_event(unsigned long data)
 
 static void sctp_generate_t5_shutdown_guard_event(unsigned long data)
 {
-        struct sctp_association *asoc = (struct sctp_association *)data;
-        sctp_generate_timeout_event(asoc,
+       struct sctp_association *asoc = (struct sctp_association *)data;
+       sctp_generate_timeout_event(asoc,
                                    SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD);
 
 } /* sctp_generate_t5_shutdown_guard_event() */
@@ -361,7 +361,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)))
@@ -380,7 +380,7 @@ void sctp_generate_heartbeat_event(unsigned long data)
                           asoc->state, asoc->ep, asoc,
                           transport, GFP_ATOMIC);
 
-         if (error)
+        if (error)
                 asoc->base.sk->sk_err = -error;
 
 out_unlock:
@@ -442,7 +442,7 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
                                         " transport IP: port:%d failed.\n",
                                         asoc,
                                         (&transport->ipaddr),
-                                        transport->ipaddr.v4.sin_port);
+                                        ntohs(transport->ipaddr.v4.sin_port));
                sctp_assoc_control_transport(asoc, transport,
                                             SCTP_TRANSPORT_DOWN,
                                             SCTP_FAILED_THRESHOLD);
@@ -453,6 +453,7 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
         * maximum value discussed in rule C7 above (RTO.max) may be
         * used to provide an upper bound to this doubling operation.
         */
+       transport->last_rto = transport->rto;
        transport->rto = min((transport->rto * 2), transport->asoc->rto_max);
 }
 
@@ -464,7 +465,7 @@ static void sctp_cmd_init_failed(sctp_cmd_seq_t *commands,
        struct sctp_ulpevent *event;
 
        event = sctp_ulpevent_make_assoc_change(asoc,0, SCTP_CANT_STR_ASSOC,
-                                               (__u16)error, 0, 0,
+                                               (__u16)error, 0, 0, NULL,
                                                GFP_ATOMIC);
 
        if (event)
@@ -492,8 +493,13 @@ static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *commands,
        /* Cancel any partial delivery in progress. */
        sctp_ulpq_abort_pd(&asoc->ulpq, GFP_ATOMIC);
 
-       event = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_COMM_LOST,
-                                               (__u16)error, 0, 0,
+       if (event_type == SCTP_EVENT_T_CHUNK && subtype.chunk == SCTP_CID_ABORT)
+               event = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_COMM_LOST,
+                                               (__u16)error, 0, 0, chunk,
+                                               GFP_ATOMIC);
+       else
+               event = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_COMM_LOST,
+                                               (__u16)error, 0, 0, NULL,
                                                GFP_ATOMIC);
        if (event)
                sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
@@ -539,14 +545,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);
@@ -557,12 +561,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);
        }
@@ -570,13 +573,12 @@ static void sctp_cmd_hb_timers_stop(sctp_cmd_seq_t *cmds,
 
 /* Helper function to stop any pending T3-RTX timers */
 static void sctp_cmd_t3_rtx_timers_stop(sctp_cmd_seq_t *cmds,
-                                       struct sctp_association *asoc)
+                                       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);
@@ -587,7 +589,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.  */
@@ -621,7 +622,13 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds,
        /* The receiver of the HEARTBEAT ACK should also perform an
         * RTT measurement for that destination transport address
         * using the time value carried in the HEARTBEAT ACK chunk.
+        * If the transport's rto_pending variable has been cleared,
+        * it was most likely due to a retransmit.  However, we want
+        * to re-enable it to properly update the rto.
         */
+       if (t->rto_pending == 0)
+               t->rto_pending = 1;
+
        hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data;
        sctp_transport_update_rto(t, (jiffies - hbinfo->sent_at));
 
@@ -669,7 +676,7 @@ static int sctp_cmd_process_sack(sctp_cmd_seq_t *cmds,
 /* Helper function to set the timeout value for T2-SHUTDOWN timer and to set
  * the transport for a shutdown chunk.
  */
-static void sctp_cmd_setup_t2(sctp_cmd_seq_t *cmds, 
+static void sctp_cmd_setup_t2(sctp_cmd_seq_t *cmds,
                              struct sctp_association *asoc,
                              struct sctp_chunk *chunk)
 {
@@ -682,7 +689,7 @@ static void sctp_cmd_setup_t2(sctp_cmd_seq_t *cmds,
 }
 
 /* Helper function to change the state of an association. */
-static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds, 
+static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds,
                               struct sctp_association *asoc,
                               sctp_state_t state)
 {
@@ -721,7 +728,7 @@ static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds,
            sctp_state(asoc, SHUTDOWN_RECEIVED)) {
                /* Wake up any processes waiting in the asoc's wait queue in
                 * sctp_wait_for_connect() or sctp_wait_for_sndbuf().
-                */
+                */
                if (waitqueue_active(&asoc->wait))
                        wake_up_interruptible(&asoc->wait);
 
@@ -743,9 +750,9 @@ static void sctp_cmd_delete_tcb(sctp_cmd_seq_t *cmds,
        struct sock *sk = asoc->base.sk;
 
        /* If it is a non-temporary association belonging to a TCP-style
-        * listening socket that is not closed, do not free it so that accept() 
+        * listening socket that is not closed, do not free it so that accept()
         * can pick it up later.
-        */ 
+        */
        if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING) &&
            (!asoc->temp) && (sk->sk_shutdown != SHUTDOWN_MASK))
                return;
@@ -758,7 +765,7 @@ static void sctp_cmd_delete_tcb(sctp_cmd_seq_t *cmds,
  * ADDIP Section 4.1 ASCONF Chunk Procedures
  * A4) Start a T-4 RTO timer, using the RTO value of the selected
  * destination address (we use active path instead of primary path just
- * because primary path may be inactive. 
+ * because primary path may be inactive.
  */
 static void sctp_cmd_setup_t4(sctp_cmd_seq_t *cmds,
                                struct sctp_association *asoc,
@@ -771,7 +778,7 @@ static void sctp_cmd_setup_t4(sctp_cmd_seq_t *cmds,
        chunk->transport = t;
 }
 
-/* Process an incoming Operation Error Chunk. */ 
+/* Process an incoming Operation Error Chunk. */
 static void sctp_cmd_process_operr(sctp_cmd_seq_t *cmds,
                                   struct sctp_association *asoc,
                                   struct sctp_chunk *chunk)
@@ -810,7 +817,7 @@ static void sctp_cmd_process_operr(sctp_cmd_seq_t *cmds,
 }
 
 /* Process variable FWDTSN chunk information. */
-static void sctp_cmd_process_fwdtsn(struct sctp_ulpq *ulpq, 
+static void sctp_cmd_process_fwdtsn(struct sctp_ulpq *ulpq,
                                    struct sctp_chunk *chunk)
 {
        struct sctp_fwdtsn_skip *skip;
@@ -822,9 +829,9 @@ static void sctp_cmd_process_fwdtsn(struct sctp_ulpq *ulpq,
        return;
 }
 
-/* Helper function to remove the association non-primary peer 
+/* Helper function to remove the association non-primary peer
  * transports.
- */ 
+ */
 static void sctp_cmd_del_non_primary(struct sctp_association *asoc)
 {
        struct sctp_transport *t;
@@ -834,7 +841,7 @@ static void sctp_cmd_del_non_primary(struct sctp_association *asoc)
        list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
                t = list_entry(pos, struct sctp_transport, transports);
                if (!sctp_cmp_addr_exact(&t->ipaddr,
-                                        &asoc->peer.primary_addr)) {
+                                        &asoc->peer.primary_addr)) {
                        sctp_assoc_del_peer(asoc, &t->ipaddr);
                }
        }
@@ -851,6 +858,33 @@ static void sctp_cmd_set_sk_err(struct sctp_association *asoc, int error)
                sk->sk_err = error;
 }
 
+/* Helper function to generate an association change event */
+static void sctp_cmd_assoc_change(sctp_cmd_seq_t *commands,
+                                struct sctp_association *asoc,
+                                u8 state)
+{
+       struct sctp_ulpevent *ev;
+
+       ev = sctp_ulpevent_make_assoc_change(asoc, 0, state, 0,
+                                           asoc->c.sinit_num_ostreams,
+                                           asoc->c.sinit_max_instreams,
+                                           NULL, GFP_ATOMIC);
+       if (ev)
+               sctp_ulpq_tail_event(&asoc->ulpq, ev);
+}
+
+/* Helper function to generate an adaptation indication event */
+static void sctp_cmd_adaptation_ind(sctp_cmd_seq_t *commands,
+                                   struct sctp_association *asoc)
+{
+       struct sctp_ulpevent *ev;
+
+       ev = sctp_ulpevent_make_adaptation_indication(asoc, GFP_ATOMIC);
+
+       if (ev)
+               sctp_ulpq_tail_event(&asoc->ulpq, ev);
+}
+
 /* These three macros allow us to pull the debugging code out of the
  * main flow of sctp_do_sm() to keep attention focused on the real
  * functionality there.
@@ -909,7 +943,7 @@ int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
        DEBUG_POST;
 
        error = sctp_side_effects(event_type, subtype, state,
-                                 ep, asoc, event_arg, status, 
+                                 ep, asoc, event_arg, status,
                                  &commands, gfp);
        DEBUG_POST_SFX;
 
@@ -962,7 +996,7 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
                error = -ENOMEM;
                break;
 
-        case SCTP_DISPOSITION_DELETE_TCB:
+       case SCTP_DISPOSITION_DELETE_TCB:
                /* This should now be a command. */
                break;
 
@@ -975,8 +1009,9 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
                break;
 
        case SCTP_DISPOSITION_VIOLATION:
-               printk(KERN_ERR "sctp protocol violation state %d "
-                      "chunkid %d\n", state, subtype.chunk);
+               if (net_ratelimit())
+                       printk(KERN_ERR "sctp protocol violation state %d "
+                              "chunkid %d\n", state, subtype.chunk);
                break;
 
        case SCTP_DISPOSITION_NOT_IMPL:
@@ -998,7 +1033,7 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
                       status, state, event_type, subtype.chunk);
                BUG();
                break;
-       };
+       }
 
 bail:
        return error;
@@ -1015,7 +1050,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                                struct sctp_endpoint *ep,
                                struct sctp_association *asoc,
                                void *event_arg,
-                               sctp_disposition_t status,
+                               sctp_disposition_t status,
                                sctp_cmd_seq_t *commands,
                                gfp_t gfp)
 {
@@ -1025,7 +1060,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;
@@ -1051,7 +1085,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                case SCTP_CMD_NEW_ASOC:
                        /* Register a new association.  */
                        if (local_cork) {
-                               sctp_outq_uncork(&asoc->outqueue); 
+                               sctp_outq_uncork(&asoc->outqueue);
                                local_cork = 0;
                        }
                        asoc = cmd->obj.ptr;
@@ -1068,7 +1102,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                       sctp_outq_teardown(&asoc->outqueue);
                       break;
 
-               case SCTP_CMD_DELETE_TCB:                       
+               case SCTP_CMD_DELETE_TCB:
                        if (local_cork) {
                                sctp_outq_uncork(&asoc->outqueue);
                                local_cork = 0;
@@ -1092,13 +1126,16 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                        /* Move the Cumulattive TSN Ack ahead. */
                        sctp_tsnmap_skip(&asoc->peer.tsn_map, cmd->obj.u32);
 
+                       /* purge the fragmentation queue */
+                       sctp_ulpq_reasm_flushtsn(&asoc->ulpq, cmd->obj.u32);
+
                        /* Abort any in progress partial delivery. */
                        sctp_ulpq_abort_pd(&asoc->ulpq, GFP_ATOMIC);
                        break;
 
                case SCTP_CMD_PROCESS_FWDTSN:
                        sctp_cmd_process_fwdtsn(&asoc->ulpq, cmd->obj.ptr);
-                        break;
+                       break;
 
                case SCTP_CMD_GEN_SACK:
                        /* Generate a Selective ACK.
@@ -1156,12 +1193,12 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                                                SCTP_CHUNK(cmd->obj.ptr));
 
                        /* FIXME - Eventually come up with a cleaner way to
-                        * enabling COOKIE-ECHO + DATA bundling during 
-                        * multihoming stale cookie scenarios, the following 
-                        * command plays with asoc->peer.retran_path to 
-                        * avoid the problem of sending the COOKIE-ECHO and 
-                        * DATA in different paths, which could result 
-                        * in the association being ABORTed if the DATA chunk 
+                        * enabling COOKIE-ECHO + DATA bundling during
+                        * multihoming stale cookie scenarios, the following
+                        * command plays with asoc->peer.retran_path to
+                        * avoid the problem of sending the COOKIE-ECHO and
+                        * DATA in different paths, which could result
+                        * in the association being ABORTed if the DATA chunk
                         * is processed first by the server.  Checking the
                         * init error counter simply causes this command
                         * to be executed only during failed attempts of
@@ -1171,7 +1208,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                             asoc->peer.primary_path) &&
                            (asoc->init_err_counter > 0)) {
                                sctp_add_cmd_sf(commands,
-                                               SCTP_CMD_FORCE_PRIM_RETRAN,
+                                               SCTP_CMD_FORCE_PRIM_RETRAN,
                                                SCTP_NULL());
                        }
 
@@ -1225,6 +1262,12 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                        sctp_ootb_pkt_free(packet);
                        break;
 
+               case SCTP_CMD_T1_RETRAN:
+                       /* Mark a transport for retransmission.  */
+                       sctp_retransmit(&asoc->outqueue, cmd->obj.transport,
+                                       SCTP_RTXR_T1_RTX);
+                       break;
+
                case SCTP_CMD_RETRAN:
                        /* Mark a transport for retransmission.  */
                        sctp_retransmit(&asoc->outqueue, cmd->obj.transport,
@@ -1348,10 +1391,10 @@ 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);
-                               sctp_retransmit_mark(&asoc->outqueue, t, 0);
+                       list_for_each_entry(t, &asoc->peer.transport_addr_list,
+                                       transports) {
+                               sctp_retransmit_mark(&asoc->outqueue, t,
+                                           SCTP_RTXR_T1_RTX);
                        }
 
                        sctp_add_cmd_sf(commands,
@@ -1365,7 +1408,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
 
                case SCTP_CMD_ASSOC_FAILED:
                        sctp_cmd_assoc_failed(commands, asoc, event_type,
-                                             subtype, chunk, cmd->obj.u32);
+                                             subtype, chunk, cmd->obj.err);
                        break;
 
                case SCTP_CMD_INIT_COUNTER_INC:
@@ -1407,7 +1450,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:
@@ -1420,7 +1463,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
 
                case SCTP_CMD_PROCESS_CTSN:
                        /* Dummy up a SACK for processing. */
-                       sackh.cum_tsn_ack = cmd->obj.u32;
+                       sackh.cum_tsn_ack = cmd->obj.be32;
                        sackh.a_rwnd = 0;
                        sackh.num_gap_ack_blocks = 0;
                        sackh.num_dup_tsns = 0;
@@ -1474,11 +1517,28 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                case SCTP_CMD_SET_SK_ERR:
                        sctp_cmd_set_sk_err(asoc, cmd->obj.error);
                        break;
+               case SCTP_CMD_ASSOC_CHANGE:
+                       sctp_cmd_assoc_change(commands, asoc,
+                                             cmd->obj.u8);
+                       break;
+               case SCTP_CMD_ADAPTATION_IND:
+                       sctp_cmd_adaptation_ind(commands, asoc);
+                       break;
+
+               case SCTP_CMD_ASSOC_SHKEY:
+                       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",
                               cmd->verb, cmd->obj.ptr);
                        break;
-               };
+               }
+
                if (error)
                        break;
        }