18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/* SCTP kernel implementation
38c2ecf20Sopenharmony_ci * (C) Copyright IBM Corp. 2001, 2004
48c2ecf20Sopenharmony_ci * Copyright (c) 1999-2000 Cisco, Inc.
58c2ecf20Sopenharmony_ci * Copyright (c) 1999-2001 Motorola, Inc.
68c2ecf20Sopenharmony_ci * Copyright (c) 2001 Intel Corp.
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci * This file is part of the SCTP kernel implementation
98c2ecf20Sopenharmony_ci *
108c2ecf20Sopenharmony_ci * These are the definitions needed for the tsnmap type.  The tsnmap is used
118c2ecf20Sopenharmony_ci * to track out of order TSNs received.
128c2ecf20Sopenharmony_ci *
138c2ecf20Sopenharmony_ci * Please send any bug reports or fixes you make to the
148c2ecf20Sopenharmony_ci * email address(es):
158c2ecf20Sopenharmony_ci *    lksctp developers <linux-sctp@vger.kernel.org>
168c2ecf20Sopenharmony_ci *
178c2ecf20Sopenharmony_ci * Written or modified by:
188c2ecf20Sopenharmony_ci *   Jon Grimm             <jgrimm@us.ibm.com>
198c2ecf20Sopenharmony_ci *   La Monte H.P. Yarroll <piggy@acm.org>
208c2ecf20Sopenharmony_ci *   Karl Knutson          <karl@athena.chicago.il.us>
218c2ecf20Sopenharmony_ci *   Sridhar Samudrala     <sri@us.ibm.com>
228c2ecf20Sopenharmony_ci */
238c2ecf20Sopenharmony_ci#include <net/sctp/constants.h>
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci#ifndef __sctp_tsnmap_h__
268c2ecf20Sopenharmony_ci#define __sctp_tsnmap_h__
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci/* RFC 2960 12.2 Parameters necessary per association (i.e. the TCB)
298c2ecf20Sopenharmony_ci * Mapping  An array of bits or bytes indicating which out of
308c2ecf20Sopenharmony_ci * Array    order TSN's have been received (relative to the
318c2ecf20Sopenharmony_ci *          Last Rcvd TSN). If no gaps exist, i.e. no out of
328c2ecf20Sopenharmony_ci *          order packets have been received, this array
338c2ecf20Sopenharmony_ci *          will be set to all zero. This structure may be
348c2ecf20Sopenharmony_ci *          in the form of a circular buffer or bit array.
358c2ecf20Sopenharmony_ci */
368c2ecf20Sopenharmony_cistruct sctp_tsnmap {
378c2ecf20Sopenharmony_ci	/* This array counts the number of chunks with each TSN.
388c2ecf20Sopenharmony_ci	 * It points at one of the two buffers with which we will
398c2ecf20Sopenharmony_ci	 * ping-pong between.
408c2ecf20Sopenharmony_ci	 */
418c2ecf20Sopenharmony_ci	unsigned long *tsn_map;
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci	/* This is the TSN at tsn_map[0].  */
448c2ecf20Sopenharmony_ci	__u32 base_tsn;
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	/* Last Rcvd   : This is the last TSN received in
478c2ecf20Sopenharmony_ci	 * TSN	       : sequence. This value is set initially by
488c2ecf20Sopenharmony_ci	 *             : taking the peer's Initial TSN, received in
498c2ecf20Sopenharmony_ci	 *             : the INIT or INIT ACK chunk, and subtracting
508c2ecf20Sopenharmony_ci	 *             : one from it.
518c2ecf20Sopenharmony_ci	 *
528c2ecf20Sopenharmony_ci	 * Throughout most of the specification this is called the
538c2ecf20Sopenharmony_ci	 * "Cumulative TSN ACK Point".  In this case, we
548c2ecf20Sopenharmony_ci	 * ignore the advice in 12.2 in favour of the term
558c2ecf20Sopenharmony_ci	 * used in the bulk of the text.
568c2ecf20Sopenharmony_ci	 */
578c2ecf20Sopenharmony_ci	__u32 cumulative_tsn_ack_point;
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	/* This is the highest TSN we've marked.  */
608c2ecf20Sopenharmony_ci	__u32 max_tsn_seen;
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	/* This is the minimum number of TSNs we can track.  This corresponds
638c2ecf20Sopenharmony_ci	 * to the size of tsn_map.   Note: the overflow_map allows us to
648c2ecf20Sopenharmony_ci	 * potentially track more than this quantity.
658c2ecf20Sopenharmony_ci	 */
668c2ecf20Sopenharmony_ci	__u16 len;
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	/* Data chunks pending receipt. used by SCTP_STATUS sockopt */
698c2ecf20Sopenharmony_ci	__u16 pending_data;
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	/* Record duplicate TSNs here.  We clear this after
728c2ecf20Sopenharmony_ci	 * every SACK.  Store up to SCTP_MAX_DUP_TSNS worth of
738c2ecf20Sopenharmony_ci	 * information.
748c2ecf20Sopenharmony_ci	 */
758c2ecf20Sopenharmony_ci	__u16 num_dup_tsns;
768c2ecf20Sopenharmony_ci	__be32 dup_tsns[SCTP_MAX_DUP_TSNS];
778c2ecf20Sopenharmony_ci};
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_cistruct sctp_tsnmap_iter {
808c2ecf20Sopenharmony_ci	__u32 start;
818c2ecf20Sopenharmony_ci};
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci/* Initialize a block of memory as a tsnmap.  */
848c2ecf20Sopenharmony_cistruct sctp_tsnmap *sctp_tsnmap_init(struct sctp_tsnmap *, __u16 len,
858c2ecf20Sopenharmony_ci				     __u32 initial_tsn, gfp_t gfp);
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_civoid sctp_tsnmap_free(struct sctp_tsnmap *map);
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci/* Test the tracking state of this TSN.
908c2ecf20Sopenharmony_ci * Returns:
918c2ecf20Sopenharmony_ci *   0 if the TSN has not yet been seen
928c2ecf20Sopenharmony_ci *  >0 if the TSN has been seen (duplicate)
938c2ecf20Sopenharmony_ci *  <0 if the TSN is invalid (too large to track)
948c2ecf20Sopenharmony_ci */
958c2ecf20Sopenharmony_ciint sctp_tsnmap_check(const struct sctp_tsnmap *, __u32 tsn);
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci/* Mark this TSN as seen.  */
988c2ecf20Sopenharmony_ciint sctp_tsnmap_mark(struct sctp_tsnmap *, __u32 tsn,
998c2ecf20Sopenharmony_ci		     struct sctp_transport *trans);
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci/* Mark this TSN and all lower as seen. */
1028c2ecf20Sopenharmony_civoid sctp_tsnmap_skip(struct sctp_tsnmap *map, __u32 tsn);
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci/* Retrieve the Cumulative TSN ACK Point.  */
1058c2ecf20Sopenharmony_cistatic inline __u32 sctp_tsnmap_get_ctsn(const struct sctp_tsnmap *map)
1068c2ecf20Sopenharmony_ci{
1078c2ecf20Sopenharmony_ci	return map->cumulative_tsn_ack_point;
1088c2ecf20Sopenharmony_ci}
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci/* Retrieve the highest TSN we've seen.  */
1118c2ecf20Sopenharmony_cistatic inline __u32 sctp_tsnmap_get_max_tsn_seen(const struct sctp_tsnmap *map)
1128c2ecf20Sopenharmony_ci{
1138c2ecf20Sopenharmony_ci	return map->max_tsn_seen;
1148c2ecf20Sopenharmony_ci}
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci/* How many duplicate TSNs are stored? */
1178c2ecf20Sopenharmony_cistatic inline __u16 sctp_tsnmap_num_dups(struct sctp_tsnmap *map)
1188c2ecf20Sopenharmony_ci{
1198c2ecf20Sopenharmony_ci	return map->num_dup_tsns;
1208c2ecf20Sopenharmony_ci}
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci/* Return pointer to duplicate tsn array as needed by SACK. */
1238c2ecf20Sopenharmony_cistatic inline __be32 *sctp_tsnmap_get_dups(struct sctp_tsnmap *map)
1248c2ecf20Sopenharmony_ci{
1258c2ecf20Sopenharmony_ci	map->num_dup_tsns = 0;
1268c2ecf20Sopenharmony_ci	return map->dup_tsns;
1278c2ecf20Sopenharmony_ci}
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_ci/* How many gap ack blocks do we have recorded? */
1308c2ecf20Sopenharmony_ci__u16 sctp_tsnmap_num_gabs(struct sctp_tsnmap *map,
1318c2ecf20Sopenharmony_ci			   struct sctp_gap_ack_block *gabs);
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci/* Refresh the count on pending data. */
1348c2ecf20Sopenharmony_ci__u16 sctp_tsnmap_pending(struct sctp_tsnmap *map);
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci/* Is there a gap in the TSN map?  */
1378c2ecf20Sopenharmony_cistatic inline int sctp_tsnmap_has_gap(const struct sctp_tsnmap *map)
1388c2ecf20Sopenharmony_ci{
1398c2ecf20Sopenharmony_ci	return map->cumulative_tsn_ack_point != map->max_tsn_seen;
1408c2ecf20Sopenharmony_ci}
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ci/* Mark a duplicate TSN.  Note:  limit the storage of duplicate TSN
1438c2ecf20Sopenharmony_ci * information.
1448c2ecf20Sopenharmony_ci */
1458c2ecf20Sopenharmony_cistatic inline void sctp_tsnmap_mark_dup(struct sctp_tsnmap *map, __u32 tsn)
1468c2ecf20Sopenharmony_ci{
1478c2ecf20Sopenharmony_ci	if (map->num_dup_tsns < SCTP_MAX_DUP_TSNS)
1488c2ecf20Sopenharmony_ci		map->dup_tsns[map->num_dup_tsns++] = htonl(tsn);
1498c2ecf20Sopenharmony_ci}
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ci/* Renege a TSN that was seen.  */
1528c2ecf20Sopenharmony_civoid sctp_tsnmap_renege(struct sctp_tsnmap *, __u32 tsn);
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci/* Is there a gap in the TSN map? */
1558c2ecf20Sopenharmony_ciint sctp_tsnmap_has_gap(const struct sctp_tsnmap *);
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_ci#endif /* __sctp_tsnmap_h__ */
158