1 /* Copyright (C) 2003-2008 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
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.
8 /* Kernel module implementing an ip hash set */
10 #include <linux/module.h>
11 #include <linux/moduleparam.h>
13 #include <linux/skbuff.h>
14 #include <linux/netfilter_ipv4/ip_set_jhash.h>
15 #include <linux/errno.h>
16 #include <asm/uaccess.h>
17 #include <asm/bitops.h>
18 #include <linux/spinlock.h>
19 #include <linux/random.h>
23 #include <linux/netfilter_ipv4/ip_set_iphash.h>
25 static int limit
= MAX_RANGE
;
28 iphash_id(struct ip_set
*set
, ip_set_ip_t ip
)
30 struct ip_set_iphash
*map
= set
->data
;
37 DP("set: %s, ip:%u.%u.%u.%u", set
->name
, HIPQUAD(ip
));
38 for (i
= 0; i
< map
->probes
; i
++) {
39 id
= jhash_ip(map
, i
, ip
) % map
->hashsize
;
40 DP("hash key: %u", id
);
41 elem
= HARRAY_ELEM(map
->members
, ip_set_ip_t
*, id
);
44 /* No shortcut - there can be deleted entries. */
50 iphash_test(struct ip_set
*set
, ip_set_ip_t ip
)
52 return (ip
&& iphash_id(set
, ip
) != UINT_MAX
);
55 #define KADT_CONDITION
58 KADT(iphash
, test
, ipaddr
)
61 __iphash_add(struct ip_set_iphash
*map
, ip_set_ip_t
*ip
)
65 ip_set_ip_t
*elem
, *slot
= NULL
;
67 for (i
= 0; i
< map
->probes
; i
++) {
68 probe
= jhash_ip(map
, i
, *ip
) % map
->hashsize
;
69 elem
= HARRAY_ELEM(map
->members
, ip_set_ip_t
*, probe
);
74 /* There can be deleted entries, must check all slots */
81 /* Trigger rehashing */
86 iphash_add(struct ip_set
*set
, ip_set_ip_t ip
)
88 struct ip_set_iphash
*map
= set
->data
;
90 if (!ip
|| map
->elements
>= limit
)
94 return __iphash_add(map
, &ip
);
98 KADT(iphash
, add
, ipaddr
)
101 __iphash_retry(struct ip_set_iphash
*tmp
, struct ip_set_iphash
*map
)
103 tmp
->netmask
= map
->netmask
;
106 HASH_RETRY(iphash
, ip_set_ip_t
)
109 iphash_del(struct ip_set
*set
, ip_set_ip_t ip
)
111 struct ip_set_iphash
*map
= set
->data
;
112 ip_set_ip_t id
, *elem
;
117 id
= iphash_id(set
, ip
);
121 elem
= HARRAY_ELEM(map
->members
, ip_set_ip_t
*, id
);
129 KADT(iphash
, del
, ipaddr
)
132 __iphash_create(const struct ip_set_req_iphash_create
*req
,
133 struct ip_set_iphash
*map
)
135 map
->netmask
= req
->netmask
;
140 HASH_CREATE(iphash
, ip_set_ip_t
)
143 HASH_FLUSH(iphash
, ip_set_ip_t
)
146 __iphash_list_header(const struct ip_set_iphash
*map
,
147 struct ip_set_req_iphash_create
*header
)
149 header
->netmask
= map
->netmask
;
152 HASH_LIST_HEADER(iphash
)
153 HASH_LIST_MEMBERS_SIZE(iphash
, ip_set_ip_t
)
154 HASH_LIST_MEMBERS(iphash
, ip_set_ip_t
)
156 IP_SET_RTYPE(iphash
, IPSET_TYPE_IP
| IPSET_DATA_SINGLE
)
158 MODULE_LICENSE("GPL");
159 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
160 MODULE_DESCRIPTION("iphash type of IP sets");
161 module_param(limit
, int, 0600);
162 MODULE_PARM_DESC(limit
, "maximal number of elements stored in the sets");
164 REGISTER_MODULE(iphash
)