Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
[linux-2.6-microblaze.git] / net / sctp / sm_make_chunk.c
index 1296e55..e47abf2 100644 (file)
 #include <net/sctp/sm.h>
 
 static struct sctp_chunk *sctp_make_control(const struct sctp_association *asoc,
-                                           __u8 type, __u8 flags, int paylen);
+                                           __u8 type, __u8 flags, int paylen,
+                                           gfp_t gfp);
 static struct sctp_chunk *sctp_make_data(const struct sctp_association *asoc,
-                                        __u8 flags, int paylen);
+                                        __u8 flags, int paylen, gfp_t gfp);
 static struct sctp_chunk *_sctp_make_chunk(const struct sctp_association *asoc,
-                                          __u8 type, __u8 flags, int paylen);
+                                          __u8 type, __u8 flags, int paylen,
+                                          gfp_t gfp);
 static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
                                        const struct sctp_association *asoc,
                                        const struct sctp_chunk *init_chunk,
@@ -318,7 +320,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
         * PLEASE DO NOT FIXME [This version does not support Host Name.]
         */
 
-       retval = sctp_make_control(asoc, SCTP_CID_INIT, 0, chunksize);
+       retval = sctp_make_control(asoc, SCTP_CID_INIT, 0, chunksize, gfp);
        if (!retval)
                goto nodata;
 
@@ -465,7 +467,7 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
                                        num_ext);
 
        /* Now allocate and fill out the chunk.  */
-       retval = sctp_make_control(asoc, SCTP_CID_INIT_ACK, 0, chunksize);
+       retval = sctp_make_control(asoc, SCTP_CID_INIT_ACK, 0, chunksize, gfp);
        if (!retval)
                goto nomem_chunk;
 
