]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - net/dccp/packet_history.h
489fff45ccdff2fd9de934721c939031522c8d0a
[linux-2.6-omap-h63xx.git] / 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 *
119                 dccp_tx_hist_head(struct list_head *list)
120 {
121         struct dccp_tx_hist_entry *head = NULL;
122
123         if (!list_empty(list))
124                 head = list_entry(list->next, struct dccp_tx_hist_entry,
125                                   dccphtx_node);
126         return head;
127 }
128
129 static inline struct dccp_rx_hist_entry *
130                              dccp_rx_hist_entry_new(struct dccp_rx_hist *hist,
131                                                     const u32 ndp, 
132                                                     const struct sk_buff *skb,
133                                                     const int prio)
134 {
135         struct dccp_rx_hist_entry *entry = kmem_cache_alloc(hist->dccprxh_slab,
136                                                             prio);
137
138         if (entry != NULL) {
139                 const struct dccp_hdr *dh = dccp_hdr(skb);
140
141                 entry->dccphrx_seqno = DCCP_SKB_CB(skb)->dccpd_seq;
142                 entry->dccphrx_ccval = dh->dccph_ccval;
143                 entry->dccphrx_type  = dh->dccph_type;
144                 entry->dccphrx_ndp   = ndp;
145                 do_gettimeofday(&(entry->dccphrx_tstamp));
146         }
147
148         return entry;
149 }
150
151 static inline void dccp_rx_hist_entry_delete(struct dccp_rx_hist *hist,
152                                              struct dccp_rx_hist_entry *entry)
153 {
154         if (entry != NULL)
155                 kmem_cache_free(hist->dccprxh_slab, entry);
156 }
157
158 extern void dccp_rx_hist_purge(struct dccp_rx_hist *hist,
159                                struct list_head *list);
160
161 static inline void dccp_rx_hist_add_entry(struct list_head *list,
162                                           struct dccp_rx_hist_entry *entry)
163 {
164         list_add(&entry->dccphrx_node, list);
165 }
166
167 static inline struct dccp_rx_hist_entry *
168                 dccp_rx_hist_head(struct list_head *list)
169 {
170         struct dccp_rx_hist_entry *head = NULL;
171
172         if (!list_empty(list))
173                 head = list_entry(list->next, struct dccp_rx_hist_entry,
174                                   dccphrx_node);
175         return head;
176 }
177
178 static inline int
179         dccp_rx_hist_entry_data_packet(const struct dccp_rx_hist_entry *entry)
180 {
181         return entry->dccphrx_type == DCCP_PKT_DATA ||
182                entry->dccphrx_type == DCCP_PKT_DATAACK;
183 }
184
185 #endif /* _DCCP_PKT_HIST_ */