aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/associola.c13
-rw-r--r--net/sctp/input.c4
-rw-r--r--net/sctp/output.c69
-rw-r--r--net/sctp/outqueue.c3
-rw-r--r--net/sctp/proc.c4
-rw-r--r--net/sctp/sm_make_chunk.c9
-rw-r--r--net/sctp/sm_statefuns.c6
-rw-r--r--net/sctp/socket.c18
-rw-r--r--net/sctp/stream.c43
-rw-r--r--net/sctp/transport.c19
10 files changed, 107 insertions, 81 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 0439a1a68367..a9708da28eb5 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -246,6 +246,9 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
246 if (!sctp_ulpq_init(&asoc->ulpq, asoc)) 246 if (!sctp_ulpq_init(&asoc->ulpq, asoc))
247 goto fail_init; 247 goto fail_init;
248 248
249 if (sctp_stream_new(asoc, gfp))
250 goto fail_init;
251
249 /* Assume that peer would support both address types unless we are 252 /* Assume that peer would support both address types unless we are
250 * told otherwise. 253 * told otherwise.
251 */ 254 */
@@ -264,7 +267,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
264 /* AUTH related initializations */ 267 /* AUTH related initializations */
265 INIT_LIST_HEAD(&asoc->endpoint_shared_keys); 268 INIT_LIST_HEAD(&asoc->endpoint_shared_keys);
266 if (sctp_auth_asoc_copy_shkeys(ep, asoc, gfp)) 269 if (sctp_auth_asoc_copy_shkeys(ep, asoc, gfp))
267 goto fail_init; 270 goto stream_free;
268 271
269 asoc->active_key_id = ep->active_key_id; 272 asoc->active_key_id = ep->active_key_id;
270 asoc->prsctp_enable = ep->prsctp_enable; 273 asoc->prsctp_enable = ep->prsctp_enable;
@@ -287,6 +290,8 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
287 290
288 return asoc; 291 return asoc;
289 292
293stream_free:
294 sctp_stream_free(asoc->stream);
290fail_init: 295fail_init:
291 sock_put(asoc->base.sk); 296 sock_put(asoc->base.sk);
292 sctp_endpoint_put(asoc->ep); 297 sctp_endpoint_put(asoc->ep);
@@ -1407,7 +1412,7 @@ sctp_assoc_choose_alter_transport(struct sctp_association *asoc,
1407/* Update the association's pmtu and frag_point by going through all the 1412/* Update the association's pmtu and frag_point by going through all the
1408 * transports. This routine is called when a transport's PMTU has changed. 1413 * transports. This routine is called when a transport's PMTU has changed.
1409 */ 1414 */
1410void sctp_assoc_sync_pmtu(struct sock *sk, struct sctp_association *asoc) 1415void sctp_assoc_sync_pmtu(struct sctp_association *asoc)
1411{ 1416{
1412 struct sctp_transport *t; 1417 struct sctp_transport *t;
1413 __u32 pmtu = 0; 1418 __u32 pmtu = 0;
@@ -1419,8 +1424,8 @@ void sctp_assoc_sync_pmtu(struct sock *sk, struct sctp_association *asoc)
1419 list_for_each_entry(t, &asoc->peer.transport_addr_list, 1424 list_for_each_entry(t, &asoc->peer.transport_addr_list,
1420 transports) { 1425 transports) {
1421 if (t->pmtu_pending && t->dst) { 1426 if (t->pmtu_pending && t->dst) {
1422 sctp_transport_update_pmtu(sk, t, 1427 sctp_transport_update_pmtu(
1423 SCTP_TRUNC4(dst_mtu(t->dst))); 1428 t, SCTP_TRUNC4(dst_mtu(t->dst)));
1424 t->pmtu_pending = 0; 1429 t->pmtu_pending = 0;
1425 } 1430 }
1426 if (!pmtu || (t->pathmtu < pmtu)) 1431 if (!pmtu || (t->pathmtu < pmtu))
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 2a28ab20487f..0e06a278d2a9 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -401,10 +401,10 @@ void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
401 401
402 if (t->param_flags & SPP_PMTUD_ENABLE) { 402 if (t->param_flags & SPP_PMTUD_ENABLE) {
403 /* Update transports view of the MTU */ 403 /* Update transports view of the MTU */
404 sctp_transport_update_pmtu(sk, t, pmtu); 404 sctp_transport_update_pmtu(t, pmtu);
405 405
406 /* Update association pmtu. */ 406 /* Update association pmtu. */
407 sctp_assoc_sync_pmtu(sk, asoc); 407 sctp_assoc_sync_pmtu(asoc);
408 } 408 }
409 409
410 /* Retransmit with the new pmtu setting. 410 /* Retransmit with the new pmtu setting.
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 1224421036b3..1409a875ad8e 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -86,43 +86,53 @@ void sctp_packet_config(struct sctp_packet *packet, __u32 vtag,
86{ 86{
87 struct sctp_transport *tp = packet->transport; 87 struct sctp_transport *tp = packet->transport;
88 struct sctp_association *asoc = tp->asoc; 88 struct sctp_association *asoc = tp->asoc;
89 struct sock *sk;
89 90
90 pr_debug("%s: packet:%p vtag:0x%x\n", __func__, packet, vtag); 91 pr_debug("%s: packet:%p vtag:0x%x\n", __func__, packet, vtag);
91
92 packet->vtag = vtag; 92 packet->vtag = vtag;
93 93
94 if (asoc && tp->dst) { 94 /* do the following jobs only once for a flush schedule */
95 struct sock *sk = asoc->base.sk; 95 if (!sctp_packet_empty(packet))
96 96 return;
97 rcu_read_lock();
98 if (__sk_dst_get(sk) != tp->dst) {
99 dst_hold(tp->dst);
100 sk_setup_caps(sk, tp->dst);
101 }
102
103 if (sk_can_gso(sk)) {
104 struct net_device *dev = tp->dst->dev;
105 97
106 packet->max_size = dev->gso_max_size; 98 /* set packet max_size with pathmtu */
107 } else { 99 packet->max_size = tp->pathmtu;
108 packet->max_size = asoc->pathmtu; 100 if (!asoc)
109 } 101 return;
110 rcu_read_unlock();
111 102
112 } else { 103 /* update dst or transport pathmtu if in need */
113 packet->max_size = tp->pathmtu; 104 sk = asoc->base.sk;
105 if (!sctp_transport_dst_check(tp)) {
106 sctp_transport_route(tp, NULL, sctp_sk(sk));
107 if (asoc->param_flags & SPP_PMTUD_ENABLE)
108 sctp_assoc_sync_pmtu(asoc);
109 } else if (!sctp_transport_pmtu_check(tp)) {
110 if (asoc->param_flags & SPP_PMTUD_ENABLE)
111 sctp_assoc_sync_pmtu(asoc);
114 } 112 }
115 113
116 if (ecn_capable && sctp_packet_empty(packet)) { 114 /* If there a is a prepend chunk stick it on the list before
117 struct sctp_chunk *chunk; 115 * any other chunks get appended.
116 */
117 if (ecn_capable) {
118 struct sctp_chunk *chunk = sctp_get_ecne_prepend(asoc);
118 119
119 /* If there a is a prepend chunk stick it on the list before
120 * any other chunks get appended.
121 */
122 chunk = sctp_get_ecne_prepend(asoc);
123 if (chunk) 120 if (chunk)
124 sctp_packet_append_chunk(packet, chunk); 121 sctp_packet_append_chunk(packet, chunk);
125 } 122 }
123
124 if (!tp->dst)
125 return;
126
127 /* set packet max_size with gso_max_size if gso is enabled*/
128 rcu_read_lock();
129 if (__sk_dst_get(sk) != tp->dst) {
130 dst_hold(tp->dst);
131 sk_setup_caps(sk, tp->dst);
132 }
133 packet->max_size = sk_can_gso(sk) ? tp->dst->dev->gso_max_size
134 : asoc->pathmtu;
135 rcu_read_unlock();
126} 136}
127 137
128/* Initialize the packet structure. */ 138/* Initialize the packet structure. */
@@ -582,12 +592,7 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
582 sh->vtag = htonl(packet->vtag); 592 sh->vtag = htonl(packet->vtag);
583 sh->checksum = 0; 593 sh->checksum = 0;
584 594
585 /* update dst if in need */ 595 /* drop packet if no dst */
586 if (!sctp_transport_dst_check(tp)) {
587 sctp_transport_route(tp, NULL, sctp_sk(sk));
588 if (asoc && asoc->param_flags & SPP_PMTUD_ENABLE)
589 sctp_assoc_sync_pmtu(sk, asoc);
590 }
591 dst = dst_clone(tp->dst); 596 dst = dst_clone(tp->dst);
592 if (!dst) { 597 if (!dst) {
593 IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); 598 IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
@@ -704,7 +709,7 @@ static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet,
704 */ 709 */
705 710
706 if ((sctp_sk(asoc->base.sk)->nodelay || inflight == 0) && 711 if ((sctp_sk(asoc->base.sk)->nodelay || inflight == 0) &&
707 !chunk->msg->force_delay) 712 !asoc->force_delay)
708 /* Nothing unacked */ 713 /* Nothing unacked */
709 return SCTP_XMIT_OK; 714 return SCTP_XMIT_OK;
710 715
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 3f78d7f06e14..fe4c3d462f6e 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -1036,8 +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 >= 1039 if (chunk->sinfo.sinfo_stream >= asoc->stream->outcnt) {
1040 asoc->c.sinit_num_ostreams) {
1041 1040
1042 /* Mark as failed send. */ 1041 /* Mark as failed send. */
1043 sctp_chunk_fail(chunk, SCTP_ERROR_INV_STRM); 1042 sctp_chunk_fail(chunk, SCTP_ERROR_INV_STRM);
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index 206377fe91ec..a0b29d43627f 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->c.sinit_max_instreams, 364 assoc->hbinterval, assoc->stream->incnt,
365 assoc->c.sinit_num_ostreams, 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 969a30c7bb54..118faff6a332 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -2460,15 +2460,10 @@ int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
2460 * association. 2460 * association.
2461 */ 2461 */
2462 if (!asoc->temp) { 2462 if (!asoc->temp) {
2463 int error; 2463 if (sctp_stream_init(asoc, gfp))
2464
2465 asoc->stream = sctp_stream_new(asoc->c.sinit_max_instreams,
2466 asoc->c.sinit_num_ostreams, gfp);
2467 if (!asoc->stream)
2468 goto clean_up; 2464 goto clean_up;
2469 2465
2470 error = sctp_assoc_set_id(asoc, gfp); 2466 if (sctp_assoc_set_id(asoc, gfp))
2471 if (error)
2472 goto clean_up; 2467 goto clean_up;
2473 } 2468 }
2474 2469
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index ab1374fa5ab0..4f5e6cfc7f60 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -3955,7 +3955,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(struct net *net,
3955 3955
3956 /* Silently discard the chunk if stream-id is not valid */ 3956 /* Silently discard the chunk if stream-id is not valid */
3957 sctp_walk_fwdtsn(skip, chunk) { 3957 sctp_walk_fwdtsn(skip, chunk) {
3958 if (ntohs(skip->stream) >= asoc->c.sinit_max_instreams) 3958 if (ntohs(skip->stream) >= asoc->stream->incnt)
3959 goto discard_noforce; 3959 goto discard_noforce;
3960 } 3960 }
3961 3961
@@ -4026,7 +4026,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_fast(
4026 4026
4027 /* Silently discard the chunk if stream-id is not valid */ 4027 /* Silently discard the chunk if stream-id is not valid */
4028 sctp_walk_fwdtsn(skip, chunk) { 4028 sctp_walk_fwdtsn(skip, chunk) {
4029 if (ntohs(skip->stream) >= asoc->c.sinit_max_instreams) 4029 if (ntohs(skip->stream) >= asoc->stream->incnt)
4030 goto gen_shutdown; 4030 goto gen_shutdown;
4031 } 4031 }
4032 4032
@@ -6362,7 +6362,7 @@ static int sctp_eat_data(const struct sctp_association *asoc,
6362 * and discard the DATA chunk. 6362 * and discard the DATA chunk.
6363 */ 6363 */
6364 sid = ntohs(data_hdr->stream); 6364 sid = ntohs(data_hdr->stream);
6365 if (sid >= asoc->c.sinit_max_instreams) { 6365 if (sid >= asoc->stream->incnt) {
6366 /* Mark tsn as received even though we drop it */ 6366 /* Mark tsn as received even though we drop it */
6367 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn)); 6367 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn));
6368 6368
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 6489446925e6..8e56df8d175d 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1907,7 +1907,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
1907 } 1907 }
1908 1908
1909 if (asoc->pmtu_pending) 1909 if (asoc->pmtu_pending)
1910 sctp_assoc_pending_pmtu(sk, asoc); 1910 sctp_assoc_pending_pmtu(asoc);
1911 1911
1912 /* If fragmentation is disabled and the message length exceeds the 1912 /* If fragmentation is disabled and the message length exceeds the
1913 * association fragmentation point, return EMSGSIZE. The I-D 1913 * association fragmentation point, return EMSGSIZE. The I-D
@@ -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->c.sinit_num_ostreams) { 1923 if (sinfo->sinfo_stream >= asoc->stream->outcnt) {
1924 err = -EINVAL; 1924 err = -EINVAL;
1925 goto out_free; 1925 goto out_free;
1926 } 1926 }
@@ -1965,7 +1965,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
1965 err = PTR_ERR(datamsg); 1965 err = PTR_ERR(datamsg);
1966 goto out_free; 1966 goto out_free;
1967 } 1967 }
1968 datamsg->force_delay = !!(msg->msg_flags & MSG_MORE); 1968 asoc->force_delay = !!(msg->msg_flags & MSG_MORE);
1969 1969
1970 /* Now send the (possibly) fragmented message. */ 1970 /* Now send the (possibly) fragmented message. */
1971 list_for_each_entry(chunk, &datamsg->chunks, frag_list) { 1971 list_for_each_entry(chunk, &datamsg->chunks, frag_list) {
@@ -2435,7 +2435,7 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
2435 if ((params->spp_flags & SPP_PMTUD_DISABLE) && params->spp_pathmtu) { 2435 if ((params->spp_flags & SPP_PMTUD_DISABLE) && params->spp_pathmtu) {
2436 if (trans) { 2436 if (trans) {
2437 trans->pathmtu = params->spp_pathmtu; 2437 trans->pathmtu = params->spp_pathmtu;
2438 sctp_assoc_sync_pmtu(sctp_opt2sk(sp), asoc); 2438 sctp_assoc_sync_pmtu(asoc);
2439 } else if (asoc) { 2439 } else if (asoc) {
2440 asoc->pathmtu = params->spp_pathmtu; 2440 asoc->pathmtu = params->spp_pathmtu;
2441 } else { 2441 } else {
@@ -2451,7 +2451,7 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
2451 (trans->param_flags & ~SPP_PMTUD) | pmtud_change; 2451 (trans->param_flags & ~SPP_PMTUD) | pmtud_change;
2452 if (update) { 2452 if (update) {
2453 sctp_transport_pmtu(trans, sctp_opt2sk(sp)); 2453 sctp_transport_pmtu(trans, sctp_opt2sk(sp));
2454 sctp_assoc_sync_pmtu(sctp_opt2sk(sp), asoc); 2454 sctp_assoc_sync_pmtu(asoc);
2455 } 2455 }
2456 } else if (asoc) { 2456 } else if (asoc) {
2457 asoc->param_flags = 2457 asoc->param_flags =
@@ -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->c.sinit_max_instreams; 4500 info->sctpi_instrms = asoc->stream->incnt;
4501 info->sctpi_outstrms = asoc->c.sinit_num_ostreams; 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->c.sinit_max_instreams; 4730 status.sstat_instrms = asoc->stream->incnt;
4731 status.sstat_outstrms = asoc->c.sinit_num_ostreams; 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,
diff --git a/net/sctp/stream.c b/net/sctp/stream.c
index 961d0a1e99d1..eff6008a32ba 100644
--- a/net/sctp/stream.c
+++ b/net/sctp/stream.c
@@ -35,33 +35,60 @@
35#include <net/sctp/sctp.h> 35#include <net/sctp/sctp.h>
36#include <net/sctp/sm.h> 36#include <net/sctp/sm.h>
37 37
38struct sctp_stream *sctp_stream_new(__u16 incnt, __u16 outcnt, gfp_t gfp) 38int sctp_stream_new(struct sctp_association *asoc, gfp_t gfp)
39{ 39{
40 struct sctp_stream *stream; 40 struct sctp_stream *stream;
41 int i; 41 int i;
42 42
43 stream = kzalloc(sizeof(*stream), gfp); 43 stream = kzalloc(sizeof(*stream), gfp);
44 if (!stream) 44 if (!stream)
45 return NULL; 45 return -ENOMEM;
46 46
47 stream->outcnt = outcnt; 47 stream->outcnt = asoc->c.sinit_num_ostreams;
48 stream->out = kcalloc(stream->outcnt, sizeof(*stream->out), gfp); 48 stream->out = kcalloc(stream->outcnt, sizeof(*stream->out), gfp);
49 if (!stream->out) { 49 if (!stream->out) {
50 kfree(stream); 50 kfree(stream);
51 return NULL; 51 return -ENOMEM;
52 } 52 }
53 for (i = 0; i < stream->outcnt; i++) 53 for (i = 0; i < stream->outcnt; i++)
54 stream->out[i].state = SCTP_STREAM_OPEN; 54 stream->out[i].state = SCTP_STREAM_OPEN;
55 55
56 stream->incnt = incnt; 56 asoc->stream = stream;
57
58 return 0;
59}
60
61int sctp_stream_init(struct sctp_association *asoc, gfp_t gfp)
62{
63 struct sctp_stream *stream = asoc->stream;
64 int i;
65
66 /* Initial stream->out size may be very big, so free it and alloc
67 * a new one with new outcnt to save memory.
68 */
69 kfree(stream->out);
70 stream->outcnt = asoc->c.sinit_num_ostreams;
71 stream->out = kcalloc(stream->outcnt, sizeof(*stream->out), gfp);
72 if (!stream->out)
73 goto nomem;
74
75 for (i = 0; i < stream->outcnt; i++)
76 stream->out[i].state = SCTP_STREAM_OPEN;
77
78 stream->incnt = asoc->c.sinit_max_instreams;
57 stream->in = kcalloc(stream->incnt, sizeof(*stream->in), gfp); 79 stream->in = kcalloc(stream->incnt, sizeof(*stream->in), gfp);
58 if (!stream->in) { 80 if (!stream->in) {
59 kfree(stream->out); 81 kfree(stream->out);
60 kfree(stream); 82 goto nomem;
61 return NULL;
62 } 83 }
63 84
64 return stream; 85 return 0;
86
87nomem:
88 asoc->stream = NULL;
89 kfree(stream);
90
91 return -ENOMEM;
65} 92}
66 93
67void sctp_stream_free(struct sctp_stream *stream) 94void sctp_stream_free(struct sctp_stream *stream)
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index 3379668af368..721eeebfcd8a 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -251,14 +251,13 @@ void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk)
251 transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; 251 transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT;
252} 252}
253 253
254void sctp_transport_update_pmtu(struct sock *sk, struct sctp_transport *t, u32 pmtu) 254void sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu)
255{ 255{
256 struct dst_entry *dst; 256 struct dst_entry *dst = sctp_transport_dst_check(t);
257 257
258 if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) { 258 if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) {
259 pr_warn("%s: Reported pmtu %d too low, using default minimum of %d\n", 259 pr_warn("%s: Reported pmtu %d too low, using default minimum of %d\n",
260 __func__, pmtu, 260 __func__, pmtu, SCTP_DEFAULT_MINSEGMENT);
261 SCTP_DEFAULT_MINSEGMENT);
262 /* Use default minimum segment size and disable 261 /* Use default minimum segment size and disable
263 * pmtu discovery on this transport. 262 * pmtu discovery on this transport.
264 */ 263 */
@@ -267,17 +266,13 @@ void sctp_transport_update_pmtu(struct sock *sk, struct sctp_transport *t, u32 p
267 t->pathmtu = pmtu; 266 t->pathmtu = pmtu;
268 } 267 }
269 268
270 dst = sctp_transport_dst_check(t);
271 if (!dst)
272 t->af_specific->get_dst(t, &t->saddr, &t->fl, sk);
273
274 if (dst) { 269 if (dst) {
275 dst->ops->update_pmtu(dst, sk, NULL, pmtu); 270 dst->ops->update_pmtu(dst, t->asoc->base.sk, NULL, pmtu);
276
277 dst = sctp_transport_dst_check(t); 271 dst = sctp_transport_dst_check(t);
278 if (!dst)
279 t->af_specific->get_dst(t, &t->saddr, &t->fl, sk);
280 } 272 }
273
274 if (!dst)
275 t->af_specific->get_dst(t, &t->saddr, &t->fl, t->asoc->base.sk);
281} 276}
282 277
283/* Caches the dst entry and source address for a transport's destination 278/* Caches the dst entry and source address for a transport's destination