@@ -477,3 +477,82 @@ struct sctp_chunk *sctp_process_strreset_inreq(
477
477
478
478
return chunk ;
479
479
}
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