[PACKET_HISTORY]: Add dccphtx_rtt and rename the win_count fields
[linux-2.6] / net / dccp / packet_history.h
1 /*
2  *  net/dccp/packet_history.h
3  *
4  *  Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand.
5  *
6  *  An implementation of the DCCP protocol
7  *
8  *  This code has been developed by the University of Waikato WAND
9  *  research group. For further information please see http://www.wand.net.nz/
10  *  or e-mail Ian McDonald - iam4@cs.waikato.ac.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  *  This program is free software; you can redistribute it and/or modify
23  *  it under the terms of the GNU General Public License as published by
24  *  the Free Software Foundation; either version 2 of the License, or
25  *  (at your option) any later version.
26  *
27  *  This program is distributed in the hope that it will be useful,
28  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
29  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30  *  GNU General Public License for more details.
31  *
32  *  You should have received a copy of the GNU General Public License
33  *  along with this program; if not, write to the Free Software
34  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35  */
36
37 #ifndef _DCCP_PKT_HIST_
38 #define _DCCP_PKT_HIST_
39
40 #include <linux/config.h>
41 #include <linux/list.h>
42 #include <linux/slab.h>
43 #include <linux/time.h>
44
45 #include "dccp.h"
46
47 struct dccp_tx_hist_entry {
48         struct list_head dccphtx_node;
49         u64              dccphtx_seqno:48,
50                          dccphtx_ccval:4,
51                          dccphtx_sent:1;
52         u32              dccphtx_rtt;
53         struct timeval   dccphtx_tstamp;
54 };
55
56 struct dccp_rx_hist_entry {
57         struct list_head dccphrx_node;
58         u64              dccphrx_seqno:48,
59                          dccphrx_ccval:4,
60                          dccphrx_type:4;
61         u32              dccphrx_ndp; /* In fact it is from 8 to 24 bits */
62         struct timeval   dccphrx_tstamp;
63 };
64
65 struct dccp_tx_hist {
66         kmem_cache_t *dccptxh_slab;
67 };
68
69 extern struct dccp_tx_hist *dccp_tx_hist_new(const char *name);
70 extern void dccp_tx_hist_delete(struct dccp_tx_hist *hist);
71
72 struct dccp_rx_hist {
73         kmem_cache_t *dccprxh_slab;
74 };
75
76 extern struct dccp_rx_hist *dccp_rx_hist_new(const char *name);
77 extern void dccp_rx_hist_delete(struct dccp_rx_hist *hist);
78 extern struct dccp_rx_hist_entry *
79                 dccp_rx_hist_find_data_packet(const struct list_head *list);
80
81 static inline struct dccp_tx_hist_entry *
82                         dccp_tx_hist_entry_new(struct dccp_tx_hist *hist,
83                                                const int prio)
84 {
85         struct dccp_tx_hist_entry *entry = kmem_cache_alloc(hist->dccptxh_slab,
86                                                             prio);
87
88         if (entry != NULL)
89                 entry->dccphtx_sent = 0;
90
91         return entry;
92 }
93
94 static inline void dccp_tx_hist_entry_delete(struct dccp_tx_hist *hist,
95                                              struct dccp_tx_hist_entry *entry)
96 {
97         if (entry != NULL)
98                 kmem_cache_free(hist->dccptxh_slab, entry);
99 }
100
101 extern struct dccp_tx_hist_entry *
102                         dccp_tx_hist_find_entry(const struct list_head *list,
103                                                 const u64 seq);
104
105 static inline void dccp_tx_hist_add_entry(struct list_head *list,
106                                           struct dccp_tx_hist_entry *entry)
107 {
108         list_add(&entry->dccphtx_node, list);
109 }
110
111 extern void dccp_tx_hist_purge_older(struct dccp_tx_hist *hist,
112                                      struct list_head *list,
113                                      struct dccp_tx_hist_entry *next);
114
115 extern void dccp_tx_hist_purge(struct dccp_tx_hist *hist,
116                                struct list_head *list);
117
118 static inline struct dccp_tx_hist_entry *dccp_tx_hist_head(struct list_head *list)
119 {
120         struct dccp_tx_hist_entry *head = NULL;
121
122         if (!list_empty(list))
123                 head = list_entry(list->next, struct dccp_tx_hist_entry,
124                                   dccphtx_node);
125         return head;
126 }
127
128 static inline struct dccp_rx_hist_entry *
129                              dccp_rx_hist_entry_new(struct dccp_rx_hist *hist,
130                                                     const u32 ndp, 
131                                                     const struct sk_buff *skb,
132                                                     const int prio)
133 {
134         struct dccp_rx_hist_entry *entry = kmem_cache_alloc(hist->dccprxh_slab,
135                                                             prio);
136
137         if (entry != NULL) {
138                 const struct dccp_hdr *dh = dccp_hdr(skb);
139
140                 entry->dccphrx_seqno = DCCP_SKB_CB(skb)->dccpd_seq;
141                 entry->dccphrx_ccval = dh->dccph_ccval;
142                 entry->dccphrx_type  = dh->dccph_type;
143                 entry->dccphrx_ndp   = ndp;
144                 do_gettimeofday(&(entry->dccphrx_tstamp));
145         }
146
147         return entry;
148 }
149
150 static inline void dccp_rx_hist_entry_delete(struct dccp_rx_hist *hist,
151                                              struct dccp_rx_hist_entry *entry)
152 {
153         if (entry != NULL)
154                 kmem_cache_free(hist->dccprxh_slab, entry);
155 }
156
157 extern void dccp_rx_hist_purge(struct dccp_rx_hist *hist,
158                                struct list_head *list);
159
160 static inline void dccp_rx_hist_add_entry(struct list_head *list,
161                                           struct dccp_rx_hist_entry *entry)
162 {
163         list_add(&entry->dccphrx_node, list);
164 }
165
166 static inline struct dccp_rx_hist_entry *dccp_rx_hist_head(struct list_head *list)
167 {
168         struct dccp_rx_hist_entry *head = NULL;
169
170         if (!list_empty(list))
171                 head = list_entry(list->next, struct dccp_rx_hist_entry,
172                                   dccphrx_node);
173         return head;
174 }
175
176 static inline int
177         dccp_rx_hist_entry_data_packet(const struct dccp_rx_hist_entry *entry)
178 {
179         return entry->dccphrx_type == DCCP_PKT_DATA ||
180                entry->dccphrx_type == DCCP_PKT_DATAACK;
181 }
182
183 #endif /* _DCCP_PKT_HIST_ */