#include <net/sctp/checksum.h>
 
 /* Forward declarations for private helpers. */
+static sctp_xmit_t __sctp_packet_append_chunk(struct sctp_packet *packet,
+                                             struct sctp_chunk *chunk);
 static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet,
                                           struct sctp_chunk *chunk);
 static void sctp_packet_append_data(struct sctp_packet *packet,
        if (!auth)
                return retval;
 
-       retval = sctp_packet_append_chunk(pkt, auth);
+       retval = __sctp_packet_append_chunk(pkt, auth);
+
+       if (retval != SCTP_XMIT_OK)
+               sctp_chunk_free(auth);
 
        return retval;
 }
                        asoc->a_rwnd = asoc->rwnd;
                        sack = sctp_make_sack(asoc);
                        if (sack) {
-                               retval = sctp_packet_append_chunk(pkt, sack);
+                               retval = __sctp_packet_append_chunk(pkt, sack);
+                               if (retval != SCTP_XMIT_OK) {
+                                       sctp_chunk_free(sack);
+                                       goto out;
+                               }
                                asoc->peer.sack_needed = 0;
                                if (del_timer(timer))
                                        sctp_association_put(asoc);
                        }
                }
        }
+out:
        return retval;
 }
 
+
 /* Append a chunk to the offered packet reporting back any inability to do
  * so.
  */
-sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet,
-                                    struct sctp_chunk *chunk)
+static sctp_xmit_t __sctp_packet_append_chunk(struct sctp_packet *packet,
+                                             struct sctp_chunk *chunk)
 {
        sctp_xmit_t retval = SCTP_XMIT_OK;
        __u16 chunk_len = WORD_ROUND(ntohs(chunk->chunk_hdr->length));
 
-       SCTP_DEBUG_PRINTK("%s: packet:%p chunk:%p\n", __func__, packet,
-                         chunk);
-
-       /* Data chunks are special.  Before seeing what else we can
-        * bundle into this packet, check to see if we are allowed to
-        * send this DATA.
-        */
-       if (sctp_chunk_is_data(chunk)) {
-               retval = sctp_packet_can_append_data(packet, chunk);
-               if (retval != SCTP_XMIT_OK)
-                       goto finish;
-       }
-
-       /* Try to bundle AUTH chunk */
-       retval = sctp_packet_bundle_auth(packet, chunk);
-       if (retval != SCTP_XMIT_OK)
-               goto finish;
-
-       /* Try to bundle SACK chunk */
-       retval = sctp_packet_bundle_sack(packet, chunk);
-       if (retval != SCTP_XMIT_OK)
-               goto finish;
-
        /* Check to see if this chunk will fit into the packet */
        retval = sctp_packet_will_fit(packet, chunk, chunk_len);
        if (retval != SCTP_XMIT_OK)
        return retval;
 }
 
+/* Append a chunk to the offered packet reporting back any inability to do
+ * so.
+ */
+sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet,
+                                    struct sctp_chunk *chunk)
+{
+       sctp_xmit_t retval = SCTP_XMIT_OK;
+
+       SCTP_DEBUG_PRINTK("%s: packet:%p chunk:%p\n", __func__, packet,
+                         chunk);
+
+       /* Data chunks are special.  Before seeing what else we can
+        * bundle into this packet, check to see if we are allowed to
+        * send this DATA.
+        */
+       if (sctp_chunk_is_data(chunk)) {
+               retval = sctp_packet_can_append_data(packet, chunk);
+               if (retval != SCTP_XMIT_OK)
+                       goto finish;
+       }
+
+       /* Try to bundle AUTH chunk */
+       retval = sctp_packet_bundle_auth(packet, chunk);
+       if (retval != SCTP_XMIT_OK)
+               goto finish;
+
+       /* Try to bundle SACK chunk */
+       retval = sctp_packet_bundle_sack(packet, chunk);
+       if (retval != SCTP_XMIT_OK)
+               goto finish;
+
+       retval = __sctp_packet_append_chunk(packet, chunk);
+
+finish:
+       return retval;
+}
+
 /* All packets are sent to the network through this function from
  * sctp_outq_tail().
  *