blob: a8332404d9b42aff862ac783ed906122c87c7864 [file] [log] [blame]
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +02001/* Copyright (C) 2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as
5 * published by the Free Software Foundation.
6 */
7
8#ifndef _IP_SET_HASH_GEN_H
9#define _IP_SET_HASH_GEN_H
10
11#include <linux/rcupdate.h>
12#include <linux/jhash.h>
13#include <linux/netfilter/ipset/ip_set_timeout.h>
14#ifndef rcu_dereference_bh
15#define rcu_dereference_bh(p) rcu_dereference(p)
16#endif
17
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +020018#define rcu_dereference_bh_nfnl(p) rcu_dereference_bh_check(p, 1)
19
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +020020/* Hashing which uses arrays to resolve clashing. The hash table is resized
21 * (doubled) when searching becomes too long.
22 * Internally jhash is used with the assumption that the size of the
23 * stored data is a multiple of sizeof(u32). If storage supports timeout,
24 * the timeout field must be the last one in the data structure - that field
25 * is ignored when computing the hash key.
26 *
27 * Readers and resizing
28 *
29 * Resizing can be triggered by userspace command only, and those
30 * are serialized by the nfnl mutex. During resizing the set is
31 * read-locked, so the only possible concurrent operations are
32 * the kernel side readers. Those must be protected by proper RCU locking.
33 */
34
35/* Number of elements to store in an initial array block */
36#define AHASH_INIT_SIZE 4
37/* Max number of elements to store in an array block */
38#define AHASH_MAX_SIZE (3*AHASH_INIT_SIZE)
39
40/* Max number of elements can be tuned */
41#ifdef IP_SET_HASH_WITH_MULTI
42#define AHASH_MAX(h) ((h)->ahash_max)
43
44static inline u8
45tune_ahash_max(u8 curr, u32 multi)
46{
47 u32 n;
48
49 if (multi < curr)
50 return curr;
51
52 n = curr + AHASH_INIT_SIZE;
53 /* Currently, at listing one hash bucket must fit into a message.
54 * Therefore we have a hard limit here.
55 */
56 return n > curr && n <= 64 ? n : curr;
57}
58#define TUNE_AHASH_MAX(h, multi) \
59 ((h)->ahash_max = tune_ahash_max((h)->ahash_max, multi))
60#else
61#define AHASH_MAX(h) AHASH_MAX_SIZE
62#define TUNE_AHASH_MAX(h, multi)
63#endif
64
65/* A hash bucket */
66struct hbucket {
67 void *value; /* the array of the values */
68 u8 size; /* size of the array */
69 u8 pos; /* position of the first free entry */
70};
71
72/* The hash table: the table size stored here in order to make resizing easy */
73struct htable {
74 u8 htable_bits; /* size of hash table == 2^htable_bits */
75 struct hbucket bucket[0]; /* hashtable buckets */
76};
77
78#define hbucket(h, i) (&((h)->bucket[i]))
79
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +020080#ifndef IPSET_NET_COUNT
81#define IPSET_NET_COUNT 1
82#endif
83
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +020084/* Book-keeping of the prefixes added to the set */
85struct net_prefixes {
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +020086 u32 nets[IPSET_NET_COUNT]; /* number of elements per cidr */
87 u8 cidr[IPSET_NET_COUNT]; /* the different cidr values in the set */
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +020088};
89
90/* Compute the hash table size */
91static size_t
92htable_size(u8 hbits)
93{
94 size_t hsize;
95
96 /* We must fit both into u32 in jhash and size_t */
97 if (hbits > 31)
98 return 0;
99 hsize = jhash_size(hbits);
100 if ((((size_t)-1) - sizeof(struct htable))/sizeof(struct hbucket)
101 < hsize)
102 return 0;
103
104 return hsize * sizeof(struct hbucket) + sizeof(struct htable);
105}
106
107/* Compute htable_bits from the user input parameter hashsize */
108static u8
109htable_bits(u32 hashsize)
110{
111 /* Assume that hashsize == 2^htable_bits */
112 u8 bits = fls(hashsize - 1);
113 if (jhash_size(bits) != hashsize)
114 /* Round up to the first 2^n value */
115 bits = fls(hashsize);
116
117 return bits;
118}
119
120/* Destroy the hashtable part of the set */
121static void
122ahash_destroy(struct htable *t)
123{
124 struct hbucket *n;
125 u32 i;
126
127 for (i = 0; i < jhash_size(t->htable_bits); i++) {
128 n = hbucket(t, i);
129 if (n->size)
130 /* FIXME: use slab cache */
131 kfree(n->value);
132 }
133
134 ip_set_free(t);
135}
136
137static int
138hbucket_elem_add(struct hbucket *n, u8 ahash_max, size_t dsize)
139{
140 if (n->pos >= n->size) {
141 void *tmp;
142
143 if (n->size >= ahash_max)
144 /* Trigger rehashing */
145 return -EAGAIN;
146
147 tmp = kzalloc((n->size + AHASH_INIT_SIZE) * dsize,
148 GFP_ATOMIC);
149 if (!tmp)
150 return -ENOMEM;
151 if (n->size) {
152 memcpy(tmp, n->value, n->size * dsize);
153 kfree(n->value);
154 }
155 n->value = tmp;
156 n->size += AHASH_INIT_SIZE;
157 }
158 return 0;
159}
160
161#ifdef IP_SET_HASH_WITH_NETS
162#ifdef IP_SET_HASH_WITH_NETS_PACKED
163/* When cidr is packed with nomatch, cidr - 1 is stored in the entry */
164#define CIDR(cidr) (cidr + 1)
165#else
166#define CIDR(cidr) (cidr)
167#endif
168
169#define SET_HOST_MASK(family) (family == AF_INET ? 32 : 128)
170
171#ifdef IP_SET_HASH_WITH_MULTI
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200172#define NLEN(family) (SET_HOST_MASK(family) + 1)
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200173#else
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200174#define NLEN(family) SET_HOST_MASK(family)
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200175#endif
176
177#else
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200178#define NLEN(family) 0
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200179#endif /* IP_SET_HASH_WITH_NETS */
180
181#define ext_timeout(e, h) \
182(unsigned long *)(((void *)(e)) + (h)->offset[IPSET_OFFSET_TIMEOUT])
Jozsef Kadlecsik00d71b22013-04-08 23:11:02 +0200183#define ext_counter(e, h) \
184(struct ip_set_counter *)(((void *)(e)) + (h)->offset[IPSET_OFFSET_COUNTER])
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200185
186#endif /* _IP_SET_HASH_GEN_H */
187
188/* Family dependent templates */
189
190#undef ahash_data
191#undef mtype_data_equal
192#undef mtype_do_data_match
193#undef mtype_data_set_flags
194#undef mtype_data_reset_flags
195#undef mtype_data_netmask
196#undef mtype_data_list
197#undef mtype_data_next
198#undef mtype_elem
199
200#undef mtype_add_cidr
201#undef mtype_del_cidr
202#undef mtype_ahash_memsize
203#undef mtype_flush
204#undef mtype_destroy
205#undef mtype_gc_init
206#undef mtype_same_set
207#undef mtype_kadt
208#undef mtype_uadt
209#undef mtype
210
211#undef mtype_add
212#undef mtype_del
213#undef mtype_test_cidrs
214#undef mtype_test
215#undef mtype_expire
216#undef mtype_resize
217#undef mtype_head
218#undef mtype_list
219#undef mtype_gc
220#undef mtype_gc_init
221#undef mtype_variant
222#undef mtype_data_match
223
224#undef HKEY
225
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +0200226#define mtype_data_equal IPSET_TOKEN(MTYPE, _data_equal)
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200227#ifdef IP_SET_HASH_WITH_NETS
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +0200228#define mtype_do_data_match IPSET_TOKEN(MTYPE, _do_data_match)
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200229#else
230#define mtype_do_data_match(d) 1
231#endif
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +0200232#define mtype_data_set_flags IPSET_TOKEN(MTYPE, _data_set_flags)
233#define mtype_data_reset_flags IPSET_TOKEN(MTYPE, _data_reset_flags)
234#define mtype_data_netmask IPSET_TOKEN(MTYPE, _data_netmask)
235#define mtype_data_list IPSET_TOKEN(MTYPE, _data_list)
236#define mtype_data_next IPSET_TOKEN(MTYPE, _data_next)
237#define mtype_elem IPSET_TOKEN(MTYPE, _elem)
238#define mtype_add_cidr IPSET_TOKEN(MTYPE, _add_cidr)
239#define mtype_del_cidr IPSET_TOKEN(MTYPE, _del_cidr)
240#define mtype_ahash_memsize IPSET_TOKEN(MTYPE, _ahash_memsize)
241#define mtype_flush IPSET_TOKEN(MTYPE, _flush)
242#define mtype_destroy IPSET_TOKEN(MTYPE, _destroy)
243#define mtype_gc_init IPSET_TOKEN(MTYPE, _gc_init)
244#define mtype_same_set IPSET_TOKEN(MTYPE, _same_set)
245#define mtype_kadt IPSET_TOKEN(MTYPE, _kadt)
246#define mtype_uadt IPSET_TOKEN(MTYPE, _uadt)
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200247#define mtype MTYPE
248
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +0200249#define mtype_elem IPSET_TOKEN(MTYPE, _elem)
250#define mtype_add IPSET_TOKEN(MTYPE, _add)
251#define mtype_del IPSET_TOKEN(MTYPE, _del)
252#define mtype_test_cidrs IPSET_TOKEN(MTYPE, _test_cidrs)
253#define mtype_test IPSET_TOKEN(MTYPE, _test)
254#define mtype_expire IPSET_TOKEN(MTYPE, _expire)
255#define mtype_resize IPSET_TOKEN(MTYPE, _resize)
256#define mtype_head IPSET_TOKEN(MTYPE, _head)
257#define mtype_list IPSET_TOKEN(MTYPE, _list)
258#define mtype_gc IPSET_TOKEN(MTYPE, _gc)
259#define mtype_variant IPSET_TOKEN(MTYPE, _variant)
260#define mtype_data_match IPSET_TOKEN(MTYPE, _data_match)
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200261
262#ifndef HKEY_DATALEN
263#define HKEY_DATALEN sizeof(struct mtype_elem)
264#endif
265
266#define HKEY(data, initval, htable_bits) \
267(jhash2((u32 *)(data), HKEY_DATALEN/sizeof(u32), initval) \
268 & jhash_mask(htable_bits))
269
270#ifndef htype
271#define htype HTYPE
272
273/* The generic hash structure */
274struct htype {
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200275 struct htable __rcu *table; /* the hash table */
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200276 u32 maxelem; /* max elements in the hash */
277 u32 elements; /* current element (vs timeout) */
278 u32 initval; /* random jhash init value */
279 u32 timeout; /* timeout value, if enabled */
280 size_t dsize; /* data struct size */
281 size_t offset[IPSET_OFFSET_MAX]; /* Offsets to extensions */
282 struct timer_list gc; /* garbage collection when timeout enabled */
283 struct mtype_elem next; /* temporary storage for uadd */
284#ifdef IP_SET_HASH_WITH_MULTI
285 u8 ahash_max; /* max elements in an array block */
286#endif
287#ifdef IP_SET_HASH_WITH_NETMASK
288 u8 netmask; /* netmask value for subnets to store */
289#endif
290#ifdef IP_SET_HASH_WITH_RBTREE
291 struct rb_root rbtree;
292#endif
293#ifdef IP_SET_HASH_WITH_NETS
294 struct net_prefixes nets[0]; /* book-keeping of prefixes */
295#endif
296};
297#endif
298
299#ifdef IP_SET_HASH_WITH_NETS
300/* Network cidr size book keeping when the hash stores different
301 * sized networks */
302static void
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200303mtype_add_cidr(struct htype *h, u8 cidr, u8 nets_length, u8 n)
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200304{
305 int i, j;
306
307 /* Add in increasing prefix order, so larger cidr first */
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200308 for (i = 0, j = -1; i < nets_length && h->nets[i].nets[n]; i++) {
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200309 if (j != -1)
310 continue;
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200311 else if (h->nets[i].cidr[n] < cidr)
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200312 j = i;
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200313 else if (h->nets[i].cidr[n] == cidr) {
314 h->nets[i].nets[n]++;
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200315 return;
316 }
317 }
318 if (j != -1) {
319 for (; i > j; i--) {
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200320 h->nets[i].cidr[n] = h->nets[i - 1].cidr[n];
321 h->nets[i].nets[n] = h->nets[i - 1].nets[n];
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200322 }
323 }
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200324 h->nets[i].cidr[n] = cidr;
325 h->nets[i].nets[n] = 1;
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200326}
327
328static void
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200329mtype_del_cidr(struct htype *h, u8 cidr, u8 nets_length, u8 n)
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200330{
Oliver Smith2cf55122013-09-16 20:30:57 +0200331 u8 i, j, net_end = nets_length - 1;
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200332
Oliver Smith2cf55122013-09-16 20:30:57 +0200333 for (i = 0; i < nets_length; i++) {
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200334 if (h->nets[i].cidr[n] != cidr)
Oliver Smith2cf55122013-09-16 20:30:57 +0200335 continue;
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200336 if (h->nets[i].nets[n] > 1 || i == net_end ||
337 h->nets[i + 1].nets[n] == 0) {
338 h->nets[i].nets[n]--;
Oliver Smith2cf55122013-09-16 20:30:57 +0200339 return;
340 }
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200341 for (j = i; j < net_end && h->nets[j].nets[n]; j++) {
342 h->nets[j].cidr[n] = h->nets[j + 1].cidr[n];
343 h->nets[j].nets[n] = h->nets[j + 1].nets[n];
Oliver Smith2cf55122013-09-16 20:30:57 +0200344 }
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200345 h->nets[j].nets[n] = 0;
Oliver Smith2cf55122013-09-16 20:30:57 +0200346 return;
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200347 }
348}
349#endif
350
351/* Calculate the actual memory size of the set data */
352static size_t
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200353mtype_ahash_memsize(const struct htype *h, const struct htable *t,
354 u8 nets_length)
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200355{
356 u32 i;
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200357 size_t memsize = sizeof(*h)
358 + sizeof(*t)
359#ifdef IP_SET_HASH_WITH_NETS
360 + sizeof(struct net_prefixes) * nets_length
361#endif
362 + jhash_size(t->htable_bits) * sizeof(struct hbucket);
363
364 for (i = 0; i < jhash_size(t->htable_bits); i++)
365 memsize += t->bucket[i].size * h->dsize;
366
367 return memsize;
368}
369
370/* Flush a hash type of set: destroy all elements */
371static void
372mtype_flush(struct ip_set *set)
373{
374 struct htype *h = set->data;
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200375 struct htable *t;
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200376 struct hbucket *n;
377 u32 i;
378
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200379 t = rcu_dereference_bh_nfnl(h->table);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200380 for (i = 0; i < jhash_size(t->htable_bits); i++) {
381 n = hbucket(t, i);
382 if (n->size) {
383 n->size = n->pos = 0;
384 /* FIXME: use slab cache */
385 kfree(n->value);
386 }
387 }
388#ifdef IP_SET_HASH_WITH_NETS
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200389 memset(h->nets, 0, sizeof(struct net_prefixes) * NLEN(set->family));
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200390#endif
391 h->elements = 0;
392}
393
394/* Destroy a hash type of set */
395static void
396mtype_destroy(struct ip_set *set)
397{
398 struct htype *h = set->data;
399
400 if (set->extensions & IPSET_EXT_TIMEOUT)
401 del_timer_sync(&h->gc);
402
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200403 ahash_destroy(rcu_dereference_bh_nfnl(h->table));
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200404#ifdef IP_SET_HASH_WITH_RBTREE
405 rbtree_destroy(&h->rbtree);
406#endif
407 kfree(h);
408
409 set->data = NULL;
410}
411
412static void
413mtype_gc_init(struct ip_set *set, void (*gc)(unsigned long ul_set))
414{
415 struct htype *h = set->data;
416
417 init_timer(&h->gc);
418 h->gc.data = (unsigned long) set;
419 h->gc.function = gc;
420 h->gc.expires = jiffies + IPSET_GC_PERIOD(h->timeout) * HZ;
421 add_timer(&h->gc);
422 pr_debug("gc initialized, run in every %u\n",
423 IPSET_GC_PERIOD(h->timeout));
424}
425
426static bool
427mtype_same_set(const struct ip_set *a, const struct ip_set *b)
428{
429 const struct htype *x = a->data;
430 const struct htype *y = b->data;
431
432 /* Resizing changes htable_bits, so we ignore it */
433 return x->maxelem == y->maxelem &&
434 x->timeout == y->timeout &&
435#ifdef IP_SET_HASH_WITH_NETMASK
436 x->netmask == y->netmask &&
437#endif
438 a->extensions == b->extensions;
439}
440
441/* Get the ith element from the array block n */
442#define ahash_data(n, i, dsize) \
443 ((struct mtype_elem *)((n)->value + ((i) * (dsize))))
444
445/* Delete expired elements from the hashtable */
446static void
447mtype_expire(struct htype *h, u8 nets_length, size_t dsize)
448{
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200449 struct htable *t;
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200450 struct hbucket *n;
451 struct mtype_elem *data;
452 u32 i;
453 int j;
454
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200455 rcu_read_lock_bh();
456 t = rcu_dereference_bh(h->table);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200457 for (i = 0; i < jhash_size(t->htable_bits); i++) {
458 n = hbucket(t, i);
459 for (j = 0; j < n->pos; j++) {
460 data = ahash_data(n, j, dsize);
461 if (ip_set_timeout_expired(ext_timeout(data, h))) {
462 pr_debug("expired %u/%u\n", i, j);
463#ifdef IP_SET_HASH_WITH_NETS
464 mtype_del_cidr(h, CIDR(data->cidr),
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200465 nets_length, 0);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200466#endif
467 if (j != n->pos - 1)
468 /* Not last one */
469 memcpy(data,
470 ahash_data(n, n->pos - 1, dsize),
471 dsize);
472 n->pos--;
473 h->elements--;
474 }
475 }
476 if (n->pos + AHASH_INIT_SIZE < n->size) {
477 void *tmp = kzalloc((n->size - AHASH_INIT_SIZE)
478 * dsize,
479 GFP_ATOMIC);
480 if (!tmp)
481 /* Still try to delete expired elements */
482 continue;
483 n->size -= AHASH_INIT_SIZE;
484 memcpy(tmp, n->value, n->size * dsize);
485 kfree(n->value);
486 n->value = tmp;
487 }
488 }
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200489 rcu_read_unlock_bh();
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200490}
491
492static void
493mtype_gc(unsigned long ul_set)
494{
495 struct ip_set *set = (struct ip_set *) ul_set;
496 struct htype *h = set->data;
497
498 pr_debug("called\n");
499 write_lock_bh(&set->lock);
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200500 mtype_expire(h, NLEN(set->family), h->dsize);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200501 write_unlock_bh(&set->lock);
502
503 h->gc.expires = jiffies + IPSET_GC_PERIOD(h->timeout) * HZ;
504 add_timer(&h->gc);
505}
506
507/* Resize a hash: create a new hash table with doubling the hashsize
508 * and inserting the elements to it. Repeat until we succeed or
509 * fail due to memory pressures. */
510static int
511mtype_resize(struct ip_set *set, bool retried)
512{
513 struct htype *h = set->data;
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200514 struct htable *t, *orig = rcu_dereference_bh_nfnl(h->table);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200515 u8 htable_bits = orig->htable_bits;
516#ifdef IP_SET_HASH_WITH_NETS
517 u8 flags;
518#endif
519 struct mtype_elem *data;
520 struct mtype_elem *d;
521 struct hbucket *n, *m;
522 u32 i, j;
523 int ret;
524
525 /* Try to cleanup once */
526 if (SET_WITH_TIMEOUT(set) && !retried) {
527 i = h->elements;
528 write_lock_bh(&set->lock);
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200529 mtype_expire(set->data, NLEN(set->family), h->dsize);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200530 write_unlock_bh(&set->lock);
531 if (h->elements < i)
532 return 0;
533 }
534
535retry:
536 ret = 0;
537 htable_bits++;
538 pr_debug("attempt to resize set %s from %u to %u, t %p\n",
539 set->name, orig->htable_bits, htable_bits, orig);
540 if (!htable_bits) {
541 /* In case we have plenty of memory :-) */
542 pr_warning("Cannot increase the hashsize of set %s further\n",
543 set->name);
544 return -IPSET_ERR_HASH_FULL;
545 }
546 t = ip_set_alloc(sizeof(*t)
547 + jhash_size(htable_bits) * sizeof(struct hbucket));
548 if (!t)
549 return -ENOMEM;
550 t->htable_bits = htable_bits;
551
552 read_lock_bh(&set->lock);
553 for (i = 0; i < jhash_size(orig->htable_bits); i++) {
554 n = hbucket(orig, i);
555 for (j = 0; j < n->pos; j++) {
556 data = ahash_data(n, j, h->dsize);
557#ifdef IP_SET_HASH_WITH_NETS
558 flags = 0;
559 mtype_data_reset_flags(data, &flags);
560#endif
561 m = hbucket(t, HKEY(data, h->initval, htable_bits));
562 ret = hbucket_elem_add(m, AHASH_MAX(h), h->dsize);
563 if (ret < 0) {
564#ifdef IP_SET_HASH_WITH_NETS
565 mtype_data_reset_flags(data, &flags);
566#endif
567 read_unlock_bh(&set->lock);
568 ahash_destroy(t);
569 if (ret == -EAGAIN)
570 goto retry;
571 return ret;
572 }
573 d = ahash_data(m, m->pos++, h->dsize);
574 memcpy(d, data, h->dsize);
575#ifdef IP_SET_HASH_WITH_NETS
576 mtype_data_reset_flags(d, &flags);
577#endif
578 }
579 }
580
581 rcu_assign_pointer(h->table, t);
582 read_unlock_bh(&set->lock);
583
584 /* Give time to other readers of the set */
585 synchronize_rcu_bh();
586
587 pr_debug("set %s resized from %u (%p) to %u (%p)\n", set->name,
588 orig->htable_bits, orig, t->htable_bits, t);
589 ahash_destroy(orig);
590
591 return 0;
592}
593
594/* Add an element to a hash and update the internal counters when succeeded,
595 * otherwise report the proper error code. */
596static int
597mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
598 struct ip_set_ext *mext, u32 flags)
599{
600 struct htype *h = set->data;
601 struct htable *t;
602 const struct mtype_elem *d = value;
603 struct mtype_elem *data;
604 struct hbucket *n;
605 int i, ret = 0;
606 int j = AHASH_MAX(h) + 1;
607 bool flag_exist = flags & IPSET_FLAG_EXIST;
608 u32 key, multi = 0;
609
610 if (SET_WITH_TIMEOUT(set) && h->elements >= h->maxelem)
611 /* FIXME: when set is full, we slow down here */
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200612 mtype_expire(h, NLEN(set->family), h->dsize);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200613
614 if (h->elements >= h->maxelem) {
615 if (net_ratelimit())
616 pr_warning("Set %s is full, maxelem %u reached\n",
617 set->name, h->maxelem);
618 return -IPSET_ERR_HASH_FULL;
619 }
620
621 rcu_read_lock_bh();
622 t = rcu_dereference_bh(h->table);
623 key = HKEY(value, h->initval, t->htable_bits);
624 n = hbucket(t, key);
625 for (i = 0; i < n->pos; i++) {
626 data = ahash_data(n, i, h->dsize);
627 if (mtype_data_equal(data, d, &multi)) {
628 if (flag_exist ||
629 (SET_WITH_TIMEOUT(set) &&
630 ip_set_timeout_expired(ext_timeout(data, h)))) {
631 /* Just the extensions could be overwritten */
632 j = i;
633 goto reuse_slot;
634 } else {
635 ret = -IPSET_ERR_EXIST;
636 goto out;
637 }
638 }
639 /* Reuse first timed out entry */
640 if (SET_WITH_TIMEOUT(set) &&
641 ip_set_timeout_expired(ext_timeout(data, h)) &&
642 j != AHASH_MAX(h) + 1)
643 j = i;
644 }
645reuse_slot:
646 if (j != AHASH_MAX(h) + 1) {
647 /* Fill out reused slot */
648 data = ahash_data(n, j, h->dsize);
649#ifdef IP_SET_HASH_WITH_NETS
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200650 mtype_del_cidr(h, CIDR(data->cidr), NLEN(set->family), 0);
651 mtype_add_cidr(h, CIDR(d->cidr), NLEN(set->family), 0);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200652#endif
653 } else {
654 /* Use/create a new slot */
655 TUNE_AHASH_MAX(h, multi);
656 ret = hbucket_elem_add(n, AHASH_MAX(h), h->dsize);
657 if (ret != 0) {
658 if (ret == -EAGAIN)
659 mtype_data_next(&h->next, d);
660 goto out;
661 }
662 data = ahash_data(n, n->pos++, h->dsize);
663#ifdef IP_SET_HASH_WITH_NETS
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200664 mtype_add_cidr(h, CIDR(d->cidr), NLEN(set->family), 0);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200665#endif
666 h->elements++;
667 }
668 memcpy(data, d, sizeof(struct mtype_elem));
669#ifdef IP_SET_HASH_WITH_NETS
670 mtype_data_set_flags(data, flags);
671#endif
672 if (SET_WITH_TIMEOUT(set))
673 ip_set_timeout_set(ext_timeout(data, h), ext->timeout);
Jozsef Kadlecsik00d71b22013-04-08 23:11:02 +0200674 if (SET_WITH_COUNTER(set))
675 ip_set_init_counter(ext_counter(data, h), ext);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200676
677out:
678 rcu_read_unlock_bh();
679 return ret;
680}
681
682/* Delete an element from the hash: swap it with the last element
683 * and free up space if possible.
684 */
685static int
686mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext,
687 struct ip_set_ext *mext, u32 flags)
688{
689 struct htype *h = set->data;
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200690 struct htable *t;
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200691 const struct mtype_elem *d = value;
692 struct mtype_elem *data;
693 struct hbucket *n;
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200694 int i, ret = -IPSET_ERR_EXIST;
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200695 u32 key, multi = 0;
696
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200697 rcu_read_lock_bh();
698 t = rcu_dereference_bh(h->table);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200699 key = HKEY(value, h->initval, t->htable_bits);
700 n = hbucket(t, key);
701 for (i = 0; i < n->pos; i++) {
702 data = ahash_data(n, i, h->dsize);
703 if (!mtype_data_equal(data, d, &multi))
704 continue;
705 if (SET_WITH_TIMEOUT(set) &&
706 ip_set_timeout_expired(ext_timeout(data, h)))
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200707 goto out;
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200708 if (i != n->pos - 1)
709 /* Not last one */
710 memcpy(data, ahash_data(n, n->pos - 1, h->dsize),
711 h->dsize);
712
713 n->pos--;
714 h->elements--;
715#ifdef IP_SET_HASH_WITH_NETS
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200716 mtype_del_cidr(h, CIDR(d->cidr), NLEN(set->family), 0);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200717#endif
718 if (n->pos + AHASH_INIT_SIZE < n->size) {
719 void *tmp = kzalloc((n->size - AHASH_INIT_SIZE)
720 * h->dsize,
721 GFP_ATOMIC);
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200722 if (!tmp) {
723 ret = 0;
724 goto out;
725 }
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200726 n->size -= AHASH_INIT_SIZE;
727 memcpy(tmp, n->value, n->size * h->dsize);
728 kfree(n->value);
729 n->value = tmp;
730 }
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200731 ret = 0;
732 goto out;
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200733 }
734
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200735out:
736 rcu_read_unlock_bh();
737 return ret;
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200738}
739
740static inline int
741mtype_data_match(struct mtype_elem *data, const struct ip_set_ext *ext,
742 struct ip_set_ext *mext, struct ip_set *set, u32 flags)
743{
Jozsef Kadlecsik00d71b22013-04-08 23:11:02 +0200744 if (SET_WITH_COUNTER(set))
745 ip_set_update_counter(ext_counter(data,
746 (struct htype *)(set->data)),
747 ext, mext, flags);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200748 return mtype_do_data_match(data);
749}
750
751#ifdef IP_SET_HASH_WITH_NETS
752/* Special test function which takes into account the different network
753 * sizes added to the set */
754static int
755mtype_test_cidrs(struct ip_set *set, struct mtype_elem *d,
756 const struct ip_set_ext *ext,
757 struct ip_set_ext *mext, u32 flags)
758{
759 struct htype *h = set->data;
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200760 struct htable *t = rcu_dereference_bh(h->table);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200761 struct hbucket *n;
762 struct mtype_elem *data;
763 int i, j = 0;
764 u32 key, multi = 0;
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200765 u8 nets_length = NLEN(set->family);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200766
767 pr_debug("test by nets\n");
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200768 for (; j < nets_length && h->nets[j].nets[0] && !multi; j++) {
769 mtype_data_netmask(d, h->nets[j].cidr[0]);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200770 key = HKEY(d, h->initval, t->htable_bits);
771 n = hbucket(t, key);
772 for (i = 0; i < n->pos; i++) {
773 data = ahash_data(n, i, h->dsize);
774 if (!mtype_data_equal(data, d, &multi))
775 continue;
776 if (SET_WITH_TIMEOUT(set)) {
777 if (!ip_set_timeout_expired(
778 ext_timeout(data, h)))
779 return mtype_data_match(data, ext,
780 mext, set,
781 flags);
782#ifdef IP_SET_HASH_WITH_MULTI
783 multi = 0;
784#endif
785 } else
786 return mtype_data_match(data, ext,
787 mext, set, flags);
788 }
789 }
790 return 0;
791}
792#endif
793
794/* Test whether the element is added to the set */
795static int
796mtype_test(struct ip_set *set, void *value, const struct ip_set_ext *ext,
797 struct ip_set_ext *mext, u32 flags)
798{
799 struct htype *h = set->data;
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200800 struct htable *t;
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200801 struct mtype_elem *d = value;
802 struct hbucket *n;
803 struct mtype_elem *data;
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200804 int i, ret = 0;
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200805 u32 key, multi = 0;
806
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200807 rcu_read_lock_bh();
808 t = rcu_dereference_bh(h->table);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200809#ifdef IP_SET_HASH_WITH_NETS
810 /* If we test an IP address and not a network address,
811 * try all possible network sizes */
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200812 if (CIDR(d->cidr) == SET_HOST_MASK(set->family)) {
813 ret = mtype_test_cidrs(set, d, ext, mext, flags);
814 goto out;
815 }
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200816#endif
817
818 key = HKEY(d, h->initval, t->htable_bits);
819 n = hbucket(t, key);
820 for (i = 0; i < n->pos; i++) {
821 data = ahash_data(n, i, h->dsize);
822 if (mtype_data_equal(data, d, &multi) &&
823 !(SET_WITH_TIMEOUT(set) &&
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200824 ip_set_timeout_expired(ext_timeout(data, h)))) {
825 ret = mtype_data_match(data, ext, mext, set, flags);
826 goto out;
827 }
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200828 }
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200829out:
830 rcu_read_unlock_bh();
831 return ret;
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200832}
833
834/* Reply a HEADER request: fill out the header part of the set */
835static int
836mtype_head(struct ip_set *set, struct sk_buff *skb)
837{
838 const struct htype *h = set->data;
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200839 const struct htable *t;
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200840 struct nlattr *nested;
841 size_t memsize;
842
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200843 t = rcu_dereference_bh_nfnl(h->table);
Jozsef Kadlecsika04d8b62013-09-30 09:05:54 +0200844 memsize = mtype_ahash_memsize(h, t, NLEN(set->family));
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200845
846 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
847 if (!nested)
848 goto nla_put_failure;
849 if (nla_put_net32(skb, IPSET_ATTR_HASHSIZE,
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200850 htonl(jhash_size(t->htable_bits))) ||
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200851 nla_put_net32(skb, IPSET_ATTR_MAXELEM, htonl(h->maxelem)))
852 goto nla_put_failure;
853#ifdef IP_SET_HASH_WITH_NETMASK
854 if (h->netmask != HOST_MASK &&
855 nla_put_u8(skb, IPSET_ATTR_NETMASK, h->netmask))
856 goto nla_put_failure;
857#endif
858 if (nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
859 nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)) ||
860 ((set->extensions & IPSET_EXT_TIMEOUT) &&
Jozsef Kadlecsik00d71b22013-04-08 23:11:02 +0200861 nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(h->timeout))) ||
862 ((set->extensions & IPSET_EXT_COUNTER) &&
863 nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS,
864 htonl(IPSET_FLAG_WITH_COUNTERS))))
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200865 goto nla_put_failure;
866 ipset_nest_end(skb, nested);
867
868 return 0;
869nla_put_failure:
870 return -EMSGSIZE;
871}
872
873/* Reply a LIST/SAVE request: dump the elements of the specified set */
874static int
875mtype_list(const struct ip_set *set,
876 struct sk_buff *skb, struct netlink_callback *cb)
877{
878 const struct htype *h = set->data;
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200879 const struct htable *t = rcu_dereference_bh_nfnl(h->table);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200880 struct nlattr *atd, *nested;
881 const struct hbucket *n;
882 const struct mtype_elem *e;
883 u32 first = cb->args[2];
884 /* We assume that one hash bucket fills into one page */
885 void *incomplete;
886 int i;
887
888 atd = ipset_nest_start(skb, IPSET_ATTR_ADT);
889 if (!atd)
890 return -EMSGSIZE;
891 pr_debug("list hash set %s\n", set->name);
892 for (; cb->args[2] < jhash_size(t->htable_bits); cb->args[2]++) {
893 incomplete = skb_tail_pointer(skb);
894 n = hbucket(t, cb->args[2]);
895 pr_debug("cb->args[2]: %lu, t %p n %p\n", cb->args[2], t, n);
896 for (i = 0; i < n->pos; i++) {
897 e = ahash_data(n, i, h->dsize);
898 if (SET_WITH_TIMEOUT(set) &&
899 ip_set_timeout_expired(ext_timeout(e, h)))
900 continue;
901 pr_debug("list hash %lu hbucket %p i %u, data %p\n",
902 cb->args[2], n, i, e);
903 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
904 if (!nested) {
905 if (cb->args[2] == first) {
906 nla_nest_cancel(skb, atd);
907 return -EMSGSIZE;
908 } else
909 goto nla_put_failure;
910 }
911 if (mtype_data_list(skb, e))
912 goto nla_put_failure;
913 if (SET_WITH_TIMEOUT(set) &&
914 nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
915 htonl(ip_set_timeout_get(
916 ext_timeout(e, h)))))
917 goto nla_put_failure;
Jozsef Kadlecsik00d71b22013-04-08 23:11:02 +0200918 if (SET_WITH_COUNTER(set) &&
919 ip_set_put_counter(skb, ext_counter(e, h)))
920 goto nla_put_failure;
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200921 ipset_nest_end(skb, nested);
922 }
923 }
924 ipset_nest_end(skb, atd);
925 /* Set listing finished */
926 cb->args[2] = 0;
927
928 return 0;
929
930nla_put_failure:
931 nlmsg_trim(skb, incomplete);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200932 if (unlikely(first == cb->args[2])) {
933 pr_warning("Can't list set %s: one bucket does not fit into "
934 "a message. Please report it!\n", set->name);
935 cb->args[2] = 0;
936 return -EMSGSIZE;
937 }
Jozsef Kadlecsik122ebbf2013-04-27 21:02:59 +0200938 ipset_nest_end(skb, atd);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200939 return 0;
940}
941
942static int
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +0200943IPSET_TOKEN(MTYPE, _kadt)(struct ip_set *set, const struct sk_buff *skb,
944 const struct xt_action_param *par,
945 enum ipset_adt adt, struct ip_set_adt_opt *opt);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200946
947static int
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +0200948IPSET_TOKEN(MTYPE, _uadt)(struct ip_set *set, struct nlattr *tb[],
949 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200950
951static const struct ip_set_type_variant mtype_variant = {
952 .kadt = mtype_kadt,
953 .uadt = mtype_uadt,
954 .adt = {
955 [IPSET_ADD] = mtype_add,
956 [IPSET_DEL] = mtype_del,
957 [IPSET_TEST] = mtype_test,
958 },
959 .destroy = mtype_destroy,
960 .flush = mtype_flush,
961 .head = mtype_head,
962 .list = mtype_list,
963 .resize = mtype_resize,
964 .same_set = mtype_same_set,
965};
966
967#ifdef IP_SET_EMIT_CREATE
968static int
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +0200969IPSET_TOKEN(HTYPE, _create)(struct ip_set *set, struct nlattr *tb[], u32 flags)
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200970{
971 u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
Jozsef Kadlecsik00d71b22013-04-08 23:11:02 +0200972 u32 cadt_flags = 0;
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200973 u8 hbits;
974#ifdef IP_SET_HASH_WITH_NETMASK
975 u8 netmask;
976#endif
977 size_t hsize;
978 struct HTYPE *h;
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +0200979 struct htable *t;
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +0200980
981 if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6))
982 return -IPSET_ERR_INVALID_FAMILY;
983#ifdef IP_SET_HASH_WITH_NETMASK
984 netmask = set->family == NFPROTO_IPV4 ? 32 : 128;
985 pr_debug("Create set %s with family %s\n",
986 set->name, set->family == NFPROTO_IPV4 ? "inet" : "inet6");
987#endif
988
989 if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
990 !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
991 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
992 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
993 return -IPSET_ERR_PROTOCOL;
994
995 if (tb[IPSET_ATTR_HASHSIZE]) {
996 hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
997 if (hashsize < IPSET_MIMINAL_HASHSIZE)
998 hashsize = IPSET_MIMINAL_HASHSIZE;
999 }
1000
1001 if (tb[IPSET_ATTR_MAXELEM])
1002 maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]);
1003
1004#ifdef IP_SET_HASH_WITH_NETMASK
1005 if (tb[IPSET_ATTR_NETMASK]) {
1006 netmask = nla_get_u8(tb[IPSET_ATTR_NETMASK]);
1007
1008 if ((set->family == NFPROTO_IPV4 && netmask > 32) ||
1009 (set->family == NFPROTO_IPV6 && netmask > 128) ||
1010 netmask == 0)
1011 return -IPSET_ERR_INVALID_NETMASK;
1012 }
1013#endif
1014
1015 hsize = sizeof(*h);
1016#ifdef IP_SET_HASH_WITH_NETS
1017 hsize += sizeof(struct net_prefixes) *
1018 (set->family == NFPROTO_IPV4 ? 32 : 128);
1019#endif
1020 h = kzalloc(hsize, GFP_KERNEL);
1021 if (!h)
1022 return -ENOMEM;
1023
1024 h->maxelem = maxelem;
1025#ifdef IP_SET_HASH_WITH_NETMASK
1026 h->netmask = netmask;
1027#endif
1028 get_random_bytes(&h->initval, sizeof(h->initval));
1029 h->timeout = IPSET_NO_TIMEOUT;
1030
1031 hbits = htable_bits(hashsize);
1032 hsize = htable_size(hbits);
1033 if (hsize == 0) {
1034 kfree(h);
1035 return -ENOMEM;
1036 }
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +02001037 t = ip_set_alloc(hsize);
1038 if (!t) {
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +02001039 kfree(h);
1040 return -ENOMEM;
1041 }
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +02001042 t->htable_bits = hbits;
1043 rcu_assign_pointer(h->table, t);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +02001044
1045 set->data = h;
1046 if (set->family == NFPROTO_IPV4)
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +02001047 set->variant = &IPSET_TOKEN(HTYPE, 4_variant);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +02001048 else
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +02001049 set->variant = &IPSET_TOKEN(HTYPE, 6_variant);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +02001050
Jozsef Kadlecsik00d71b22013-04-08 23:11:02 +02001051 if (tb[IPSET_ATTR_CADT_FLAGS])
1052 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
1053 if (cadt_flags & IPSET_FLAG_WITH_COUNTERS) {
1054 set->extensions |= IPSET_EXT_COUNTER;
1055 if (tb[IPSET_ATTR_TIMEOUT]) {
1056 h->timeout =
1057 ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
1058 set->extensions |= IPSET_EXT_TIMEOUT;
1059 if (set->family == NFPROTO_IPV4) {
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +02001060 h->dsize = sizeof(struct
1061 IPSET_TOKEN(HTYPE, 4ct_elem));
Jozsef Kadlecsik00d71b22013-04-08 23:11:02 +02001062 h->offset[IPSET_OFFSET_TIMEOUT] =
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +02001063 offsetof(struct
1064 IPSET_TOKEN(HTYPE, 4ct_elem),
1065 timeout);
Jozsef Kadlecsik00d71b22013-04-08 23:11:02 +02001066 h->offset[IPSET_OFFSET_COUNTER] =
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +02001067 offsetof(struct
1068 IPSET_TOKEN(HTYPE, 4ct_elem),
1069 counter);
1070 IPSET_TOKEN(HTYPE, 4_gc_init)(set,
1071 IPSET_TOKEN(HTYPE, 4_gc));
Jozsef Kadlecsik00d71b22013-04-08 23:11:02 +02001072 } else {
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +02001073 h->dsize = sizeof(struct
1074 IPSET_TOKEN(HTYPE, 6ct_elem));
Jozsef Kadlecsik00d71b22013-04-08 23:11:02 +02001075 h->offset[IPSET_OFFSET_TIMEOUT] =
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +02001076 offsetof(struct
1077 IPSET_TOKEN(HTYPE, 6ct_elem),
1078 timeout);
Jozsef Kadlecsik00d71b22013-04-08 23:11:02 +02001079 h->offset[IPSET_OFFSET_COUNTER] =
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +02001080 offsetof(struct
1081 IPSET_TOKEN(HTYPE, 6ct_elem),
1082 counter);
1083 IPSET_TOKEN(HTYPE, 6_gc_init)(set,
1084 IPSET_TOKEN(HTYPE, 6_gc));
Jozsef Kadlecsik00d71b22013-04-08 23:11:02 +02001085 }
1086 } else {
1087 if (set->family == NFPROTO_IPV4) {
1088 h->dsize =
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +02001089 sizeof(struct
1090 IPSET_TOKEN(HTYPE, 4c_elem));
Jozsef Kadlecsik00d71b22013-04-08 23:11:02 +02001091 h->offset[IPSET_OFFSET_COUNTER] =
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +02001092 offsetof(struct
1093 IPSET_TOKEN(HTYPE, 4c_elem),
1094 counter);
Jozsef Kadlecsik00d71b22013-04-08 23:11:02 +02001095 } else {
1096 h->dsize =
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +02001097 sizeof(struct
1098 IPSET_TOKEN(HTYPE, 6c_elem));
Jozsef Kadlecsik00d71b22013-04-08 23:11:02 +02001099 h->offset[IPSET_OFFSET_COUNTER] =
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +02001100 offsetof(struct
1101 IPSET_TOKEN(HTYPE, 6c_elem),
1102 counter);
Jozsef Kadlecsik00d71b22013-04-08 23:11:02 +02001103 }
1104 }
1105 } else if (tb[IPSET_ATTR_TIMEOUT]) {
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +02001106 h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
1107 set->extensions |= IPSET_EXT_TIMEOUT;
1108 if (set->family == NFPROTO_IPV4) {
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +02001109 h->dsize = sizeof(struct IPSET_TOKEN(HTYPE, 4t_elem));
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +02001110 h->offset[IPSET_OFFSET_TIMEOUT] =
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +02001111 offsetof(struct IPSET_TOKEN(HTYPE, 4t_elem),
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +02001112 timeout);
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +02001113 IPSET_TOKEN(HTYPE, 4_gc_init)(set,
1114 IPSET_TOKEN(HTYPE, 4_gc));
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +02001115 } else {
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +02001116 h->dsize = sizeof(struct IPSET_TOKEN(HTYPE, 6t_elem));
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +02001117 h->offset[IPSET_OFFSET_TIMEOUT] =
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +02001118 offsetof(struct IPSET_TOKEN(HTYPE, 6t_elem),
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +02001119 timeout);
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +02001120 IPSET_TOKEN(HTYPE, 6_gc_init)(set,
1121 IPSET_TOKEN(HTYPE, 6_gc));
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +02001122 }
1123 } else {
1124 if (set->family == NFPROTO_IPV4)
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +02001125 h->dsize = sizeof(struct IPSET_TOKEN(HTYPE, 4_elem));
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +02001126 else
Jozsef Kadlecsik35b8dcf2013-04-30 23:02:43 +02001127 h->dsize = sizeof(struct IPSET_TOKEN(HTYPE, 6_elem));
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +02001128 }
1129
1130 pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
Jozsef Kadlecsika0f28dc2013-04-30 21:23:18 +02001131 set->name, jhash_size(t->htable_bits),
1132 t->htable_bits, h->maxelem, set->data, t);
Jozsef Kadlecsik1feab102013-04-08 21:05:44 +02001133
1134 return 0;
1135}
1136#endif /* IP_SET_EMIT_CREATE */