1 #ifndef _IP_SET_AHASH_H
2 #define _IP_SET_AHASH_H
4 #include <linux/rcupdate.h>
5 #include <linux/jhash.h>
6 #include <linux/netfilter/ipset/ip_set_timeout.h>
8 #define CONCAT(a, b, c) a##b##c
9 #define TOKEN(a, b, c) CONCAT(a, b, c)
11 #define type_pf_next TOKEN(TYPE, PF, _elem)
13 /* Hashing which uses arrays to resolve clashing. The hash table is resized
14 * (doubled) when searching becomes too long.
15 * Internally jhash is used with the assumption that the size of the
16 * stored data is a multiple of sizeof(u32). If storage supports timeout,
17 * the timeout field must be the last one in the data structure - that field
18 * is ignored when computing the hash key.
20 * Readers and resizing
22 * Resizing can be triggered by userspace command only, and those
23 * are serialized by the nfnl mutex. During resizing the set is
24 * read-locked, so the only possible concurrent operations are
25 * the kernel side readers. Those must be protected by proper RCU locking.
28 /* Number of elements to store in an initial array block */
29 #define AHASH_INIT_SIZE 4
30 /* Max number of elements to store in an array block */
31 #define AHASH_MAX_SIZE (3*AHASH_INIT_SIZE)
33 /* Max number of elements can be tuned */
34 #ifdef IP_SET_HASH_WITH_MULTI
35 #define AHASH_MAX(h) ((h)->ahash_max)
38 tune_ahash_max(u8 curr, u32 multi)
45 n = curr + AHASH_INIT_SIZE;
46 /* Currently, at listing one hash bucket must fit into a message.
47 * Therefore we have a hard limit here.
49 return n > curr && n <= 64 ? n : curr;
51 #define TUNE_AHASH_MAX(h, multi) \
52 ((h)->ahash_max = tune_ahash_max((h)->ahash_max, multi))
54 #define AHASH_MAX(h) AHASH_MAX_SIZE
55 #define TUNE_AHASH_MAX(h, multi)
60 void *value; /* the array of the values */
61 u8 size; /* size of the array */
62 u8 pos; /* position of the first free entry */
65 /* The hash table: the table size stored here in order to make resizing easy */
67 u8 htable_bits; /* size of hash table == 2^htable_bits */
68 struct hbucket bucket[0]; /* hashtable buckets */
71 #define hbucket(h, i) (&((h)->bucket[i]))
73 /* Book-keeping of the prefixes added to the set */
74 struct ip_set_hash_nets {
75 u8 cidr; /* the different cidr values in the set */
76 u32 nets; /* number of elements per cidr */
79 /* The generic ip_set hash structure */
81 struct htable *table; /* the hash table */
82 u32 maxelem; /* max elements in the hash */
83 u32 elements; /* current element (vs timeout) */
84 u32 initval; /* random jhash init value */
85 u32 timeout; /* timeout value, if enabled */
86 struct timer_list gc; /* garbage collection when timeout enabled */
87 struct type_pf_next next; /* temporary storage for uadd */
88 #ifdef IP_SET_HASH_WITH_MULTI
89 u8 ahash_max; /* max elements in an array block */
91 #ifdef IP_SET_HASH_WITH_NETMASK
92 u8 netmask; /* netmask value for subnets to store */
94 #ifdef IP_SET_HASH_WITH_RBTREE
95 struct rb_root rbtree;
97 #ifdef IP_SET_HASH_WITH_NETS
98 struct ip_set_hash_nets nets[0]; /* book-keeping of prefixes */
103 htable_size(u8 hbits)
107 /* We must fit both into u32 in jhash and size_t */
110 hsize = jhash_size(hbits);
111 if ((((size_t)-1) - sizeof(struct htable))/sizeof(struct hbucket)
115 return hsize * sizeof(struct hbucket) + sizeof(struct htable);
118 /* Compute htable_bits from the user input parameter hashsize */
120 htable_bits(u32 hashsize)
122 /* Assume that hashsize == 2^htable_bits */
123 u8 bits = fls(hashsize - 1);
124 if (jhash_size(bits) != hashsize)
125 /* Round up to the first 2^n value */
126 bits = fls(hashsize);
131 #ifdef IP_SET_HASH_WITH_NETS
132 #ifdef IP_SET_HASH_WITH_NETS_PACKED
133 /* When cidr is packed with nomatch, cidr - 1 is stored in the entry */
134 #define CIDR(cidr) (cidr + 1)
136 #define CIDR(cidr) (cidr)
139 #define SET_HOST_MASK(family) (family == AF_INET ? 32 : 128)
141 /* Network cidr size book keeping when the hash stores different
144 add_cidr(struct ip_set_hash *h, u8 cidr, u8 host_mask)
148 ++h->nets[cidr-1].nets;
150 pr_debug("add_cidr added %u: %u\n", cidr, h->nets[cidr-1].nets);
152 if (h->nets[cidr-1].nets > 1)
156 for (i = 0; i < host_mask && h->nets[i].cidr; i++) {
157 /* Add in increasing prefix order, so larger cidr first */
158 if (h->nets[i].cidr < cidr)
159 swap(h->nets[i].cidr, cidr);
162 h->nets[i].cidr = cidr;
166 del_cidr(struct ip_set_hash *h, u8 cidr, u8 host_mask)
170 --h->nets[cidr-1].nets;
172 pr_debug("del_cidr deleted %u: %u\n", cidr, h->nets[cidr-1].nets);
174 if (h->nets[cidr-1].nets != 0)
177 /* All entries with this cidr size deleted, so cleanup h->cidr[] */
178 for (i = 0; i < host_mask - 1 && h->nets[i].cidr; i++) {
179 if (h->nets[i].cidr == cidr)
180 h->nets[i].cidr = cidr = h->nets[i+1].cidr;
182 h->nets[i - 1].cidr = 0;
186 /* Destroy the hashtable part of the set */
188 ahash_destroy(struct htable *t)
193 for (i = 0; i < jhash_size(t->htable_bits); i++) {
196 /* FIXME: use slab cache */
203 /* Calculate the actual memory size of the set data */
205 ahash_memsize(const struct ip_set_hash *h, size_t dsize, u8 host_mask)
208 struct htable *t = h->table;
209 size_t memsize = sizeof(*h)
211 #ifdef IP_SET_HASH_WITH_NETS
212 + sizeof(struct ip_set_hash_nets) * host_mask
214 + jhash_size(t->htable_bits) * sizeof(struct hbucket);
216 for (i = 0; i < jhash_size(t->htable_bits); i++)
217 memsize += t->bucket[i].size * dsize;
222 /* Flush a hash type of set: destroy all elements */
224 ip_set_hash_flush(struct ip_set *set)
226 struct ip_set_hash *h = set->data;
227 struct htable *t = h->table;
231 for (i = 0; i < jhash_size(t->htable_bits); i++) {
234 n->size = n->pos = 0;
235 /* FIXME: use slab cache */
239 #ifdef IP_SET_HASH_WITH_NETS
240 memset(h->nets, 0, sizeof(struct ip_set_hash_nets)
241 * SET_HOST_MASK(set->family));
246 /* Destroy a hash type of set */
248 ip_set_hash_destroy(struct ip_set *set)
250 struct ip_set_hash *h = set->data;
252 if (with_timeout(h->timeout))
253 del_timer_sync(&h->gc);
255 ahash_destroy(h->table);
256 #ifdef IP_SET_HASH_WITH_RBTREE
257 rbtree_destroy(&h->rbtree);
264 #endif /* _IP_SET_AHASH_H */
267 #define HKEY_DATALEN sizeof(struct type_pf_elem)
270 #define HKEY(data, initval, htable_bits) \
271 (jhash2((u32 *)(data), HKEY_DATALEN/sizeof(u32), initval) \
272 & jhash_mask(htable_bits))
274 #define CONCAT(a, b, c) a##b##c
275 #define TOKEN(a, b, c) CONCAT(a, b, c)
277 /* Type/family dependent function prototypes */
279 #define type_pf_data_equal TOKEN(TYPE, PF, _data_equal)
280 #define type_pf_data_isnull TOKEN(TYPE, PF, _data_isnull)
281 #define type_pf_data_copy TOKEN(TYPE, PF, _data_copy)
282 #define type_pf_data_zero_out TOKEN(TYPE, PF, _data_zero_out)
283 #define type_pf_data_netmask TOKEN(TYPE, PF, _data_netmask)
284 #define type_pf_data_list TOKEN(TYPE, PF, _data_list)
285 #define type_pf_data_tlist TOKEN(TYPE, PF, _data_tlist)
286 #define type_pf_data_next TOKEN(TYPE, PF, _data_next)
287 #define type_pf_data_flags TOKEN(TYPE, PF, _data_flags)
288 #ifdef IP_SET_HASH_WITH_NETS
289 #define type_pf_data_match TOKEN(TYPE, PF, _data_match)
291 #define type_pf_data_match(d) 1
294 #define type_pf_elem TOKEN(TYPE, PF, _elem)
295 #define type_pf_telem TOKEN(TYPE, PF, _telem)
296 #define type_pf_data_timeout TOKEN(TYPE, PF, _data_timeout)
297 #define type_pf_data_expired TOKEN(TYPE, PF, _data_expired)
298 #define type_pf_data_timeout_set TOKEN(TYPE, PF, _data_timeout_set)
300 #define type_pf_elem_add TOKEN(TYPE, PF, _elem_add)
301 #define type_pf_add TOKEN(TYPE, PF, _add)
302 #define type_pf_del TOKEN(TYPE, PF, _del)
303 #define type_pf_test_cidrs TOKEN(TYPE, PF, _test_cidrs)
304 #define type_pf_test TOKEN(TYPE, PF, _test)
306 #define type_pf_elem_tadd TOKEN(TYPE, PF, _elem_tadd)
307 #define type_pf_del_telem TOKEN(TYPE, PF, _ahash_del_telem)
308 #define type_pf_expire TOKEN(TYPE, PF, _expire)
309 #define type_pf_tadd TOKEN(TYPE, PF, _tadd)
310 #define type_pf_tdel TOKEN(TYPE, PF, _tdel)
311 #define type_pf_ttest_cidrs TOKEN(TYPE, PF, _ahash_ttest_cidrs)
312 #define type_pf_ttest TOKEN(TYPE, PF, _ahash_ttest)
314 #define type_pf_resize TOKEN(TYPE, PF, _resize)
315 #define type_pf_tresize TOKEN(TYPE, PF, _tresize)
316 #define type_pf_flush ip_set_hash_flush
317 #define type_pf_destroy ip_set_hash_destroy
318 #define type_pf_head TOKEN(TYPE, PF, _head)
319 #define type_pf_list TOKEN(TYPE, PF, _list)
320 #define type_pf_tlist TOKEN(TYPE, PF, _tlist)
321 #define type_pf_same_set TOKEN(TYPE, PF, _same_set)
322 #define type_pf_kadt TOKEN(TYPE, PF, _kadt)
323 #define type_pf_uadt TOKEN(TYPE, PF, _uadt)
324 #define type_pf_gc TOKEN(TYPE, PF, _gc)
325 #define type_pf_gc_init TOKEN(TYPE, PF, _gc_init)
326 #define type_pf_variant TOKEN(TYPE, PF, _variant)
327 #define type_pf_tvariant TOKEN(TYPE, PF, _tvariant)
329 /* Flavour without timeout */
331 /* Get the ith element from the array block n */
332 #define ahash_data(n, i) \
333 ((struct type_pf_elem *)((n)->value) + (i))
335 /* Add an element to the hash table when resizing the set:
336 * we spare the maintenance of the internal counters. */
338 type_pf_elem_add(struct hbucket *n, const struct type_pf_elem *value,
339 u8 ahash_max, u32 cadt_flags)
341 struct type_pf_elem *data;
343 if (n->pos >= n->size) {
346 if (n->size >= ahash_max)
347 /* Trigger rehashing */
350 tmp = kzalloc((n->size + AHASH_INIT_SIZE)
351 * sizeof(struct type_pf_elem),
356 memcpy(tmp, n->value,
357 sizeof(struct type_pf_elem) * n->size);
361 n->size += AHASH_INIT_SIZE;
363 data = ahash_data(n, n->pos++);
364 type_pf_data_copy(data, value);
365 #ifdef IP_SET_HASH_WITH_NETS
366 /* Resizing won't overwrite stored flags */
368 type_pf_data_flags(data, cadt_flags);
373 /* Resize a hash: create a new hash table with doubling the hashsize
374 * and inserting the elements to it. Repeat until we succeed or
375 * fail due to memory pressures. */
377 type_pf_resize(struct ip_set *set, bool retried)
379 struct ip_set_hash *h = set->data;
380 struct htable *t, *orig = h->table;
381 u8 htable_bits = orig->htable_bits;
382 const struct type_pf_elem *data;
383 struct hbucket *n, *m;
390 pr_debug("attempt to resize set %s from %u to %u, t %p\n",
391 set->name, orig->htable_bits, htable_bits, orig);
393 /* In case we have plenty of memory :-) */
394 pr_warning("Cannot increase the hashsize of set %s further\n",
396 return -IPSET_ERR_HASH_FULL;
398 t = ip_set_alloc(sizeof(*t)
399 + jhash_size(htable_bits) * sizeof(struct hbucket));
402 t->htable_bits = htable_bits;
404 read_lock_bh(&set->lock);
405 for (i = 0; i < jhash_size(orig->htable_bits); i++) {
406 n = hbucket(orig, i);
407 for (j = 0; j < n->pos; j++) {
408 data = ahash_data(n, j);
409 m = hbucket(t, HKEY(data, h->initval, htable_bits));
410 ret = type_pf_elem_add(m, data, AHASH_MAX(h), 0);
412 read_unlock_bh(&set->lock);
421 rcu_assign_pointer(h->table, t);
422 read_unlock_bh(&set->lock);
424 /* Give time to other readers of the set */
425 synchronize_rcu_bh();
427 pr_debug("set %s resized from %u (%p) to %u (%p)\n", set->name,
428 orig->htable_bits, orig, t->htable_bits, t);
435 type_pf_data_next(struct ip_set_hash *h, const struct type_pf_elem *d);
437 /* Add an element to a hash and update the internal counters when succeeded,
438 * otherwise report the proper error code. */
440 type_pf_add(struct ip_set *set, void *value, u32 timeout, u32 flags)
442 struct ip_set_hash *h = set->data;
444 const struct type_pf_elem *d = value;
448 u32 cadt_flags = flags >> 16;
450 if (h->elements >= h->maxelem) {
452 pr_warning("Set %s is full, maxelem %u reached\n",
453 set->name, h->maxelem);
454 return -IPSET_ERR_HASH_FULL;
458 t = rcu_dereference_bh(h->table);
459 key = HKEY(value, h->initval, t->htable_bits);
461 for (i = 0; i < n->pos; i++)
462 if (type_pf_data_equal(ahash_data(n, i), d, &multi)) {
463 #ifdef IP_SET_HASH_WITH_NETS
464 if (flags & IPSET_FLAG_EXIST)
465 /* Support overwriting just the flags */
466 type_pf_data_flags(ahash_data(n, i),
469 ret = -IPSET_ERR_EXIST;
472 TUNE_AHASH_MAX(h, multi);
473 ret = type_pf_elem_add(n, value, AHASH_MAX(h), cadt_flags);
476 type_pf_data_next(h, d);
480 #ifdef IP_SET_HASH_WITH_NETS
481 add_cidr(h, CIDR(d->cidr), HOST_MASK);
485 rcu_read_unlock_bh();
489 /* Delete an element from the hash: swap it with the last element
490 * and free up space if possible.
493 type_pf_del(struct ip_set *set, void *value, u32 timeout, u32 flags)
495 struct ip_set_hash *h = set->data;
496 struct htable *t = h->table;
497 const struct type_pf_elem *d = value;
500 struct type_pf_elem *data;
503 key = HKEY(value, h->initval, t->htable_bits);
505 for (i = 0; i < n->pos; i++) {
506 data = ahash_data(n, i);
507 if (!type_pf_data_equal(data, d, &multi))
511 type_pf_data_copy(data, ahash_data(n, n->pos - 1));
515 #ifdef IP_SET_HASH_WITH_NETS
516 del_cidr(h, CIDR(d->cidr), HOST_MASK);
518 if (n->pos + AHASH_INIT_SIZE < n->size) {
519 void *tmp = kzalloc((n->size - AHASH_INIT_SIZE)
520 * sizeof(struct type_pf_elem),
524 n->size -= AHASH_INIT_SIZE;
525 memcpy(tmp, n->value,
526 n->size * sizeof(struct type_pf_elem));
533 return -IPSET_ERR_EXIST;
536 #ifdef IP_SET_HASH_WITH_NETS
538 /* Special test function which takes into account the different network
539 * sizes added to the set */
541 type_pf_test_cidrs(struct ip_set *set, struct type_pf_elem *d, u32 timeout)
543 struct ip_set_hash *h = set->data;
544 struct htable *t = h->table;
546 const struct type_pf_elem *data;
549 u8 host_mask = SET_HOST_MASK(set->family);
551 pr_debug("test by nets\n");
552 for (; j < host_mask && h->nets[j].cidr && !multi; j++) {
553 type_pf_data_netmask(d, h->nets[j].cidr);
554 key = HKEY(d, h->initval, t->htable_bits);
556 for (i = 0; i < n->pos; i++) {
557 data = ahash_data(n, i);
558 if (type_pf_data_equal(data, d, &multi))
559 return type_pf_data_match(data);
566 /* Test whether the element is added to the set */
568 type_pf_test(struct ip_set *set, void *value, u32 timeout, u32 flags)
570 struct ip_set_hash *h = set->data;
571 struct htable *t = h->table;
572 struct type_pf_elem *d = value;
574 const struct type_pf_elem *data;
578 #ifdef IP_SET_HASH_WITH_NETS
579 /* If we test an IP address and not a network address,
580 * try all possible network sizes */
581 if (CIDR(d->cidr) == SET_HOST_MASK(set->family))
582 return type_pf_test_cidrs(set, d, timeout);
585 key = HKEY(d, h->initval, t->htable_bits);
587 for (i = 0; i < n->pos; i++) {
588 data = ahash_data(n, i);
589 if (type_pf_data_equal(data, d, &multi))
590 return type_pf_data_match(data);
595 /* Reply a HEADER request: fill out the header part of the set */
597 type_pf_head(struct ip_set *set, struct sk_buff *skb)
599 const struct ip_set_hash *h = set->data;
600 struct nlattr *nested;
603 read_lock_bh(&set->lock);
604 memsize = ahash_memsize(h, with_timeout(h->timeout)
605 ? sizeof(struct type_pf_telem)
606 : sizeof(struct type_pf_elem),
607 set->family == AF_INET ? 32 : 128);
608 read_unlock_bh(&set->lock);
610 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
612 goto nla_put_failure;
613 NLA_PUT_NET32(skb, IPSET_ATTR_HASHSIZE,
614 htonl(jhash_size(h->table->htable_bits)));
615 NLA_PUT_NET32(skb, IPSET_ATTR_MAXELEM, htonl(h->maxelem));
616 #ifdef IP_SET_HASH_WITH_NETMASK
617 if (h->netmask != HOST_MASK)
618 NLA_PUT_U8(skb, IPSET_ATTR_NETMASK, h->netmask);
620 NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1));
621 NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize));
622 if (with_timeout(h->timeout))
623 NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(h->timeout));
624 ipset_nest_end(skb, nested);
631 /* Reply a LIST/SAVE request: dump the elements of the specified set */
633 type_pf_list(const struct ip_set *set,
634 struct sk_buff *skb, struct netlink_callback *cb)
636 const struct ip_set_hash *h = set->data;
637 const struct htable *t = h->table;
638 struct nlattr *atd, *nested;
639 const struct hbucket *n;
640 const struct type_pf_elem *data;
641 u32 first = cb->args[2];
642 /* We assume that one hash bucket fills into one page */
646 atd = ipset_nest_start(skb, IPSET_ATTR_ADT);
649 pr_debug("list hash set %s\n", set->name);
650 for (; cb->args[2] < jhash_size(t->htable_bits); cb->args[2]++) {
651 incomplete = skb_tail_pointer(skb);
652 n = hbucket(t, cb->args[2]);
653 pr_debug("cb->args[2]: %lu, t %p n %p\n", cb->args[2], t, n);
654 for (i = 0; i < n->pos; i++) {
655 data = ahash_data(n, i);
656 pr_debug("list hash %lu hbucket %p i %u, data %p\n",
657 cb->args[2], n, i, data);
658 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
660 if (cb->args[2] == first) {
661 nla_nest_cancel(skb, atd);
664 goto nla_put_failure;
666 if (type_pf_data_list(skb, data))
667 goto nla_put_failure;
668 ipset_nest_end(skb, nested);
671 ipset_nest_end(skb, atd);
672 /* Set listing finished */
678 nlmsg_trim(skb, incomplete);
679 ipset_nest_end(skb, atd);
680 if (unlikely(first == cb->args[2])) {
681 pr_warning("Can't list set %s: one bucket does not fit into "
682 "a message. Please report it!\n", set->name);
690 type_pf_kadt(struct ip_set *set, const struct sk_buff * skb,
691 const struct xt_action_param *par,
692 enum ipset_adt adt, const struct ip_set_adt_opt *opt);
694 type_pf_uadt(struct ip_set *set, struct nlattr *tb[],
695 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried);
697 static const struct ip_set_type_variant type_pf_variant = {
698 .kadt = type_pf_kadt,
699 .uadt = type_pf_uadt,
701 [IPSET_ADD] = type_pf_add,
702 [IPSET_DEL] = type_pf_del,
703 [IPSET_TEST] = type_pf_test,
705 .destroy = type_pf_destroy,
706 .flush = type_pf_flush,
707 .head = type_pf_head,
708 .list = type_pf_list,
709 .resize = type_pf_resize,
710 .same_set = type_pf_same_set,
713 /* Flavour with timeout support */
715 #define ahash_tdata(n, i) \
716 (struct type_pf_elem *)((struct type_pf_telem *)((n)->value) + (i))
719 type_pf_data_timeout(const struct type_pf_elem *data)
721 const struct type_pf_telem *tdata =
722 (const struct type_pf_telem *) data;
724 return tdata->timeout;
728 type_pf_data_expired(const struct type_pf_elem *data)
730 const struct type_pf_telem *tdata =
731 (const struct type_pf_telem *) data;
733 return ip_set_timeout_expired(tdata->timeout);
737 type_pf_data_timeout_set(struct type_pf_elem *data, u32 timeout)
739 struct type_pf_telem *tdata = (struct type_pf_telem *) data;
741 tdata->timeout = ip_set_timeout_set(timeout);
745 type_pf_elem_tadd(struct hbucket *n, const struct type_pf_elem *value,
746 u8 ahash_max, u32 cadt_flags, u32 timeout)
748 struct type_pf_elem *data;
750 if (n->pos >= n->size) {
753 if (n->size >= ahash_max)
754 /* Trigger rehashing */
757 tmp = kzalloc((n->size + AHASH_INIT_SIZE)
758 * sizeof(struct type_pf_telem),
763 memcpy(tmp, n->value,
764 sizeof(struct type_pf_telem) * n->size);
768 n->size += AHASH_INIT_SIZE;
770 data = ahash_tdata(n, n->pos++);
771 type_pf_data_copy(data, value);
772 type_pf_data_timeout_set(data, timeout);
773 #ifdef IP_SET_HASH_WITH_NETS
774 /* Resizing won't overwrite stored flags */
776 type_pf_data_flags(data, cadt_flags);
781 /* Delete expired elements from the hashtable */
783 type_pf_expire(struct ip_set_hash *h)
785 struct htable *t = h->table;
787 struct type_pf_elem *data;
791 for (i = 0; i < jhash_size(t->htable_bits); i++) {
793 for (j = 0; j < n->pos; j++) {
794 data = ahash_tdata(n, j);
795 if (type_pf_data_expired(data)) {
796 pr_debug("expired %u/%u\n", i, j);
797 #ifdef IP_SET_HASH_WITH_NETS
798 del_cidr(h, CIDR(data->cidr), HOST_MASK);
802 type_pf_data_copy(data,
803 ahash_tdata(n, n->pos - 1));
808 if (n->pos + AHASH_INIT_SIZE < n->size) {
809 void *tmp = kzalloc((n->size - AHASH_INIT_SIZE)
810 * sizeof(struct type_pf_telem),
813 /* Still try to delete expired elements */
815 n->size -= AHASH_INIT_SIZE;
816 memcpy(tmp, n->value,
817 n->size * sizeof(struct type_pf_telem));
825 type_pf_tresize(struct ip_set *set, bool retried)
827 struct ip_set_hash *h = set->data;
828 struct htable *t, *orig = h->table;
829 u8 htable_bits = orig->htable_bits;
830 const struct type_pf_elem *data;
831 struct hbucket *n, *m;
835 /* Try to cleanup once */
838 write_lock_bh(&set->lock);
839 type_pf_expire(set->data);
840 write_unlock_bh(&set->lock);
849 /* In case we have plenty of memory :-) */
850 pr_warning("Cannot increase the hashsize of set %s further\n",
852 return -IPSET_ERR_HASH_FULL;
854 t = ip_set_alloc(sizeof(*t)
855 + jhash_size(htable_bits) * sizeof(struct hbucket));
858 t->htable_bits = htable_bits;
860 read_lock_bh(&set->lock);
861 for (i = 0; i < jhash_size(orig->htable_bits); i++) {
862 n = hbucket(orig, i);
863 for (j = 0; j < n->pos; j++) {
864 data = ahash_tdata(n, j);
865 m = hbucket(t, HKEY(data, h->initval, htable_bits));
866 ret = type_pf_elem_tadd(m, data, AHASH_MAX(h), 0,
867 type_pf_data_timeout(data));
869 read_unlock_bh(&set->lock);
878 rcu_assign_pointer(h->table, t);
879 read_unlock_bh(&set->lock);
881 /* Give time to other readers of the set */
882 synchronize_rcu_bh();
890 type_pf_tadd(struct ip_set *set, void *value, u32 timeout, u32 flags)
892 struct ip_set_hash *h = set->data;
893 struct htable *t = h->table;
894 const struct type_pf_elem *d = value;
896 struct type_pf_elem *data;
897 int ret = 0, i, j = AHASH_MAX(h) + 1;
898 bool flag_exist = flags & IPSET_FLAG_EXIST;
900 u32 cadt_flags = flags >> 16;
902 if (h->elements >= h->maxelem)
903 /* FIXME: when set is full, we slow down here */
905 if (h->elements >= h->maxelem) {
907 pr_warning("Set %s is full, maxelem %u reached\n",
908 set->name, h->maxelem);
909 return -IPSET_ERR_HASH_FULL;
913 t = rcu_dereference_bh(h->table);
914 key = HKEY(d, h->initval, t->htable_bits);
916 for (i = 0; i < n->pos; i++) {
917 data = ahash_tdata(n, i);
918 if (type_pf_data_equal(data, d, &multi)) {
919 if (type_pf_data_expired(data) || flag_exist)
920 /* Just timeout value may be updated */
923 ret = -IPSET_ERR_EXIST;
926 } else if (j == AHASH_MAX(h) + 1 &&
927 type_pf_data_expired(data))
930 if (j != AHASH_MAX(h) + 1) {
931 data = ahash_tdata(n, j);
932 #ifdef IP_SET_HASH_WITH_NETS
933 del_cidr(h, CIDR(data->cidr), HOST_MASK);
934 add_cidr(h, CIDR(d->cidr), HOST_MASK);
936 type_pf_data_copy(data, d);
937 type_pf_data_timeout_set(data, timeout);
938 #ifdef IP_SET_HASH_WITH_NETS
939 type_pf_data_flags(data, cadt_flags);
943 TUNE_AHASH_MAX(h, multi);
944 ret = type_pf_elem_tadd(n, d, AHASH_MAX(h), cadt_flags, timeout);
947 type_pf_data_next(h, d);
951 #ifdef IP_SET_HASH_WITH_NETS
952 add_cidr(h, CIDR(d->cidr), HOST_MASK);
956 rcu_read_unlock_bh();
961 type_pf_tdel(struct ip_set *set, void *value, u32 timeout, u32 flags)
963 struct ip_set_hash *h = set->data;
964 struct htable *t = h->table;
965 const struct type_pf_elem *d = value;
968 struct type_pf_elem *data;
971 key = HKEY(value, h->initval, t->htable_bits);
973 for (i = 0; i < n->pos; i++) {
974 data = ahash_tdata(n, i);
975 if (!type_pf_data_equal(data, d, &multi))
977 if (type_pf_data_expired(data))
978 return -IPSET_ERR_EXIST;
981 type_pf_data_copy(data, ahash_tdata(n, n->pos - 1));
985 #ifdef IP_SET_HASH_WITH_NETS
986 del_cidr(h, CIDR(d->cidr), HOST_MASK);
988 if (n->pos + AHASH_INIT_SIZE < n->size) {
989 void *tmp = kzalloc((n->size - AHASH_INIT_SIZE)
990 * sizeof(struct type_pf_telem),
994 n->size -= AHASH_INIT_SIZE;
995 memcpy(tmp, n->value,
996 n->size * sizeof(struct type_pf_telem));
1003 return -IPSET_ERR_EXIST;
1006 #ifdef IP_SET_HASH_WITH_NETS
1008 type_pf_ttest_cidrs(struct ip_set *set, struct type_pf_elem *d, u32 timeout)
1010 struct ip_set_hash *h = set->data;
1011 struct htable *t = h->table;
1012 struct type_pf_elem *data;
1016 u8 host_mask = SET_HOST_MASK(set->family);
1018 for (; j < host_mask && h->nets[j].cidr && !multi; j++) {
1019 type_pf_data_netmask(d, h->nets[j].cidr);
1020 key = HKEY(d, h->initval, t->htable_bits);
1021 n = hbucket(t, key);
1022 for (i = 0; i < n->pos; i++) {
1023 data = ahash_tdata(n, i);
1024 #ifdef IP_SET_HASH_WITH_MULTI
1025 if (type_pf_data_equal(data, d, &multi)) {
1026 if (!type_pf_data_expired(data))
1027 return type_pf_data_match(data);
1031 if (type_pf_data_equal(data, d, &multi) &&
1032 !type_pf_data_expired(data))
1033 return type_pf_data_match(data);
1042 type_pf_ttest(struct ip_set *set, void *value, u32 timeout, u32 flags)
1044 struct ip_set_hash *h = set->data;
1045 struct htable *t = h->table;
1046 struct type_pf_elem *data, *d = value;
1051 #ifdef IP_SET_HASH_WITH_NETS
1052 if (CIDR(d->cidr) == SET_HOST_MASK(set->family))
1053 return type_pf_ttest_cidrs(set, d, timeout);
1055 key = HKEY(d, h->initval, t->htable_bits);
1056 n = hbucket(t, key);
1057 for (i = 0; i < n->pos; i++) {
1058 data = ahash_tdata(n, i);
1059 if (type_pf_data_equal(data, d, &multi) &&
1060 !type_pf_data_expired(data))
1061 return type_pf_data_match(data);
1067 type_pf_tlist(const struct ip_set *set,
1068 struct sk_buff *skb, struct netlink_callback *cb)
1070 const struct ip_set_hash *h = set->data;
1071 const struct htable *t = h->table;
1072 struct nlattr *atd, *nested;
1073 const struct hbucket *n;
1074 const struct type_pf_elem *data;
1075 u32 first = cb->args[2];
1076 /* We assume that one hash bucket fills into one page */
1080 atd = ipset_nest_start(skb, IPSET_ATTR_ADT);
1083 for (; cb->args[2] < jhash_size(t->htable_bits); cb->args[2]++) {
1084 incomplete = skb_tail_pointer(skb);
1085 n = hbucket(t, cb->args[2]);
1086 for (i = 0; i < n->pos; i++) {
1087 data = ahash_tdata(n, i);
1088 pr_debug("list %p %u\n", n, i);
1089 if (type_pf_data_expired(data))
1091 pr_debug("do list %p %u\n", n, i);
1092 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
1094 if (cb->args[2] == first) {
1095 nla_nest_cancel(skb, atd);
1098 goto nla_put_failure;
1100 if (type_pf_data_tlist(skb, data))
1101 goto nla_put_failure;
1102 ipset_nest_end(skb, nested);
1105 ipset_nest_end(skb, atd);
1106 /* Set listing finished */
1112 nlmsg_trim(skb, incomplete);
1113 ipset_nest_end(skb, atd);
1114 if (unlikely(first == cb->args[2])) {
1115 pr_warning("Can't list set %s: one bucket does not fit into "
1116 "a message. Please report it!\n", set->name);
1123 static const struct ip_set_type_variant type_pf_tvariant = {
1124 .kadt = type_pf_kadt,
1125 .uadt = type_pf_uadt,
1127 [IPSET_ADD] = type_pf_tadd,
1128 [IPSET_DEL] = type_pf_tdel,
1129 [IPSET_TEST] = type_pf_ttest,
1131 .destroy = type_pf_destroy,
1132 .flush = type_pf_flush,
1133 .head = type_pf_head,
1134 .list = type_pf_tlist,
1135 .resize = type_pf_tresize,
1136 .same_set = type_pf_same_set,
1140 type_pf_gc(unsigned long ul_set)
1142 struct ip_set *set = (struct ip_set *) ul_set;
1143 struct ip_set_hash *h = set->data;
1145 pr_debug("called\n");
1146 write_lock_bh(&set->lock);
1148 write_unlock_bh(&set->lock);
1150 h->gc.expires = jiffies + IPSET_GC_PERIOD(h->timeout) * HZ;
1155 type_pf_gc_init(struct ip_set *set)
1157 struct ip_set_hash *h = set->data;
1160 h->gc.data = (unsigned long) set;
1161 h->gc.function = type_pf_gc;
1162 h->gc.expires = jiffies + IPSET_GC_PERIOD(h->timeout) * HZ;
1164 pr_debug("gc initialized, run in every %u\n",
1165 IPSET_GC_PERIOD(h->timeout));
1170 #undef type_pf_data_equal
1171 #undef type_pf_data_isnull
1172 #undef type_pf_data_copy
1173 #undef type_pf_data_zero_out
1174 #undef type_pf_data_netmask
1175 #undef type_pf_data_list
1176 #undef type_pf_data_tlist
1177 #undef type_pf_data_next
1178 #undef type_pf_data_flags
1179 #undef type_pf_data_match
1182 #undef type_pf_telem
1183 #undef type_pf_data_timeout
1184 #undef type_pf_data_expired
1185 #undef type_pf_data_timeout_set
1187 #undef type_pf_elem_add
1190 #undef type_pf_test_cidrs
1193 #undef type_pf_elem_tadd
1194 #undef type_pf_del_telem
1195 #undef type_pf_expire
1198 #undef type_pf_ttest_cidrs
1199 #undef type_pf_ttest
1201 #undef type_pf_resize
1202 #undef type_pf_tresize
1203 #undef type_pf_flush
1204 #undef type_pf_destroy
1207 #undef type_pf_tlist
1208 #undef type_pf_same_set
1212 #undef type_pf_gc_init
1213 #undef type_pf_variant
1214 #undef type_pf_tvariant