summaryrefslogtreecommitdiffstats
path: root/net/sctp/stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/stream.c')
-rw-r--r--net/sctp/stream.c58
1 files changed, 25 insertions, 33 deletions
diff --git a/net/sctp/stream.c b/net/sctp/stream.c
index 3892e7630f3a..80e0ae5534ec 100644
--- a/net/sctp/stream.c
+++ b/net/sctp/stream.c
@@ -585,9 +585,9 @@ struct sctp_chunk *sctp_process_strreset_outreq(
585 struct sctp_strreset_outreq *outreq = param.v; 585 struct sctp_strreset_outreq *outreq = param.v;
586 struct sctp_stream *stream = &asoc->stream; 586 struct sctp_stream *stream = &asoc->stream;
587 __u32 result = SCTP_STRRESET_DENIED; 587 __u32 result = SCTP_STRRESET_DENIED;
588 __u16 i, nums, flags = 0;
589 __be16 *str_p = NULL; 588 __be16 *str_p = NULL;
590 __u32 request_seq; 589 __u32 request_seq;
590 __u16 i, nums;
591 591
592 request_seq = ntohl(outreq->request_seq); 592 request_seq = ntohl(outreq->request_seq);
593 593
@@ -615,6 +615,15 @@ struct sctp_chunk *sctp_process_strreset_outreq(
615 if (!(asoc->strreset_enable & SCTP_ENABLE_RESET_STREAM_REQ)) 615 if (!(asoc->strreset_enable & SCTP_ENABLE_RESET_STREAM_REQ))
616 goto out; 616 goto out;
617 617
618 nums = (ntohs(param.p->length) - sizeof(*outreq)) / sizeof(__u16);
619 str_p = outreq->list_of_streams;
620 for (i = 0; i < nums; i++) {
621 if (ntohs(str_p[i]) >= stream->incnt) {
622 result = SCTP_STRRESET_ERR_WRONG_SSN;
623 goto out;
624 }
625 }
626
618 if (asoc->strreset_chunk) { 627 if (asoc->strreset_chunk) {
619 if (!sctp_chunk_lookup_strreset_param( 628 if (!sctp_chunk_lookup_strreset_param(
620 asoc, outreq->response_seq, 629 asoc, outreq->response_seq,
@@ -637,32 +646,19 @@ struct sctp_chunk *sctp_process_strreset_outreq(
637 sctp_chunk_put(asoc->strreset_chunk); 646 sctp_chunk_put(asoc->strreset_chunk);
638 asoc->strreset_chunk = NULL; 647 asoc->strreset_chunk = NULL;
639 } 648 }
640
641 flags = SCTP_STREAM_RESET_INCOMING_SSN;
642 } 649 }
643 650
644 nums = (ntohs(param.p->length) - sizeof(*outreq)) / sizeof(__u16); 651 if (nums)
645 if (nums) {
646 str_p = outreq->list_of_streams;
647 for (i = 0; i < nums; i++) {
648 if (ntohs(str_p[i]) >= stream->incnt) {
649 result = SCTP_STRRESET_ERR_WRONG_SSN;
650 goto out;
651 }
652 }
653
654 for (i = 0; i < nums; i++) 652 for (i = 0; i < nums; i++)
655 SCTP_SI(stream, ntohs(str_p[i]))->mid = 0; 653 SCTP_SI(stream, ntohs(str_p[i]))->mid = 0;
656 } else { 654 else
657 for (i = 0; i < stream->incnt; i++) 655 for (i = 0; i < stream->incnt; i++)
658 SCTP_SI(stream, i)->mid = 0; 656 SCTP_SI(stream, i)->mid = 0;
659 }
660 657
661 result = SCTP_STRRESET_PERFORMED; 658 result = SCTP_STRRESET_PERFORMED;
662 659
663 *evp = sctp_ulpevent_make_stream_reset_event(asoc, 660 *evp = sctp_ulpevent_make_stream_reset_event(asoc,
664 flags | SCTP_STREAM_RESET_OUTGOING_SSN, nums, str_p, 661 SCTP_STREAM_RESET_INCOMING_SSN, nums, str_p, GFP_ATOMIC);
665 GFP_ATOMIC);
666 662
667out: 663out:
668 sctp_update_strreset_result(asoc, result); 664 sctp_update_strreset_result(asoc, result);
@@ -738,9 +734,6 @@ struct sctp_chunk *sctp_process_strreset_inreq(
738 734
739 result = SCTP_STRRESET_PERFORMED; 735 result = SCTP_STRRESET_PERFORMED;
740 736
741 *evp = sctp_ulpevent_make_stream_reset_event(asoc,
742 SCTP_STREAM_RESET_INCOMING_SSN, nums, str_p, GFP_ATOMIC);
743
744out: 737out:
745 sctp_update_strreset_result(asoc, result); 738 sctp_update_strreset_result(asoc, result);
746err: 739err:
@@ -873,6 +866,14 @@ struct sctp_chunk *sctp_process_strreset_addstrm_out(
873 if (!(asoc->strreset_enable & SCTP_ENABLE_CHANGE_ASSOC_REQ)) 866 if (!(asoc->strreset_enable & SCTP_ENABLE_CHANGE_ASSOC_REQ))
874 goto out; 867 goto out;
875 868
869 in = ntohs(addstrm->number_of_streams);
870 incnt = stream->incnt + in;
871 if (!in || incnt > SCTP_MAX_STREAM)
872 goto out;
873
874 if (sctp_stream_alloc_in(stream, incnt, GFP_ATOMIC))
875 goto out;
876
876 if (asoc->strreset_chunk) { 877 if (asoc->strreset_chunk) {
877 if (!sctp_chunk_lookup_strreset_param( 878 if (!sctp_chunk_lookup_strreset_param(
878 asoc, 0, SCTP_PARAM_RESET_ADD_IN_STREAMS)) { 879 asoc, 0, SCTP_PARAM_RESET_ADD_IN_STREAMS)) {
@@ -896,14 +897,6 @@ struct sctp_chunk *sctp_process_strreset_addstrm_out(
896 } 897 }
897 } 898 }
898 899
899 in = ntohs(addstrm->number_of_streams);
900 incnt = stream->incnt + in;
901 if (!in || incnt > SCTP_MAX_STREAM)
902 goto out;
903
904 if (sctp_stream_alloc_in(stream, incnt, GFP_ATOMIC))
905 goto out;
906
907 stream->incnt = incnt; 900 stream->incnt = incnt;
908 901
909 result = SCTP_STRRESET_PERFORMED; 902 result = SCTP_STRRESET_PERFORMED;
@@ -973,9 +966,6 @@ struct sctp_chunk *sctp_process_strreset_addstrm_in(
973 966
974 result = SCTP_STRRESET_PERFORMED; 967 result = SCTP_STRRESET_PERFORMED;
975 968
976 *evp = sctp_ulpevent_make_stream_change_event(asoc,
977 0, 0, ntohs(addstrm->number_of_streams), GFP_ATOMIC);
978
979out: 969out:
980 sctp_update_strreset_result(asoc, result); 970 sctp_update_strreset_result(asoc, result);
981err: 971err:
@@ -1036,10 +1026,10 @@ struct sctp_chunk *sctp_process_strreset_resp(
1036 sout->mid_uo = 0; 1026 sout->mid_uo = 0;
1037 } 1027 }
1038 } 1028 }
1039
1040 flags = SCTP_STREAM_RESET_OUTGOING_SSN;
1041 } 1029 }
1042 1030
1031 flags |= SCTP_STREAM_RESET_OUTGOING_SSN;
1032
1043 for (i = 0; i < stream->outcnt; i++) 1033 for (i = 0; i < stream->outcnt; i++)
1044 SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN; 1034 SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
1045 1035
@@ -1058,6 +1048,8 @@ struct sctp_chunk *sctp_process_strreset_resp(
1058 nums = (ntohs(inreq->param_hdr.length) - sizeof(*inreq)) / 1048 nums = (ntohs(inreq->param_hdr.length) - sizeof(*inreq)) /
1059 sizeof(__u16); 1049 sizeof(__u16);
1060 1050
1051 flags |= SCTP_STREAM_RESET_INCOMING_SSN;
1052
1061 *evp = sctp_ulpevent_make_stream_reset_event(asoc, flags, 1053 *evp = sctp_ulpevent_make_stream_reset_event(asoc, flags,
1062 nums, str_p, GFP_ATOMIC); 1054 nums, str_p, GFP_ATOMIC);
1063 } else if (req->type == SCTP_PARAM_RESET_TSN_REQUEST) { 1055 } else if (req->type == SCTP_PARAM_RESET_TSN_REQUEST) {