stream.c (c74a7469f97c0f40b46e82ee979f9fb1bb6e847c) stream.c (05364ca03cfd419caecb292fede20eb39667eaae)
1/* SCTP kernel implementation
2 * (C) Copyright IBM Corp. 2001, 2004
3 * Copyright (c) 1999-2000 Cisco, Inc.
4 * Copyright (c) 1999-2001 Motorola, Inc.
5 * Copyright (c) 2001 Intel Corp.
6 *
7 * This file is part of the SCTP kernel implementation
8 *

--- 148 unchanged lines hidden (view full) ---

157 sched->sched_all(stream);
158
159 ret = sctp_stream_alloc_out(stream, outcnt, gfp);
160 if (ret)
161 goto out;
162
163 stream->outcnt = outcnt;
164 for (i = 0; i < stream->outcnt; i++)
1/* SCTP kernel implementation
2 * (C) Copyright IBM Corp. 2001, 2004
3 * Copyright (c) 1999-2000 Cisco, Inc.
4 * Copyright (c) 1999-2001 Motorola, Inc.
5 * Copyright (c) 2001 Intel Corp.
6 *
7 * This file is part of the SCTP kernel implementation
8 *

--- 148 unchanged lines hidden (view full) ---

157 sched->sched_all(stream);
158
159 ret = sctp_stream_alloc_out(stream, outcnt, gfp);
160 if (ret)
161 goto out;
162
163 stream->outcnt = outcnt;
164 for (i = 0; i < stream->outcnt; i++)
165 stream->out[i].state = SCTP_STREAM_OPEN;
165 SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
166
167 sched->init(stream);
168
169in:
170 sctp_stream_interleave_init(stream);
171 if (!incnt)
172 goto out;
173

--- 14 unchanged lines hidden (view full) ---

188
189int sctp_stream_init_ext(struct sctp_stream *stream, __u16 sid)
190{
191 struct sctp_stream_out_ext *soute;
192
193 soute = kzalloc(sizeof(*soute), GFP_KERNEL);
194 if (!soute)
195 return -ENOMEM;
166
167 sched->init(stream);
168
169in:
170 sctp_stream_interleave_init(stream);
171 if (!incnt)
172 goto out;
173

--- 14 unchanged lines hidden (view full) ---

188
189int sctp_stream_init_ext(struct sctp_stream *stream, __u16 sid)
190{
191 struct sctp_stream_out_ext *soute;
192
193 soute = kzalloc(sizeof(*soute), GFP_KERNEL);
194 if (!soute)
195 return -ENOMEM;
196 stream->out[sid].ext = soute;
196 SCTP_SO(stream, sid)->ext = soute;
197
198 return sctp_sched_init_sid(stream, sid, GFP_KERNEL);
199}
200
201void sctp_stream_free(struct sctp_stream *stream)
202{
203 struct sctp_sched_ops *sched = sctp_sched_ops_from_stream(stream);
204 int i;
205
206 sched->free(stream);
207 for (i = 0; i < stream->outcnt; i++)
197
198 return sctp_sched_init_sid(stream, sid, GFP_KERNEL);
199}
200
201void sctp_stream_free(struct sctp_stream *stream)
202{
203 struct sctp_sched_ops *sched = sctp_sched_ops_from_stream(stream);
204 int i;
205
206 sched->free(stream);
207 for (i = 0; i < stream->outcnt; i++)
208 kfree(stream->out[i].ext);
208 kfree(SCTP_SO(stream, i)->ext);
209 kfree(stream->out);
210 kfree(stream->in);
211}
212
213void sctp_stream_clear(struct sctp_stream *stream)
214{
215 int i;
216
217 for (i = 0; i < stream->outcnt; i++) {
209 kfree(stream->out);
210 kfree(stream->in);
211}
212
213void sctp_stream_clear(struct sctp_stream *stream)
214{
215 int i;
216
217 for (i = 0; i < stream->outcnt; i++) {
218 stream->out[i].mid = 0;
219 stream->out[i].mid_uo = 0;
218 SCTP_SO(stream, i)->mid = 0;
219 SCTP_SO(stream, i)->mid_uo = 0;
220 }
221
222 for (i = 0; i < stream->incnt; i++)
220 }
221
222 for (i = 0; i < stream->incnt; i++)
223 stream->in[i].mid = 0;
223 SCTP_SI(stream, i)->mid = 0;
224}
225
226void sctp_stream_update(struct sctp_stream *stream, struct sctp_stream *new)
227{
228 struct sctp_sched_ops *sched = sctp_sched_ops_from_stream(stream);
229
230 sched->unsched_all(stream);
231 sctp_stream_outq_migrate(stream, new, new->outcnt);

--- 36 unchanged lines hidden (view full) ---

268 return true;
269
270 if (!str_nums)
271 return false;
272
273 for (i = 0; i < str_nums; i++) {
274 __u16 sid = ntohs(str_list[i]);
275
224}
225
226void sctp_stream_update(struct sctp_stream *stream, struct sctp_stream *new)
227{
228 struct sctp_sched_ops *sched = sctp_sched_ops_from_stream(stream);
229
230 sched->unsched_all(stream);
231 sctp_stream_outq_migrate(stream, new, new->outcnt);

--- 36 unchanged lines hidden (view full) ---

268 return true;
269
270 if (!str_nums)
271 return false;
272
273 for (i = 0; i < str_nums; i++) {
274 __u16 sid = ntohs(str_list[i]);
275
276 if (stream->out[sid].ext &&
277 !list_empty(&stream->out[sid].ext->outq))
276 if (SCTP_SO(stream, sid)->ext &&
277 !list_empty(&SCTP_SO(stream, sid)->ext->outq))
278 return false;
279 }
280
281 return true;
282}
283
284int sctp_send_reset_streams(struct sctp_association *asoc,
285 struct sctp_reset_streams *params)

--- 70 unchanged lines hidden (view full) ---

356 if (!chunk) {
357 retval = -ENOMEM;
358 goto out;
359 }
360
361 if (out) {
362 if (str_nums)
363 for (i = 0; i < str_nums; i++)
278 return false;
279 }
280
281 return true;
282}
283
284int sctp_send_reset_streams(struct sctp_association *asoc,
285 struct sctp_reset_streams *params)

--- 70 unchanged lines hidden (view full) ---

356 if (!chunk) {
357 retval = -ENOMEM;
358 goto out;
359 }
360
361 if (out) {
362 if (str_nums)
363 for (i = 0; i < str_nums; i++)
364 stream->out[str_list[i]].state =
364 SCTP_SO(stream, str_list[i])->state =
365 SCTP_STREAM_CLOSED;
366 else
367 for (i = 0; i < stream->outcnt; i++)
365 SCTP_STREAM_CLOSED;
366 else
367 for (i = 0; i < stream->outcnt; i++)
368 stream->out[i].state = SCTP_STREAM_CLOSED;
368 SCTP_SO(stream, i)->state = SCTP_STREAM_CLOSED;
369 }
370
371 asoc->strreset_chunk = chunk;
372 sctp_chunk_hold(asoc->strreset_chunk);
373
374 retval = sctp_send_reconf(asoc, chunk);
375 if (retval) {
376 sctp_chunk_put(asoc->strreset_chunk);
377 asoc->strreset_chunk = NULL;
378 if (!out)
379 goto out;
380
381 if (str_nums)
382 for (i = 0; i < str_nums; i++)
369 }
370
371 asoc->strreset_chunk = chunk;
372 sctp_chunk_hold(asoc->strreset_chunk);
373
374 retval = sctp_send_reconf(asoc, chunk);
375 if (retval) {
376 sctp_chunk_put(asoc->strreset_chunk);
377 asoc->strreset_chunk = NULL;
378 if (!out)
379 goto out;
380
381 if (str_nums)
382 for (i = 0; i < str_nums; i++)
383 stream->out[str_list[i]].state =
383 SCTP_SO(stream, str_list[i])->state =
384 SCTP_STREAM_OPEN;
385 else
386 for (i = 0; i < stream->outcnt; i++)
384 SCTP_STREAM_OPEN;
385 else
386 for (i = 0; i < stream->outcnt; i++)
387 stream->out[i].state = SCTP_STREAM_OPEN;
387 SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
388
389 goto out;
390 }
391
392 asoc->strreset_outstanding = out + in;
393
394out:
395 return retval;

--- 17 unchanged lines hidden (view full) ---

413 return -EAGAIN;
414
415 chunk = sctp_make_strreset_tsnreq(asoc);
416 if (!chunk)
417 return -ENOMEM;
418
419 /* Block further xmit of data until this request is completed */
420 for (i = 0; i < stream->outcnt; i++)
388
389 goto out;
390 }
391
392 asoc->strreset_outstanding = out + in;
393
394out:
395 return retval;

