ipv6: Fix tcp_v6_send_response transport header setting.
[safe/jmp/linux-2.6] / net / sctp / sm_make_chunk.c
index 3d867ce..17cb400 100644 (file)
@@ -58,6 +58,7 @@
 #include <linux/inet.h>
 #include <linux/scatterlist.h>
 #include <linux/crypto.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 
 #include <linux/skbuff.h>
@@ -987,7 +988,10 @@ static void *sctp_addto_param(struct sctp_chunk *chunk, int len,
 
        target = skb_put(chunk->skb, len);
 
-       memcpy(target, data, len);
+       if (data)
+               memcpy(target, data, len);
+       else
+               memset(target, 0, len);
 
        /* Adjust the chunk length field.  */
        chunk->chunk_hdr->length = htons(chunklen + len);
@@ -1129,16 +1133,18 @@ nodata:
 struct sctp_chunk *sctp_make_op_error(const struct sctp_association *asoc,
                                 const struct sctp_chunk *chunk,
                                 __be16 cause_code, const void *payload,
-                                size_t paylen)
+                                size_t paylen, size_t reserve_tail)
 {
        struct sctp_chunk *retval;
 
-       retval = sctp_make_op_error_space(asoc, chunk, paylen);
+       retval = sctp_make_op_error_space(asoc, chunk, paylen + reserve_tail);
        if (!retval)
                goto nodata;
 
-       sctp_init_cause(retval, cause_code, paylen);
+       sctp_init_cause(retval, cause_code, paylen + reserve_tail);
        sctp_addto_chunk(retval, paylen, payload);
+       if (reserve_tail)
+               sctp_addto_param(retval, reserve_tail, NULL);
 
 nodata:
        return retval;
@@ -3134,6 +3140,14 @@ static void sctp_asconf_param_success(struct sctp_association *asoc,
                                saddr->state = SCTP_ADDR_SRC;
                }
                local_bh_enable();
+               list_for_each_entry(transport, &asoc->peer.transport_addr_list,
+                               transports) {
+                       if (transport->state == SCTP_ACTIVE)
+                               continue;
+                       dst_release(transport->dst);
+                       sctp_transport_route(transport, NULL,
+                                            sctp_sk(asoc->base.sk));
+               }
                break;
        case SCTP_PARAM_DEL_IP:
                local_bh_disable();