diff options
author | Pavel Emelyanov <xemul@openvz.org> | 2007-10-17 22:47:21 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-10-17 22:47:21 -0400 |
commit | abd6523d15f40bfee14652619a31a7f65f77f581 (patch) | |
tree | ad5692b3c115c4859b99a5e87db8d4b2d991e5a8 /net/ipv4 | |
parent | c6fda282294da882f8d8cc4c513940277dd380f5 (diff) |
[INET]: Consolidate xxx_find() in fragment management
Here we need another callback ->match to check whether the
entry found in hash matches the key passed. The key used
is the same as the creation argument for inet_frag_create.
Yet again, this ->match is the same for netfilter and ipv6.
Running a frew steps forward - this callback will later
replace the ->equal one.
Since the inet_frag_find() uses the already consolidated
inet_frag_create() remove the xxx_frag_create from protocol
codes.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/inet_fragment.c | 25 | ||||
-rw-r--r-- | net/ipv4/ip_fragment.c | 57 |
2 files changed, 43 insertions, 39 deletions
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c index b531f803cda4..6ba98ebbed93 100644 --- a/net/ipv4/inet_fragment.c +++ b/net/ipv4/inet_fragment.c | |||
@@ -226,8 +226,8 @@ static struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f, void *arg) | |||
226 | return q; | 226 | return q; |
227 | } | 227 | } |
228 | 228 | ||
229 | struct inet_frag_queue *inet_frag_create(struct inet_frags *f, void *arg, | 229 | static struct inet_frag_queue *inet_frag_create(struct inet_frags *f, |
230 | unsigned int hash) | 230 | void *arg, unsigned int hash) |
231 | { | 231 | { |
232 | struct inet_frag_queue *q; | 232 | struct inet_frag_queue *q; |
233 | 233 | ||
@@ -237,4 +237,23 @@ struct inet_frag_queue *inet_frag_create(struct inet_frags *f, void *arg, | |||
237 | 237 | ||
238 | return inet_frag_intern(q, f, hash); | 238 | return inet_frag_intern(q, f, hash); |
239 | } | 239 | } |
240 | EXPORT_SYMBOL(inet_frag_create); | 240 | |
241 | struct inet_frag_queue *inet_frag_find(struct inet_frags *f, void *key, | ||
242 | unsigned int hash) | ||
243 | { | ||
244 | struct inet_frag_queue *q; | ||
245 | struct hlist_node *n; | ||
246 | |||
247 | read_lock(&f->lock); | ||
248 | hlist_for_each_entry(q, n, &f->hash[hash], list) { | ||
249 | if (f->match(q, key)) { | ||
250 | atomic_inc(&q->refcnt); | ||
251 | read_unlock(&f->lock); | ||
252 | return q; | ||
253 | } | ||
254 | } | ||
255 | read_unlock(&f->lock); | ||
256 | |||
257 | return inet_frag_create(f, key, hash); | ||
258 | } | ||
259 | EXPORT_SYMBOL(inet_frag_find); | ||
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 0d6cff1de5a3..928259dbc0f8 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
@@ -142,6 +142,19 @@ static int ip4_frag_equal(struct inet_frag_queue *q1, | |||
142 | qp1->user == qp2->user); | 142 | qp1->user == qp2->user); |
143 | } | 143 | } |
144 | 144 | ||
145 | static int ip4_frag_match(struct inet_frag_queue *q, void *a) | ||
146 | { | ||
147 | struct ipq *qp; | ||
148 | struct ip4_create_arg *arg = a; | ||
149 | |||
150 | qp = container_of(q, struct ipq, q); | ||
151 | return (qp->id == arg->iph->id && | ||
152 | qp->saddr == arg->iph->saddr && | ||
153 | qp->daddr == arg->iph->daddr && | ||
154 | qp->protocol == arg->iph->protocol && | ||
155 | qp->user == arg->user); | ||
156 | } | ||
157 | |||
145 | /* Memory Tracking Functions. */ | 158 | /* Memory Tracking Functions. */ |
146 | static __inline__ void frag_kfree_skb(struct sk_buff *skb, int *work) | 159 | static __inline__ void frag_kfree_skb(struct sk_buff *skb, int *work) |
147 | { | 160 | { |
@@ -235,18 +248,20 @@ out: | |||
235 | ipq_put(qp); | 248 | ipq_put(qp); |
236 | } | 249 | } |
237 | 250 | ||
238 | /* Creation primitives. */ | 251 | /* Find the correct entry in the "incomplete datagrams" queue for |
239 | 252 | * this IP datagram, and create new one, if nothing is found. | |
240 | /* Add an entry to the 'ipq' queue for a newly received IP datagram. */ | 253 | */ |
241 | static struct ipq *ip_frag_create(struct iphdr *iph, u32 user, unsigned int h) | 254 | static inline struct ipq *ip_find(struct iphdr *iph, u32 user) |
242 | { | 255 | { |
243 | struct inet_frag_queue *q; | 256 | struct inet_frag_queue *q; |
244 | struct ip4_create_arg arg; | 257 | struct ip4_create_arg arg; |
258 | unsigned int hash; | ||
245 | 259 | ||
246 | arg.iph = iph; | 260 | arg.iph = iph; |
247 | arg.user = user; | 261 | arg.user = user; |
262 | hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol); | ||
248 | 263 | ||
249 | q = inet_frag_create(&ip4_frags, &arg, h); | 264 | q = inet_frag_find(&ip4_frags, &arg, hash); |
250 | if (q == NULL) | 265 | if (q == NULL) |
251 | goto out_nomem; | 266 | goto out_nomem; |
252 | 267 | ||
@@ -257,37 +272,6 @@ out_nomem: | |||
257 | return NULL; | 272 | return NULL; |
258 | } | 273 | } |
259 | 274 | ||
260 | /* Find the correct entry in the "incomplete datagrams" queue for | ||
261 | * this IP datagram, and create new one, if nothing is found. | ||
262 | */ | ||
263 | static inline struct ipq *ip_find(struct iphdr *iph, u32 user) | ||
264 | { | ||
265 | __be16 id = iph->id; | ||
266 | __be32 saddr = iph->saddr; | ||
267 | __be32 daddr = iph->daddr; | ||
268 | __u8 protocol = iph->protocol; | ||
269 | unsigned int hash; | ||
270 | struct ipq *qp; | ||
271 | struct hlist_node *n; | ||
272 | |||
273 | read_lock(&ip4_frags.lock); | ||
274 | hash = ipqhashfn(id, saddr, daddr, protocol); | ||
275 | hlist_for_each_entry(qp, n, &ip4_frags.hash[hash], q.list) { | ||
276 | if (qp->id == id && | ||
277 | qp->saddr == saddr && | ||
278 | qp->daddr == daddr && | ||
279 | qp->protocol == protocol && | ||
280 | qp->user == user) { | ||
281 | atomic_inc(&qp->q.refcnt); | ||
282 | read_unlock(&ip4_frags.lock); | ||
283 | return qp; | ||
284 | } | ||
285 | } | ||
286 | read_unlock(&ip4_frags.lock); | ||
287 | |||
288 | return ip_frag_create(iph, user, hash); | ||
289 | } | ||
290 | |||
291 | /* Is the fragment too far ahead to be part of ipq? */ | 275 | /* Is the fragment too far ahead to be part of ipq? */ |
292 | static inline int ip_frag_too_far(struct ipq *qp) | 276 | static inline int ip_frag_too_far(struct ipq *qp) |
293 | { | 277 | { |
@@ -648,6 +632,7 @@ void __init ipfrag_init(void) | |||
648 | ip4_frags.skb_free = NULL; | 632 | ip4_frags.skb_free = NULL; |
649 | ip4_frags.qsize = sizeof(struct ipq); | 633 | ip4_frags.qsize = sizeof(struct ipq); |
650 | ip4_frags.equal = ip4_frag_equal; | 634 | ip4_frags.equal = ip4_frag_equal; |
635 | ip4_frags.match = ip4_frag_match; | ||
651 | ip4_frags.frag_expire = ip_expire; | 636 | ip4_frags.frag_expire = ip_expire; |
652 | inet_frags_init(&ip4_frags); | 637 | inet_frags_init(&ip4_frags); |
653 | } | 638 | } |