--- 17 unchanged lines hidden (view full) ---

413 return -EAGAIN;
414
415 chunk = sctp_make_strreset_tsnreq(asoc);
416 if (!chunk)
417 return -ENOMEM;
418
419 /* Block further xmit of data until this request is completed */
420 for (i = 0; i < stream->outcnt; i++)
421 stream->out[i].state = SCTP_STREAM_CLOSED;
421 SCTP_SO(stream, i)->state = SCTP_STREAM_CLOSED;
422
423 asoc->strreset_chunk = chunk;
424 sctp_chunk_hold(asoc->strreset_chunk);
425
426 retval = sctp_send_reconf(asoc, chunk);
427 if (retval) {
428 sctp_chunk_put(asoc->strreset_chunk);
429 asoc->strreset_chunk = NULL;
430
431 for (i = 0; i < stream->outcnt; i++)
422
423 asoc->strreset_chunk = chunk;
424 sctp_chunk_hold(asoc->strreset_chunk);
425
426 retval = sctp_send_reconf(asoc, chunk);
427 if (retval) {
428 sctp_chunk_put(asoc->strreset_chunk);
429 asoc->strreset_chunk = NULL;
430
431 for (i = 0; i < stream->outcnt; i++)
432 stream->out[i].state = SCTP_STREAM_OPEN;
432 SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
433
434 return retval;
435 }
436
437 asoc->strreset_outstanding = 1;
438
439 return 0;
440}

