aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/stream.c')
-rw-r--r--net/sctp/stream.c68
1 files changed, 33 insertions, 35 deletions
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
38int sctp_stream_new(struct sctp_association *asoc, 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 = &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
61int sctp_stream_init(struct sctp_association *asoc, gfp_t gfp) 54int 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
87nomem:
88 asoc->stream = NULL;
89 kfree(stream);
90
91 return -ENOMEM;
92} 80}
93 81
94void sctp_stream_free(struct sctp_stream *stream) 82void 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
104void sctp_stream_clear(struct sctp_stream *stream) 88void 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
99void 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
115static int sctp_send_reconf(struct sctp_association *asoc, 112static 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,
128int sctp_send_reset_streams(struct sctp_association *asoc, 125int 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
215int sctp_send_reset_assoc(struct sctp_association *asoc) 212int 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)
255int sctp_send_add_streams(struct sctp_association *asoc, 253int 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;