diff options
Diffstat (limited to 'net/sctp/stream.c')
-rw-r--r-- | net/sctp/stream.c | 58 |
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 | ||
667 | out: | 663 | out: |
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 | |||
744 | out: | 737 | out: |
745 | sctp_update_strreset_result(asoc, result); | 738 | sctp_update_strreset_result(asoc, result); |
746 | err: | 739 | err: |
@@ -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 | |||
979 | out: | 969 | out: |
980 | sctp_update_strreset_result(asoc, result); | 970 | sctp_update_strreset_result(asoc, result); |
981 | err: | 971 | err: |
@@ -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) { |