xref: /openbmc/linux/include/net/sctp/tsnmap.h (revision 58e16d792a6a8c6b750f637a4649967fcac853dc)
1*47505b8bSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
260c778b2SVlad Yasevich /* SCTP kernel implementation
31da177e4SLinus Torvalds  * (C) Copyright IBM Corp. 2001, 2004
41da177e4SLinus Torvalds  * Copyright (c) 1999-2000 Cisco, Inc.
51da177e4SLinus Torvalds  * Copyright (c) 1999-2001 Motorola, Inc.
61da177e4SLinus Torvalds  * Copyright (c) 2001 Intel Corp.
71da177e4SLinus Torvalds  *
860c778b2SVlad Yasevich  * This file is part of the SCTP kernel implementation
91da177e4SLinus Torvalds  *
101da177e4SLinus Torvalds  * These are the definitions needed for the tsnmap type.  The tsnmap is used
111da177e4SLinus Torvalds  * to track out of order TSNs received.
121da177e4SLinus Torvalds  *
131da177e4SLinus Torvalds  * Please send any bug reports or fixes you make to the
141da177e4SLinus Torvalds  * email address(es):
1591705c61SDaniel Borkmann  *    lksctp developers <linux-sctp@vger.kernel.org>
161da177e4SLinus Torvalds  *
171da177e4SLinus Torvalds  * Written or modified by:
181da177e4SLinus Torvalds  *   Jon Grimm             <jgrimm@us.ibm.com>
191da177e4SLinus Torvalds  *   La Monte H.P. Yarroll <piggy@acm.org>
201da177e4SLinus Torvalds  *   Karl Knutson          <karl@athena.chicago.il.us>
211da177e4SLinus Torvalds  *   Sridhar Samudrala     <sri@us.ibm.com>
221da177e4SLinus Torvalds  */
231da177e4SLinus Torvalds #include <net/sctp/constants.h>
241da177e4SLinus Torvalds 
251da177e4SLinus Torvalds #ifndef __sctp_tsnmap_h__
261da177e4SLinus Torvalds #define __sctp_tsnmap_h__
271da177e4SLinus Torvalds 
281da177e4SLinus Torvalds /* RFC 2960 12.2 Parameters necessary per association (i.e. the TCB)
291da177e4SLinus Torvalds  * Mapping  An array of bits or bytes indicating which out of
301da177e4SLinus Torvalds  * Array    order TSN's have been received (relative to the
311da177e4SLinus Torvalds  *          Last Rcvd TSN). If no gaps exist, i.e. no out of
321da177e4SLinus Torvalds  *          order packets have been received, this array
331da177e4SLinus Torvalds  *          will be set to all zero. This structure may be
341da177e4SLinus Torvalds  *          in the form of a circular buffer or bit array.
351da177e4SLinus Torvalds  */
361da177e4SLinus Torvalds struct sctp_tsnmap {
371da177e4SLinus Torvalds 	/* This array counts the number of chunks with each TSN.
381da177e4SLinus Torvalds 	 * It points at one of the two buffers with which we will
391da177e4SLinus Torvalds 	 * ping-pong between.
401da177e4SLinus Torvalds 	 */
418e1ee18cSVlad Yasevich 	unsigned long *tsn_map;
421da177e4SLinus Torvalds 
431da177e4SLinus Torvalds 	/* This is the TSN at tsn_map[0].  */
441da177e4SLinus Torvalds 	__u32 base_tsn;
451da177e4SLinus Torvalds 
461da177e4SLinus Torvalds 	/* Last Rcvd   : This is the last TSN received in
471da177e4SLinus Torvalds 	 * TSN	       : sequence. This value is set initially by
481da177e4SLinus Torvalds 	 *             : taking the peer's Initial TSN, received in
491da177e4SLinus Torvalds 	 *             : the INIT or INIT ACK chunk, and subtracting
501da177e4SLinus Torvalds 	 *             : one from it.
511da177e4SLinus Torvalds 	 *
521da177e4SLinus Torvalds 	 * Throughout most of the specification this is called the
531da177e4SLinus Torvalds 	 * "Cumulative TSN ACK Point".  In this case, we
541da177e4SLinus Torvalds 	 * ignore the advice in 12.2 in favour of the term
551da177e4SLinus Torvalds 	 * used in the bulk of the text.
561da177e4SLinus Torvalds 	 */
571da177e4SLinus Torvalds 	__u32 cumulative_tsn_ack_point;
581da177e4SLinus Torvalds 
598e1ee18cSVlad Yasevich 	/* This is the highest TSN we've marked.  */
608e1ee18cSVlad Yasevich 	__u32 max_tsn_seen;
618e1ee18cSVlad Yasevich 
621da177e4SLinus Torvalds 	/* This is the minimum number of TSNs we can track.  This corresponds
631da177e4SLinus Torvalds 	 * to the size of tsn_map.   Note: the overflow_map allows us to
641da177e4SLinus Torvalds 	 * potentially track more than this quantity.
651da177e4SLinus Torvalds 	 */
661da177e4SLinus Torvalds 	__u16 len;
671da177e4SLinus Torvalds 
681da177e4SLinus Torvalds 	/* Data chunks pending receipt. used by SCTP_STATUS sockopt */
691da177e4SLinus Torvalds 	__u16 pending_data;
701da177e4SLinus Torvalds 
711da177e4SLinus Torvalds 	/* Record duplicate TSNs here.  We clear this after
721da177e4SLinus Torvalds 	 * every SACK.  Store up to SCTP_MAX_DUP_TSNS worth of
731da177e4SLinus Torvalds 	 * information.
741da177e4SLinus Torvalds 	 */
751da177e4SLinus Torvalds 	__u16 num_dup_tsns;
7602015180SVlad Yasevich 	__be32 dup_tsns[SCTP_MAX_DUP_TSNS];
771da177e4SLinus Torvalds };
781da177e4SLinus Torvalds 
791da177e4SLinus Torvalds struct sctp_tsnmap_iter {
801da177e4SLinus Torvalds 	__u32 start;
811da177e4SLinus Torvalds };
821da177e4SLinus Torvalds 
831da177e4SLinus Torvalds /* Initialize a block of memory as a tsnmap.  */
841da177e4SLinus Torvalds struct sctp_tsnmap *sctp_tsnmap_init(struct sctp_tsnmap *, __u16 len,
858e1ee18cSVlad Yasevich 				     __u32 initial_tsn, gfp_t gfp);
868e1ee18cSVlad Yasevich 
878e1ee18cSVlad Yasevich void sctp_tsnmap_free(struct sctp_tsnmap *map);
881da177e4SLinus Torvalds 
891da177e4SLinus Torvalds /* Test the tracking state of this TSN.
901da177e4SLinus Torvalds  * Returns:
911da177e4SLinus Torvalds  *   0 if the TSN has not yet been seen
921da177e4SLinus Torvalds  *  >0 if the TSN has been seen (duplicate)
931da177e4SLinus Torvalds  *  <0 if the TSN is invalid (too large to track)
941da177e4SLinus Torvalds  */
951da177e4SLinus Torvalds int sctp_tsnmap_check(const struct sctp_tsnmap *, __u32 tsn);
961da177e4SLinus Torvalds 
971da177e4SLinus Torvalds /* Mark this TSN as seen.  */
984244854dSNeil Horman int sctp_tsnmap_mark(struct sctp_tsnmap *, __u32 tsn,
994244854dSNeil Horman 		     struct sctp_transport *trans);
1001da177e4SLinus Torvalds 
1011da177e4SLinus Torvalds /* Mark this TSN and all lower as seen. */
1021da177e4SLinus Torvalds void sctp_tsnmap_skip(struct sctp_tsnmap *map, __u32 tsn);
1031da177e4SLinus Torvalds 
1041da177e4SLinus Torvalds /* Retrieve the Cumulative TSN ACK Point.  */
sctp_tsnmap_get_ctsn(const struct sctp_tsnmap * map)1051da177e4SLinus Torvalds static inline __u32 sctp_tsnmap_get_ctsn(const struct sctp_tsnmap *map)
1061da177e4SLinus Torvalds {
1071da177e4SLinus Torvalds 	return map->cumulative_tsn_ack_point;
1081da177e4SLinus Torvalds }
1091da177e4SLinus Torvalds 
1101da177e4SLinus Torvalds /* Retrieve the highest TSN we've seen.  */
sctp_tsnmap_get_max_tsn_seen(const struct sctp_tsnmap * map)1111da177e4SLinus Torvalds static inline __u32 sctp_tsnmap_get_max_tsn_seen(const struct sctp_tsnmap *map)
1121da177e4SLinus Torvalds {
1131da177e4SLinus Torvalds 	return map->max_tsn_seen;
1141da177e4SLinus Torvalds }
1151da177e4SLinus Torvalds 
1161da177e4SLinus Torvalds /* How many duplicate TSNs are stored? */
sctp_tsnmap_num_dups(struct sctp_tsnmap * map)1171da177e4SLinus Torvalds static inline __u16 sctp_tsnmap_num_dups(struct sctp_tsnmap *map)
1181da177e4SLinus Torvalds {
1191da177e4SLinus Torvalds 	return map->num_dup_tsns;
1201da177e4SLinus Torvalds }
1211da177e4SLinus Torvalds 
1221da177e4SLinus Torvalds /* Return pointer to duplicate tsn array as needed by SACK. */
sctp_tsnmap_get_dups(struct sctp_tsnmap * map)12372f17e1cSAl Viro static inline __be32 *sctp_tsnmap_get_dups(struct sctp_tsnmap *map)
1241da177e4SLinus Torvalds {
1251da177e4SLinus Torvalds 	map->num_dup_tsns = 0;
1261da177e4SLinus Torvalds 	return map->dup_tsns;
1271da177e4SLinus Torvalds }
1281da177e4SLinus Torvalds 
1291da177e4SLinus Torvalds /* How many gap ack blocks do we have recorded? */
13002015180SVlad Yasevich __u16 sctp_tsnmap_num_gabs(struct sctp_tsnmap *map,
13102015180SVlad Yasevich 			   struct sctp_gap_ack_block *gabs);
1321da177e4SLinus Torvalds 
1331da177e4SLinus Torvalds /* Refresh the count on pending data. */
1341da177e4SLinus Torvalds __u16 sctp_tsnmap_pending(struct sctp_tsnmap *map);
1351da177e4SLinus Torvalds 
1361da177e4SLinus Torvalds /* Is there a gap in the TSN map?  */
sctp_tsnmap_has_gap(const struct sctp_tsnmap * map)1371da177e4SLinus Torvalds static inline int sctp_tsnmap_has_gap(const struct sctp_tsnmap *map)
1381da177e4SLinus Torvalds {
139a02cec21SEric Dumazet 	return map->cumulative_tsn_ack_point != map->max_tsn_seen;
1401da177e4SLinus Torvalds }
1411da177e4SLinus Torvalds 
1421da177e4SLinus Torvalds /* Mark a duplicate TSN.  Note:  limit the storage of duplicate TSN
1431da177e4SLinus Torvalds  * information.
1441da177e4SLinus Torvalds  */
sctp_tsnmap_mark_dup(struct sctp_tsnmap * map,__u32 tsn)1451da177e4SLinus Torvalds static inline void sctp_tsnmap_mark_dup(struct sctp_tsnmap *map, __u32 tsn)
1461da177e4SLinus Torvalds {
1471da177e4SLinus Torvalds 	if (map->num_dup_tsns < SCTP_MAX_DUP_TSNS)
1481da177e4SLinus Torvalds 		map->dup_tsns[map->num_dup_tsns++] = htonl(tsn);
1491da177e4SLinus Torvalds }
1501da177e4SLinus Torvalds 
1511da177e4SLinus Torvalds /* Renege a TSN that was seen.  */
1521da177e4SLinus Torvalds void sctp_tsnmap_renege(struct sctp_tsnmap *, __u32 tsn);
1531da177e4SLinus Torvalds 
1541da177e4SLinus Torvalds /* Is there a gap in the TSN map? */
1551da177e4SLinus Torvalds int sctp_tsnmap_has_gap(const struct sctp_tsnmap *);
1561da177e4SLinus Torvalds 
1571da177e4SLinus Torvalds #endif /* __sctp_tsnmap_h__ */
158