Merge branch 'master' into for-2.6.35
[safe/jmp/linux-2.6] / net / sctp / chunk.c
index acf7c4d..476caaf 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/net.h>
 #include <linux/inet.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
@@ -57,9 +58,9 @@ static void sctp_datamsg_init(struct sctp_datamsg *msg)
        msg->send_failed = 0;
        msg->send_error = 0;
        msg->can_abandon = 0;
+       msg->can_delay = 1;
        msg->expires_at = 0;
        INIT_LIST_HEAD(&msg->chunks);
-       msg->msg_size = 0;
 }
 
 /* Allocate and initialize datamsg. */
@@ -156,7 +157,6 @@ static void sctp_datamsg_assign(struct sctp_datamsg *msg, struct sctp_chunk *chu
 {
        sctp_datamsg_hold(msg);
        chunk->msg = msg;
-       msg->msg_size += chunk->skb->len;
 }
 
 
@@ -246,6 +246,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
        if (msg_len >= first_len) {
                msg_len -= first_len;
                whole = 1;
+               msg->can_delay = 0;
        }
 
        /* How many full sized?  How many bytes leftover? */
@@ -263,9 +264,18 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
                if (0 == i)
                        frag |= SCTP_DATA_FIRST_FRAG;
 
-               if ((i == (whole - 1)) && !over)
+               if ((i == (whole - 1)) && !over) {
                        frag |= SCTP_DATA_LAST_FRAG;
 
+                       /* The application requests to set the I-bit of the
+                        * last DATA chunk of a user message when providing
+                        * the user message to the SCTP implementation.
+                        */
+                       if ((sinfo->sinfo_flags & SCTP_EOF) ||
+                           (sinfo->sinfo_flags & SCTP_SACK_IMMEDIATELY))
+                               frag |= SCTP_DATA_SACK_IMM;
+               }
+
                chunk = sctp_make_datafrag_empty(asoc, sinfo, len, frag, 0);
 
                if (!chunk)
@@ -297,6 +307,10 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
                else
                        frag = SCTP_DATA_LAST_FRAG;
 
+               if ((sinfo->sinfo_flags & SCTP_EOF) ||
+                   (sinfo->sinfo_flags & SCTP_SACK_IMMEDIATELY))
+                       frag |= SCTP_DATA_SACK_IMM;
+
                chunk = sctp_make_datafrag_empty(asoc, sinfo, over, frag, 0);
 
                if (!chunk)