aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/inet_frag.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/inet_frag.h')
-rw-r--r--include/net/inet_frag.h38
1 files changed, 34 insertions, 4 deletions
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
index 76c3fe5ecc2e..bfcbc0017950 100644
--- a/include/net/inet_frag.h
+++ b/include/net/inet_frag.h
@@ -41,12 +41,25 @@ struct inet_frag_queue {
41 struct netns_frags *net; 41 struct netns_frags *net;
42}; 42};
43 43
44#define INETFRAGS_HASHSZ 64 44#define INETFRAGS_HASHSZ 1024
45
46/* averaged:
47 * max_depth = default ipfrag_high_thresh / INETFRAGS_HASHSZ /
48 * rounded up (SKB_TRUELEN(0) + sizeof(struct ipq or
49 * struct frag_queue))
50 */
51#define INETFRAGS_MAXDEPTH 128
52
53struct inet_frag_bucket {
54 struct hlist_head chain;
55 spinlock_t chain_lock;
56};
45 57
46struct inet_frags { 58struct inet_frags {
47 struct hlist_head hash[INETFRAGS_HASHSZ]; 59 struct inet_frag_bucket hash[INETFRAGS_HASHSZ];
48 /* This rwlock is a global lock (seperate per IPv4, IPv6 and 60 /* This rwlock is a global lock (seperate per IPv4, IPv6 and
49 * netfilter). Important to keep this on a seperate cacheline. 61 * netfilter). Important to keep this on a seperate cacheline.
62 * Its primarily a rebuild protection rwlock.
50 */ 63 */
51 rwlock_t lock ____cacheline_aligned_in_smp; 64 rwlock_t lock ____cacheline_aligned_in_smp;
52 int secret_interval; 65 int secret_interval;
@@ -76,6 +89,8 @@ int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f, bool force);
76struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, 89struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
77 struct inet_frags *f, void *key, unsigned int hash) 90 struct inet_frags *f, void *key, unsigned int hash)
78 __releases(&f->lock); 91 __releases(&f->lock);
92void inet_frag_maybe_warn_overflow(struct inet_frag_queue *q,
93 const char *prefix);
79 94
80static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f) 95static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f)
81{ 96{
@@ -126,14 +141,16 @@ static inline int sum_frag_mem_limit(struct netns_frags *nf)
126static inline void inet_frag_lru_move(struct inet_frag_queue *q) 141static inline void inet_frag_lru_move(struct inet_frag_queue *q)
127{ 142{
128 spin_lock(&q->net->lru_lock); 143 spin_lock(&q->net->lru_lock);
129 list_move_tail(&q->lru_list, &q->net->lru_list); 144 if (!list_empty(&q->lru_list))
145 list_move_tail(&q->lru_list, &q->net->lru_list);
130 spin_unlock(&q->net->lru_lock); 146 spin_unlock(&q->net->lru_lock);
131} 147}
132 148
133static inline void inet_frag_lru_del(struct inet_frag_queue *q) 149static inline void inet_frag_lru_del(struct inet_frag_queue *q)
134{ 150{
135 spin_lock(&q->net->lru_lock); 151 spin_lock(&q->net->lru_lock);
136 list_del(&q->lru_list); 152 list_del_init(&q->lru_list);
153 q->net->nqueues--;
137 spin_unlock(&q->net->lru_lock); 154 spin_unlock(&q->net->lru_lock);
138} 155}
139 156
@@ -142,6 +159,19 @@ static inline void inet_frag_lru_add(struct netns_frags *nf,
142{ 159{
143 spin_lock(&nf->lru_lock); 160 spin_lock(&nf->lru_lock);
144 list_add_tail(&q->lru_list, &nf->lru_list); 161 list_add_tail(&q->lru_list, &nf->lru_list);
162 q->net->nqueues++;
145 spin_unlock(&nf->lru_lock); 163 spin_unlock(&nf->lru_lock);
146} 164}
165
166/* RFC 3168 support :
167 * We want to check ECN values of all fragments, do detect invalid combinations.
168 * In ipq->ecn, we store the OR value of each ip4_frag_ecn() fragment value.
169 */
170#define IPFRAG_ECN_NOT_ECT 0x01 /* one frag had ECN_NOT_ECT */
171#define IPFRAG_ECN_ECT_1 0x02 /* one frag had ECN_ECT_1 */
172#define IPFRAG_ECN_ECT_0 0x04 /* one frag had ECN_ECT_0 */
173#define IPFRAG_ECN_CE 0x08 /* one frag had ECN_CE */
174
175extern const u8 ip_frag_ecn_table[16];
176
147#endif 177#endif