aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/dccp/ccids/lib/packet_history.c219
1 files changed, 112 insertions, 107 deletions
diff --git a/net/dccp/ccids/lib/packet_history.c b/net/dccp/ccids/lib/packet_history.c
index b876c9c81c65..2e8ef42721e2 100644
--- a/net/dccp/ccids/lib/packet_history.c
+++ b/net/dccp/ccids/lib/packet_history.c
@@ -36,9 +36,100 @@
36 36
37#include <linux/module.h> 37#include <linux/module.h>
38#include <linux/string.h> 38#include <linux/string.h>
39
40#include "packet_history.h" 39#include "packet_history.h"
41 40
41/*
42 * Transmitter History Routines
43 */
44struct dccp_tx_hist *dccp_tx_hist_new(const char *name)
45{
46 struct dccp_tx_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC);
47 static const char dccp_tx_hist_mask[] = "tx_hist_%s";
48 char *slab_name;
49
50 if (hist == NULL)
51 goto out;
52
53 slab_name = kmalloc(strlen(name) + sizeof(dccp_tx_hist_mask) - 1,
54 GFP_ATOMIC);
55 if (slab_name == NULL)
56 goto out_free_hist;
57
58 sprintf(slab_name, dccp_tx_hist_mask, name);
59 hist->dccptxh_slab = kmem_cache_create(slab_name,
60 sizeof(struct dccp_tx_hist_entry),
61 0, SLAB_HWCACHE_ALIGN,
62 NULL, NULL);
63 if (hist->dccptxh_slab == NULL)
64 goto out_free_slab_name;
65out:
66 return hist;
67out_free_slab_name:
68 kfree(slab_name);
69out_free_hist:
70 kfree(hist);
71 hist = NULL;
72 goto out;
73}
74
75EXPORT_SYMBOL_GPL(dccp_tx_hist_new);
76
77void dccp_tx_hist_delete(struct dccp_tx_hist *hist)
78{
79 const char* name = kmem_cache_name(hist->dccptxh_slab);
80
81 kmem_cache_destroy(hist->dccptxh_slab);
82 kfree(name);
83 kfree(hist);
84}
85
86EXPORT_SYMBOL_GPL(dccp_tx_hist_delete);
87
88struct dccp_tx_hist_entry *
89 dccp_tx_hist_find_entry(const struct list_head *list, const u64 seq)
90{
91 struct dccp_tx_hist_entry *packet = NULL, *entry;
92
93 list_for_each_entry(entry, list, dccphtx_node)
94 if (entry->dccphtx_seqno == seq) {
95 packet = entry;
96 break;
97 }
98
99 return packet;
100}
101
102EXPORT_SYMBOL_GPL(dccp_tx_hist_find_entry);
103
104void dccp_tx_hist_purge(struct dccp_tx_hist *hist, struct list_head *list)
105{
106 struct dccp_tx_hist_entry *entry, *next;
107
108 list_for_each_entry_safe(entry, next, list, dccphtx_node) {
109 list_del_init(&entry->dccphtx_node);
110 dccp_tx_hist_entry_delete(hist, entry);
111 }
112}
113
114EXPORT_SYMBOL_GPL(dccp_tx_hist_purge);
115
116void dccp_tx_hist_purge_older(struct dccp_tx_hist *hist,
117 struct list_head *list,
118 struct dccp_tx_hist_entry *packet)
119{
120 struct dccp_tx_hist_entry *next;
121
122 list_for_each_entry_safe_continue(packet, next, list, dccphtx_node) {
123 list_del_init(&packet->dccphtx_node);
124 dccp_tx_hist_entry_delete(hist, packet);
125 }
126}
127
128EXPORT_SYMBOL_GPL(dccp_tx_hist_purge_older);
129
130/*
131 * Receiver History Routines
132 */
42struct dccp_rx_hist *dccp_rx_hist_new(const char *name) 133struct dccp_rx_hist *dccp_rx_hist_new(const char *name)
43{ 134{
44 struct dccp_rx_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC); 135 struct dccp_rx_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC);
@@ -83,18 +174,24 @@ void dccp_rx_hist_delete(struct dccp_rx_hist *hist)
83 174
84EXPORT_SYMBOL_GPL(dccp_rx_hist_delete); 175EXPORT_SYMBOL_GPL(dccp_rx_hist_delete);
85 176
86void dccp_rx_hist_purge(struct dccp_rx_hist *hist, struct list_head *list) 177int dccp_rx_hist_find_entry(const struct list_head *list, const u64 seq,
178 u8 *ccval)
87{ 179{
88 struct dccp_rx_hist_entry *entry, *next; 180 struct dccp_rx_hist_entry *packet = NULL, *entry;
89 181
90 list_for_each_entry_safe(entry, next, list, dccphrx_node) { 182 list_for_each_entry(entry, list, dccphrx_node)
91 list_del_init(&entry->dccphrx_node); 183 if (entry->dccphrx_seqno == seq) {
92 kmem_cache_free(hist->dccprxh_slab, entry); 184 packet = entry;
93 } 185 break;
94} 186 }
95 187
96EXPORT_SYMBOL_GPL(dccp_rx_hist_purge); 188 if (packet)
189 *ccval = packet->dccphrx_ccval;
97 190
191 return packet != NULL;
192}
193
194EXPORT_SYMBOL_GPL(dccp_rx_hist_find_entry);
98struct dccp_rx_hist_entry * 195struct dccp_rx_hist_entry *
99 dccp_rx_hist_find_data_packet(const struct list_head *list) 196 dccp_rx_hist_find_data_packet(const struct list_head *list)
100{ 197{
@@ -184,110 +281,18 @@ void dccp_rx_hist_add_packet(struct dccp_rx_hist *hist,
184 281
185EXPORT_SYMBOL_GPL(dccp_rx_hist_add_packet); 282EXPORT_SYMBOL_GPL(dccp_rx_hist_add_packet);
186 283
187struct dccp_tx_hist *dccp_tx_hist_new(const char *name) 284void dccp_rx_hist_purge(struct dccp_rx_hist *hist, struct list_head *list)
188{
189 struct dccp_tx_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC);
190 static const char dccp_tx_hist_mask[] = "tx_hist_%s";
191 char *slab_name;
192
193 if (hist == NULL)
194 goto out;
195
196 slab_name = kmalloc(strlen(name) + sizeof(dccp_tx_hist_mask) - 1,
197 GFP_ATOMIC);
198 if (slab_name == NULL)
199 goto out_free_hist;
200
201 sprintf(slab_name, dccp_tx_hist_mask, name);
202 hist->dccptxh_slab = kmem_cache_create(slab_name,
203 sizeof(struct dccp_tx_hist_entry),
204 0, SLAB_HWCACHE_ALIGN,
205 NULL, NULL);
206 if (hist->dccptxh_slab == NULL)
207 goto out_free_slab_name;
208out:
209 return hist;
210out_free_slab_name:
211 kfree(slab_name);
212out_free_hist:
213 kfree(hist);
214 hist = NULL;
215 goto out;
216}
217
218EXPORT_SYMBOL_GPL(dccp_tx_hist_new);
219
220void dccp_tx_hist_delete(struct dccp_tx_hist *hist)
221{
222 const char* name = kmem_cache_name(hist->dccptxh_slab);
223
224 kmem_cache_destroy(hist->dccptxh_slab);
225 kfree(name);
226 kfree(hist);
227}
228
229EXPORT_SYMBOL_GPL(dccp_tx_hist_delete);
230
231struct dccp_tx_hist_entry *
232 dccp_tx_hist_find_entry(const struct list_head *list, const u64 seq)
233{
234 struct dccp_tx_hist_entry *packet = NULL, *entry;
235
236 list_for_each_entry(entry, list, dccphtx_node)
237 if (entry->dccphtx_seqno == seq) {
238 packet = entry;
239 break;
240 }
241
242 return packet;
243}
244
245EXPORT_SYMBOL_GPL(dccp_tx_hist_find_entry);
246
247int dccp_rx_hist_find_entry(const struct list_head *list, const u64 seq,
248 u8 *ccval)
249{
250 struct dccp_rx_hist_entry *packet = NULL, *entry;
251
252 list_for_each_entry(entry, list, dccphrx_node)
253 if (entry->dccphrx_seqno == seq) {
254 packet = entry;
255 break;
256 }
257
258 if (packet)
259 *ccval = packet->dccphrx_ccval;
260
261 return packet != NULL;
262}
263
264EXPORT_SYMBOL_GPL(dccp_rx_hist_find_entry);
265
266void dccp_tx_hist_purge_older(struct dccp_tx_hist *hist,
267 struct list_head *list,
268 struct dccp_tx_hist_entry *packet)
269{ 285{
270 struct dccp_tx_hist_entry *next; 286 struct dccp_rx_hist_entry *entry, *next;
271 287
272 list_for_each_entry_safe_continue(packet, next, list, dccphtx_node) { 288 list_for_each_entry_safe(entry, next, list, dccphrx_node) {
273 list_del_init(&packet->dccphtx_node); 289 list_del_init(&entry->dccphrx_node);
274 dccp_tx_hist_entry_delete(hist, packet); 290 kmem_cache_free(hist->dccprxh_slab, entry);
275 } 291 }
276} 292}
277 293
278EXPORT_SYMBOL_GPL(dccp_tx_hist_purge_older); 294EXPORT_SYMBOL_GPL(dccp_rx_hist_purge);
279
280void dccp_tx_hist_purge(struct dccp_tx_hist *hist, struct list_head *list)
281{
282 struct dccp_tx_hist_entry *entry, *next;
283
284 list_for_each_entry_safe(entry, next, list, dccphtx_node) {
285 list_del_init(&entry->dccphtx_node);
286 dccp_tx_hist_entry_delete(hist, entry);
287 }
288}
289 295
290EXPORT_SYMBOL_GPL(dccp_tx_hist_purge);
291 296
292MODULE_AUTHOR("Ian McDonald <ian.mcdonald@jandi.co.nz>, " 297MODULE_AUTHOR("Ian McDonald <ian.mcdonald@jandi.co.nz>, "
293 "Arnaldo Carvalho de Melo <acme@ghostprotocols.net>"); 298 "Arnaldo Carvalho de Melo <acme@ghostprotocols.net>");