diff options
Diffstat (limited to 'net/sctp')
| -rw-r--r-- | net/sctp/associola.c | 6 | ||||
| -rw-r--r-- | net/sctp/auth.c | 1 | ||||
| -rw-r--r-- | net/sctp/bind_addr.c | 1 | ||||
| -rw-r--r-- | net/sctp/chunk.c | 1 | ||||
| -rw-r--r-- | net/sctp/endpointola.c | 1 | ||||
| -rw-r--r-- | net/sctp/input.c | 1 | ||||
| -rw-r--r-- | net/sctp/inqueue.c | 1 | ||||
| -rw-r--r-- | net/sctp/ipv6.c | 1 | ||||
| -rw-r--r-- | net/sctp/output.c | 1 | ||||
| -rw-r--r-- | net/sctp/outqueue.c | 1 | ||||
| -rw-r--r-- | net/sctp/primitive.c | 1 | ||||
| -rw-r--r-- | net/sctp/protocol.c | 1 | ||||
| -rw-r--r-- | net/sctp/sm_make_chunk.c | 95 | ||||
| -rw-r--r-- | net/sctp/sm_sideeffect.c | 27 | ||||
| -rw-r--r-- | net/sctp/sm_statefuns.c | 9 | ||||
| -rw-r--r-- | net/sctp/socket.c | 15 | ||||
| -rw-r--r-- | net/sctp/ssnmap.c | 1 | ||||
| -rw-r--r-- | net/sctp/transport.c | 1 | ||||
| -rw-r--r-- | net/sctp/tsnmap.c | 1 | ||||
| -rw-r--r-- | net/sctp/ulpevent.c | 1 | ||||
| -rw-r--r-- | net/sctp/ulpqueue.c | 1 |
21 files changed, 136 insertions, 32 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index df5abbff63e2..99c93ee98ad9 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
| @@ -1194,8 +1194,10 @@ void sctp_assoc_update(struct sctp_association *asoc, | |||
| 1194 | /* Remove any peer addresses not present in the new association. */ | 1194 | /* Remove any peer addresses not present in the new association. */ |
| 1195 | list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { | 1195 | list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { |
| 1196 | trans = list_entry(pos, struct sctp_transport, transports); | 1196 | trans = list_entry(pos, struct sctp_transport, transports); |
| 1197 | if (!sctp_assoc_lookup_paddr(new, &trans->ipaddr)) | 1197 | if (!sctp_assoc_lookup_paddr(new, &trans->ipaddr)) { |
| 1198 | sctp_assoc_del_peer(asoc, &trans->ipaddr); | 1198 | sctp_assoc_rm_peer(asoc, trans); |
| 1199 | continue; | ||
| 1200 | } | ||
| 1199 | 1201 | ||
| 1200 | if (asoc->state >= SCTP_STATE_ESTABLISHED) | 1202 | if (asoc->state >= SCTP_STATE_ESTABLISHED) |
| 1201 | sctp_transport_reset(trans); | 1203 | sctp_transport_reset(trans); |
diff --git a/net/sctp/auth.c b/net/sctp/auth.c index 56935bbc1496..86366390038a 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | * be incorporated into the next SCTP release. | 34 | * be incorporated into the next SCTP release. |
| 35 | */ | 35 | */ |
| 36 | 36 | ||
| 37 | #include <linux/slab.h> | ||
| 37 | #include <linux/types.h> | 38 | #include <linux/types.h> |
| 38 | #include <linux/crypto.h> | 39 | #include <linux/crypto.h> |
| 39 | #include <linux/scatterlist.h> | 40 | #include <linux/scatterlist.h> |
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c index bef133731683..faf71d179e46 100644 --- a/net/sctp/bind_addr.c +++ b/net/sctp/bind_addr.c | |||
| @@ -43,6 +43,7 @@ | |||
| 43 | */ | 43 | */ |
| 44 | 44 | ||
| 45 | #include <linux/types.h> | 45 | #include <linux/types.h> |
| 46 | #include <linux/slab.h> | ||
| 46 | #include <linux/in.h> | 47 | #include <linux/in.h> |
| 47 | #include <net/sock.h> | 48 | #include <net/sock.h> |
| 48 | #include <net/ipv6.h> | 49 | #include <net/ipv6.h> |
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c index 8e4320040f05..3eab6db59a37 100644 --- a/net/sctp/chunk.c +++ b/net/sctp/chunk.c | |||
| @@ -42,6 +42,7 @@ | |||
| 42 | #include <linux/net.h> | 42 | #include <linux/net.h> |
| 43 | #include <linux/inet.h> | 43 | #include <linux/inet.h> |
| 44 | #include <linux/skbuff.h> | 44 | #include <linux/skbuff.h> |
| 45 | #include <linux/slab.h> | ||
| 45 | #include <net/sock.h> | 46 | #include <net/sock.h> |
| 46 | #include <net/sctp/sctp.h> | 47 | #include <net/sctp/sctp.h> |
| 47 | #include <net/sctp/sm.h> | 48 | #include <net/sctp/sm.h> |
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 905fda582b92..7ec09ba03a1c 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c | |||
| @@ -144,6 +144,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | |||
| 144 | /* Use SCTP specific send buffer space queues. */ | 144 | /* Use SCTP specific send buffer space queues. */ |
| 145 | ep->sndbuf_policy = sctp_sndbuf_policy; | 145 | ep->sndbuf_policy = sctp_sndbuf_policy; |
| 146 | 146 | ||
| 147 | sk->sk_data_ready = sctp_data_ready; | ||
| 147 | sk->sk_write_space = sctp_write_space; | 148 | sk->sk_write_space = sctp_write_space; |
| 148 | sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); | 149 | sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); |
| 149 | 150 | ||
diff --git a/net/sctp/input.c b/net/sctp/input.c index 3d74b264ea22..2a570184e5a9 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
| @@ -53,6 +53,7 @@ | |||
| 53 | #include <linux/socket.h> | 53 | #include <linux/socket.h> |
| 54 | #include <linux/ip.h> | 54 | #include <linux/ip.h> |
| 55 | #include <linux/time.h> /* For struct timeval */ | 55 | #include <linux/time.h> /* For struct timeval */ |
| 56 | #include <linux/slab.h> | ||
| 56 | #include <net/ip.h> | 57 | #include <net/ip.h> |
| 57 | #include <net/icmp.h> | 58 | #include <net/icmp.h> |
| 58 | #include <net/snmp.h> | 59 | #include <net/snmp.h> |
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c index bbf5dd2a97c4..ccb6dc48d15b 100644 --- a/net/sctp/inqueue.c +++ b/net/sctp/inqueue.c | |||
| @@ -46,6 +46,7 @@ | |||
| 46 | #include <net/sctp/sctp.h> | 46 | #include <net/sctp/sctp.h> |
| 47 | #include <net/sctp/sm.h> | 47 | #include <net/sctp/sm.h> |
| 48 | #include <linux/interrupt.h> | 48 | #include <linux/interrupt.h> |
| 49 | #include <linux/slab.h> | ||
| 49 | 50 | ||
| 50 | /* Initialize an SCTP inqueue. */ | 51 | /* Initialize an SCTP inqueue. */ |
| 51 | void sctp_inq_init(struct sctp_inq *queue) | 52 | void sctp_inq_init(struct sctp_inq *queue) |
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 1d7ac70ba39f..9fb5d37c37ad 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
| @@ -58,6 +58,7 @@ | |||
| 58 | #include <linux/netdevice.h> | 58 | #include <linux/netdevice.h> |
| 59 | #include <linux/init.h> | 59 | #include <linux/init.h> |
| 60 | #include <linux/ipsec.h> | 60 | #include <linux/ipsec.h> |
| 61 | #include <linux/slab.h> | ||
| 61 | 62 | ||
| 62 | #include <linux/ipv6.h> | 63 | #include <linux/ipv6.h> |
| 63 | #include <linux/icmpv6.h> | 64 | #include <linux/icmpv6.h> |
diff --git a/net/sctp/output.c b/net/sctp/output.c index 7c5589363433..fad261d41ec2 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
| @@ -48,6 +48,7 @@ | |||
| 48 | #include <linux/ip.h> | 48 | #include <linux/ip.h> |
| 49 | #include <linux/ipv6.h> | 49 | #include <linux/ipv6.h> |
| 50 | #include <linux/init.h> | 50 | #include <linux/init.h> |
| 51 | #include <linux/slab.h> | ||
| 51 | #include <net/inet_ecn.h> | 52 | #include <net/inet_ecn.h> |
| 52 | #include <net/ip.h> | 53 | #include <net/ip.h> |
| 53 | #include <net/icmp.h> | 54 | #include <net/icmp.h> |
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 229690f02a1d..abfc0b8dee74 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
| @@ -50,6 +50,7 @@ | |||
| 50 | #include <linux/list.h> /* For struct list_head */ | 50 | #include <linux/list.h> /* For struct list_head */ |
| 51 | #include <linux/socket.h> | 51 | #include <linux/socket.h> |
| 52 | #include <linux/ip.h> | 52 | #include <linux/ip.h> |
| 53 | #include <linux/slab.h> | ||
| 53 | #include <net/sock.h> /* For skb_set_owner_w */ | 54 | #include <net/sock.h> /* For skb_set_owner_w */ |
| 54 | 55 | ||
| 55 | #include <net/sctp/sctp.h> | 56 | #include <net/sctp/sctp.h> |
diff --git a/net/sctp/primitive.c b/net/sctp/primitive.c index 8cb4f060bce6..534c7eae9d15 100644 --- a/net/sctp/primitive.c +++ b/net/sctp/primitive.c | |||
| @@ -50,6 +50,7 @@ | |||
| 50 | #include <linux/socket.h> | 50 | #include <linux/socket.h> |
| 51 | #include <linux/ip.h> | 51 | #include <linux/ip.h> |
| 52 | #include <linux/time.h> /* For struct timeval */ | 52 | #include <linux/time.h> /* For struct timeval */ |
| 53 | #include <linux/gfp.h> | ||
| 53 | #include <net/sock.h> | 54 | #include <net/sock.h> |
| 54 | #include <net/sctp/sctp.h> | 55 | #include <net/sctp/sctp.h> |
| 55 | #include <net/sctp/sm.h> | 56 | #include <net/sctp/sm.h> |
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index e771690f6d5d..a56f98e82f92 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
| @@ -54,6 +54,7 @@ | |||
| 54 | #include <linux/bootmem.h> | 54 | #include <linux/bootmem.h> |
| 55 | #include <linux/highmem.h> | 55 | #include <linux/highmem.h> |
| 56 | #include <linux/swap.h> | 56 | #include <linux/swap.h> |
| 57 | #include <linux/slab.h> | ||
| 57 | #include <net/net_namespace.h> | 58 | #include <net/net_namespace.h> |
| 58 | #include <net/protocol.h> | 59 | #include <net/protocol.h> |
| 59 | #include <net/ip.h> | 60 | #include <net/ip.h> |
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 9e732916b671..30c1767186b8 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
| @@ -58,6 +58,7 @@ | |||
| 58 | #include <linux/inet.h> | 58 | #include <linux/inet.h> |
| 59 | #include <linux/scatterlist.h> | 59 | #include <linux/scatterlist.h> |
| 60 | #include <linux/crypto.h> | 60 | #include <linux/crypto.h> |
| 61 | #include <linux/slab.h> | ||
| 61 | #include <net/sock.h> | 62 | #include <net/sock.h> |
| 62 | 63 | ||
| 63 | #include <linux/skbuff.h> | 64 | #include <linux/skbuff.h> |
| @@ -107,7 +108,7 @@ static const struct sctp_paramhdr prsctp_param = { | |||
| 107 | cpu_to_be16(sizeof(struct sctp_paramhdr)), | 108 | cpu_to_be16(sizeof(struct sctp_paramhdr)), |
| 108 | }; | 109 | }; |
| 109 | 110 | ||
| 110 | /* A helper to initialize to initialize an op error inside a | 111 | /* A helper to initialize an op error inside a |
| 111 | * provided chunk, as most cause codes will be embedded inside an | 112 | * provided chunk, as most cause codes will be embedded inside an |
| 112 | * abort chunk. | 113 | * abort chunk. |
| 113 | */ | 114 | */ |
| @@ -124,6 +125,29 @@ void sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code, | |||
| 124 | chunk->subh.err_hdr = sctp_addto_chunk(chunk, sizeof(sctp_errhdr_t), &err); | 125 | chunk->subh.err_hdr = sctp_addto_chunk(chunk, sizeof(sctp_errhdr_t), &err); |
| 125 | } | 126 | } |
| 126 | 127 | ||
| 128 | /* A helper to initialize an op error inside a | ||
| 129 | * provided chunk, as most cause codes will be embedded inside an | ||
| 130 | * abort chunk. Differs from sctp_init_cause in that it won't oops | ||
| 131 | * if there isn't enough space in the op error chunk | ||
| 132 | */ | ||
| 133 | int sctp_init_cause_fixed(struct sctp_chunk *chunk, __be16 cause_code, | ||
| 134 | size_t paylen) | ||
| 135 | { | ||
| 136 | sctp_errhdr_t err; | ||
| 137 | __u16 len; | ||
| 138 | |||
| 139 | /* Cause code constants are now defined in network order. */ | ||
| 140 | err.cause = cause_code; | ||
| 141 | len = sizeof(sctp_errhdr_t) + paylen; | ||
| 142 | err.length = htons(len); | ||
| 143 | |||
| 144 | if (skb_tailroom(chunk->skb) > len) | ||
| 145 | return -ENOSPC; | ||
| 146 | chunk->subh.err_hdr = sctp_addto_chunk_fixed(chunk, | ||
| 147 | sizeof(sctp_errhdr_t), | ||
| 148 | &err); | ||
| 149 | return 0; | ||
| 150 | } | ||
| 127 | /* 3.3.2 Initiation (INIT) (1) | 151 | /* 3.3.2 Initiation (INIT) (1) |
| 128 | * | 152 | * |
| 129 | * This chunk is used to initiate a SCTP association between two | 153 | * This chunk is used to initiate a SCTP association between two |
| @@ -207,7 +231,8 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, | |||
| 207 | sp = sctp_sk(asoc->base.sk); | 231 | sp = sctp_sk(asoc->base.sk); |
| 208 | num_types = sp->pf->supported_addrs(sp, types); | 232 | num_types = sp->pf->supported_addrs(sp, types); |
| 209 | 233 | ||
| 210 | chunksize = sizeof(init) + addrs_len + SCTP_SAT_LEN(num_types); | 234 | chunksize = sizeof(init) + addrs_len; |
| 235 | chunksize += WORD_ROUND(SCTP_SAT_LEN(num_types)); | ||
| 211 | chunksize += sizeof(ecap_param); | 236 | chunksize += sizeof(ecap_param); |
| 212 | 237 | ||
| 213 | if (sctp_prsctp_enable) | 238 | if (sctp_prsctp_enable) |
| @@ -237,14 +262,14 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, | |||
| 237 | /* Add HMACS parameter length if any were defined */ | 262 | /* Add HMACS parameter length if any were defined */ |
| 238 | auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs; | 263 | auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs; |
| 239 | if (auth_hmacs->length) | 264 | if (auth_hmacs->length) |
| 240 | chunksize += ntohs(auth_hmacs->length); | 265 | chunksize += WORD_ROUND(ntohs(auth_hmacs->length)); |
| 241 | else | 266 | else |
| 242 | auth_hmacs = NULL; | 267 | auth_hmacs = NULL; |
| 243 | 268 | ||
| 244 | /* Add CHUNKS parameter length */ | 269 | /* Add CHUNKS parameter length */ |
| 245 | auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks; | 270 | auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks; |
| 246 | if (auth_chunks->length) | 271 | if (auth_chunks->length) |
| 247 | chunksize += ntohs(auth_chunks->length); | 272 | chunksize += WORD_ROUND(ntohs(auth_chunks->length)); |
| 248 | else | 273 | else |
| 249 | auth_chunks = NULL; | 274 | auth_chunks = NULL; |
| 250 | 275 | ||
| @@ -254,7 +279,8 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, | |||
| 254 | 279 | ||
| 255 | /* If we have any extensions to report, account for that */ | 280 | /* If we have any extensions to report, account for that */ |
| 256 | if (num_ext) | 281 | if (num_ext) |
| 257 | chunksize += sizeof(sctp_supported_ext_param_t) + num_ext; | 282 | chunksize += WORD_ROUND(sizeof(sctp_supported_ext_param_t) + |
| 283 | num_ext); | ||
| 258 | 284 | ||
| 259 | /* RFC 2960 3.3.2 Initiation (INIT) (1) | 285 | /* RFC 2960 3.3.2 Initiation (INIT) (1) |
| 260 | * | 286 | * |
| @@ -396,13 +422,13 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, | |||
| 396 | 422 | ||
| 397 | auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs; | 423 | auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs; |
| 398 | if (auth_hmacs->length) | 424 | if (auth_hmacs->length) |
| 399 | chunksize += ntohs(auth_hmacs->length); | 425 | chunksize += WORD_ROUND(ntohs(auth_hmacs->length)); |
| 400 | else | 426 | else |
| 401 | auth_hmacs = NULL; | 427 | auth_hmacs = NULL; |
| 402 | 428 | ||
| 403 | auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks; | 429 | auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks; |
| 404 | if (auth_chunks->length) | 430 | if (auth_chunks->length) |
| 405 | chunksize += ntohs(auth_chunks->length); | 431 | chunksize += WORD_ROUND(ntohs(auth_chunks->length)); |
| 406 | else | 432 | else |
| 407 | auth_chunks = NULL; | 433 | auth_chunks = NULL; |
| 408 | 434 | ||
| @@ -411,7 +437,8 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, | |||
| 411 | } | 437 | } |
| 412 | 438 | ||
| 413 | if (num_ext) | 439 | if (num_ext) |
| 414 | chunksize += sizeof(sctp_supported_ext_param_t) + num_ext; | 440 | chunksize += WORD_ROUND(sizeof(sctp_supported_ext_param_t) + |
| 441 | num_ext); | ||
| 415 | 442 | ||
| 416 | /* Now allocate and fill out the chunk. */ | 443 | /* Now allocate and fill out the chunk. */ |
| 417 | retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize); | 444 | retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize); |
| @@ -1128,6 +1155,24 @@ nodata: | |||
| 1128 | return retval; | 1155 | return retval; |
| 1129 | } | 1156 | } |
| 1130 | 1157 | ||
| 1158 | /* Create an Operation Error chunk of a fixed size, | ||
| 1159 | * specifically, max(asoc->pathmtu, SCTP_DEFAULT_MAXSEGMENT) | ||
| 1160 | * This is a helper function to allocate an error chunk for | ||
| 1161 | * for those invalid parameter codes in which we may not want | ||
| 1162 | * to report all the errors, if the incomming chunk is large | ||
| 1163 | */ | ||
| 1164 | static inline struct sctp_chunk *sctp_make_op_error_fixed( | ||
| 1165 | const struct sctp_association *asoc, | ||
| 1166 | const struct sctp_chunk *chunk) | ||
| 1167 | { | ||
| 1168 | size_t size = asoc ? asoc->pathmtu : 0; | ||
| 1169 | |||
| 1170 | if (!size) | ||
| 1171 | size = SCTP_DEFAULT_MAXSEGMENT; | ||
| 1172 | |||
| 1173 | return sctp_make_op_error_space(asoc, chunk, size); | ||
| 1174 | } | ||
| 1175 | |||
| 1131 | /* Create an Operation Error chunk. */ | 1176 | /* Create an Operation Error chunk. */ |
| 1132 | struct sctp_chunk *sctp_make_op_error(const struct sctp_association *asoc, | 1177 | struct sctp_chunk *sctp_make_op_error(const struct sctp_association *asoc, |
| 1133 | const struct sctp_chunk *chunk, | 1178 | const struct sctp_chunk *chunk, |
| @@ -1370,6 +1415,18 @@ void *sctp_addto_chunk(struct sctp_chunk *chunk, int len, const void *data) | |||
| 1370 | return target; | 1415 | return target; |
| 1371 | } | 1416 | } |
| 1372 | 1417 | ||
| 1418 | /* Append bytes to the end of a chunk. Returns NULL if there isn't sufficient | ||
| 1419 | * space in the chunk | ||
| 1420 | */ | ||
| 1421 | void *sctp_addto_chunk_fixed(struct sctp_chunk *chunk, | ||
| 1422 | int len, const void *data) | ||
| 1423 | { | ||
| 1424 | if (skb_tailroom(chunk->skb) > len) | ||
| 1425 | return sctp_addto_chunk(chunk, len, data); | ||
| 1426 | else | ||
| 1427 | return NULL; | ||
| 1428 | } | ||
| 1429 | |||
| 1373 | /* Append bytes from user space to the end of a chunk. Will panic if | 1430 | /* Append bytes from user space to the end of a chunk. Will panic if |
| 1374 | * chunk is not big enough. | 1431 | * chunk is not big enough. |
| 1375 | * Returns a kernel err value. | 1432 | * Returns a kernel err value. |
| @@ -1973,13 +2030,12 @@ static sctp_ierror_t sctp_process_unk_param(const struct sctp_association *asoc, | |||
| 1973 | * returning multiple unknown parameters. | 2030 | * returning multiple unknown parameters. |
| 1974 | */ | 2031 | */ |
| 1975 | if (NULL == *errp) | 2032 | if (NULL == *errp) |
| 1976 | *errp = sctp_make_op_error_space(asoc, chunk, | 2033 | *errp = sctp_make_op_error_fixed(asoc, chunk); |
| 1977 | ntohs(chunk->chunk_hdr->length)); | ||
| 1978 | 2034 | ||
| 1979 | if (*errp) { | 2035 | if (*errp) { |
| 1980 | sctp_init_cause(*errp, SCTP_ERROR_UNKNOWN_PARAM, | 2036 | sctp_init_cause_fixed(*errp, SCTP_ERROR_UNKNOWN_PARAM, |
| 1981 | WORD_ROUND(ntohs(param.p->length))); | 2037 | WORD_ROUND(ntohs(param.p->length))); |
| 1982 | sctp_addto_chunk(*errp, | 2038 | sctp_addto_chunk_fixed(*errp, |
| 1983 | WORD_ROUND(ntohs(param.p->length)), | 2039 | WORD_ROUND(ntohs(param.p->length)), |
| 1984 | param.v); | 2040 | param.v); |
| 1985 | } else { | 2041 | } else { |
| @@ -3314,21 +3370,6 @@ int sctp_process_asconf_ack(struct sctp_association *asoc, | |||
| 3314 | sctp_chunk_free(asconf); | 3370 | sctp_chunk_free(asconf); |
| 3315 | asoc->addip_last_asconf = NULL; | 3371 | asoc->addip_last_asconf = NULL; |
| 3316 | 3372 | ||
| 3317 | /* Send the next asconf chunk from the addip chunk queue. */ | ||
| 3318 | if (!list_empty(&asoc->addip_chunk_list)) { | ||
| 3319 | struct list_head *entry = asoc->addip_chunk_list.next; | ||
| 3320 | asconf = list_entry(entry, struct sctp_chunk, list); | ||
| 3321 | |||
| 3322 | list_del_init(entry); | ||
| 3323 | |||
| 3324 | /* Hold the chunk until an ASCONF_ACK is received. */ | ||
| 3325 | sctp_chunk_hold(asconf); | ||
| 3326 | if (sctp_primitive_ASCONF(asoc, asconf)) | ||
| 3327 | sctp_chunk_free(asconf); | ||
| 3328 | else | ||
| 3329 | asoc->addip_last_asconf = asconf; | ||
| 3330 | } | ||
| 3331 | |||
| 3332 | return retval; | 3373 | return retval; |
| 3333 | } | 3374 | } |
| 3334 | 3375 | ||
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 500886bda9b4..d5ae450b6f02 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
| @@ -51,6 +51,7 @@ | |||
| 51 | #include <linux/types.h> | 51 | #include <linux/types.h> |
| 52 | #include <linux/socket.h> | 52 | #include <linux/socket.h> |
| 53 | #include <linux/ip.h> | 53 | #include <linux/ip.h> |
| 54 | #include <linux/gfp.h> | ||
| 54 | #include <net/sock.h> | 55 | #include <net/sock.h> |
| 55 | #include <net/sctp/sctp.h> | 56 | #include <net/sctp/sctp.h> |
| 56 | #include <net/sctp/sm.h> | 57 | #include <net/sctp/sm.h> |
| @@ -961,6 +962,29 @@ static int sctp_cmd_send_msg(struct sctp_association *asoc, | |||
| 961 | } | 962 | } |
| 962 | 963 | ||
| 963 | 964 | ||
| 965 | /* Sent the next ASCONF packet currently stored in the association. | ||
| 966 | * This happens after the ASCONF_ACK was succeffully processed. | ||
| 967 | */ | ||
| 968 | static void sctp_cmd_send_asconf(struct sctp_association *asoc) | ||
| 969 | { | ||
| 970 | /* Send the next asconf chunk from the addip chunk | ||
| 971 | * queue. | ||
| 972 | */ | ||
| 973 | if (!list_empty(&asoc->addip_chunk_list)) { | ||
| 974 | struct list_head *entry = asoc->addip_chunk_list.next; | ||
| 975 | struct sctp_chunk *asconf = list_entry(entry, | ||
| 976 | struct sctp_chunk, list); | ||
| 977 | list_del_init(entry); | ||
| 978 | |||
| 979 | /* Hold the chunk until an ASCONF_ACK is received. */ | ||
| 980 | sctp_chunk_hold(asconf); | ||
| 981 | if (sctp_primitive_ASCONF(asoc, asconf)) | ||
| 982 | sctp_chunk_free(asconf); | ||
| 983 | else | ||
| 984 | asoc->addip_last_asconf = asconf; | ||
| 985 | } | ||
| 986 | } | ||
| 987 | |||
| 964 | 988 | ||
| 965 | /* These three macros allow us to pull the debugging code out of the | 989 | /* These three macros allow us to pull the debugging code out of the |
| 966 | * main flow of sctp_do_sm() to keep attention focused on the real | 990 | * main flow of sctp_do_sm() to keep attention focused on the real |
| @@ -1616,6 +1640,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
| 1616 | } | 1640 | } |
| 1617 | error = sctp_cmd_send_msg(asoc, cmd->obj.msg); | 1641 | error = sctp_cmd_send_msg(asoc, cmd->obj.msg); |
| 1618 | break; | 1642 | break; |
| 1643 | case SCTP_CMD_SEND_NEXT_ASCONF: | ||
| 1644 | sctp_cmd_send_asconf(asoc); | ||
| 1645 | break; | ||
| 1619 | default: | 1646 | default: |
| 1620 | printk(KERN_WARNING "Impossible command: %u, %p\n", | 1647 | printk(KERN_WARNING "Impossible command: %u, %p\n", |
| 1621 | cmd->verb, cmd->obj.ptr); | 1648 | cmd->verb, cmd->obj.ptr); |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 47bc20d3a85b..24b2cd555637 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
| @@ -56,6 +56,7 @@ | |||
| 56 | #include <linux/ipv6.h> | 56 | #include <linux/ipv6.h> |
| 57 | #include <linux/net.h> | 57 | #include <linux/net.h> |
| 58 | #include <linux/inet.h> | 58 | #include <linux/inet.h> |
| 59 | #include <linux/slab.h> | ||
| 59 | #include <net/sock.h> | 60 | #include <net/sock.h> |
| 60 | #include <net/inet_ecn.h> | 61 | #include <net/inet_ecn.h> |
| 61 | #include <linux/skbuff.h> | 62 | #include <linux/skbuff.h> |
| @@ -3675,8 +3676,14 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep, | |||
| 3675 | SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); | 3676 | SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); |
| 3676 | 3677 | ||
| 3677 | if (!sctp_process_asconf_ack((struct sctp_association *)asoc, | 3678 | if (!sctp_process_asconf_ack((struct sctp_association *)asoc, |
| 3678 | asconf_ack)) | 3679 | asconf_ack)) { |
| 3680 | /* Successfully processed ASCONF_ACK. We can | ||
| 3681 | * release the next asconf if we have one. | ||
| 3682 | */ | ||
| 3683 | sctp_add_cmd_sf(commands, SCTP_CMD_SEND_NEXT_ASCONF, | ||
| 3684 | SCTP_NULL()); | ||
| 3679 | return SCTP_DISPOSITION_CONSUME; | 3685 | return SCTP_DISPOSITION_CONSUME; |
| 3686 | } | ||
| 3680 | 3687 | ||
| 3681 | abort = sctp_make_abort(asoc, asconf_ack, | 3688 | abort = sctp_make_abort(asoc, asconf_ack, |
| 3682 | sizeof(sctp_errhdr_t)); | 3689 | sizeof(sctp_errhdr_t)); |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index dfc5c127efd4..44a1ab03a3f0 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
| @@ -67,6 +67,7 @@ | |||
| 67 | #include <linux/poll.h> | 67 | #include <linux/poll.h> |
| 68 | #include <linux/init.h> | 68 | #include <linux/init.h> |
| 69 | #include <linux/crypto.h> | 69 | #include <linux/crypto.h> |
| 70 | #include <linux/slab.h> | ||
| 70 | 71 | ||
| 71 | #include <net/ip.h> | 72 | #include <net/ip.h> |
| 72 | #include <net/icmp.h> | 73 | #include <net/icmp.h> |
| @@ -3718,12 +3719,12 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
| 3718 | sp->hmac = NULL; | 3719 | sp->hmac = NULL; |
| 3719 | 3720 | ||
| 3720 | SCTP_DBG_OBJCNT_INC(sock); | 3721 | SCTP_DBG_OBJCNT_INC(sock); |
| 3721 | percpu_counter_inc(&sctp_sockets_allocated); | ||
| 3722 | 3722 | ||
| 3723 | /* Set socket backlog limit. */ | 3723 | /* Set socket backlog limit. */ |
| 3724 | sk->sk_backlog.limit = sysctl_sctp_rmem[1]; | 3724 | sk->sk_backlog.limit = sysctl_sctp_rmem[1]; |
| 3725 | 3725 | ||
| 3726 | local_bh_disable(); | 3726 | local_bh_disable(); |
| 3727 | percpu_counter_inc(&sctp_sockets_allocated); | ||
| 3727 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); | 3728 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); |
| 3728 | local_bh_enable(); | 3729 | local_bh_enable(); |
| 3729 | 3730 | ||
| @@ -3740,8 +3741,8 @@ SCTP_STATIC void sctp_destroy_sock(struct sock *sk) | |||
| 3740 | /* Release our hold on the endpoint. */ | 3741 | /* Release our hold on the endpoint. */ |
| 3741 | ep = sctp_sk(sk)->ep; | 3742 | ep = sctp_sk(sk)->ep; |
| 3742 | sctp_endpoint_free(ep); | 3743 | sctp_endpoint_free(ep); |
| 3743 | percpu_counter_dec(&sctp_sockets_allocated); | ||
| 3744 | local_bh_disable(); | 3744 | local_bh_disable(); |
| 3745 | percpu_counter_dec(&sctp_sockets_allocated); | ||
| 3745 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); | 3746 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); |
| 3746 | local_bh_enable(); | 3747 | local_bh_enable(); |
| 3747 | } | 3748 | } |
| @@ -6188,6 +6189,16 @@ do_nonblock: | |||
| 6188 | goto out; | 6189 | goto out; |
| 6189 | } | 6190 | } |
| 6190 | 6191 | ||
| 6192 | void sctp_data_ready(struct sock *sk, int len) | ||
| 6193 | { | ||
| 6194 | read_lock_bh(&sk->sk_callback_lock); | ||
| 6195 | if (sk_has_sleeper(sk)) | ||
| 6196 | wake_up_interruptible_sync_poll(sk->sk_sleep, POLLIN | | ||
| 6197 | POLLRDNORM | POLLRDBAND); | ||
| 6198 | sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN); | ||
| 6199 | read_unlock_bh(&sk->sk_callback_lock); | ||
| 6200 | } | ||
| 6201 | |||
| 6191 | /* If socket sndbuf has changed, wake up all per association waiters. */ | 6202 | /* If socket sndbuf has changed, wake up all per association waiters. */ |
| 6192 | void sctp_write_space(struct sock *sk) | 6203 | void sctp_write_space(struct sock *sk) |
| 6193 | { | 6204 | { |
diff --git a/net/sctp/ssnmap.c b/net/sctp/ssnmap.c index 737d330e5ffc..442ad4ed6315 100644 --- a/net/sctp/ssnmap.c +++ b/net/sctp/ssnmap.c | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | */ | 37 | */ |
| 38 | 38 | ||
| 39 | #include <linux/types.h> | 39 | #include <linux/types.h> |
| 40 | #include <linux/slab.h> | ||
| 40 | #include <net/sctp/sctp.h> | 41 | #include <net/sctp/sctp.h> |
| 41 | #include <net/sctp/sm.h> | 42 | #include <net/sctp/sm.h> |
| 42 | 43 | ||
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index b827d21dbe54..be4d63d5a5cc 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
| @@ -48,6 +48,7 @@ | |||
| 48 | * be incorporated into the next SCTP release. | 48 | * be incorporated into the next SCTP release. |
| 49 | */ | 49 | */ |
| 50 | 50 | ||
| 51 | #include <linux/slab.h> | ||
| 51 | #include <linux/types.h> | 52 | #include <linux/types.h> |
| 52 | #include <linux/random.h> | 53 | #include <linux/random.h> |
| 53 | #include <net/sctp/sctp.h> | 54 | #include <net/sctp/sctp.h> |
diff --git a/net/sctp/tsnmap.c b/net/sctp/tsnmap.c index 9bd64565021a..747d5412c463 100644 --- a/net/sctp/tsnmap.c +++ b/net/sctp/tsnmap.c | |||
| @@ -42,6 +42,7 @@ | |||
| 42 | * be incorporated into the next SCTP release. | 42 | * be incorporated into the next SCTP release. |
| 43 | */ | 43 | */ |
| 44 | 44 | ||
| 45 | #include <linux/slab.h> | ||
| 45 | #include <linux/types.h> | 46 | #include <linux/types.h> |
| 46 | #include <linux/bitmap.h> | 47 | #include <linux/bitmap.h> |
| 47 | #include <net/sctp/sctp.h> | 48 | #include <net/sctp/sctp.h> |
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index 8b3560fd876d..aa72e89c3ee1 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c | |||
| @@ -43,6 +43,7 @@ | |||
| 43 | * be incorporated into the next SCTP release. | 43 | * be incorporated into the next SCTP release. |
| 44 | */ | 44 | */ |
| 45 | 45 | ||
| 46 | #include <linux/slab.h> | ||
| 46 | #include <linux/types.h> | 47 | #include <linux/types.h> |
| 47 | #include <linux/skbuff.h> | 48 | #include <linux/skbuff.h> |
| 48 | #include <net/sctp/structs.h> | 49 | #include <net/sctp/structs.h> |
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c index 7b23803343cc..3a448536f0b6 100644 --- a/net/sctp/ulpqueue.c +++ b/net/sctp/ulpqueue.c | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | * be incorporated into the next SCTP release. | 41 | * be incorporated into the next SCTP release. |
| 42 | */ | 42 | */ |
| 43 | 43 | ||
| 44 | #include <linux/slab.h> | ||
| 44 | #include <linux/types.h> | 45 | #include <linux/types.h> |
| 45 | #include <linux/skbuff.h> | 46 | #include <linux/skbuff.h> |
| 46 | #include <net/sock.h> | 47 | #include <net/sock.h> |
