]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/sctp/sm_make_chunk.c
regulator: Use menuconfig in Kconfig
[linux-2.6-omap-h63xx.git] / net / sctp / sm_make_chunk.c
index b599cbba4fbe33eb2eaa0a5a4033f1bb00d2c99f..fd8acb48c3f2827f069c36b8ef01e0fd34f14349 100644 (file)
@@ -702,12 +702,14 @@ struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc)
        __u32 ctsn;
        __u16 num_gabs, num_dup_tsns;
        struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map;
+       struct sctp_gap_ack_block gabs[SCTP_MAX_GABS];
 
+       memset(gabs, 0, sizeof(gabs));
        ctsn = sctp_tsnmap_get_ctsn(map);
        SCTP_DEBUG_PRINTK("sackCTSNAck sent:  0x%x.\n", ctsn);
 
        /* How much room is needed in the chunk? */
-       num_gabs = sctp_tsnmap_num_gabs(map);
+       num_gabs = sctp_tsnmap_num_gabs(map, gabs);
        num_dup_tsns = sctp_tsnmap_num_dups(map);
 
        /* Initialize the SACK header.  */
@@ -763,7 +765,7 @@ struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc)
        /* Add the gap ack block information.   */
        if (num_gabs)
                sctp_addto_chunk(retval, sizeof(__u32) * num_gabs,
-                                sctp_tsnmap_get_gabs(map));
+                                gabs);
 
        /* Add the duplicate TSN information.  */
        if (num_dup_tsns)
@@ -1012,6 +1014,29 @@ end:
        return retval;
 }
 
+struct sctp_chunk *sctp_make_violation_paramlen(
+       const struct sctp_association *asoc,
+       const struct sctp_chunk *chunk,
+       struct sctp_paramhdr *param)
+{
+       struct sctp_chunk *retval;
+       static const char error[] = "The following parameter had invalid length:";
+       size_t payload_len = sizeof(error) + sizeof(sctp_errhdr_t) +
+                               sizeof(sctp_paramhdr_t);
+
+       retval = sctp_make_abort(asoc, chunk, payload_len);
+       if (!retval)
+               goto nodata;
+
+       sctp_init_cause(retval, SCTP_ERROR_PROTO_VIOLATION,
+                       sizeof(error) + sizeof(sctp_paramhdr_t));
+       sctp_addto_chunk(retval, sizeof(error), error);
+       sctp_addto_param(retval, sizeof(sctp_paramhdr_t), param);
+
+nodata:
+       return retval;
+}
+
 /* Make a HEARTBEAT chunk.  */
 struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc,
                                  const struct sctp_transport *transport,
@@ -1188,7 +1213,7 @@ struct sctp_chunk *sctp_chunkify(struct sk_buff *skb,
         */
        retval->tsn_missing_report = 0;
        retval->tsn_gap_acked = 0;
-       retval->fast_retransmit = 0;
+       retval->fast_retransmit = SCTP_CAN_FRTX;
 
        /* If this is a fragmented message, track all fragments
         * of the message (for SEND_FAILED).
@@ -1782,11 +1807,6 @@ static int sctp_process_inv_paramlength(const struct sctp_association *asoc,
                                        const struct sctp_chunk *chunk,
                                        struct sctp_chunk **errp)
 {
-       static const char error[] = "The following parameter had invalid length:";
-       size_t          payload_len = WORD_ROUND(sizeof(error)) +
-                                               sizeof(sctp_paramhdr_t);
-
-
        /* This is a fatal error.  Any accumulated non-fatal errors are
         * not reported.
         */
@@ -1794,14 +1814,7 @@ static int sctp_process_inv_paramlength(const struct sctp_association *asoc,
                sctp_chunk_free(*errp);
 
        /* Create an error chunk and fill it in with our payload. */
-       *errp = sctp_make_op_error_space(asoc, chunk, payload_len);
-
-       if (*errp) {
-               sctp_init_cause(*errp, SCTP_ERROR_PROTO_VIOLATION,
-                               sizeof(error) + sizeof(sctp_paramhdr_t));
-               sctp_addto_chunk(*errp, sizeof(error), error);
-               sctp_addto_param(*errp, sizeof(sctp_paramhdr_t), param);
-       }
+       *errp = sctp_make_violation_paramlen(asoc, chunk, param);
 
        return 0;
 }
@@ -2277,8 +2290,9 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
        }
 
        /* Set up the TSN tracking pieces.  */
-       sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_SIZE,
-                        asoc->peer.i.initial_tsn);
+       if (!sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_INITIAL,
+                               asoc->peer.i.initial_tsn, gfp))
+               goto clean_up;
 
        /* RFC 2960 6.5 Stream Identifier and Stream Sequence Number
         *
@@ -2456,7 +2470,7 @@ do_addr_param:
                break;
 
        case SCTP_PARAM_ADAPTATION_LAYER_IND:
-               asoc->peer.adaptation_ind = param.aind->adaptation_ind;
+               asoc->peer.adaptation_ind = ntohl(param.aind->adaptation_ind);
                break;
 
        case SCTP_PARAM_SET_PRIMARY: