[PATCH] e1000: Fix PBA allocation calculations
[safe/jmp/linux-2.6] / net / sctp / sm_sideeffect.c
index 39c970b..7bbc615 100644 (file)
@@ -63,7 +63,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                                void *event_arg,
                                sctp_disposition_t status,
                                sctp_cmd_seq_t *commands,
-                               unsigned int __nocast gfp);
+                               gfp_t gfp);
 static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
                             sctp_state_t state,
                             struct sctp_endpoint *ep,
@@ -71,7 +71,7 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
                             void *event_arg,
                             sctp_disposition_t status,
                             sctp_cmd_seq_t *commands,
-                            unsigned int __nocast gfp);
+                            gfp_t gfp);
 
 /********************************************************************
  * Helper functions
@@ -157,9 +157,12 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force,
 {
        __u32 ctsn, max_tsn_seen;
        struct sctp_chunk *sack;
+       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;
 
        ctsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map);
@@ -189,7 +192,22 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force,
        if (!asoc->peer.sack_needed) {
                /* We will need a SACK for the next packet.  */
                asoc->peer.sack_needed = 1;
-               goto out;
+
+               /* 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)
+                       asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = 
+                               trans->sackdelay;
+               else
+                       asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = 
+                               asoc->sackdelay;
+
+               /* Restart the SACK timer. */
+               sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
+                               SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
        } else {
                if (asoc->a_rwnd > asoc->rwnd)
                        asoc->a_rwnd = asoc->rwnd;
@@ -205,7 +223,7 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force,
                sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
                                SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
        }
-out:
+
        return error;
 nomem:
        error = -ENOMEM;
@@ -385,7 +403,7 @@ sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES] = {
        NULL,
        sctp_generate_t4_rto_event,
        sctp_generate_t5_shutdown_guard_event,
-       sctp_generate_heartbeat_event,
+       NULL,
        sctp_generate_sack_event,
        sctp_generate_autoclose_event,
 };
@@ -412,15 +430,19 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
        /* The check for association's overall error counter exceeding the
         * threshold is done in the state function.
         */
-       asoc->overall_error_count++;
+       /* When probing UNCONFIRMED addresses, the association overall
+        * error count is NOT incremented
+        */
+       if (transport->state != SCTP_UNCONFIRMED)
+               asoc->overall_error_count++;
 
        if (transport->state != SCTP_INACTIVE &&
-           (transport->error_count++ >= transport->max_retrans)) {
+           (transport->error_count++ >= transport->pathmaxrxt)) {
                SCTP_DEBUG_PRINTK_IPADDR("transport_strike:association %p",
                                         " 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);
@@ -480,10 +502,6 @@ static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *commands,
        sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
                        SCTP_STATE(SCTP_STATE_CLOSED));
 
-       /* Set sk_err to ECONNRESET on a 1-1 style socket. */
-       if (!sctp_style(asoc->base.sk, UDP))
-               asoc->base.sk->sk_err = ECONNRESET; 
-
        /* SEND_FAILED sent later when cleaning up the association. */
        asoc->outqueue.error = error;
        sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
@@ -498,7 +516,7 @@ static int sctp_cmd_process_init(sctp_cmd_seq_t *commands,
                                 struct sctp_association *asoc,
                                 struct sctp_chunk *chunk,
                                 sctp_init_chunk_t *peer_init,
-                                unsigned int __nocast gfp)
+                                gfp_t gfp)
 {
        int error;
 
@@ -596,7 +614,7 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds,
        /* Mark the destination transport address as active if it is not so
         * marked.
         */
-       if (t->state == SCTP_INACTIVE)
+       if ((t->state == SCTP_INACTIVE) || (t->state == SCTP_UNCONFIRMED))
                sctp_assoc_control_transport(asoc, t, SCTP_TRANSPORT_UP,
                                             SCTP_HEARTBEAT_SUCCESS);
 
@@ -606,6 +624,10 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds,
         */
        hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data;
        sctp_transport_update_rto(t, (jiffies - hbinfo->sent_at));
+
+       /* Update the heartbeat timer.  */
+       if (!mod_timer(&t->hb_timer, sctp_transport_timeout(t)))
+               sctp_transport_hold(t);
 }
 
 /* Helper function to do a transport reset at the expiry of the hearbeat
@@ -689,9 +711,9 @@ static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds,
                 * increased due to timer expirations.
                 */
                asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] =
-                       asoc->ep->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT];
+                                               asoc->rto_initial;
                asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] =
-                       asoc->ep->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE];
+                                               asoc->rto_initial;
        }
 
        if (sctp_state(asoc, ESTABLISHED) ||
@@ -820,6 +842,15 @@ static void sctp_cmd_del_non_primary(struct sctp_association *asoc)
        return;
 }
 
+/* Helper function to set sk_err on a 1-1 style socket. */
+static void sctp_cmd_set_sk_err(struct sctp_association *asoc, int error)
+{
+       struct sock *sk = asoc->base.sk;
+
+       if (!sctp_style(sk, UDP))
+               sk->sk_err = error;
+}
+
 /* 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.
@@ -853,7 +884,7 @@ int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
               struct sctp_endpoint *ep,
               struct sctp_association *asoc,
               void *event_arg,
-              unsigned int __nocast gfp)
+              gfp_t gfp)
 {
        sctp_cmd_seq_t commands;
        const sctp_sm_table_entry_t *state_fn;
@@ -898,7 +929,7 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
                             void *event_arg,
                             sctp_disposition_t status,
                             sctp_cmd_seq_t *commands,
-                            unsigned int __nocast gfp)
+                            gfp_t gfp)
 {
        int error;
 
@@ -986,7 +1017,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                                void *event_arg,
                                sctp_disposition_t status,
                                sctp_cmd_seq_t *commands,
-                               unsigned int __nocast gfp)
+                               gfp_t gfp)
 {
        int error = 0;
        int force;
@@ -1232,8 +1263,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                case SCTP_CMD_TIMER_START:
                        timer = &asoc->timers[cmd->obj.to];
                        timeout = asoc->timeouts[cmd->obj.to];
-                       if (!timeout)
-                               BUG();
+                       BUG_ON(!timeout);
 
                        timer->expires = jiffies + timeout;
                        sctp_association_hold(asoc);
@@ -1283,7 +1313,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                                        "T1 INIT Timeout adjustment"
                                        " init_err_counter: %d"
                                        " cycle: %d"
-                                       " timeout: %d\n",
+                                       " timeout: %ld\n",
                                        asoc->init_err_counter,
                                        asoc->init_cycle,
                                        asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT]);
@@ -1311,7 +1341,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                        SCTP_DEBUG_PRINTK(
                                "T1 COOKIE Timeout adjustment"
                                " init_err_counter: %d"
-                               " timeout: %d\n",
+                               " timeout: %ld\n",
                                asoc->init_err_counter,
                                asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE]);
 
@@ -1330,12 +1360,12 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                        break;
 
                case SCTP_CMD_INIT_FAILED:
-                       sctp_cmd_init_failed(commands, asoc, cmd->obj.u32);
+                       sctp_cmd_init_failed(commands, asoc, cmd->obj.err);
                        break;
 
                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:
@@ -1390,7 +1420,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;
@@ -1441,6 +1471,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                        local_cork = 0;
                        asoc->peer.retran_path = t;
                        break;
+               case SCTP_CMD_SET_SK_ERR:
+                       sctp_cmd_set_sk_err(asoc, cmd->obj.error);
+                       break;
                default:
                        printk(KERN_WARNING "Impossible command: %u, %p\n",
                               cmd->verb, cmd->obj.ptr);