]> git.proxmox.com Git - mirror_ovs.git/blame - datapath/linux/compat/inet_fragment.c
compat: Simplify inet_fragment backports.
[mirror_ovs.git] / datapath / linux / compat / inet_fragment.c
CommitLineData
595e069a
JS
1/*
2 * inet fragments management
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Authors: Pavel Emelyanov <xemul@openvz.org>
10 * Started as consolidation of ipv4/ip_fragment.c,
11 * ipv6/reassembly. and ipv6 nf conntrack reassembly
12 */
13
3cdc5697 14#ifndef HAVE_CORRECT_MRU_HANDLING
595e069a
JS
15
16#include <linux/list.h>
17#include <linux/spinlock.h>
18#include <linux/module.h>
19#include <linux/timer.h>
20#include <linux/mm.h>
21#include <linux/random.h>
22#include <linux/skbuff.h>
23#include <linux/rtnetlink.h>
24#include <linux/slab.h>
25
26#include <net/sock.h>
27#include <net/inet_frag.h>
28#include <net/inet_ecn.h>
29
91408ae0 30#ifdef HAVE_INET_FRAGS_WITH_FRAGS_WORK
595e069a
JS
31static bool inet_fragq_should_evict(const struct inet_frag_queue *q)
32{
33 return q->net->low_thresh == 0 ||
34 frag_mem_limit(q->net) >= q->net->low_thresh;
35}
36
37static unsigned int
38inet_evict_bucket(struct inet_frags *f, struct inet_frag_bucket *hb)
39{
595e069a
JS
40 struct inet_frag_queue *fq;
41 struct hlist_node *n;
42 unsigned int evicted = 0;
43 HLIST_HEAD(expired);
44
45 spin_lock(&hb->chain_lock);
46
47 hlist_for_each_entry_safe(fq, n, &hb->chain, list) {
48 if (!inet_fragq_should_evict(fq))
49 continue;
50
51 if (!del_timer(&fq->timer))
52 continue;
53
e0d45da3
JS
54#ifdef HAVE_INET_FRAG_QUEUE_WITH_LIST_EVICTOR
55 hlist_add_head(&fq->list_evictor, &expired);
56#else
ccd0a13b
JS
57 hlist_del(&fq->list);
58 hlist_add_head(&fq->list, &expired);
595e069a
JS
59#endif
60 ++evicted;
61 }
62
63 spin_unlock(&hb->chain_lock);
64
e0d45da3 65#ifdef HAVE_INET_FRAG_QUEUE_WITH_LIST_EVICTOR
595e069a 66 hlist_for_each_entry_safe(fq, n, &expired, list_evictor)
e0d45da3 67#else
ccd0a13b 68 hlist_for_each_entry_safe(fq, n, &expired, list)
595e069a 69#endif
ccd0a13b 70 f->frag_expire((unsigned long) fq);
595e069a
JS
71
72 return evicted;
73}
74
595e069a
JS
75void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f)
76{
ccd0a13b 77 int thresh = nf->low_thresh;
595e069a 78 unsigned int seq;
ccd0a13b
JS
79 int i;
80
81 nf->low_thresh = 0;
595e069a
JS
82
83evict_again:
84 local_bh_disable();
85 seq = read_seqbegin(&f->rnd_seqlock);
86
ccd0a13b
JS
87 for (i = 0; i < INETFRAGS_HASHSZ ; i++)
88 inet_evict_bucket(f, &f->hash[i]);
595e069a
JS
89
90 local_bh_enable();
91 cond_resched();
92
93 if (read_seqretry(&f->rnd_seqlock, seq) ||
94 percpu_counter_sum(&nf->mem))
95 goto evict_again;
595e069a 96
ccd0a13b 97 nf->low_thresh = thresh;
595e069a 98}
ccd0a13b
JS
99#else /* HAVE_INET_FRAGS_WITH_FRAGS_WORK */
100void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f)
595e069a 101{
ccd0a13b 102 int thresh = nf->low_thresh;
595e069a 103
ccd0a13b 104 nf->low_thresh = 0;
595e069a 105
ccd0a13b
JS
106 local_bh_disable();
107 inet_frag_evictor(nf, f, true);
108 local_bh_enable();
595e069a 109
ccd0a13b 110 nf->low_thresh = thresh;
595e069a 111}
ccd0a13b 112#endif /* HAVE_INET_FRAGS_WITH_FRAGS_WORK */
595e069a 113
3cdc5697 114#endif /* !HAVE_CORRECT_MRU_HANDLING */