--- 163 unchanged lines hidden (view full) ---

604 for (i = 0; i < nums; i++) {
605 if (ntohs(str_p[i]) >= stream->incnt) {
606 result = SCTP_STRRESET_ERR_WRONG_SSN;
607 goto out;
608 }
609 }
610
611 for (i = 0; i < nums; i++)
433
434 return retval;
435 }
436
437 asoc->strreset_outstanding = 1;
438
439 return 0;
440}

--- 163 unchanged lines hidden (view full) ---

604 for (i = 0; i < nums; i++) {
605 if (ntohs(str_p[i]) >= stream->incnt) {
606 result = SCTP_STRRESET_ERR_WRONG_SSN;
607 goto out;
608 }
609 }
610
611 for (i = 0; i < nums; i++)
612 stream->in[ntohs(str_p[i])].mid = 0;
612 SCTP_SI(stream, ntohs(str_p[i]))->mid = 0;
613 } else {
614 for (i = 0; i < stream->incnt; i++)
613 } else {
614 for (i = 0; i < stream->incnt; i++)
615 stream->in[i].mid = 0;
615 SCTP_SI(stream, i)->mid = 0;
616 }
617
618 result = SCTP_STRRESET_PERFORMED;
619
620 *evp = sctp_ulpevent_make_stream_reset_event(asoc,
621 flags | SCTP_STREAM_RESET_OUTGOING_SSN, nums, str_p,
622 GFP_ATOMIC);
623

--- 54 unchanged lines hidden (view full) ---

678 }
679
680 chunk = sctp_make_strreset_req(asoc, nums, str_p, 1, 0);
681 if (!chunk)
682 goto out;
683
684 if (nums)
685 for (i = 0; i < nums; i++)
616 }
617
618 result = SCTP_STRRESET_PERFORMED;
619
620 *evp = sctp_ulpevent_make_stream_reset_event(asoc,
621 flags | SCTP_STREAM_RESET_OUTGOING_SSN, nums, str_p,
622 GFP_ATOMIC);
623

--- 54 unchanged lines hidden (view full) ---

