Arnaldo Carvalho de Melo | 8c60f3f | 2005-08-10 12:59:38 -0300 | [diff] [blame] | 1 | /* |
Arnaldo Carvalho de Melo | 276f2ed | 2007-11-28 11:15:40 -0200 | [diff] [blame] | 2 | * Packet RX/TX history data structures and routines for TFRC-based protocols. |
Arnaldo Carvalho de Melo | 8c60f3f | 2005-08-10 12:59:38 -0300 | [diff] [blame] | 3 | * |
Arnaldo Carvalho de Melo | 276f2ed | 2007-11-28 11:15:40 -0200 | [diff] [blame] | 4 | * Copyright (c) 2007 The University of Aberdeen, Scotland, UK |
Ian McDonald | e6bccd3 | 2006-08-26 19:01:30 -0700 | [diff] [blame] | 5 | * Copyright (c) 2005-6 The University of Waikato, Hamilton, New Zealand. |
Arnaldo Carvalho de Melo | 8c60f3f | 2005-08-10 12:59:38 -0300 | [diff] [blame] | 6 | * |
Arnaldo Carvalho de Melo | 8c60f3f | 2005-08-10 12:59:38 -0300 | [diff] [blame] | 7 | * This code has been developed by the University of Waikato WAND |
| 8 | * research group. For further information please see http://www.wand.net.nz/ |
Ian McDonald | e6bccd3 | 2006-08-26 19:01:30 -0700 | [diff] [blame] | 9 | * or e-mail Ian McDonald - ian.mcdonald@jandi.co.nz |
Arnaldo Carvalho de Melo | 8c60f3f | 2005-08-10 12:59:38 -0300 | [diff] [blame] | 10 | * |
| 11 | * This code also uses code from Lulea University, rereleased as GPL by its |
| 12 | * authors: |
| 13 | * Copyright (c) 2003 Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon |
| 14 | * |
| 15 | * Changes to meet Linux coding standards, to make it meet latest ccid3 draft |
| 16 | * and to make it work as a loadable module in the DCCP stack written by |
| 17 | * Arnaldo Carvalho de Melo <acme@conectiva.com.br>. |
| 18 | * |
| 19 | * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br> |
| 20 | * |
| 21 | * This program is free software; you can redistribute it and/or modify |
| 22 | * it under the terms of the GNU General Public License as published by |
| 23 | * the Free Software Foundation; either version 2 of the License, or |
| 24 | * (at your option) any later version. |
| 25 | * |
| 26 | * This program is distributed in the hope that it will be useful, |
| 27 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 28 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 29 | * GNU General Public License for more details. |
| 30 | * |
| 31 | * You should have received a copy of the GNU General Public License |
| 32 | * along with this program; if not, write to the Free Software |
| 33 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 34 | */ |
| 35 | |
| 36 | #ifndef _DCCP_PKT_HIST_ |
| 37 | #define _DCCP_PKT_HIST_ |
| 38 | |
Gerrit Renker | 8a9c7e9 | 2007-12-12 13:50:51 -0200 | [diff] [blame] | 39 | #include <linux/list.h> |
| 40 | #include <linux/slab.h> |
| 41 | #include "tfrc.h" |
Arnaldo Carvalho de Melo | 072ab6c | 2005-08-28 01:19:14 -0300 | [diff] [blame] | 42 | |
Gerrit Renker | d2c7263 | 2010-09-14 20:18:00 +0200 | [diff] [blame] | 43 | /** |
| 44 | * tfrc_tx_hist_entry - Simple singly-linked TX history list |
| 45 | * @next: next oldest entry (LIFO order) |
| 46 | * @seqno: sequence number of this entry |
| 47 | * @stamp: send time of packet with sequence number @seqno |
| 48 | */ |
| 49 | struct tfrc_tx_hist_entry { |
| 50 | struct tfrc_tx_hist_entry *next; |
| 51 | u64 seqno; |
| 52 | ktime_t stamp; |
| 53 | }; |
| 54 | |
| 55 | static inline struct tfrc_tx_hist_entry * |
| 56 | tfrc_tx_hist_find_entry(struct tfrc_tx_hist_entry *head, u64 seqno) |
| 57 | { |
| 58 | while (head != NULL && head->seqno != seqno) |
| 59 | head = head->next; |
| 60 | return head; |
| 61 | } |
Arnaldo Carvalho de Melo | 8c60f3f | 2005-08-10 12:59:38 -0300 | [diff] [blame] | 62 | |
Joe Perches | a402a5a | 2013-10-18 13:48:23 -0700 | [diff] [blame] | 63 | int tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno); |
| 64 | void tfrc_tx_hist_purge(struct tfrc_tx_hist_entry **headp); |
Gerrit Renker | 85dcb1f | 2006-12-10 00:24:11 -0200 | [diff] [blame] | 65 | |
Arnaldo Carvalho de Melo | b84a218 | 2007-12-06 13:18:11 -0200 | [diff] [blame] | 66 | /* Subtraction a-b modulo-16, respects circular wrap-around */ |
| 67 | #define SUB16(a, b) (((a) + 16 - (b)) & 0xF) |
| 68 | |
| 69 | /* Number of packets to wait after a missing packet (RFC 4342, 6.1) */ |
| 70 | #define TFRC_NDUPACK 3 |
| 71 | |
| 72 | /** |
| 73 | * tfrc_rx_hist_entry - Store information about a single received packet |
| 74 | * @tfrchrx_seqno: DCCP packet sequence number |
| 75 | * @tfrchrx_ccval: window counter value of packet (RFC 4342, 8.1) |
| 76 | * @tfrchrx_ndp: the NDP count (if any) of the packet |
| 77 | * @tfrchrx_tstamp: actual receive time of packet |
Gerrit Renker | 85dcb1f | 2006-12-10 00:24:11 -0200 | [diff] [blame] | 78 | */ |
Arnaldo Carvalho de Melo | d58d1af | 2007-12-06 12:28:39 -0200 | [diff] [blame] | 79 | struct tfrc_rx_hist_entry { |
Arnaldo Carvalho de Melo | d58d1af | 2007-12-06 12:28:39 -0200 | [diff] [blame] | 80 | u64 tfrchrx_seqno:48, |
| 81 | tfrchrx_ccval:4, |
| 82 | tfrchrx_type:4; |
Gerrit Renker | 5b5d0e7 | 2008-07-13 11:51:40 +0100 | [diff] [blame] | 83 | u64 tfrchrx_ndp:48; |
Arnaldo Carvalho de Melo | d58d1af | 2007-12-06 12:28:39 -0200 | [diff] [blame] | 84 | ktime_t tfrchrx_tstamp; |
Gerrit Renker | 85dcb1f | 2006-12-10 00:24:11 -0200 | [diff] [blame] | 85 | }; |
| 86 | |
Arnaldo Carvalho de Melo | b84a218 | 2007-12-06 13:18:11 -0200 | [diff] [blame] | 87 | /** |
| 88 | * tfrc_rx_hist - RX history structure for TFRC-based protocols |
Arnaldo Carvalho de Melo | b84a218 | 2007-12-06 13:18:11 -0200 | [diff] [blame] | 89 | * @ring: Packet history for RTT sampling and loss detection |
| 90 | * @loss_count: Number of entries in circular history |
| 91 | * @loss_start: Movable index (for loss detection) |
| 92 | * @rtt_sample_prev: Used during RTT sampling, points to candidate entry |
| 93 | */ |
| 94 | struct tfrc_rx_hist { |
| 95 | struct tfrc_rx_hist_entry *ring[TFRC_NDUPACK + 1]; |
| 96 | u8 loss_count:2, |
| 97 | loss_start:2; |
| 98 | #define rtt_sample_prev loss_start |
| 99 | }; |
Arnaldo Carvalho de Melo | 8c60f3f | 2005-08-10 12:59:38 -0300 | [diff] [blame] | 100 | |
Gerrit Renker | 8995a23 | 2007-12-12 12:28:40 -0200 | [diff] [blame] | 101 | /** |
| 102 | * tfrc_rx_hist_index - index to reach n-th entry after loss_start |
| 103 | */ |
| 104 | static inline u8 tfrc_rx_hist_index(const struct tfrc_rx_hist *h, const u8 n) |
| 105 | { |
| 106 | return (h->loss_start + n) & TFRC_NDUPACK; |
| 107 | } |
| 108 | |
| 109 | /** |
| 110 | * tfrc_rx_hist_last_rcv - entry with highest-received-seqno so far |
| 111 | */ |
| 112 | static inline struct tfrc_rx_hist_entry * |
| 113 | tfrc_rx_hist_last_rcv(const struct tfrc_rx_hist *h) |
| 114 | { |
| 115 | return h->ring[tfrc_rx_hist_index(h, h->loss_count)]; |
| 116 | } |
| 117 | |
| 118 | /** |
| 119 | * tfrc_rx_hist_entry - return the n-th history entry after loss_start |
| 120 | */ |
| 121 | static inline struct tfrc_rx_hist_entry * |
| 122 | tfrc_rx_hist_entry(const struct tfrc_rx_hist *h, const u8 n) |
| 123 | { |
| 124 | return h->ring[tfrc_rx_hist_index(h, n)]; |
| 125 | } |
| 126 | |
| 127 | /** |
| 128 | * tfrc_rx_hist_loss_prev - entry with highest-received-seqno before loss was detected |
| 129 | */ |
| 130 | static inline struct tfrc_rx_hist_entry * |
| 131 | tfrc_rx_hist_loss_prev(const struct tfrc_rx_hist *h) |
| 132 | { |
| 133 | return h->ring[h->loss_start]; |
| 134 | } |
| 135 | |
Gerrit Renker | de0d411 | 2007-12-12 14:03:01 -0200 | [diff] [blame] | 136 | /* indicate whether previously a packet was detected missing */ |
Gerrit Renker | b552c62 | 2008-07-13 11:51:40 +0100 | [diff] [blame] | 137 | static inline bool tfrc_rx_hist_loss_pending(const struct tfrc_rx_hist *h) |
Gerrit Renker | de0d411 | 2007-12-12 14:03:01 -0200 | [diff] [blame] | 138 | { |
Gerrit Renker | b552c62 | 2008-07-13 11:51:40 +0100 | [diff] [blame] | 139 | return h->loss_count > 0; |
Gerrit Renker | de0d411 | 2007-12-12 14:03:01 -0200 | [diff] [blame] | 140 | } |
| 141 | |
Joe Perches | a402a5a | 2013-10-18 13:48:23 -0700 | [diff] [blame] | 142 | void tfrc_rx_hist_add_packet(struct tfrc_rx_hist *h, const struct sk_buff *skb, |
| 143 | const u64 ndp); |
Gerrit Renker | 85dcb1f | 2006-12-10 00:24:11 -0200 | [diff] [blame] | 144 | |
Joe Perches | a402a5a | 2013-10-18 13:48:23 -0700 | [diff] [blame] | 145 | int tfrc_rx_hist_duplicate(struct tfrc_rx_hist *h, struct sk_buff *skb); |
Gerrit Renker | de0d411 | 2007-12-12 14:03:01 -0200 | [diff] [blame] | 146 | |
Gerrit Renker | 8a9c7e9 | 2007-12-12 13:50:51 -0200 | [diff] [blame] | 147 | struct tfrc_loss_hist; |
Joe Perches | a402a5a | 2013-10-18 13:48:23 -0700 | [diff] [blame] | 148 | int tfrc_rx_handle_loss(struct tfrc_rx_hist *h, struct tfrc_loss_hist *lh, |
| 149 | struct sk_buff *skb, const u64 ndp, |
| 150 | u32 (*first_li)(struct sock *sk), struct sock *sk); |
| 151 | u32 tfrc_rx_hist_sample_rtt(struct tfrc_rx_hist *h, const struct sk_buff *skb); |
| 152 | int tfrc_rx_hist_alloc(struct tfrc_rx_hist *h); |
| 153 | void tfrc_rx_hist_purge(struct tfrc_rx_hist *h); |
Arnaldo Carvalho de Melo | 29e4f8b | 2005-08-28 02:00:28 -0300 | [diff] [blame] | 154 | |
Arnaldo Carvalho de Melo | 8c60f3f | 2005-08-10 12:59:38 -0300 | [diff] [blame] | 155 | #endif /* _DCCP_PKT_HIST_ */ |