blob: f252a9555e313b97fe86e2fd1f2d0f67c60afe0c [file] [log] [blame]
Arnaldo Carvalho de Melo8c60f3f2005-08-10 12:59:38 -03001/*
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#include <linux/config.h>
Arnaldo Carvalho de Melo5cea0dd2005-08-27 23:50:46 -030038#include <linux/module.h>
Arnaldo Carvalho de Melo8c60f3f2005-08-10 12:59:38 -030039#include <linux/string.h>
40
41#include "packet_history.h"
42
43struct dccp_rx_hist *dccp_rx_hist_new(const char *name)
44{
45 struct dccp_rx_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC);
46 static const char dccp_rx_hist_mask[] = "rx_hist_%s";
47 char *slab_name;
48
49 if (hist == NULL)
50 goto out;
51
52 slab_name = kmalloc(strlen(name) + sizeof(dccp_rx_hist_mask) - 1,
53 GFP_ATOMIC);
54 if (slab_name == NULL)
55 goto out_free_hist;
56
57 sprintf(slab_name, dccp_rx_hist_mask, name);
58 hist->dccprxh_slab = kmem_cache_create(slab_name,
Arnaldo Carvalho de Melo7690af32005-08-13 20:34:54 -030059 sizeof(struct dccp_rx_hist_entry),
Arnaldo Carvalho de Melo8c60f3f2005-08-10 12:59:38 -030060 0, SLAB_HWCACHE_ALIGN,
61 NULL, NULL);
62 if (hist->dccprxh_slab == NULL)
63 goto out_free_slab_name;
64out:
65 return hist;
66out_free_slab_name:
67 kfree(slab_name);
68out_free_hist:
69 kfree(hist);
70 hist = NULL;
71 goto out;
72}
73
74EXPORT_SYMBOL_GPL(dccp_rx_hist_new);
75
76void dccp_rx_hist_delete(struct dccp_rx_hist *hist)
77{
78 const char* name = kmem_cache_name(hist->dccprxh_slab);
79
80 kmem_cache_destroy(hist->dccprxh_slab);
81 kfree(name);
82 kfree(hist);
83}
84
85EXPORT_SYMBOL_GPL(dccp_rx_hist_delete);
86
87void dccp_rx_hist_purge(struct dccp_rx_hist *hist, struct list_head *list)
88{
89 struct dccp_rx_hist_entry *entry, *next;
90
91 list_for_each_entry_safe(entry, next, list, dccphrx_node) {
92 list_del_init(&entry->dccphrx_node);
93 kmem_cache_free(hist->dccprxh_slab, entry);
94 }
95}
96
97EXPORT_SYMBOL_GPL(dccp_rx_hist_purge);
98
99struct dccp_rx_hist_entry *
100 dccp_rx_hist_find_data_packet(const struct list_head *list)
101{
102 struct dccp_rx_hist_entry *entry, *packet = NULL;
103
104 list_for_each_entry(entry, list, dccphrx_node)
105 if (entry->dccphrx_type == DCCP_PKT_DATA ||
106 entry->dccphrx_type == DCCP_PKT_DATAACK) {
107 packet = entry;
108 break;
109 }
110
111 return packet;
112}
113
114EXPORT_SYMBOL_GPL(dccp_rx_hist_find_data_packet);
115
116struct dccp_tx_hist *dccp_tx_hist_new(const char *name)
117{
118 struct dccp_tx_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC);
119 static const char dccp_tx_hist_mask[] = "tx_hist_%s";
120 char *slab_name;
121
122 if (hist == NULL)
123 goto out;
124
125 slab_name = kmalloc(strlen(name) + sizeof(dccp_tx_hist_mask) - 1,
126 GFP_ATOMIC);
127 if (slab_name == NULL)
128 goto out_free_hist;
129
130 sprintf(slab_name, dccp_tx_hist_mask, name);
131 hist->dccptxh_slab = kmem_cache_create(slab_name,
Arnaldo Carvalho de Melo7690af32005-08-13 20:34:54 -0300132 sizeof(struct dccp_tx_hist_entry),
Arnaldo Carvalho de Melo8c60f3f2005-08-10 12:59:38 -0300133 0, SLAB_HWCACHE_ALIGN,
134 NULL, NULL);
135 if (hist->dccptxh_slab == NULL)
136 goto out_free_slab_name;
137out:
138 return hist;
139out_free_slab_name:
140 kfree(slab_name);
141out_free_hist:
142 kfree(hist);
143 hist = NULL;
144 goto out;
145}
146
147EXPORT_SYMBOL_GPL(dccp_tx_hist_new);
148
149void dccp_tx_hist_delete(struct dccp_tx_hist *hist)
150{
151 const char* name = kmem_cache_name(hist->dccptxh_slab);
152
153 kmem_cache_destroy(hist->dccptxh_slab);
154 kfree(name);
155 kfree(hist);
156}
157
158EXPORT_SYMBOL_GPL(dccp_tx_hist_delete);
159
Arnaldo Carvalho de Melo7690af32005-08-13 20:34:54 -0300160struct dccp_tx_hist_entry *
161 dccp_tx_hist_find_entry(const struct list_head *list, const u64 seq)
Arnaldo Carvalho de Melo8c60f3f2005-08-10 12:59:38 -0300162{
163 struct dccp_tx_hist_entry *packet = NULL, *entry;
164
165 list_for_each_entry(entry, list, dccphtx_node)
166 if (entry->dccphtx_seqno == seq) {
167 packet = entry;
168 break;
169 }
170
171 return packet;
172}
173
174EXPORT_SYMBOL_GPL(dccp_tx_hist_find_entry);
175
Arnaldo Carvalho de Melo7690af32005-08-13 20:34:54 -0300176void dccp_tx_hist_purge_older(struct dccp_tx_hist *hist,
177 struct list_head *list,
Arnaldo Carvalho de Melo8c60f3f2005-08-10 12:59:38 -0300178 struct dccp_tx_hist_entry *packet)
179{
180 struct dccp_tx_hist_entry *next;
181
182 list_for_each_entry_safe_continue(packet, next, list, dccphtx_node) {
183 list_del_init(&packet->dccphtx_node);
184 dccp_tx_hist_entry_delete(hist, packet);
185 }
186}
187
188EXPORT_SYMBOL_GPL(dccp_tx_hist_purge_older);
189
190void dccp_tx_hist_purge(struct dccp_tx_hist *hist, struct list_head *list)
191{
192 struct dccp_tx_hist_entry *entry, *next;
193
194 list_for_each_entry_safe(entry, next, list, dccphtx_node) {
195 list_del_init(&entry->dccphtx_node);
196 dccp_tx_hist_entry_delete(hist, entry);
197 }
198}
199
200EXPORT_SYMBOL_GPL(dccp_tx_hist_purge);
Arnaldo Carvalho de Melo5cea0dd2005-08-27 23:50:46 -0300201
202MODULE_AUTHOR("Ian McDonald <iam4@cs.waikato.ac.nz>, "
203 "Arnaldo Carvalho de Melo <acme@ghostprotocols.net>");
204MODULE_DESCRIPTION("DCCP TFRC library");
205MODULE_LICENSE("GPL");