Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[cascardo/linux.git] / net / sctp / chunk.c
index a55e547..7a1cdf4 100644 (file)
@@ -70,6 +70,19 @@ static struct sctp_datamsg *sctp_datamsg_new(gfp_t gfp)
        return msg;
 }
 
+void sctp_datamsg_free(struct sctp_datamsg *msg)
+{
+       struct sctp_chunk *chunk;
+
+       /* This doesn't have to be a _safe vairant because
+        * sctp_chunk_free() only drops the refs.
+        */
+       list_for_each_entry(chunk, &msg->chunks, frag_list)
+               sctp_chunk_free(chunk);
+
+       sctp_datamsg_put(msg);
+}
+
 /* Final destructruction of datamsg memory. */
 static void sctp_datamsg_destroy(struct sctp_datamsg *msg)
 {
@@ -179,12 +192,18 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
                         msg, msg->expires_at, jiffies);
        }
 
+       if (asoc->peer.prsctp_capable &&
+           SCTP_PR_TTL_ENABLED(sinfo->sinfo_flags))
+               msg->expires_at =
+                       jiffies + msecs_to_jiffies(sinfo->sinfo_timetolive);
+
        /* This is the biggest possible DATA chunk that can fit into
         * the packet
         */
-       max_data = (asoc->pathmtu -
-               sctp_sk(asoc->base.sk)->pf->af->net_header_len -
-               sizeof(struct sctphdr) - sizeof(struct sctp_data_chunk)) & ~3;
+       max_data = asoc->pathmtu -
+                  sctp_sk(asoc->base.sk)->pf->af->net_header_len -
+                  sizeof(struct sctphdr) - sizeof(struct sctp_data_chunk);
+       max_data = SCTP_TRUNC4(max_data);
 
        max = asoc->frag_point;
        /* If the the peer requested that we authenticate DATA chunks
@@ -195,8 +214,8 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
                struct sctp_hmac *hmac_desc = sctp_auth_asoc_get_hmac(asoc);
 
                if (hmac_desc)
-                       max_data -= WORD_ROUND(sizeof(sctp_auth_chunk_t) +
-                                           hmac_desc->hmac_len);
+                       max_data -= SCTP_PAD4(sizeof(sctp_auth_chunk_t) +
+                                             hmac_desc->hmac_len);
        }
 
        /* Now, check if we need to reduce our max */
@@ -216,7 +235,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
            asoc->outqueue.out_qlen == 0 &&
            list_empty(&asoc->outqueue.retransmit) &&
            msg_len > max)
-               max_data -= WORD_ROUND(sizeof(sctp_sack_chunk_t));
+               max_data -= SCTP_PAD4(sizeof(sctp_sack_chunk_t));
 
        /* Encourage Cookie-ECHO bundling. */
        if (asoc->state < SCTP_STATE_COOKIE_ECHOED)
@@ -335,7 +354,7 @@ errout:
 /* Check whether this message has expired. */
 int sctp_chunk_abandoned(struct sctp_chunk *chunk)
 {
-       if (!chunk->asoc->prsctp_enable ||
+       if (!chunk->asoc->peer.prsctp_capable ||
            !SCTP_PR_POLICY(chunk->sinfo.sinfo_flags)) {
                struct sctp_datamsg *msg = chunk->msg;
 
@@ -349,14 +368,14 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
        }
 
        if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) &&
-           time_after(jiffies, chunk->prsctp_param)) {
+           time_after(jiffies, chunk->msg->expires_at)) {
                if (chunk->sent_count)
                        chunk->asoc->abandoned_sent[SCTP_PR_INDEX(TTL)]++;
                else
                        chunk->asoc->abandoned_unsent[SCTP_PR_INDEX(TTL)]++;
                return 1;
        } else if (SCTP_PR_RTX_ENABLED(chunk->sinfo.sinfo_flags) &&
-                  chunk->sent_count > chunk->prsctp_param) {
+                  chunk->sent_count > chunk->sinfo.sinfo_timetolive) {
                chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
                return 1;
        }