@@ -477,3 +477,82 @@ struct sctp_chunk *sctp_process_strreset_inreq(
477477
478478 return chunk ;
479479}
480+
481+ struct sctp_chunk * sctp_process_strreset_tsnreq (
482+ struct sctp_association * asoc ,
483+ union sctp_params param ,
484+ struct sctp_ulpevent * * evp )
485+ {
486+ __u32 init_tsn = 0 , next_tsn = 0 , max_tsn_seen ;
487+ struct sctp_strreset_tsnreq * tsnreq = param .v ;
488+ struct sctp_stream * stream = asoc -> stream ;
489+ __u32 result = SCTP_STRRESET_DENIED ;
490+ __u32 request_seq ;
491+ __u16 i ;
492+
493+ request_seq = ntohl (tsnreq -> request_seq );
494+ if (request_seq > asoc -> strreset_inseq ) {
495+ result = SCTP_STRRESET_ERR_BAD_SEQNO ;
496+ goto out ;
497+ } else if (request_seq == asoc -> strreset_inseq ) {
498+ asoc -> strreset_inseq ++ ;
499+ }
500+
501+ if (!(asoc -> strreset_enable & SCTP_ENABLE_RESET_ASSOC_REQ ))
502+ goto out ;
503+
504+ if (asoc -> strreset_outstanding ) {
505+ result = SCTP_STRRESET_ERR_IN_PROGRESS ;
506+ goto out ;
507+ }
508+
509+ /* G3: The same processing as though a SACK chunk with no gap report
510+ * and a cumulative TSN ACK of the Sender's Next TSN minus 1 were
511+ * received MUST be performed.
512+ */
513+ max_tsn_seen = sctp_tsnmap_get_max_tsn_seen (& asoc -> peer .tsn_map );
514+ sctp_ulpq_reasm_flushtsn (& asoc -> ulpq , max_tsn_seen );
515+ sctp_ulpq_abort_pd (& asoc -> ulpq , GFP_ATOMIC );
516+
517+ /* G1: Compute an appropriate value for the Receiver's Next TSN -- the
518+ * TSN that the peer should use to send the next DATA chunk. The
519+ * value SHOULD be the smallest TSN not acknowledged by the
520+ * receiver of the request plus 2^31.
521+ */
522+ init_tsn = sctp_tsnmap_get_ctsn (& asoc -> peer .tsn_map ) + (1 << 31 );
523+ sctp_tsnmap_init (& asoc -> peer .tsn_map , SCTP_TSN_MAP_INITIAL ,
524+ init_tsn , GFP_ATOMIC );
525+
526+ /* G4: The same processing as though a FWD-TSN chunk (as defined in
527+ * [RFC3758]) with all streams affected and a new cumulative TSN
528+ * ACK of the Receiver's Next TSN minus 1 were received MUST be
529+ * performed.
530+ */
531+ sctp_outq_free (& asoc -> outqueue );
532+
533+ /* G2: Compute an appropriate value for the local endpoint's next TSN,
534+ * i.e., the next TSN assigned by the receiver of the SSN/TSN reset
535+ * chunk. The value SHOULD be the highest TSN sent by the receiver
536+ * of the request plus 1.
537+ */
538+ next_tsn = asoc -> next_tsn ;
539+ asoc -> ctsn_ack_point = next_tsn - 1 ;
540+ asoc -> adv_peer_ack_point = asoc -> ctsn_ack_point ;
541+
542+ /* G5: The next expected and outgoing SSNs MUST be reset to 0 for all
543+ * incoming and outgoing streams.
544+ */
545+ for (i = 0 ; i < stream -> outcnt ; i ++ )
546+ stream -> out [i ].ssn = 0 ;
547+ for (i = 0 ; i < stream -> incnt ; i ++ )
548+ stream -> in [i ].ssn = 0 ;
549+
550+ result = SCTP_STRRESET_PERFORMED ;
551+
552+ * evp = sctp_ulpevent_make_assoc_reset_event (asoc , 0 , init_tsn ,
553+ next_tsn , GFP_ATOMIC );
554+
555+ out :
556+ return sctp_make_strreset_tsnresp (asoc , result , request_seq ,
557+ next_tsn , init_tsn );
558+ }
0 commit comments