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