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*4)
35 void *value; /* the array of the values */
36 u8 size; /* size of the array */
37 u8 pos; /* position of the first free entry */
40 /* The hash table: the table size stored here in order to make resizing easy */
42 u8 htable_bits; /* size of hash table == 2^htable_bits */
43 struct hbucket bucket[0]; /* hashtable buckets */
46 #define hbucket(h, i) &((h)->bucket[i])
48 /* Book-keeping of the prefixes added to the set */
49 struct ip_set_hash_nets {
50 u8 cidr; /* the different cidr values in the set */
51 u32 nets; /* number of elements per cidr */
54 /* The generic ip_set hash structure */
56 struct htable *table; /* the hash table */
57 u32 maxelem; /* max elements in the hash */
58 u32 elements; /* current element (vs timeout) */
59 u32 initval; /* random jhash init value */
60 u32 timeout; /* timeout value, if enabled */
61 struct timer_list gc; /* garbage collection when timeout enabled */
62 struct type_pf_next next; /* temporary storage for uadd */
63 #ifdef IP_SET_HASH_WITH_NETMASK
64 u8 netmask; /* netmask value for subnets to store */
66 #ifdef IP_SET_HASH_WITH_NETS
67 struct ip_set_hash_nets nets[0]; /* book-keeping of prefixes */
71 /* Compute htable_bits from the user input parameter hashsize */
73 htable_bits(u32 hashsize)
75 /* Assume that hashsize == 2^htable_bits */
76 u8 bits = fls(hashsize - 1);
77 if (jhash_size(bits) != hashsize)
78 /* Round up to the first 2^n value */
84 #ifdef IP_SET_HASH_WITH_NETS
86 #define SET_HOST_MASK(family) (family == AF_INET ? 32 : 128)
88 /* Network cidr size book keeping when the hash stores different
91 add_cidr(struct ip_set_hash *h, u8 cidr, u8 host_mask)
95 ++h->nets[cidr-1].nets;
97 pr_debug("add_cidr added %u: %u\n", cidr, h->nets[cidr-1].nets);
99 if (h->nets[cidr-1].nets > 1)
103 for (i = 0; i < host_mask && h->nets[i].cidr; i++) {
104 /* Add in increasing prefix order, so larger cidr first */
105 if (h->nets[i].cidr < cidr)
106 swap(h->nets[i].cidr, cidr);
109 h->nets[i].cidr = cidr;
113 del_cidr(struct ip_set_hash *h, u8 cidr, u8 host_mask)
117 --h->nets[cidr-1].nets;
119 pr_debug("del_cidr deleted %u: %u\n", cidr, h->nets[cidr-1].nets);
121 if (h->nets[cidr-1].nets != 0)
124 /* All entries with this cidr size deleted, so cleanup h->cidr[] */
125 for (i = 0; i < host_mask - 1 && h->nets[i].cidr; i++) {
126 if (h->nets[i].cidr == cidr)
127 h->nets[i].cidr = cidr = h->nets[i+1].cidr;
129 h->nets[i - 1].cidr = 0;
133 /* Destroy the hashtable part of the set */
135 ahash_destroy(struct htable *t)
140 for (i = 0; i < jhash_size(t->htable_bits); i++) {
143 /* FIXME: use slab cache */
150 /* Calculate the actual memory size of the set data */
152 ahash_memsize(const struct ip_set_hash *h, size_t dsize, u8 host_mask)
155 struct htable *t = h->table;
156 size_t memsize = sizeof(*h)
158 #ifdef IP_SET_HASH_WITH_NETS
159 + sizeof(struct ip_set_hash_nets) * host_mask
161 + jhash_size(t->htable_bits) * sizeof(struct hbucket);
163 for (i = 0; i < jhash_size(t->htable_bits); i++)
164 memsize += t->bucket[i].size * dsize;
169 /* Flush a hash type of set: destroy all elements */
171 ip_set_hash_flush(struct ip_set *set)
173 struct ip_set_hash *h = set->data;
174 struct htable *t = h->table;
178 for (i = 0; i < jhash_size(t->htable_bits); i++) {
181 n->size = n->pos = 0;
182 /* FIXME: use slab cache */
186 #ifdef IP_SET_HASH_WITH_NETS
187 memset(h->nets, 0, sizeof(struct ip_set_hash_nets)
188 * SET_HOST_MASK(set->family));
193 /* Destroy a hash type of set */
195 ip_set_hash_destroy(struct ip_set *set)
197 struct ip_set_hash *h = set->data;
199 if (with_timeout(h->timeout))
200 del_timer_sync(&h->gc);
202 ahash_destroy(h->table);
208 #define HKEY(data, initval, htable_bits) \
209 (jhash2((u32 *)(data), sizeof(struct type_pf_elem)/sizeof(u32), initval) \
210 & jhash_mask(htable_bits))
212 #endif /* _IP_SET_AHASH_H */
214 #define CONCAT(a, b, c) a##b##c
215 #define TOKEN(a, b, c) CONCAT(a, b, c)
217 /* Type/family dependent function prototypes */
219 #define type_pf_data_equal TOKEN(TYPE, PF, _data_equal)
220 #define type_pf_data_isnull TOKEN(TYPE, PF, _data_isnull)
221 #define type_pf_data_copy TOKEN(TYPE, PF, _data_copy)
222 #define type_pf_data_zero_out TOKEN(TYPE, PF, _data_zero_out)
223 #define type_pf_data_netmask TOKEN(TYPE, PF, _data_netmask)
224 #define type_pf_data_list TOKEN(TYPE, PF, _data_list)
225 #define type_pf_data_tlist TOKEN(TYPE, PF, _data_tlist)
226 #define type_pf_data_next TOKEN(TYPE, PF, _data_next)
228 #define type_pf_elem TOKEN(TYPE, PF, _elem)
229 #define type_pf_telem TOKEN(TYPE, PF, _telem)
230 #define type_pf_data_timeout TOKEN(TYPE, PF, _data_timeout)
231 #define type_pf_data_expired TOKEN(TYPE, PF, _data_expired)
232 #define type_pf_data_timeout_set TOKEN(TYPE, PF, _data_timeout_set)
234 #define type_pf_elem_add TOKEN(TYPE, PF, _elem_add)
235 #define type_pf_add TOKEN(TYPE, PF, _add)
236 #define type_pf_del TOKEN(TYPE, PF, _del)
237 #define type_pf_test_cidrs TOKEN(TYPE, PF, _test_cidrs)
238 #define type_pf_test TOKEN(TYPE, PF, _test)
240 #define type_pf_elem_tadd TOKEN(TYPE, PF, _elem_tadd)
241 #define type_pf_del_telem TOKEN(TYPE, PF, _ahash_del_telem)
242 #define type_pf_expire TOKEN(TYPE, PF, _expire)
243 #define type_pf_tadd TOKEN(TYPE, PF, _tadd)
244 #define type_pf_tdel TOKEN(TYPE, PF, _tdel)
245 #define type_pf_ttest_cidrs TOKEN(TYPE, PF, _ahash_ttest_cidrs)
246 #define type_pf_ttest TOKEN(TYPE, PF, _ahash_ttest)
248 #define type_pf_resize TOKEN(TYPE, PF, _resize)
249 #define type_pf_tresize TOKEN(TYPE, PF, _tresize)
250 #define type_pf_flush ip_set_hash_flush
251 #define type_pf_destroy ip_set_hash_destroy
252 #define type_pf_head TOKEN(TYPE, PF, _head)
253 #define type_pf_list TOKEN(TYPE, PF, _list)
254 #define type_pf_tlist TOKEN(TYPE, PF, _tlist)
255 #define type_pf_same_set TOKEN(TYPE, PF, _same_set)
256 #define type_pf_kadt TOKEN(TYPE, PF, _kadt)
257 #define type_pf_uadt TOKEN(TYPE, PF, _uadt)
258 #define type_pf_gc TOKEN(TYPE, PF, _gc)
259 #define type_pf_gc_init TOKEN(TYPE, PF, _gc_init)
260 #define type_pf_variant TOKEN(TYPE, PF, _variant)
261 #define type_pf_tvariant TOKEN(TYPE, PF, _tvariant)
263 /* Flavour without timeout */
265 /* Get the ith element from the array block n */
266 #define ahash_data(n, i) \
267 ((struct type_pf_elem *)((n)->value) + (i))
269 /* Add an element to the hash table when resizing the set:
270 * we spare the maintenance of the internal counters. */
272 type_pf_elem_add(struct hbucket *n, const struct type_pf_elem *value)
274 if (n->pos >= n->size) {
277 if (n->size >= AHASH_MAX_SIZE)
278 /* Trigger rehashing */
281 tmp = kzalloc((n->size + AHASH_INIT_SIZE)
282 * sizeof(struct type_pf_elem),
287 memcpy(tmp, n->value,
288 sizeof(struct type_pf_elem) * n->size);
292 n->size += AHASH_INIT_SIZE;
294 type_pf_data_copy(ahash_data(n, n->pos++), value);
298 /* Resize a hash: create a new hash table with doubling the hashsize
299 * and inserting the elements to it. Repeat until we succeed or
300 * fail due to memory pressures. */
302 type_pf_resize(struct ip_set *set, bool retried)
304 struct ip_set_hash *h = set->data;
305 struct htable *t, *orig = h->table;
306 u8 htable_bits = orig->htable_bits;
307 const struct type_pf_elem *data;
308 struct hbucket *n, *m;
315 pr_debug("attempt to resize set %s from %u to %u, t %p\n",
316 set->name, orig->htable_bits, htable_bits, orig);
318 /* In case we have plenty of memory :-) */
319 return -IPSET_ERR_HASH_FULL;
320 t = ip_set_alloc(sizeof(*t)
321 + jhash_size(htable_bits) * sizeof(struct hbucket));
324 t->htable_bits = htable_bits;
326 read_lock_bh(&set->lock);
327 for (i = 0; i < jhash_size(orig->htable_bits); i++) {
328 n = hbucket(orig, i);
329 for (j = 0; j < n->pos; j++) {
330 data = ahash_data(n, j);
331 m = hbucket(t, HKEY(data, h->initval, htable_bits));
332 ret = type_pf_elem_add(m, data);
334 read_unlock_bh(&set->lock);
343 rcu_assign_pointer(h->table, t);
344 read_unlock_bh(&set->lock);
346 /* Give time to other readers of the set */
347 synchronize_rcu_bh();
349 pr_debug("set %s resized from %u (%p) to %u (%p)\n", set->name,
350 orig->htable_bits, orig, t->htable_bits, t);
357 type_pf_data_next(struct ip_set_hash *h, const struct type_pf_elem *d);
359 /* Add an element to a hash and update the internal counters when succeeded,
360 * otherwise report the proper error code. */
362 type_pf_add(struct ip_set *set, void *value, u32 timeout, u32 flags)
364 struct ip_set_hash *h = set->data;
366 const struct type_pf_elem *d = value;
371 if (h->elements >= h->maxelem)
372 return -IPSET_ERR_HASH_FULL;
375 t = rcu_dereference_bh(h->table);
376 key = HKEY(value, h->initval, t->htable_bits);
378 for (i = 0; i < n->pos; i++)
379 if (type_pf_data_equal(ahash_data(n, i), d)) {
380 ret = -IPSET_ERR_EXIST;
384 ret = type_pf_elem_add(n, value);
387 type_pf_data_next(h, d);
391 #ifdef IP_SET_HASH_WITH_NETS
392 add_cidr(h, d->cidr, HOST_MASK);
396 rcu_read_unlock_bh();
400 /* Delete an element from the hash: swap it with the last element
401 * and free up space if possible.
404 type_pf_del(struct ip_set *set, void *value, u32 timeout, u32 flags)
406 struct ip_set_hash *h = set->data;
407 struct htable *t = h->table;
408 const struct type_pf_elem *d = value;
411 struct type_pf_elem *data;
414 key = HKEY(value, h->initval, t->htable_bits);
416 for (i = 0; i < n->pos; i++) {
417 data = ahash_data(n, i);
418 if (!type_pf_data_equal(data, d))
422 type_pf_data_copy(data, ahash_data(n, n->pos - 1));
426 #ifdef IP_SET_HASH_WITH_NETS
427 del_cidr(h, d->cidr, HOST_MASK);
429 if (n->pos + AHASH_INIT_SIZE < n->size) {
430 void *tmp = kzalloc((n->size - AHASH_INIT_SIZE)
431 * sizeof(struct type_pf_elem),
435 n->size -= AHASH_INIT_SIZE;
436 memcpy(tmp, n->value,
437 n->size * sizeof(struct type_pf_elem));
444 return -IPSET_ERR_EXIST;
447 #ifdef IP_SET_HASH_WITH_NETS
449 /* Special test function which takes into account the different network
450 * sizes added to the set */
452 type_pf_test_cidrs(struct ip_set *set, struct type_pf_elem *d, u32 timeout)
454 struct ip_set_hash *h = set->data;
455 struct htable *t = h->table;
457 const struct type_pf_elem *data;
460 u8 host_mask = SET_HOST_MASK(set->family);
462 pr_debug("test by nets\n");
463 for (; j < host_mask && h->nets[j].cidr; j++) {
464 type_pf_data_netmask(d, h->nets[j].cidr);
465 key = HKEY(d, h->initval, t->htable_bits);
467 for (i = 0; i < n->pos; i++) {
468 data = ahash_data(n, i);
469 if (type_pf_data_equal(data, d))
477 /* Test whether the element is added to the set */
479 type_pf_test(struct ip_set *set, void *value, u32 timeout, u32 flags)
481 struct ip_set_hash *h = set->data;
482 struct htable *t = h->table;
483 struct type_pf_elem *d = value;
485 const struct type_pf_elem *data;
489 #ifdef IP_SET_HASH_WITH_NETS
490 /* If we test an IP address and not a network address,
491 * try all possible network sizes */
492 if (d->cidr == SET_HOST_MASK(set->family))
493 return type_pf_test_cidrs(set, d, timeout);
496 key = HKEY(d, h->initval, t->htable_bits);
498 for (i = 0; i < n->pos; i++) {
499 data = ahash_data(n, i);
500 if (type_pf_data_equal(data, d))
506 /* Reply a HEADER request: fill out the header part of the set */
508 type_pf_head(struct ip_set *set, struct sk_buff *skb)
510 const struct ip_set_hash *h = set->data;
511 struct nlattr *nested;
514 read_lock_bh(&set->lock);
515 memsize = ahash_memsize(h, with_timeout(h->timeout)
516 ? sizeof(struct type_pf_telem)
517 : sizeof(struct type_pf_elem),
518 set->family == AF_INET ? 32 : 128);
519 read_unlock_bh(&set->lock);
521 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
523 goto nla_put_failure;
524 NLA_PUT_NET32(skb, IPSET_ATTR_HASHSIZE,
525 htonl(jhash_size(h->table->htable_bits)));
526 NLA_PUT_NET32(skb, IPSET_ATTR_MAXELEM, htonl(h->maxelem));
527 #ifdef IP_SET_HASH_WITH_NETMASK
528 if (h->netmask != HOST_MASK)
529 NLA_PUT_U8(skb, IPSET_ATTR_NETMASK, h->netmask);
531 NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1));
532 NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize));
533 if (with_timeout(h->timeout))
534 NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(h->timeout));
535 ipset_nest_end(skb, nested);
542 /* Reply a LIST/SAVE request: dump the elements of the specified set */
544 type_pf_list(const struct ip_set *set,
545 struct sk_buff *skb, struct netlink_callback *cb)
547 const struct ip_set_hash *h = set->data;
548 const struct htable *t = h->table;
549 struct nlattr *atd, *nested;
550 const struct hbucket *n;
551 const struct type_pf_elem *data;
552 u32 first = cb->args[2];
553 /* We assume that one hash bucket fills into one page */
557 atd = ipset_nest_start(skb, IPSET_ATTR_ADT);
560 pr_debug("list hash set %s\n", set->name);
561 for (; cb->args[2] < jhash_size(t->htable_bits); cb->args[2]++) {
562 incomplete = skb_tail_pointer(skb);
563 n = hbucket(t, cb->args[2]);
564 pr_debug("cb->args[2]: %lu, t %p n %p\n", cb->args[2], t, n);
565 for (i = 0; i < n->pos; i++) {
566 data = ahash_data(n, i);
567 pr_debug("list hash %lu hbucket %p i %u, data %p\n",
568 cb->args[2], n, i, data);
569 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
571 if (cb->args[2] == first) {
572 nla_nest_cancel(skb, atd);
575 goto nla_put_failure;
577 if (type_pf_data_list(skb, data))
578 goto nla_put_failure;
579 ipset_nest_end(skb, nested);
582 ipset_nest_end(skb, atd);
583 /* Set listing finished */
589 nlmsg_trim(skb, incomplete);
590 ipset_nest_end(skb, atd);
591 if (unlikely(first == cb->args[2])) {
592 pr_warning("Can't list set %s: one bucket does not fit into "
593 "a message. Please report it!\n", set->name);
601 type_pf_kadt(struct ip_set *set, const struct sk_buff * skb,
602 enum ipset_adt adt, const struct ip_set_adt_opt *opt);
604 type_pf_uadt(struct ip_set *set, struct nlattr *tb[],
605 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried);
607 static const struct ip_set_type_variant type_pf_variant = {
608 .kadt = type_pf_kadt,
609 .uadt = type_pf_uadt,
611 [IPSET_ADD] = type_pf_add,
612 [IPSET_DEL] = type_pf_del,
613 [IPSET_TEST] = type_pf_test,
615 .destroy = type_pf_destroy,
616 .flush = type_pf_flush,
617 .head = type_pf_head,
618 .list = type_pf_list,
619 .resize = type_pf_resize,
620 .same_set = type_pf_same_set,
623 /* Flavour with timeout support */
625 #define ahash_tdata(n, i) \
626 (struct type_pf_elem *)((struct type_pf_telem *)((n)->value) + (i))
629 type_pf_data_timeout(const struct type_pf_elem *data)
631 const struct type_pf_telem *tdata =
632 (const struct type_pf_telem *) data;
634 return tdata->timeout;
638 type_pf_data_expired(const struct type_pf_elem *data)
640 const struct type_pf_telem *tdata =
641 (const struct type_pf_telem *) data;
643 return ip_set_timeout_expired(tdata->timeout);
647 type_pf_data_timeout_set(struct type_pf_elem *data, u32 timeout)
649 struct type_pf_telem *tdata = (struct type_pf_telem *) data;
651 tdata->timeout = ip_set_timeout_set(timeout);
655 type_pf_elem_tadd(struct hbucket *n, const struct type_pf_elem *value,
658 struct type_pf_elem *data;
660 if (n->pos >= n->size) {
663 if (n->size >= AHASH_MAX_SIZE)
664 /* Trigger rehashing */
667 tmp = kzalloc((n->size + AHASH_INIT_SIZE)
668 * sizeof(struct type_pf_telem),
673 memcpy(tmp, n->value,
674 sizeof(struct type_pf_telem) * n->size);
678 n->size += AHASH_INIT_SIZE;
680 data = ahash_tdata(n, n->pos++);
681 type_pf_data_copy(data, value);
682 type_pf_data_timeout_set(data, timeout);
686 /* Delete expired elements from the hashtable */
688 type_pf_expire(struct ip_set_hash *h)
690 struct htable *t = h->table;
692 struct type_pf_elem *data;
696 for (i = 0; i < jhash_size(t->htable_bits); i++) {
698 for (j = 0; j < n->pos; j++) {
699 data = ahash_tdata(n, j);
700 if (type_pf_data_expired(data)) {
701 pr_debug("expired %u/%u\n", i, j);
702 #ifdef IP_SET_HASH_WITH_NETS
703 del_cidr(h, data->cidr, HOST_MASK);
707 type_pf_data_copy(data,
708 ahash_tdata(n, n->pos - 1));
713 if (n->pos + AHASH_INIT_SIZE < n->size) {
714 void *tmp = kzalloc((n->size - AHASH_INIT_SIZE)
715 * sizeof(struct type_pf_telem),
718 /* Still try to delete expired elements */
720 n->size -= AHASH_INIT_SIZE;
721 memcpy(tmp, n->value,
722 n->size * sizeof(struct type_pf_telem));
730 type_pf_tresize(struct ip_set *set, bool retried)
732 struct ip_set_hash *h = set->data;
733 struct htable *t, *orig = h->table;
734 u8 htable_bits = orig->htable_bits;
735 const struct type_pf_elem *data;
736 struct hbucket *n, *m;
740 /* Try to cleanup once */
743 write_lock_bh(&set->lock);
744 type_pf_expire(set->data);
745 write_unlock_bh(&set->lock);
754 /* In case we have plenty of memory :-) */
755 return -IPSET_ERR_HASH_FULL;
756 t = ip_set_alloc(sizeof(*t)
757 + jhash_size(htable_bits) * sizeof(struct hbucket));
760 t->htable_bits = htable_bits;
762 read_lock_bh(&set->lock);
763 for (i = 0; i < jhash_size(orig->htable_bits); i++) {
764 n = hbucket(orig, i);
765 for (j = 0; j < n->pos; j++) {
766 data = ahash_tdata(n, j);
767 m = hbucket(t, HKEY(data, h->initval, htable_bits));
768 ret = type_pf_elem_tadd(m, data,
769 type_pf_data_timeout(data));
771 read_unlock_bh(&set->lock);
780 rcu_assign_pointer(h->table, t);
781 read_unlock_bh(&set->lock);
783 /* Give time to other readers of the set */
784 synchronize_rcu_bh();
792 type_pf_tadd(struct ip_set *set, void *value, u32 timeout, u32 flags)
794 struct ip_set_hash *h = set->data;
795 struct htable *t = h->table;
796 const struct type_pf_elem *d = value;
798 struct type_pf_elem *data;
799 int ret = 0, i, j = AHASH_MAX_SIZE + 1;
800 bool flag_exist = flags & IPSET_FLAG_EXIST;
803 if (h->elements >= h->maxelem)
804 /* FIXME: when set is full, we slow down here */
806 if (h->elements >= h->maxelem)
807 return -IPSET_ERR_HASH_FULL;
810 t = rcu_dereference_bh(h->table);
811 key = HKEY(d, h->initval, t->htable_bits);
813 for (i = 0; i < n->pos; i++) {
814 data = ahash_tdata(n, i);
815 if (type_pf_data_equal(data, d)) {
816 if (type_pf_data_expired(data) || flag_exist)
819 ret = -IPSET_ERR_EXIST;
822 } else if (j == AHASH_MAX_SIZE + 1 &&
823 type_pf_data_expired(data))
826 if (j != AHASH_MAX_SIZE + 1) {
827 data = ahash_tdata(n, j);
828 #ifdef IP_SET_HASH_WITH_NETS
829 del_cidr(h, data->cidr, HOST_MASK);
830 add_cidr(h, d->cidr, HOST_MASK);
832 type_pf_data_copy(data, d);
833 type_pf_data_timeout_set(data, timeout);
836 ret = type_pf_elem_tadd(n, d, timeout);
839 type_pf_data_next(h, d);
843 #ifdef IP_SET_HASH_WITH_NETS
844 add_cidr(h, d->cidr, HOST_MASK);
848 rcu_read_unlock_bh();
853 type_pf_tdel(struct ip_set *set, void *value, u32 timeout, u32 flags)
855 struct ip_set_hash *h = set->data;
856 struct htable *t = h->table;
857 const struct type_pf_elem *d = value;
860 struct type_pf_elem *data;
863 key = HKEY(value, h->initval, t->htable_bits);
865 for (i = 0; i < n->pos; i++) {
866 data = ahash_tdata(n, i);
867 if (!type_pf_data_equal(data, d))
869 if (type_pf_data_expired(data))
870 return -IPSET_ERR_EXIST;
873 type_pf_data_copy(data, ahash_tdata(n, n->pos - 1));
877 #ifdef IP_SET_HASH_WITH_NETS
878 del_cidr(h, d->cidr, HOST_MASK);
880 if (n->pos + AHASH_INIT_SIZE < n->size) {
881 void *tmp = kzalloc((n->size - AHASH_INIT_SIZE)
882 * sizeof(struct type_pf_telem),
886 n->size -= AHASH_INIT_SIZE;
887 memcpy(tmp, n->value,
888 n->size * sizeof(struct type_pf_telem));
895 return -IPSET_ERR_EXIST;
898 #ifdef IP_SET_HASH_WITH_NETS
900 type_pf_ttest_cidrs(struct ip_set *set, struct type_pf_elem *d, u32 timeout)
902 struct ip_set_hash *h = set->data;
903 struct htable *t = h->table;
904 struct type_pf_elem *data;
908 u8 host_mask = SET_HOST_MASK(set->family);
910 for (; j < host_mask && h->nets[j].cidr; j++) {
911 type_pf_data_netmask(d, h->nets[j].cidr);
912 key = HKEY(d, h->initval, t->htable_bits);
914 for (i = 0; i < n->pos; i++) {
915 data = ahash_tdata(n, i);
916 if (type_pf_data_equal(data, d))
917 return !type_pf_data_expired(data);
925 type_pf_ttest(struct ip_set *set, void *value, u32 timeout, u32 flags)
927 struct ip_set_hash *h = set->data;
928 struct htable *t = h->table;
929 struct type_pf_elem *data, *d = value;
934 #ifdef IP_SET_HASH_WITH_NETS
935 if (d->cidr == SET_HOST_MASK(set->family))
936 return type_pf_ttest_cidrs(set, d, timeout);
938 key = HKEY(d, h->initval, t->htable_bits);
940 for (i = 0; i < n->pos; i++) {
941 data = ahash_tdata(n, i);
942 if (type_pf_data_equal(data, d))
943 return !type_pf_data_expired(data);
949 type_pf_tlist(const struct ip_set *set,
950 struct sk_buff *skb, struct netlink_callback *cb)
952 const struct ip_set_hash *h = set->data;
953 const struct htable *t = h->table;
954 struct nlattr *atd, *nested;
955 const struct hbucket *n;
956 const struct type_pf_elem *data;
957 u32 first = cb->args[2];
958 /* We assume that one hash bucket fills into one page */
962 atd = ipset_nest_start(skb, IPSET_ATTR_ADT);
965 for (; cb->args[2] < jhash_size(t->htable_bits); cb->args[2]++) {
966 incomplete = skb_tail_pointer(skb);
967 n = hbucket(t, cb->args[2]);
968 for (i = 0; i < n->pos; i++) {
969 data = ahash_tdata(n, i);
970 pr_debug("list %p %u\n", n, i);
971 if (type_pf_data_expired(data))
973 pr_debug("do list %p %u\n", n, i);
974 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
976 if (cb->args[2] == first) {
977 nla_nest_cancel(skb, atd);
980 goto nla_put_failure;
982 if (type_pf_data_tlist(skb, data))
983 goto nla_put_failure;
984 ipset_nest_end(skb, nested);
987 ipset_nest_end(skb, atd);
988 /* Set listing finished */
994 nlmsg_trim(skb, incomplete);
995 ipset_nest_end(skb, atd);
996 if (unlikely(first == cb->args[2])) {
997 pr_warning("Can't list set %s: one bucket does not fit into "
998 "a message. Please report it!\n", set->name);
1005 static const struct ip_set_type_variant type_pf_tvariant = {
1006 .kadt = type_pf_kadt,
1007 .uadt = type_pf_uadt,
1009 [IPSET_ADD] = type_pf_tadd,
1010 [IPSET_DEL] = type_pf_tdel,
1011 [IPSET_TEST] = type_pf_ttest,
1013 .destroy = type_pf_destroy,
1014 .flush = type_pf_flush,
1015 .head = type_pf_head,
1016 .list = type_pf_tlist,
1017 .resize = type_pf_tresize,
1018 .same_set = type_pf_same_set,
1022 type_pf_gc(unsigned long ul_set)
1024 struct ip_set *set = (struct ip_set *) ul_set;
1025 struct ip_set_hash *h = set->data;
1027 pr_debug("called\n");
1028 write_lock_bh(&set->lock);
1030 write_unlock_bh(&set->lock);
1032 h->gc.expires = jiffies + IPSET_GC_PERIOD(h->timeout) * HZ;
1037 type_pf_gc_init(struct ip_set *set)
1039 struct ip_set_hash *h = set->data;
1042 h->gc.data = (unsigned long) set;
1043 h->gc.function = type_pf_gc;
1044 h->gc.expires = jiffies + IPSET_GC_PERIOD(h->timeout) * HZ;
1046 pr_debug("gc initialized, run in every %u\n",
1047 IPSET_GC_PERIOD(h->timeout));
1050 #undef type_pf_data_equal
1051 #undef type_pf_data_isnull
1052 #undef type_pf_data_copy
1053 #undef type_pf_data_zero_out
1054 #undef type_pf_data_list
1055 #undef type_pf_data_tlist
1058 #undef type_pf_telem
1059 #undef type_pf_data_timeout
1060 #undef type_pf_data_expired
1061 #undef type_pf_data_netmask
1062 #undef type_pf_data_timeout_set
1064 #undef type_pf_elem_add
1067 #undef type_pf_test_cidrs
1070 #undef type_pf_elem_tadd
1071 #undef type_pf_expire
1074 #undef type_pf_ttest_cidrs
1075 #undef type_pf_ttest
1077 #undef type_pf_resize
1078 #undef type_pf_tresize
1079 #undef type_pf_flush
1080 #undef type_pf_destroy
1083 #undef type_pf_tlist
1084 #undef type_pf_same_set
1088 #undef type_pf_gc_init
1089 #undef type_pf_variant
1090 #undef type_pf_tvariant