aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/sm_statefuns.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/sm_statefuns.c')
-rw-r--r--net/sctp/sm_statefuns.c103
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
100static 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
100static sctp_disposition_t sctp_sf_violation_chunklen( 107static 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
114static 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 */
3714static sctp_disposition_t sctp_sf_violation_chunklen( 3718static 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 */
3780static 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 */
3799static 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 ***************************************************************************/