packet_history.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. * Packet RX/TX history data structures and routines for TFRC-based protocols.
  4. *
  5. * Copyright (c) 2007 The University of Aberdeen, Scotland, UK
  6. * Copyright (c) 2005-6 The University of Waikato, Hamilton, New Zealand.
  7. *
  8. * This code has been developed by the University of Waikato WAND
  9. * research group. For further information please see https://www.wand.net.nz/
  10. * or e-mail Ian McDonald - ian.mcdonald@jandi.co.nz
  11. *
  12. * This code also uses code from Lulea University, rereleased as GPL by its
  13. * authors:
  14. * Copyright (c) 2003 Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon
  15. *
  16. * Changes to meet Linux coding standards, to make it meet latest ccid3 draft
  17. * and to make it work as a loadable module in the DCCP stack written by
  18. * Arnaldo Carvalho de Melo <acme@conectiva.com.br>.
  19. *
  20. * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  21. */
  22. #ifndef _DCCP_PKT_HIST_
  23. #define _DCCP_PKT_HIST_
  24. #include <linux/list.h>
  25. #include <linux/slab.h>
  26. #include "tfrc.h"
  27. /**
  28. * tfrc_tx_hist_entry - Simple singly-linked TX history list
  29. * @next: next oldest entry (LIFO order)
  30. * @seqno: sequence number of this entry
  31. * @stamp: send time of packet with sequence number @seqno
  32. */
  33. struct tfrc_tx_hist_entry {
  34. struct tfrc_tx_hist_entry *next;
  35. u64 seqno;
  36. ktime_t stamp;
  37. };
  38. static inline struct tfrc_tx_hist_entry *
  39. tfrc_tx_hist_find_entry(struct tfrc_tx_hist_entry *head, u64 seqno)
  40. {
  41. while (head != NULL && head->seqno != seqno)
  42. head = head->next;
  43. return head;
  44. }
  45. int tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno);
  46. void tfrc_tx_hist_purge(struct tfrc_tx_hist_entry **headp);
  47. /* Subtraction a-b modulo-16, respects circular wrap-around */
  48. #define SUB16(a, b) (((a) + 16 - (b)) & 0xF)
  49. /* Number of packets to wait after a missing packet (RFC 4342, 6.1) */
  50. #define TFRC_NDUPACK 3
  51. /**
  52. * tfrc_rx_hist_entry - Store information about a single received packet
  53. * @tfrchrx_seqno: DCCP packet sequence number
  54. * @tfrchrx_ccval: window counter value of packet (RFC 4342, 8.1)
  55. * @tfrchrx_ndp: the NDP count (if any) of the packet
  56. * @tfrchrx_tstamp: actual receive time of packet
  57. */
  58. struct tfrc_rx_hist_entry {
  59. u64 tfrchrx_seqno:48,
  60. tfrchrx_ccval:4,
  61. tfrchrx_type:4;
  62. u64 tfrchrx_ndp:48;
  63. ktime_t tfrchrx_tstamp;
  64. };
  65. /**
  66. * tfrc_rx_hist - RX history structure for TFRC-based protocols
  67. * @ring: Packet history for RTT sampling and loss detection
  68. * @loss_count: Number of entries in circular history
  69. * @loss_start: Movable index (for loss detection)
  70. * @rtt_sample_prev: Used during RTT sampling, points to candidate entry
  71. */
  72. struct tfrc_rx_hist {
  73. struct tfrc_rx_hist_entry *ring[TFRC_NDUPACK + 1];
  74. u8 loss_count:2,
  75. loss_start:2;
  76. #define rtt_sample_prev loss_start
  77. };
  78. /**
  79. * tfrc_rx_hist_index - index to reach n-th entry after loss_start
  80. */
  81. static inline u8 tfrc_rx_hist_index(const struct tfrc_rx_hist *h, const u8 n)
  82. {
  83. return (h->loss_start + n) & TFRC_NDUPACK;
  84. }
  85. /**
  86. * tfrc_rx_hist_last_rcv - entry with highest-received-seqno so far
  87. */
  88. static inline struct tfrc_rx_hist_entry *
  89. tfrc_rx_hist_last_rcv(const struct tfrc_rx_hist *h)
  90. {
  91. return h->ring[tfrc_rx_hist_index(h, h->loss_count)];
  92. }
  93. /**
  94. * tfrc_rx_hist_entry - return the n-th history entry after loss_start
  95. */
  96. static inline struct tfrc_rx_hist_entry *
  97. tfrc_rx_hist_entry(const struct tfrc_rx_hist *h, const u8 n)
  98. {
  99. return h->ring[tfrc_rx_hist_index(h, n)];
  100. }
  101. /**
  102. * tfrc_rx_hist_loss_prev - entry with highest-received-seqno before loss was detected
  103. */
  104. static inline struct tfrc_rx_hist_entry *
  105. tfrc_rx_hist_loss_prev(const struct tfrc_rx_hist *h)
  106. {
  107. return h->ring[h->loss_start];
  108. }
  109. /* indicate whether previously a packet was detected missing */
  110. static inline bool tfrc_rx_hist_loss_pending(const struct tfrc_rx_hist *h)
  111. {
  112. return h->loss_count > 0;
  113. }
  114. void tfrc_rx_hist_add_packet(struct tfrc_rx_hist *h, const struct sk_buff *skb,
  115. const u64 ndp);
  116. int tfrc_rx_hist_duplicate(struct tfrc_rx_hist *h, struct sk_buff *skb);
  117. struct tfrc_loss_hist;
  118. int tfrc_rx_handle_loss(struct tfrc_rx_hist *h, struct tfrc_loss_hist *lh,
  119. struct sk_buff *skb, const u64 ndp,
  120. u32 (*first_li)(struct sock *sk), struct sock *sk);
  121. u32 tfrc_rx_hist_sample_rtt(struct tfrc_rx_hist *h, const struct sk_buff *skb);
  122. int tfrc_rx_hist_alloc(struct tfrc_rx_hist *h);
  123. void tfrc_rx_hist_purge(struct tfrc_rx_hist *h);
  124. #endif /* _DCCP_PKT_HIST_ */