@@ -570,7 +572,8 @@ struct sctp_chunk *sctp_make_cookie_echo(const struct sctp_association *asoc,
        cookie_len = asoc->peer.cookie_len;
 
        /* Build a cookie echo chunk.  */
-       retval = sctp_make_control(asoc, SCTP_CID_COOKIE_ECHO, 0, cookie_len);
+       retval = sctp_make_control(asoc, SCTP_CID_COOKIE_ECHO, 0,
+                                  cookie_len, GFP_ATOMIC);
        if (!retval)
                goto nodata;
        retval->subh.cookie_hdr =
@@ -615,7 +618,7 @@ struct sctp_chunk *sctp_make_cookie_ack(const struct sctp_association *asoc,
 {
        struct sctp_chunk *retval;
 
-       retval = sctp_make_control(asoc, SCTP_CID_COOKIE_ACK, 0, 0);
+       retval = sctp_make_control(asoc, SCTP_CID_COOKIE_ACK, 0, 0, GFP_ATOMIC);
 
        /* RFC 2960 6.4 Multi-homed SCTP Endpoints
         *
@@ -664,7 +667,7 @@ struct sctp_chunk *sctp_make_cwr(const struct sctp_association *asoc,
 
        cwr.lowest_tsn = htonl(lowest_tsn);
        retval = sctp_make_control(asoc, SCTP_CID_ECN_CWR, 0,
-                                  sizeof(sctp_cwrhdr_t));
+                                  sizeof(sctp_cwrhdr_t), GFP_ATOMIC);
 
        if (!retval)
                goto nodata;
@@ -698,7 +701,7 @@ struct sctp_chunk *sctp_make_ecne(const struct sctp_association *asoc,
 
        ecne.lowest_tsn = htonl(lowest_tsn);
        retval = sctp_make_control(asoc, SCTP_CID_ECN_ECNE, 0,
-                                  sizeof(sctp_ecnehdr_t));
+                                  sizeof(sctp_ecnehdr_t), GFP_ATOMIC);
        if (!retval)
                goto nodata;
        retval->subh.ecne_hdr =
@@ -713,7 +716,8 @@ nodata:
  */
 struct sctp_chunk *sctp_make_datafrag_empty(struct sctp_association *asoc,
                                       const struct sctp_sndrcvinfo *sinfo,
-                                      int data_len, __u8 flags, __u16 ssn)
+                                      int data_len, __u8 flags, __u16 ssn,
+                                      gfp_t gfp)
 {
        struct sctp_chunk *retval;
        struct sctp_datahdr dp;
@@ -734,7 +738,7 @@ struct sctp_chunk *sctp_make_datafrag_empty(struct sctp_association *asoc,
                dp.ssn = htons(ssn);
 
        chunk_len = sizeof(dp) + data_len;
-       retval = sctp_make_data(asoc, flags, chunk_len);
+       retval = sctp_make_data(asoc, flags, chunk_len, gfp);
        if (!retval)
                goto nodata;
 
@@ -781,7 +785,7 @@ struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc)
                + sizeof(__u32) * num_dup_tsns;
 
        /* Create the chunk.  */
-       retval = sctp_make_control(asoc, SCTP_CID_SACK, 0, len);
+       retval = sctp_make_control(asoc, SCTP_CID_SACK, 0, len, GFP_ATOMIC);
        if (!retval)
                goto nodata;
 
@@ -861,7 +865,7 @@ struct sctp_chunk *sctp_make_shutdown(const struct sctp_association *asoc,
        shut.cum_tsn_ack = htonl(ctsn);
 
        retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN, 0,
-                                  sizeof(sctp_shutdownhdr_t));
+                                  sizeof(sctp_shutdownhdr_t), GFP_ATOMIC);
        if (!retval)
                goto nodata;
 
@@ -879,7 +883,8 @@ struct sctp_chunk *sctp_make_shutdown_ack(const struct sctp_association *asoc,
 {
        struct sctp_chunk *retval;
 
-       retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN_ACK, 0, 0);
+       retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN_ACK, 0, 0,
+                                  GFP_ATOMIC);
 
        /* RFC 2960 6.4 Multi-homed SCTP Endpoints
         *
@@ -908,7 +913,8 @@ struct sctp_chunk *sctp_make_shutdown_complete(
         */
        flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T;
 
-       retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN_COMPLETE, flags, 0);
+       retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN_COMPLETE, flags,
+                                  0, GFP_ATOMIC);
 
        /* RFC 2960 6.4 Multi-homed SCTP Endpoints
         *
@@ -947,7 +953,8 @@ struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc,
                        flags = SCTP_CHUNK_FLAG_T;
        }
 
-       retval = sctp_make_control(asoc, SCTP_CID_ABORT, flags, hint);
+       retval = sctp_make_control(asoc, SCTP_CID_ABORT, flags, hint,
+                                  GFP_ATOMIC);
 
        /* RFC 2960 6.4 Multi-homed SCTP Endpoints
         *
@@ -1139,7 +1146,8 @@ struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc,
        struct sctp_chunk *retval;
        sctp_sender_hb_info_t hbinfo;
 
-       retval = sctp_make_control(asoc, SCTP_CID_HEARTBEAT, 0, sizeof(hbinfo));
+       retval = sctp_make_control(asoc, SCTP_CID_HEARTBEAT, 0,
+                                  sizeof(hbinfo), GFP_ATOMIC);
 
        if (!retval)
                goto nodata;
@@ -1167,7 +1175,8 @@ struct sctp_chunk *sctp_make_heartbeat_ack(const struct sctp_association *asoc,
 {
        struct sctp_chunk *retval;
 
-       retval  = sctp_make_control(asoc, SCTP_CID_HEARTBEAT_ACK, 0, paylen);
+       retval  = sctp_make_control(asoc, SCTP_CID_HEARTBEAT_ACK, 0, paylen,
+                                   GFP_ATOMIC);
        if (!retval)
                goto nodata;
 
@@ -1200,7 +1209,7 @@ static struct sctp_chunk *sctp_make_op_error_space(
        struct sctp_chunk *retval;
 
        retval = sctp_make_control(asoc, SCTP_CID_ERROR, 0,
-                                  sizeof(sctp_errhdr_t) + size);
+                                  sizeof(sctp_errhdr_t) + size, GFP_ATOMIC);
        if (!retval)
                goto nodata;
 
@@ -1271,7 +1280,8 @@ struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc)
                return NULL;
 
        retval = sctp_make_control(asoc, SCTP_CID_AUTH, 0,
-                       hmac_desc->hmac_len + sizeof(sctp_authhdr_t));
+                       hmac_desc->hmac_len + sizeof(sctp_authhdr_t),
+                       GFP_ATOMIC);
        if (!retval)
                return NULL;
 
@@ -1309,11 +1319,11 @@ struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc)
  */
 struct sctp_chunk *sctp_chunkify(struct sk_buff *skb,
                            const struct sctp_association *asoc,
-                           struct sock *sk)
+                           struct sock *sk, gfp_t gfp)
 {
        struct sctp_chunk *retval;
 
-       retval = kmem_cache_zalloc(sctp_chunk_cachep, GFP_ATOMIC);
+       retval = kmem_cache_zalloc(sctp_chunk_cachep, gfp);
 
        if (!retval)
                goto nodata;
@@ -1361,7 +1371,8 @@ const union sctp_addr *sctp_source(const struct sctp_chunk *chunk)
  * arguments, reserving enough space for a 'paylen' byte payload.
  */
 static struct sctp_chunk *_sctp_make_chunk(const struct sctp_association *asoc,
-                                           __u8 type, __u8 flags, int paylen)
+                                           __u8 type, __u8 flags, int paylen,
+                                           gfp_t gfp)
 {
        struct sctp_chunk *retval;
        sctp_chunkhdr_t *chunk_hdr;
@@ -1369,8 +1380,7 @@ static struct sctp_chunk *_sctp_make_chunk(const struct sctp_association *asoc,
        struct sock *sk;
 
        /* No need to allocate LL here, as this is only a chunk. */
-       skb = alloc_skb(WORD_ROUND(sizeof(sctp_chunkhdr_t) + paylen),
-                       GFP_ATOMIC);
+       skb = alloc_skb(WORD_ROUND(sizeof(sctp_chunkhdr_t) + paylen), gfp);
        if (!skb)
                goto nodata;
 
@@ -1381,7 +1391,7 @@ static struct sctp_chunk *_sctp_make_chunk(const struct sctp_association *asoc,
        chunk_hdr->length = htons(sizeof(sctp_chunkhdr_t));
 
        sk = asoc ? asoc->base.sk : NULL;
-       retval = sctp_chunkify(skb, asoc, sk);
+       retval = sctp_chunkify(skb, asoc, sk, gfp);
        if (!retval) {
                kfree_skb(skb);
                goto nodata;
@@ -1400,16 +1410,18 @@ nodata:
 }
 
 static struct sctp_chunk *sctp_make_data(const struct sctp_association *asoc,
-                                        __u8 flags, int paylen)
+                                        __u8 flags, int paylen, gfp_t gfp)
 {
-       return _sctp_make_chunk(asoc, SCTP_CID_DATA, flags, paylen);
+       return _sctp_make_chunk(asoc, SCTP_CID_DATA, flags, paylen, gfp);
 }
 
 static struct sctp_chunk *sctp_make_control(const struct sctp_association *asoc,
-                                           __u8 type, __u8 flags, int paylen)
+                                           __u8 type, __u8 flags, int paylen,
+                                           gfp_t gfp)
 {
-       struct sctp_chunk *chunk = _sctp_make_chunk(asoc, type, flags, paylen);
+       struct sctp_chunk *chunk;
 
+       chunk = _sctp_make_chunk(asoc, type, flags, paylen, gfp);
        if (chunk)
                sctp_control_set_owner_w(chunk);
 
@@ -2763,7 +2775,8 @@ static struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
        length += addrlen;
 
        /* Create the chunk.  */
-       retval = sctp_make_control(asoc, SCTP_CID_ASCONF, 0, length);
+       retval = sctp_make_control(asoc, SCTP_CID_ASCONF, 0, length,
+                                  GFP_ATOMIC);
        if (!retval)
                return NULL;
 
@@ -2947,7 +2960,8 @@ static struct sctp_chunk *sctp_make_asconf_ack(const struct sctp_association *as
        int                     length = sizeof(asconf) + vparam_len;
 
        /* Create the chunk.  */
-       retval = sctp_make_control(asoc, SCTP_CID_ASCONF_ACK, 0, length);
+       retval = sctp_make_control(asoc, SCTP_CID_ASCONF_ACK, 0, length,
+                                  GFP_ATOMIC);
        if (!retval)
                return NULL;
 
@@ -3507,7 +3521,7 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
 
        hint = (nstreams + 1) * sizeof(__u32);
 
-       retval = sctp_make_control(asoc, SCTP_CID_FWD_TSN, 0, hint);
+       retval = sctp_make_control(asoc, SCTP_CID_FWD_TSN, 0, hint, GFP_ATOMIC);
 
        if (!retval)
                return NULL;