diff options
Diffstat (limited to 'net/sctp/sm_statefuns.c')
-rw-r--r-- | net/sctp/sm_statefuns.c | 103 |
1 files changed, 78 insertions, 25 deletions
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index fd2dfdd7d7fd..71cad56dd73f 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -97,6 +97,13 @@ static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, | |||
97 | const struct sctp_association *asoc, | 97 | const struct sctp_association *asoc, |
98 | struct sctp_transport *transport); | 98 | struct sctp_transport *transport); |
99 | 99 | ||
100 | static sctp_disposition_t sctp_sf_abort_violation( | ||
101 | const struct sctp_association *asoc, | ||
102 | void *arg, | ||
103 | sctp_cmd_seq_t *commands, | ||
104 | const __u8 *payload, | ||
105 | const size_t paylen); | ||
106 | |||
100 | static sctp_disposition_t sctp_sf_violation_chunklen( | 107 | static sctp_disposition_t sctp_sf_violation_chunklen( |
101 | const struct sctp_endpoint *ep, | 108 | const struct sctp_endpoint *ep, |
102 | const struct sctp_association *asoc, | 109 | const struct sctp_association *asoc, |
@@ -104,6 +111,13 @@ static sctp_disposition_t sctp_sf_violation_chunklen( | |||
104 | void *arg, | 111 | void *arg, |
105 | sctp_cmd_seq_t *commands); | 112 | sctp_cmd_seq_t *commands); |
106 | 113 | ||
114 | static sctp_disposition_t sctp_sf_violation_ctsn( | ||
115 | const struct sctp_endpoint *ep, | ||
116 | const struct sctp_association *asoc, | ||
117 | const sctp_subtype_t type, | ||
118 | void *arg, | ||
119 | sctp_cmd_seq_t *commands); | ||
120 | |||
107 | /* Small helper function that checks if the chunk length | 121 | /* Small helper function that checks if the chunk length |
108 | * is of the appropriate length. The 'required_length' argument | 122 | * is of the appropriate length. The 'required_length' argument |
109 | * is set to be the size of a specific chunk we are testing. | 123 | * is set to be the size of a specific chunk we are testing. |
@@ -2880,6 +2894,13 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep, | |||
2880 | return SCTP_DISPOSITION_DISCARD; | 2894 | return SCTP_DISPOSITION_DISCARD; |
2881 | } | 2895 | } |
2882 | 2896 | ||
2897 | /* If Cumulative TSN Ack beyond the max tsn currently | ||
2898 | * send, terminating the association and respond to the | ||
2899 | * sender with an ABORT. | ||
2900 | */ | ||
2901 | if (!TSN_lt(ctsn, asoc->next_tsn)) | ||
2902 | return sctp_sf_violation_ctsn(ep, asoc, type, arg, commands); | ||
2903 | |||
2883 | /* Return this SACK for further processing. */ | 2904 | /* Return this SACK for further processing. */ |
2884 | sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK, SCTP_SACKH(sackh)); | 2905 | sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK, SCTP_SACKH(sackh)); |
2885 | 2906 | ||
@@ -3691,40 +3712,21 @@ sctp_disposition_t sctp_sf_violation(const struct sctp_endpoint *ep, | |||
3691 | return SCTP_DISPOSITION_VIOLATION; | 3712 | return SCTP_DISPOSITION_VIOLATION; |
3692 | } | 3713 | } |
3693 | 3714 | ||
3694 | |||
3695 | /* | 3715 | /* |
3696 | * Handle a protocol violation when the chunk length is invalid. | 3716 | * Common function to handle a protocol violation. |
3697 | * "Invalid" length is identified as smaller then the minimal length a | ||
3698 | * given chunk can be. For example, a SACK chunk has invalid length | ||
3699 | * if it's length is set to be smaller then the size of sctp_sack_chunk_t. | ||
3700 | * | ||
3701 | * We inform the other end by sending an ABORT with a Protocol Violation | ||
3702 | * error code. | ||
3703 | * | ||
3704 | * Section: Not specified | ||
3705 | * Verification Tag: Nothing to do | ||
3706 | * Inputs | ||
3707 | * (endpoint, asoc, chunk) | ||
3708 | * | ||
3709 | * Outputs | ||
3710 | * (reply_msg, msg_up, counters) | ||
3711 | * | ||
3712 | * Generate an ABORT chunk and terminate the association. | ||
3713 | */ | 3717 | */ |
3714 | static sctp_disposition_t sctp_sf_violation_chunklen( | 3718 | static sctp_disposition_t sctp_sf_abort_violation( |
3715 | const struct sctp_endpoint *ep, | ||
3716 | const struct sctp_association *asoc, | 3719 | const struct sctp_association *asoc, |
3717 | const sctp_subtype_t type, | ||
3718 | void *arg, | 3720 | void *arg, |
3719 | sctp_cmd_seq_t *commands) | 3721 | sctp_cmd_seq_t *commands, |
3722 | const __u8 *payload, | ||
3723 | const size_t paylen) | ||
3720 | { | 3724 | { |
3721 | struct sctp_chunk *chunk = arg; | 3725 | struct sctp_chunk *chunk = arg; |
3722 | struct sctp_chunk *abort = NULL; | 3726 | struct sctp_chunk *abort = NULL; |
3723 | char err_str[]="The following chunk had invalid length:"; | ||
3724 | 3727 | ||
3725 | /* Make the abort chunk. */ | 3728 | /* Make the abort chunk. */ |
3726 | abort = sctp_make_abort_violation(asoc, chunk, err_str, | 3729 | abort = sctp_make_abort_violation(asoc, chunk, payload, paylen); |
3727 | sizeof(err_str)); | ||
3728 | if (!abort) | 3730 | if (!abort) |
3729 | goto nomem; | 3731 | goto nomem; |
3730 | 3732 | ||
@@ -3756,6 +3758,57 @@ nomem: | |||
3756 | return SCTP_DISPOSITION_NOMEM; | 3758 | return SCTP_DISPOSITION_NOMEM; |
3757 | } | 3759 | } |
3758 | 3760 | ||
3761 | /* | ||
3762 | * Handle a protocol violation when the chunk length is invalid. | ||
3763 | * "Invalid" length is identified as smaller then the minimal length a | ||
3764 | * given chunk can be. For example, a SACK chunk has invalid length | ||
3765 | * if it's length is set to be smaller then the size of sctp_sack_chunk_t. | ||
3766 | * | ||
3767 | * We inform the other end by sending an ABORT with a Protocol Violation | ||
3768 | * error code. | ||
3769 | * | ||
3770 | * Section: Not specified | ||
3771 | * Verification Tag: Nothing to do | ||
3772 | * Inputs | ||
3773 | * (endpoint, asoc, chunk) | ||
3774 | * | ||
3775 | * Outputs | ||
3776 | * (reply_msg, msg_up, counters) | ||
3777 | * | ||
3778 | * Generate an ABORT chunk and terminate the association. | ||
3779 | */ | ||
3780 | static sctp_disposition_t sctp_sf_violation_chunklen( | ||
3781 | const struct sctp_endpoint *ep, | ||
3782 | const struct sctp_association *asoc, | ||
3783 | const sctp_subtype_t type, | ||
3784 | void *arg, | ||
3785 | sctp_cmd_seq_t *commands) | ||
3786 | { | ||
3787 | char err_str[]="The following chunk had invalid length:"; | ||
3788 | |||
3789 | return sctp_sf_abort_violation(asoc, arg, commands, err_str, | ||
3790 | sizeof(err_str)); | ||
3791 | } | ||
3792 | |||
3793 | /* Handle a protocol violation when the peer trying to advance the | ||
3794 | * cumulative tsn ack to a point beyond the max tsn currently sent. | ||
3795 | * | ||
3796 | * We inform the other end by sending an ABORT with a Protocol Violation | ||
3797 | * error code. | ||
3798 | */ | ||
3799 | static sctp_disposition_t sctp_sf_violation_ctsn( | ||
3800 | const struct sctp_endpoint *ep, | ||
3801 | const struct sctp_association *asoc, | ||
3802 | const sctp_subtype_t type, | ||
3803 | void *arg, | ||
3804 | sctp_cmd_seq_t *commands) | ||
3805 | { | ||
3806 | char err_str[]="The cumulative tsn ack beyond the max tsn currently sent:"; | ||
3807 | |||
3808 | return sctp_sf_abort_violation(asoc, arg, commands, err_str, | ||
3809 | sizeof(err_str)); | ||
3810 | } | ||
3811 | |||
3759 | /*************************************************************************** | 3812 | /*************************************************************************** |
3760 | * These are the state functions for handling primitive (Section 10) events. | 3813 | * These are the state functions for handling primitive (Section 10) events. |
3761 | ***************************************************************************/ | 3814 | ***************************************************************************/ |