diff options
-rw-r--r-- | include/net/sctp/structs.h | 3 | ||||
-rw-r--r-- | net/sctp/associola.c | 13 | ||||
-rw-r--r-- | net/sctp/chunk.c | 4 | ||||
-rw-r--r-- | net/sctp/outqueue.c | 10 | ||||
-rw-r--r-- | net/sctp/proc.c | 4 | ||||
-rw-r--r-- | net/sctp/sm_make_chunk.c | 2 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 8 | ||||
-rw-r--r-- | net/sctp/socket.c | 14 | ||||
-rw-r--r-- | net/sctp/stream.c | 68 | ||||
-rw-r--r-- | net/sctp/ulpqueue.c | 8 |
10 files changed, 65 insertions, 69 deletions
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index a8b38e123f97..c8dbf410c4f5 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -381,6 +381,7 @@ int sctp_stream_new(struct sctp_association *asoc, gfp_t gfp); | |||
381 | int sctp_stream_init(struct sctp_association *asoc, gfp_t gfp); | 381 | int sctp_stream_init(struct sctp_association *asoc, gfp_t gfp); |
382 | void sctp_stream_free(struct sctp_stream *stream); | 382 | void sctp_stream_free(struct sctp_stream *stream); |
383 | void sctp_stream_clear(struct sctp_stream *stream); | 383 | void sctp_stream_clear(struct sctp_stream *stream); |
384 | void sctp_stream_update(struct sctp_stream *stream, struct sctp_stream *new); | ||
384 | 385 | ||
385 | /* What is the current SSN number for this stream? */ | 386 | /* What is the current SSN number for this stream? */ |
386 | #define sctp_ssn_peek(stream, type, sid) \ | 387 | #define sctp_ssn_peek(stream, type, sid) \ |
@@ -1750,7 +1751,7 @@ struct sctp_association { | |||
1750 | __u32 default_rcv_context; | 1751 | __u32 default_rcv_context; |
1751 | 1752 | ||
1752 | /* Stream arrays */ | 1753 | /* Stream arrays */ |
1753 | struct sctp_stream *stream; | 1754 | struct sctp_stream stream; |
1754 | 1755 | ||
1755 | /* All outbound chunks go through this structure. */ | 1756 | /* All outbound chunks go through this structure. */ |
1756 | struct sctp_outq outqueue; | 1757 | struct sctp_outq outqueue; |
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 95238284c422..6625b15ab81a 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -291,7 +291,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
291 | return asoc; | 291 | return asoc; |
292 | 292 | ||
293 | stream_free: | 293 | stream_free: |
294 | sctp_stream_free(asoc->stream); | 294 | sctp_stream_free(&asoc->stream); |
295 | fail_init: | 295 | fail_init: |
296 | sock_put(asoc->base.sk); | 296 | sock_put(asoc->base.sk); |
297 | sctp_endpoint_put(asoc->ep); | 297 | sctp_endpoint_put(asoc->ep); |
@@ -365,7 +365,7 @@ void sctp_association_free(struct sctp_association *asoc) | |||
365 | sctp_tsnmap_free(&asoc->peer.tsn_map); | 365 | sctp_tsnmap_free(&asoc->peer.tsn_map); |
366 | 366 | ||
367 | /* Free stream information. */ | 367 | /* Free stream information. */ |
368 | sctp_stream_free(asoc->stream); | 368 | sctp_stream_free(&asoc->stream); |
369 | 369 | ||
370 | if (asoc->strreset_chunk) | 370 | if (asoc->strreset_chunk) |
371 | sctp_chunk_free(asoc->strreset_chunk); | 371 | sctp_chunk_free(asoc->strreset_chunk); |
@@ -1151,7 +1151,7 @@ void sctp_assoc_update(struct sctp_association *asoc, | |||
1151 | /* Reinitialize SSN for both local streams | 1151 | /* Reinitialize SSN for both local streams |
1152 | * and peer's streams. | 1152 | * and peer's streams. |
1153 | */ | 1153 | */ |
1154 | sctp_stream_clear(asoc->stream); | 1154 | sctp_stream_clear(&asoc->stream); |
1155 | 1155 | ||
1156 | /* Flush the ULP reassembly and ordered queue. | 1156 | /* Flush the ULP reassembly and ordered queue. |
1157 | * Any data there will now be stale and will | 1157 | * Any data there will now be stale and will |
@@ -1177,11 +1177,8 @@ void sctp_assoc_update(struct sctp_association *asoc, | |||
1177 | asoc->ctsn_ack_point = asoc->next_tsn - 1; | 1177 | asoc->ctsn_ack_point = asoc->next_tsn - 1; |
1178 | asoc->adv_peer_ack_point = asoc->ctsn_ack_point; | 1178 | asoc->adv_peer_ack_point = asoc->ctsn_ack_point; |
1179 | 1179 | ||
1180 | if (sctp_state(asoc, COOKIE_WAIT)) { | 1180 | if (sctp_state(asoc, COOKIE_WAIT)) |
1181 | sctp_stream_free(asoc->stream); | 1181 | sctp_stream_update(&asoc->stream, &new->stream); |
1182 | asoc->stream = new->stream; | ||
1183 | new->stream = NULL; | ||
1184 | } | ||
1185 | 1182 | ||
1186 | if (!asoc->assoc_id) { | 1183 | if (!asoc->assoc_id) { |
1187 | /* get a new association id since we don't have one | 1184 | /* get a new association id since we don't have one |
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c index 697721a7a3f1..81466f6442e8 100644 --- a/net/sctp/chunk.c +++ b/net/sctp/chunk.c | |||
@@ -307,7 +307,7 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk) | |||
307 | if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) && | 307 | if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) && |
308 | time_after(jiffies, chunk->msg->expires_at)) { | 308 | time_after(jiffies, chunk->msg->expires_at)) { |
309 | struct sctp_stream_out *streamout = | 309 | struct sctp_stream_out *streamout = |
310 | &chunk->asoc->stream->out[chunk->sinfo.sinfo_stream]; | 310 | &chunk->asoc->stream.out[chunk->sinfo.sinfo_stream]; |
311 | 311 | ||
312 | if (chunk->sent_count) { | 312 | if (chunk->sent_count) { |
313 | chunk->asoc->abandoned_sent[SCTP_PR_INDEX(TTL)]++; | 313 | chunk->asoc->abandoned_sent[SCTP_PR_INDEX(TTL)]++; |
@@ -320,7 +320,7 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk) | |||
320 | } else if (SCTP_PR_RTX_ENABLED(chunk->sinfo.sinfo_flags) && | 320 | } else if (SCTP_PR_RTX_ENABLED(chunk->sinfo.sinfo_flags) && |
321 | chunk->sent_count > chunk->sinfo.sinfo_timetolive) { | 321 | chunk->sent_count > chunk->sinfo.sinfo_timetolive) { |
322 | struct sctp_stream_out *streamout = | 322 | struct sctp_stream_out *streamout = |
323 | &chunk->asoc->stream->out[chunk->sinfo.sinfo_stream]; | 323 | &chunk->asoc->stream.out[chunk->sinfo.sinfo_stream]; |
324 | 324 | ||
325 | chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++; | 325 | chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++; |
326 | streamout->abandoned_sent[SCTP_PR_INDEX(RTX)]++; | 326 | streamout->abandoned_sent[SCTP_PR_INDEX(RTX)]++; |
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index fe4c3d462f6e..20299df163b9 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -363,7 +363,7 @@ static int sctp_prsctp_prune_sent(struct sctp_association *asoc, | |||
363 | sctp_insert_list(&asoc->outqueue.abandoned, | 363 | sctp_insert_list(&asoc->outqueue.abandoned, |
364 | &chk->transmitted_list); | 364 | &chk->transmitted_list); |
365 | 365 | ||
366 | streamout = &asoc->stream->out[chk->sinfo.sinfo_stream]; | 366 | streamout = &asoc->stream.out[chk->sinfo.sinfo_stream]; |
367 | asoc->sent_cnt_removable--; | 367 | asoc->sent_cnt_removable--; |
368 | asoc->abandoned_sent[SCTP_PR_INDEX(PRIO)]++; | 368 | asoc->abandoned_sent[SCTP_PR_INDEX(PRIO)]++; |
369 | streamout->abandoned_sent[SCTP_PR_INDEX(PRIO)]++; | 369 | streamout->abandoned_sent[SCTP_PR_INDEX(PRIO)]++; |
@@ -400,9 +400,9 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc, | |||
400 | q->out_qlen -= chk->skb->len; | 400 | q->out_qlen -= chk->skb->len; |
401 | asoc->sent_cnt_removable--; | 401 | asoc->sent_cnt_removable--; |
402 | asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++; | 402 | asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++; |
403 | if (chk->sinfo.sinfo_stream < asoc->stream->outcnt) { | 403 | if (chk->sinfo.sinfo_stream < asoc->stream.outcnt) { |
404 | struct sctp_stream_out *streamout = | 404 | struct sctp_stream_out *streamout = |
405 | &asoc->stream->out[chk->sinfo.sinfo_stream]; | 405 | &asoc->stream.out[chk->sinfo.sinfo_stream]; |
406 | 406 | ||
407 | streamout->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++; | 407 | streamout->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++; |
408 | } | 408 | } |
@@ -1036,7 +1036,7 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) | |||
1036 | /* RFC 2960 6.5 Every DATA chunk MUST carry a valid | 1036 | /* RFC 2960 6.5 Every DATA chunk MUST carry a valid |
1037 | * stream identifier. | 1037 | * stream identifier. |
1038 | */ | 1038 | */ |
1039 | if (chunk->sinfo.sinfo_stream >= asoc->stream->outcnt) { | 1039 | if (chunk->sinfo.sinfo_stream >= asoc->stream.outcnt) { |
1040 | 1040 | ||
1041 | /* Mark as failed send. */ | 1041 | /* Mark as failed send. */ |
1042 | sctp_chunk_fail(chunk, SCTP_ERROR_INV_STRM); | 1042 | sctp_chunk_fail(chunk, SCTP_ERROR_INV_STRM); |
@@ -1054,7 +1054,7 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) | |||
1054 | continue; | 1054 | continue; |
1055 | } | 1055 | } |
1056 | 1056 | ||
1057 | if (asoc->stream->out[sid].state == SCTP_STREAM_CLOSED) { | 1057 | if (asoc->stream.out[sid].state == SCTP_STREAM_CLOSED) { |
1058 | sctp_outq_head_data(q, chunk); | 1058 | sctp_outq_head_data(q, chunk); |
1059 | goto sctp_flush_out; | 1059 | goto sctp_flush_out; |
1060 | } | 1060 | } |
diff --git a/net/sctp/proc.c b/net/sctp/proc.c index a0b29d43627f..5a27d0f03df5 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c | |||
@@ -361,8 +361,8 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v) | |||
361 | sctp_seq_dump_remote_addrs(seq, assoc); | 361 | sctp_seq_dump_remote_addrs(seq, assoc); |
362 | seq_printf(seq, "\t%8lu %5d %5d %4d %4d %4d %8d " | 362 | seq_printf(seq, "\t%8lu %5d %5d %4d %4d %4d %8d " |
363 | "%8d %8d %8d %8d", | 363 | "%8d %8d %8d %8d", |
364 | assoc->hbinterval, assoc->stream->incnt, | 364 | assoc->hbinterval, assoc->stream.incnt, |
365 | assoc->stream->outcnt, assoc->max_retrans, | 365 | assoc->stream.outcnt, assoc->max_retrans, |
366 | assoc->init_retries, assoc->shutdown_retries, | 366 | assoc->init_retries, assoc->shutdown_retries, |
367 | assoc->rtx_data_chunks, | 367 | assoc->rtx_data_chunks, |
368 | atomic_read(&sk->sk_wmem_alloc), | 368 | atomic_read(&sk->sk_wmem_alloc), |
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 92e332e17391..244181413bca 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
@@ -1544,7 +1544,7 @@ void sctp_chunk_assign_ssn(struct sctp_chunk *chunk) | |||
1544 | 1544 | ||
1545 | /* All fragments will be on the same stream */ | 1545 | /* All fragments will be on the same stream */ |
1546 | sid = ntohs(chunk->subh.data_hdr->stream); | 1546 | sid = ntohs(chunk->subh.data_hdr->stream); |
1547 | stream = chunk->asoc->stream; | 1547 | stream = &chunk->asoc->stream; |
1548 | 1548 | ||
1549 | /* Now assign the sequence number to the entire message. | 1549 | /* Now assign the sequence number to the entire message. |
1550 | * All fragments must have the same stream sequence number. | 1550 | * All fragments must have the same stream sequence number. |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index f863b5573e42..df73190da761 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -3958,7 +3958,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(struct net *net, | |||
3958 | 3958 | ||
3959 | /* Silently discard the chunk if stream-id is not valid */ | 3959 | /* Silently discard the chunk if stream-id is not valid */ |
3960 | sctp_walk_fwdtsn(skip, chunk) { | 3960 | sctp_walk_fwdtsn(skip, chunk) { |
3961 | if (ntohs(skip->stream) >= asoc->stream->incnt) | 3961 | if (ntohs(skip->stream) >= asoc->stream.incnt) |
3962 | goto discard_noforce; | 3962 | goto discard_noforce; |
3963 | } | 3963 | } |
3964 | 3964 | ||
@@ -4029,7 +4029,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_fast( | |||
4029 | 4029 | ||
4030 | /* Silently discard the chunk if stream-id is not valid */ | 4030 | /* Silently discard the chunk if stream-id is not valid */ |
4031 | sctp_walk_fwdtsn(skip, chunk) { | 4031 | sctp_walk_fwdtsn(skip, chunk) { |
4032 | if (ntohs(skip->stream) >= asoc->stream->incnt) | 4032 | if (ntohs(skip->stream) >= asoc->stream.incnt) |
4033 | goto gen_shutdown; | 4033 | goto gen_shutdown; |
4034 | } | 4034 | } |
4035 | 4035 | ||
@@ -6365,7 +6365,7 @@ static int sctp_eat_data(const struct sctp_association *asoc, | |||
6365 | * and discard the DATA chunk. | 6365 | * and discard the DATA chunk. |
6366 | */ | 6366 | */ |
6367 | sid = ntohs(data_hdr->stream); | 6367 | sid = ntohs(data_hdr->stream); |
6368 | if (sid >= asoc->stream->incnt) { | 6368 | if (sid >= asoc->stream.incnt) { |
6369 | /* Mark tsn as received even though we drop it */ | 6369 | /* Mark tsn as received even though we drop it */ |
6370 | sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn)); | 6370 | sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn)); |
6371 | 6371 | ||
@@ -6387,7 +6387,7 @@ static int sctp_eat_data(const struct sctp_association *asoc, | |||
6387 | * and is invalid. | 6387 | * and is invalid. |
6388 | */ | 6388 | */ |
6389 | ssn = ntohs(data_hdr->ssn); | 6389 | ssn = ntohs(data_hdr->ssn); |
6390 | if (ordered && SSN_lt(ssn, sctp_ssn_peek(asoc->stream, in, sid))) | 6390 | if (ordered && SSN_lt(ssn, sctp_ssn_peek(&asoc->stream, in, sid))) |
6391 | return SCTP_IERROR_PROTO_VIOLATION; | 6391 | return SCTP_IERROR_PROTO_VIOLATION; |
6392 | 6392 | ||
6393 | /* Send the data up to the user. Note: Schedule the | 6393 | /* Send the data up to the user. Note: Schedule the |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index f16c8d97b7f3..0822046e4f3f 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -1920,7 +1920,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len) | |||
1920 | } | 1920 | } |
1921 | 1921 | ||
1922 | /* Check for invalid stream. */ | 1922 | /* Check for invalid stream. */ |
1923 | if (sinfo->sinfo_stream >= asoc->stream->outcnt) { | 1923 | if (sinfo->sinfo_stream >= asoc->stream.outcnt) { |
1924 | err = -EINVAL; | 1924 | err = -EINVAL; |
1925 | goto out_free; | 1925 | goto out_free; |
1926 | } | 1926 | } |
@@ -4497,8 +4497,8 @@ int sctp_get_sctp_info(struct sock *sk, struct sctp_association *asoc, | |||
4497 | info->sctpi_rwnd = asoc->a_rwnd; | 4497 | info->sctpi_rwnd = asoc->a_rwnd; |
4498 | info->sctpi_unackdata = asoc->unack_data; | 4498 | info->sctpi_unackdata = asoc->unack_data; |
4499 | info->sctpi_penddata = sctp_tsnmap_pending(&asoc->peer.tsn_map); | 4499 | info->sctpi_penddata = sctp_tsnmap_pending(&asoc->peer.tsn_map); |
4500 | info->sctpi_instrms = asoc->stream->incnt; | 4500 | info->sctpi_instrms = asoc->stream.incnt; |
4501 | info->sctpi_outstrms = asoc->stream->outcnt; | 4501 | info->sctpi_outstrms = asoc->stream.outcnt; |
4502 | list_for_each(pos, &asoc->base.inqueue.in_chunk_list) | 4502 | list_for_each(pos, &asoc->base.inqueue.in_chunk_list) |
4503 | info->sctpi_inqueue++; | 4503 | info->sctpi_inqueue++; |
4504 | list_for_each(pos, &asoc->outqueue.out_chunk_list) | 4504 | list_for_each(pos, &asoc->outqueue.out_chunk_list) |
@@ -4727,8 +4727,8 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len, | |||
4727 | status.sstat_unackdata = asoc->unack_data; | 4727 | status.sstat_unackdata = asoc->unack_data; |
4728 | 4728 | ||
4729 | status.sstat_penddata = sctp_tsnmap_pending(&asoc->peer.tsn_map); | 4729 | status.sstat_penddata = sctp_tsnmap_pending(&asoc->peer.tsn_map); |
4730 | status.sstat_instrms = asoc->stream->incnt; | 4730 | status.sstat_instrms = asoc->stream.incnt; |
4731 | status.sstat_outstrms = asoc->stream->outcnt; | 4731 | status.sstat_outstrms = asoc->stream.outcnt; |
4732 | status.sstat_fragmentation_point = asoc->frag_point; | 4732 | status.sstat_fragmentation_point = asoc->frag_point; |
4733 | status.sstat_primary.spinfo_assoc_id = sctp_assoc2id(transport->asoc); | 4733 | status.sstat_primary.spinfo_assoc_id = sctp_assoc2id(transport->asoc); |
4734 | memcpy(&status.sstat_primary.spinfo_address, &transport->ipaddr, | 4734 | memcpy(&status.sstat_primary.spinfo_address, &transport->ipaddr, |
@@ -6600,10 +6600,10 @@ static int sctp_getsockopt_pr_streamstatus(struct sock *sk, int len, | |||
6600 | goto out; | 6600 | goto out; |
6601 | 6601 | ||
6602 | asoc = sctp_id2assoc(sk, params.sprstat_assoc_id); | 6602 | asoc = sctp_id2assoc(sk, params.sprstat_assoc_id); |
6603 | if (!asoc || params.sprstat_sid >= asoc->stream->outcnt) | 6603 | if (!asoc || params.sprstat_sid >= asoc->stream.outcnt) |
6604 | goto out; | 6604 | goto out; |
6605 | 6605 | ||
6606 | streamout = &asoc->stream->out[params.sprstat_sid]; | 6606 | streamout = &asoc->stream.out[params.sprstat_sid]; |
6607 | if (policy == SCTP_PR_SCTP_NONE) { | 6607 | if (policy == SCTP_PR_SCTP_NONE) { |
6608 | params.sprstat_abandoned_unsent = 0; | 6608 | params.sprstat_abandoned_unsent = 0; |
6609 | params.sprstat_abandoned_sent = 0; | 6609 | params.sprstat_abandoned_sent = 0; |
diff --git a/net/sctp/stream.c b/net/sctp/stream.c index dda53a293986..af6b49850344 100644 --- a/net/sctp/stream.c +++ b/net/sctp/stream.c | |||
@@ -37,30 +37,23 @@ | |||
37 | 37 | ||
38 | int sctp_stream_new(struct sctp_association *asoc, gfp_t gfp) | 38 | int sctp_stream_new(struct sctp_association *asoc, gfp_t gfp) |
39 | { | 39 | { |
40 | struct sctp_stream *stream; | 40 | struct sctp_stream *stream = &asoc->stream; |
41 | int i; | 41 | int i; |
42 | 42 | ||
43 | stream = kzalloc(sizeof(*stream), gfp); | ||
44 | if (!stream) | ||
45 | return -ENOMEM; | ||
46 | |||
47 | stream->outcnt = asoc->c.sinit_num_ostreams; | 43 | stream->outcnt = asoc->c.sinit_num_ostreams; |
48 | stream->out = kcalloc(stream->outcnt, sizeof(*stream->out), gfp); | 44 | stream->out = kcalloc(stream->outcnt, sizeof(*stream->out), gfp); |
49 | if (!stream->out) { | 45 | if (!stream->out) |
50 | kfree(stream); | ||
51 | return -ENOMEM; | 46 | return -ENOMEM; |
52 | } | 47 | |
53 | for (i = 0; i < stream->outcnt; i++) | 48 | for (i = 0; i < stream->outcnt; i++) |
54 | stream->out[i].state = SCTP_STREAM_OPEN; | 49 | stream->out[i].state = SCTP_STREAM_OPEN; |
55 | 50 | ||
56 | asoc->stream = stream; | ||
57 | |||
58 | return 0; | 51 | return 0; |
59 | } | 52 | } |
60 | 53 | ||
61 | int sctp_stream_init(struct sctp_association *asoc, gfp_t gfp) | 54 | int sctp_stream_init(struct sctp_association *asoc, gfp_t gfp) |
62 | { | 55 | { |
63 | struct sctp_stream *stream = asoc->stream; | 56 | struct sctp_stream *stream = &asoc->stream; |
64 | int i; | 57 | int i; |
65 | 58 | ||
66 | /* Initial stream->out size may be very big, so free it and alloc | 59 | /* Initial stream->out size may be very big, so free it and alloc |
@@ -70,7 +63,7 @@ int sctp_stream_init(struct sctp_association *asoc, gfp_t gfp) | |||
70 | stream->outcnt = asoc->c.sinit_num_ostreams; | 63 | stream->outcnt = asoc->c.sinit_num_ostreams; |
71 | stream->out = kcalloc(stream->outcnt, sizeof(*stream->out), gfp); | 64 | stream->out = kcalloc(stream->outcnt, sizeof(*stream->out), gfp); |
72 | if (!stream->out) | 65 | if (!stream->out) |
73 | goto nomem; | 66 | return -ENOMEM; |
74 | 67 | ||
75 | for (i = 0; i < stream->outcnt; i++) | 68 | for (i = 0; i < stream->outcnt; i++) |
76 | stream->out[i].state = SCTP_STREAM_OPEN; | 69 | stream->out[i].state = SCTP_STREAM_OPEN; |
@@ -79,26 +72,17 @@ int sctp_stream_init(struct sctp_association *asoc, gfp_t gfp) | |||
79 | stream->in = kcalloc(stream->incnt, sizeof(*stream->in), gfp); | 72 | stream->in = kcalloc(stream->incnt, sizeof(*stream->in), gfp); |
80 | if (!stream->in) { | 73 | if (!stream->in) { |
81 | kfree(stream->out); | 74 | kfree(stream->out); |
82 | goto nomem; | 75 | stream->out = NULL; |
76 | return -ENOMEM; | ||
83 | } | 77 | } |
84 | 78 | ||
85 | return 0; | 79 | return 0; |
86 | |||
87 | nomem: | ||
88 | asoc->stream = NULL; | ||
89 | kfree(stream); | ||
90 | |||
91 | return -ENOMEM; | ||
92 | } | 80 | } |
93 | 81 | ||
94 | void sctp_stream_free(struct sctp_stream *stream) | 82 | void sctp_stream_free(struct sctp_stream *stream) |
95 | { | 83 | { |
96 | if (unlikely(!stream)) | ||
97 | return; | ||
98 | |||
99 | kfree(stream->out); | 84 | kfree(stream->out); |
100 | kfree(stream->in); | 85 | kfree(stream->in); |
101 | kfree(stream); | ||
102 | } | 86 | } |
103 | 87 | ||
104 | void sctp_stream_clear(struct sctp_stream *stream) | 88 | void sctp_stream_clear(struct sctp_stream *stream) |
@@ -112,6 +96,19 @@ void sctp_stream_clear(struct sctp_stream *stream) | |||
112 | stream->in[i].ssn = 0; | 96 | stream->in[i].ssn = 0; |
113 | } | 97 | } |
114 | 98 | ||
99 | void sctp_stream_update(struct sctp_stream *stream, struct sctp_stream *new) | ||
100 | { | ||
101 | sctp_stream_free(stream); | ||
102 | |||
103 | stream->out = new->out; | ||
104 | stream->in = new->in; | ||
105 | stream->outcnt = new->outcnt; | ||
106 | stream->incnt = new->incnt; | ||
107 | |||
108 | new->out = NULL; | ||
109 | new->in = NULL; | ||
110 | } | ||
111 | |||
115 | static int sctp_send_reconf(struct sctp_association *asoc, | 112 | static int sctp_send_reconf(struct sctp_association *asoc, |
116 | struct sctp_chunk *chunk) | 113 | struct sctp_chunk *chunk) |
117 | { | 114 | { |
@@ -128,7 +125,7 @@ static int sctp_send_reconf(struct sctp_association *asoc, | |||
128 | int sctp_send_reset_streams(struct sctp_association *asoc, | 125 | int sctp_send_reset_streams(struct sctp_association *asoc, |
129 | struct sctp_reset_streams *params) | 126 | struct sctp_reset_streams *params) |
130 | { | 127 | { |
131 | struct sctp_stream *stream = asoc->stream; | 128 | struct sctp_stream *stream = &asoc->stream; |
132 | __u16 i, str_nums, *str_list; | 129 | __u16 i, str_nums, *str_list; |
133 | struct sctp_chunk *chunk; | 130 | struct sctp_chunk *chunk; |
134 | int retval = -EINVAL; | 131 | int retval = -EINVAL; |
@@ -214,6 +211,7 @@ out: | |||
214 | 211 | ||
215 | int sctp_send_reset_assoc(struct sctp_association *asoc) | 212 | int sctp_send_reset_assoc(struct sctp_association *asoc) |
216 | { | 213 | { |
214 | struct sctp_stream *stream = &asoc->stream; | ||
217 | struct sctp_chunk *chunk = NULL; | 215 | struct sctp_chunk *chunk = NULL; |
218 | int retval; | 216 | int retval; |
219 | __u16 i; | 217 | __u16 i; |
@@ -230,8 +228,8 @@ int sctp_send_reset_assoc(struct sctp_association *asoc) | |||
230 | return -ENOMEM; | 228 | return -ENOMEM; |
231 | 229 | ||
232 | /* Block further xmit of data until this request is completed */ | 230 | /* Block further xmit of data until this request is completed */ |
233 | for (i = 0; i < asoc->stream->outcnt; i++) | 231 | for (i = 0; i < stream->outcnt; i++) |
234 | asoc->stream->out[i].state = SCTP_STREAM_CLOSED; | 232 | stream->out[i].state = SCTP_STREAM_CLOSED; |
235 | 233 | ||
236 | asoc->strreset_chunk = chunk; | 234 | asoc->strreset_chunk = chunk; |
237 | sctp_chunk_hold(asoc->strreset_chunk); | 235 | sctp_chunk_hold(asoc->strreset_chunk); |
@@ -241,8 +239,8 @@ int sctp_send_reset_assoc(struct sctp_association *asoc) | |||
241 | sctp_chunk_put(asoc->strreset_chunk); | 239 | sctp_chunk_put(asoc->strreset_chunk); |
242 | asoc->strreset_chunk = NULL; | 240 | asoc->strreset_chunk = NULL; |
243 | 241 | ||
244 | for (i = 0; i < asoc->stream->outcnt; i++) | 242 | for (i = 0; i < stream->outcnt; i++) |
245 | asoc->stream->out[i].state = SCTP_STREAM_OPEN; | 243 | stream->out[i].state = SCTP_STREAM_OPEN; |
246 | 244 | ||
247 | return retval; | 245 | return retval; |
248 | } | 246 | } |
@@ -255,7 +253,7 @@ int sctp_send_reset_assoc(struct sctp_association *asoc) | |||
255 | int sctp_send_add_streams(struct sctp_association *asoc, | 253 | int sctp_send_add_streams(struct sctp_association *asoc, |
256 | struct sctp_add_streams *params) | 254 | struct sctp_add_streams *params) |
257 | { | 255 | { |
258 | struct sctp_stream *stream = asoc->stream; | 256 | struct sctp_stream *stream = &asoc->stream; |
259 | struct sctp_chunk *chunk = NULL; | 257 | struct sctp_chunk *chunk = NULL; |
260 | int retval = -ENOMEM; | 258 | int retval = -ENOMEM; |
261 | __u32 outcnt, incnt; | 259 | __u32 outcnt, incnt; |
@@ -357,7 +355,7 @@ struct sctp_chunk *sctp_process_strreset_outreq( | |||
357 | struct sctp_ulpevent **evp) | 355 | struct sctp_ulpevent **evp) |
358 | { | 356 | { |
359 | struct sctp_strreset_outreq *outreq = param.v; | 357 | struct sctp_strreset_outreq *outreq = param.v; |
360 | struct sctp_stream *stream = asoc->stream; | 358 | struct sctp_stream *stream = &asoc->stream; |
361 | __u16 i, nums, flags = 0, *str_p = NULL; | 359 | __u16 i, nums, flags = 0, *str_p = NULL; |
362 | __u32 result = SCTP_STRRESET_DENIED; | 360 | __u32 result = SCTP_STRRESET_DENIED; |
363 | __u32 request_seq; | 361 | __u32 request_seq; |
@@ -449,7 +447,7 @@ struct sctp_chunk *sctp_process_strreset_inreq( | |||
449 | struct sctp_ulpevent **evp) | 447 | struct sctp_ulpevent **evp) |
450 | { | 448 | { |
451 | struct sctp_strreset_inreq *inreq = param.v; | 449 | struct sctp_strreset_inreq *inreq = param.v; |
452 | struct sctp_stream *stream = asoc->stream; | 450 | struct sctp_stream *stream = &asoc->stream; |
453 | __u32 result = SCTP_STRRESET_DENIED; | 451 | __u32 result = SCTP_STRRESET_DENIED; |
454 | struct sctp_chunk *chunk = NULL; | 452 | struct sctp_chunk *chunk = NULL; |
455 | __u16 i, nums, *str_p; | 453 | __u16 i, nums, *str_p; |
@@ -523,7 +521,7 @@ struct sctp_chunk *sctp_process_strreset_tsnreq( | |||
523 | { | 521 | { |
524 | __u32 init_tsn = 0, next_tsn = 0, max_tsn_seen; | 522 | __u32 init_tsn = 0, next_tsn = 0, max_tsn_seen; |
525 | struct sctp_strreset_tsnreq *tsnreq = param.v; | 523 | struct sctp_strreset_tsnreq *tsnreq = param.v; |
526 | struct sctp_stream *stream = asoc->stream; | 524 | struct sctp_stream *stream = &asoc->stream; |
527 | __u32 result = SCTP_STRRESET_DENIED; | 525 | __u32 result = SCTP_STRRESET_DENIED; |
528 | __u32 request_seq; | 526 | __u32 request_seq; |
529 | __u16 i; | 527 | __u16 i; |
@@ -612,7 +610,7 @@ struct sctp_chunk *sctp_process_strreset_addstrm_out( | |||
612 | struct sctp_ulpevent **evp) | 610 | struct sctp_ulpevent **evp) |
613 | { | 611 | { |
614 | struct sctp_strreset_addstrm *addstrm = param.v; | 612 | struct sctp_strreset_addstrm *addstrm = param.v; |
615 | struct sctp_stream *stream = asoc->stream; | 613 | struct sctp_stream *stream = &asoc->stream; |
616 | __u32 result = SCTP_STRRESET_DENIED; | 614 | __u32 result = SCTP_STRRESET_DENIED; |
617 | struct sctp_stream_in *streamin; | 615 | struct sctp_stream_in *streamin; |
618 | __u32 request_seq, incnt; | 616 | __u32 request_seq, incnt; |
@@ -687,7 +685,7 @@ struct sctp_chunk *sctp_process_strreset_addstrm_in( | |||
687 | struct sctp_ulpevent **evp) | 685 | struct sctp_ulpevent **evp) |
688 | { | 686 | { |
689 | struct sctp_strreset_addstrm *addstrm = param.v; | 687 | struct sctp_strreset_addstrm *addstrm = param.v; |
690 | struct sctp_stream *stream = asoc->stream; | 688 | struct sctp_stream *stream = &asoc->stream; |
691 | __u32 result = SCTP_STRRESET_DENIED; | 689 | __u32 result = SCTP_STRRESET_DENIED; |
692 | struct sctp_stream_out *streamout; | 690 | struct sctp_stream_out *streamout; |
693 | struct sctp_chunk *chunk = NULL; | 691 | struct sctp_chunk *chunk = NULL; |
@@ -758,8 +756,8 @@ struct sctp_chunk *sctp_process_strreset_resp( | |||
758 | union sctp_params param, | 756 | union sctp_params param, |
759 | struct sctp_ulpevent **evp) | 757 | struct sctp_ulpevent **evp) |
760 | { | 758 | { |
759 | struct sctp_stream *stream = &asoc->stream; | ||
761 | struct sctp_strreset_resp *resp = param.v; | 760 | struct sctp_strreset_resp *resp = param.v; |
762 | struct sctp_stream *stream = asoc->stream; | ||
763 | struct sctp_transport *t; | 761 | struct sctp_transport *t; |
764 | __u16 i, nums, flags = 0; | 762 | __u16 i, nums, flags = 0; |
765 | sctp_paramhdr_t *req; | 763 | sctp_paramhdr_t *req; |
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c index aa3624d50278..25f7e4140566 100644 --- a/net/sctp/ulpqueue.c +++ b/net/sctp/ulpqueue.c | |||
@@ -764,7 +764,7 @@ static void sctp_ulpq_retrieve_ordered(struct sctp_ulpq *ulpq, | |||
764 | __u16 sid, csid, cssn; | 764 | __u16 sid, csid, cssn; |
765 | 765 | ||
766 | sid = event->stream; | 766 | sid = event->stream; |
767 | stream = ulpq->asoc->stream; | 767 | stream = &ulpq->asoc->stream; |
768 | 768 | ||
769 | event_list = (struct sk_buff_head *) sctp_event2skb(event)->prev; | 769 | event_list = (struct sk_buff_head *) sctp_event2skb(event)->prev; |
770 | 770 | ||
@@ -858,7 +858,7 @@ static struct sctp_ulpevent *sctp_ulpq_order(struct sctp_ulpq *ulpq, | |||
858 | /* Note: The stream ID must be verified before this routine. */ | 858 | /* Note: The stream ID must be verified before this routine. */ |
859 | sid = event->stream; | 859 | sid = event->stream; |
860 | ssn = event->ssn; | 860 | ssn = event->ssn; |
861 | stream = ulpq->asoc->stream; | 861 | stream = &ulpq->asoc->stream; |
862 | 862 | ||
863 | /* Is this the expected SSN for this stream ID? */ | 863 | /* Is this the expected SSN for this stream ID? */ |
864 | if (ssn != sctp_ssn_peek(stream, in, sid)) { | 864 | if (ssn != sctp_ssn_peek(stream, in, sid)) { |
@@ -893,7 +893,7 @@ static void sctp_ulpq_reap_ordered(struct sctp_ulpq *ulpq, __u16 sid) | |||
893 | struct sk_buff_head *lobby = &ulpq->lobby; | 893 | struct sk_buff_head *lobby = &ulpq->lobby; |
894 | __u16 csid, cssn; | 894 | __u16 csid, cssn; |
895 | 895 | ||
896 | stream = ulpq->asoc->stream; | 896 | stream = &ulpq->asoc->stream; |
897 | 897 | ||
898 | /* We are holding the chunks by stream, by SSN. */ | 898 | /* We are holding the chunks by stream, by SSN. */ |
899 | skb_queue_head_init(&temp); | 899 | skb_queue_head_init(&temp); |
@@ -958,7 +958,7 @@ void sctp_ulpq_skip(struct sctp_ulpq *ulpq, __u16 sid, __u16 ssn) | |||
958 | struct sctp_stream *stream; | 958 | struct sctp_stream *stream; |
959 | 959 | ||
960 | /* Note: The stream ID must be verified before this routine. */ | 960 | /* Note: The stream ID must be verified before this routine. */ |
961 | stream = ulpq->asoc->stream; | 961 | stream = &ulpq->asoc->stream; |
962 | 962 | ||
963 | /* Is this an old SSN? If so ignore. */ | 963 | /* Is this an old SSN? If so ignore. */ |
964 | if (SSN_lt(ssn, sctp_ssn_peek(stream, in, sid))) | 964 | if (SSN_lt(ssn, sctp_ssn_peek(stream, in, sid))) |