678 }
679
680 chunk = sctp_make_strreset_req(asoc, nums, str_p, 1, 0);
681 if (!chunk)
682 goto out;
683
684 if (nums)
685 for (i = 0; i < nums; i++)
686 stream->out[ntohs(str_p[i])].state =
686 SCTP_SO(stream, ntohs(str_p[i]))->state =
687 SCTP_STREAM_CLOSED;
688 else
689 for (i = 0; i < stream->outcnt; i++)
687 SCTP_STREAM_CLOSED;
688 else
689 for (i = 0; i < stream->outcnt; i++)
690 stream->out[i].state = SCTP_STREAM_CLOSED;
690 SCTP_SO(stream, i)->state = SCTP_STREAM_CLOSED;
691
692 asoc->strreset_chunk = chunk;
693 asoc->strreset_outstanding = 1;
694 sctp_chunk_hold(asoc->strreset_chunk);
695
696 result = SCTP_STRRESET_PERFORMED;
697
698 *evp = sctp_ulpevent_make_stream_reset_event(asoc,

--- 82 unchanged lines hidden (view full) ---

781 next_tsn = asoc->next_tsn;
782 asoc->ctsn_ack_point = next_tsn - 1;
783 asoc->adv_peer_ack_point = asoc->ctsn_ack_point;
784
785 /* G5: The next expected and outgoing SSNs MUST be reset to 0 for all
786 * incoming and outgoing streams.
787 */
788 for (i = 0; i < stream->outcnt; i++) {
691
692 asoc->strreset_chunk = chunk;
693 asoc->strreset_outstanding = 1;
694 sctp_chunk_hold(asoc->strreset_chunk);
695
696 result = SCTP_STRRESET_PERFORMED;
697
698 *evp = sctp_ulpevent_make_stream_reset_event(asoc,

--- 82 unchanged lines hidden (view full) ---

781 next_tsn = asoc->next_tsn;
782 asoc->ctsn_ack_point = next_tsn - 1;
783 asoc->adv_peer_ack_point = asoc->ctsn_ack_point;
784
785 /* G5: The next expected and outgoing SSNs MUST be reset to 0 for all
786 * incoming and outgoing streams.
787 */
788 for (i = 0; i < stream->outcnt; i++) {
789 stream->out[i].mid = 0;
790 stream->out[i].mid_uo = 0;
789 SCTP_SO(stream, i)->mid = 0;
790 SCTP_SO(stream, i)->mid_uo = 0;
791 }
792 for (i = 0; i < stream->incnt; i++)
791 }
792 for (i = 0; i < stream->incnt; i++)
793 stream->in[i].mid = 0;
793 SCTP_SI(stream, i)->mid = 0;
794
795 result = SCTP_STRRESET_PERFORMED;
796
797 *evp = sctp_ulpevent_make_assoc_reset_event(asoc, 0, init_tsn,
798 next_tsn, GFP_ATOMIC);
799
800out:
801 sctp_update_strreset_result(asoc, result);

--- 172 unchanged lines hidden (view full) ---

974 __be16 *str_p;
975
976 outreq = (struct sctp_strreset_outreq *)req;
977 str_p = outreq->list_of_streams;
978 nums = (ntohs(outreq->param_hdr.length) - sizeof(*outreq)) /
979 sizeof(__u16);
980
981 if (result == SCTP_STRRESET_PERFORMED) {
794
795 result = SCTP_STRRESET_PERFORMED;
796
797 *evp = sctp_ulpevent_make_assoc_reset_event(asoc, 0, init_tsn,
798 next_tsn, GFP_ATOMIC);
799
800out:
801 sctp_update_strreset_result(asoc, result);

--- 172 unchanged lines hidden (view full) ---

974 __be16 *str_p;
975
976 outreq = (struct sctp_strreset_outreq *)req;
977 str_p = outreq->list_of_streams;
978 nums = (ntohs(outreq->param_hdr.length) - sizeof(*outreq)) /
979 sizeof(__u16);
980
981 if (result == SCTP_STRRESET_PERFORMED) {
982 struct sctp_stream_out *sout;
982 if (nums) {
983 for (i = 0; i < nums; i++) {
983 if (nums) {
984 for (i = 0; i < nums; i++) {
984 stream->out[ntohs(str_p[i])].mid = 0;
985 stream->out[ntohs(str_p[i])].mid_uo = 0;
985 sout = SCTP_SO(stream, ntohs(str_p[i]));
986 sout->mid = 0;
987 sout->mid_uo = 0;
986 }
987 } else {
988 for (i = 0; i < stream->outcnt; i++) {
988 }
989 } else {
990 for (i = 0; i < stream->outcnt; i++) {
989 stream->out[i].mid = 0;
990 stream->out[i].mid_uo = 0;
991 sout = SCTP_SO(stream, i);
992 sout->mid = 0;
993 sout->mid_uo = 0;
991 }
992 }
993
994 flags = SCTP_STREAM_RESET_OUTGOING_SSN;
995 }
996
997 for (i = 0; i < stream->outcnt; i++)
994 }
995 }
996
997 flags = SCTP_STREAM_RESET_OUTGOING_SSN;
998 }
999
1000 for (i = 0; i < stream->outcnt; i++)
998 stream->out[i].state = SCTP_STREAM_OPEN;
1001 SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
999
1000 *evp = sctp_ulpevent_make_stream_reset_event(asoc, flags,
1001 nums, str_p, GFP_ATOMIC);
1002 } else if (req->type == SCTP_PARAM_RESET_IN_REQUEST) {
1003 struct sctp_strreset_inreq *inreq;
1004 __be16 *str_p;
1005
1006 /* if the result is performed, it's impossible for inreq */

--- 38 unchanged lines hidden (view full) ---

1045 sctp_outq_free(&asoc->outqueue);
1046 list_splice_init(&temp, &asoc->outqueue.out_chunk_list);
1047
1048 asoc->next_tsn = rtsn;
1049 asoc->ctsn_ack_point = asoc->next_tsn - 1;
1050 asoc->adv_peer_ack_point = asoc->ctsn_ack_point;
1051
1052 for (i = 0; i < stream->outcnt; i++) {
1002
1003 *evp = sctp_ulpevent_make_stream_reset_event(asoc, flags,
1004 nums, str_p, GFP_ATOMIC);
1005 } else if (req->type == SCTP_PARAM_RESET_IN_REQUEST) {
1006 struct sctp_strreset_inreq *inreq;
1007 __be16 *str_p;
1008
1009 /* if the result is performed, it's impossible for inreq */

--- 38 unchanged lines hidden (view full) ---

1048 sctp_outq_free(&asoc->outqueue);
1049 list_splice_init(&temp, &asoc->outqueue.out_chunk_list);
1050
1051 asoc->next_tsn = rtsn;
1052 asoc->ctsn_ack_point = asoc->next_tsn - 1;
1053 asoc->adv_peer_ack_point = asoc->ctsn_ack_point;
1054
1055 for (i = 0; i < stream->outcnt; i++) {
1053 stream->out[i].mid = 0;
1054 stream->out[i].mid_uo = 0;
1056 SCTP_SO(stream, i)->mid = 0;
1057 SCTP_SO(stream, i)->mid_uo = 0;
1055 }
1056 for (i = 0; i < stream->incnt; i++)
1058 }
1059 for (i = 0; i < stream->incnt; i++)
1057 stream->in[i].mid = 0;
1060 SCTP_SI(stream, i)->mid = 0;
1058 }
1059
1060 for (i = 0; i < stream->outcnt; i++)
1061 }
1062
1063 for (i = 0; i < stream->outcnt; i++)
1061 stream->out[i].state = SCTP_STREAM_OPEN;
1064 SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
1062
1063 *evp = sctp_ulpevent_make_assoc_reset_event(asoc, flags,
1064 stsn, rtsn, GFP_ATOMIC);
1065 } else if (req->type == SCTP_PARAM_RESET_ADD_OUT_STREAMS) {
1066 struct sctp_strreset_addstrm *addstrm;
1067 __u16 number;
1068
1069 addstrm = (struct sctp_strreset_addstrm *)req;
1070 nums = ntohs(addstrm->number_of_streams);
1071 number = stream->outcnt - nums;
1072
1073 if (result == SCTP_STRRESET_PERFORMED)
1074 for (i = number; i < stream->outcnt; i++)
1065
1066 *evp = sctp_ulpevent_make_assoc_reset_event(asoc, flags,
1067 stsn, rtsn, GFP_ATOMIC);
1068 } else if (req->type == SCTP_PARAM_RESET_ADD_OUT_STREAMS) {
1069 struct sctp_strreset_addstrm *addstrm;
1070 __u16 number;
1071
1072 addstrm = (struct sctp_strreset_addstrm *)req;
1073 nums = ntohs(addstrm->number_of_streams);
1074 number = stream->outcnt - nums;
1075
1076 if (result == SCTP_STRRESET_PERFORMED)
1077 for (i = number; i < stream->outcnt; i++)
1075 stream->out[i].state = SCTP_STREAM_OPEN;
1078 SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
1076 else
1077 stream->outcnt = number;
1078
1079 *evp = sctp_ulpevent_make_stream_change_event(asoc, flags,
1080 0, nums, GFP_ATOMIC);
1081 } else if (req->type == SCTP_PARAM_RESET_ADD_IN_STREAMS) {
1082 struct sctp_strreset_addstrm *addstrm;
1083

--- 28 unchanged lines hidden ---
1079 else
1080 stream->outcnt = number;
1081
1082 *evp = sctp_ulpevent_make_stream_change_event(asoc, flags,
1083 0, nums, GFP_ATOMIC);
1084 } else if (req->type == SCTP_PARAM_RESET_ADD_IN_STREAMS) {
1085 struct sctp_strreset_addstrm *addstrm;
1086

--- 28 unchanged lines hidden ---