aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Hunt <johunt@akamai.com>2014-02-28 22:14:57 -0500
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2014-03-06 03:31:43 -0500
commit07cf8f5ae2657ac495b906c68ff3441ff8ba80ba (patch)
tree1492748285640e3445dfc7c0287836a84db60ffe
parent6843bc3c568128e8771ba35cfefe95b7ec1c93a8 (diff)
netfilter: ipset: add forceadd kernel support for hash set types
Adds a new property for hash set types, where if a set is created with the 'forceadd' option and the set becomes full the next addition to the set may succeed and evict a random entry from the set. To keep overhead low eviction is done very simply. It checks to see which bucket the new entry would be added. If the bucket's pos value is non-zero (meaning there's at least one entry in the bucket) it replaces the first entry in the bucket. If pos is zero, then it continues down the normal add process. This property is useful if you have a set for 'ban' lists where it may not matter if you release some entries from the set early. Signed-off-by: Josh Hunt <johunt@akamai.com> Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
-rw-r--r--include/linux/netfilter/ipset/ip_set.h3
-rw-r--r--include/uapi/linux/netfilter/ipset/ip_set.h7
-rw-r--r--net/netfilter/ipset/ip_set_core.c2
-rw-r--r--net/netfilter/ipset/ip_set_hash_gen.h12
-rw-r--r--net/netfilter/ipset/ip_set_hash_ip.c3
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipmark.c2
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipport.c3
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipportip.c3
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipportnet.c3
-rw-r--r--net/netfilter/ipset/ip_set_hash_net.c3
-rw-r--r--net/netfilter/ipset/ip_set_hash_netiface.c3
-rw-r--r--net/netfilter/ipset/ip_set_hash_netnet.c2
-rw-r--r--net/netfilter/ipset/ip_set_hash_netport.c3
-rw-r--r--net/netfilter/ipset/ip_set_hash_netportnet.c3
14 files changed, 40 insertions, 12 deletions
diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h
index f476bcec25ea..96afc29184be 100644
--- a/include/linux/netfilter/ipset/ip_set.h
+++ b/include/linux/netfilter/ipset/ip_set.h
@@ -65,6 +65,7 @@ enum ip_set_extension {
65#define SET_WITH_TIMEOUT(s) ((s)->extensions & IPSET_EXT_TIMEOUT) 65#define SET_WITH_TIMEOUT(s) ((s)->extensions & IPSET_EXT_TIMEOUT)
66#define SET_WITH_COUNTER(s) ((s)->extensions & IPSET_EXT_COUNTER) 66#define SET_WITH_COUNTER(s) ((s)->extensions & IPSET_EXT_COUNTER)
67#define SET_WITH_COMMENT(s) ((s)->extensions & IPSET_EXT_COMMENT) 67#define SET_WITH_COMMENT(s) ((s)->extensions & IPSET_EXT_COMMENT)
68#define SET_WITH_FORCEADD(s) ((s)->flags & IPSET_CREATE_FLAG_FORCEADD)
68 69
69/* Extension id, in size order */ 70/* Extension id, in size order */
70enum ip_set_ext_id { 71enum ip_set_ext_id {
@@ -255,6 +256,8 @@ ip_set_put_flags(struct sk_buff *skb, struct ip_set *set)
255 cadt_flags |= IPSET_FLAG_WITH_COUNTERS; 256 cadt_flags |= IPSET_FLAG_WITH_COUNTERS;
256 if (SET_WITH_COMMENT(set)) 257 if (SET_WITH_COMMENT(set))
257 cadt_flags |= IPSET_FLAG_WITH_COMMENT; 258 cadt_flags |= IPSET_FLAG_WITH_COMMENT;
259 if (SET_WITH_FORCEADD(set))
260 cadt_flags |= IPSET_FLAG_WITH_FORCEADD;
258 261
259 if (!cadt_flags) 262 if (!cadt_flags)
260 return 0; 263 return 0;
diff --git a/include/uapi/linux/netfilter/ipset/ip_set.h b/include/uapi/linux/netfilter/ipset/ip_set.h
index a1ca24408206..78c2f2e79920 100644
--- a/include/uapi/linux/netfilter/ipset/ip_set.h
+++ b/include/uapi/linux/netfilter/ipset/ip_set.h
@@ -185,13 +185,16 @@ enum ipset_cadt_flags {
185 IPSET_FLAG_WITH_COUNTERS = (1 << IPSET_FLAG_BIT_WITH_COUNTERS), 185 IPSET_FLAG_WITH_COUNTERS = (1 << IPSET_FLAG_BIT_WITH_COUNTERS),
186 IPSET_FLAG_BIT_WITH_COMMENT = 4, 186 IPSET_FLAG_BIT_WITH_COMMENT = 4,
187 IPSET_FLAG_WITH_COMMENT = (1 << IPSET_FLAG_BIT_WITH_COMMENT), 187 IPSET_FLAG_WITH_COMMENT = (1 << IPSET_FLAG_BIT_WITH_COMMENT),
188 IPSET_FLAG_BIT_WITH_FORCEADD = 5,
189 IPSET_FLAG_WITH_FORCEADD = (1 << IPSET_FLAG_BIT_WITH_FORCEADD),
188 IPSET_FLAG_CADT_MAX = 15, 190 IPSET_FLAG_CADT_MAX = 15,
189}; 191};
190 192
191/* The flag bits which correspond to the non-extension create flags */ 193/* The flag bits which correspond to the non-extension create flags */
192enum ipset_create_flags { 194enum ipset_create_flags {
193 IPSET_CREATE_FLAG_NONE = 0, 195 IPSET_CREATE_FLAG_BIT_FORCEADD = 0,
194 IPSET_CREATE_FLAG_MAX = 7, 196 IPSET_CREATE_FLAG_FORCEADD = (1 << IPSET_CREATE_FLAG_BIT_FORCEADD),
197 IPSET_CREATE_FLAG_BIT_MAX = 7,
195}; 198};
196 199
197/* Commands with settype-specific attributes */ 200/* Commands with settype-specific attributes */
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index 636cb8df5354..117208321f16 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -368,6 +368,8 @@ ip_set_elem_len(struct ip_set *set, struct nlattr *tb[], size_t len)
368 368
369 if (tb[IPSET_ATTR_CADT_FLAGS]) 369 if (tb[IPSET_ATTR_CADT_FLAGS])
370 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); 370 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
371 if (cadt_flags & IPSET_FLAG_WITH_FORCEADD)
372 set->flags |= IPSET_CREATE_FLAG_FORCEADD;
371 for (id = 0; id < IPSET_EXT_ID_MAX; id++) { 373 for (id = 0; id < IPSET_EXT_ID_MAX; id++) {
372 if (!add_extension(id, cadt_flags, tb)) 374 if (!add_extension(id, cadt_flags, tb))
373 continue; 375 continue;
diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h
index b1eed81e24c5..61c7fb052802 100644
--- a/net/netfilter/ipset/ip_set_hash_gen.h
+++ b/net/netfilter/ipset/ip_set_hash_gen.h
@@ -633,6 +633,18 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
633 bool flag_exist = flags & IPSET_FLAG_EXIST; 633 bool flag_exist = flags & IPSET_FLAG_EXIST;
634 u32 key, multi = 0; 634 u32 key, multi = 0;
635 635
636 if (h->elements >= h->maxelem && SET_WITH_FORCEADD(set)) {
637 rcu_read_lock_bh();
638 t = rcu_dereference_bh(h->table);
639 key = HKEY(value, h->initval, t->htable_bits);
640 n = hbucket(t,key);
641 if (n->pos) {
642 /* Choosing the first entry in the array to replace */
643 j = 0;
644 goto reuse_slot;
645 }
646 rcu_read_unlock_bh();
647 }
636 if (SET_WITH_TIMEOUT(set) && h->elements >= h->maxelem) 648 if (SET_WITH_TIMEOUT(set) && h->elements >= h->maxelem)
637 /* FIXME: when set is full, we slow down here */ 649 /* FIXME: when set is full, we slow down here */
638 mtype_expire(set, h, NLEN(set->family), set->dsize); 650 mtype_expire(set, h, NLEN(set->family), set->dsize);
diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c
index e65fc2423d56..dd40607f878e 100644
--- a/net/netfilter/ipset/ip_set_hash_ip.c
+++ b/net/netfilter/ipset/ip_set_hash_ip.c
@@ -25,7 +25,8 @@
25 25
26#define IPSET_TYPE_REV_MIN 0 26#define IPSET_TYPE_REV_MIN 0
27/* 1 Counters support */ 27/* 1 Counters support */
28#define IPSET_TYPE_REV_MAX 2 /* Comments support */ 28/* 2 Comments support */
29#define IPSET_TYPE_REV_MAX 3 /* Forceadd support */
29 30
30MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
31MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 32MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
diff --git a/net/netfilter/ipset/ip_set_hash_ipmark.c b/net/netfilter/ipset/ip_set_hash_ipmark.c
index 1bf8e8524218..4eff0a297254 100644
--- a/net/netfilter/ipset/ip_set_hash_ipmark.c
+++ b/net/netfilter/ipset/ip_set_hash_ipmark.c
@@ -25,7 +25,7 @@
25#include <linux/netfilter/ipset/ip_set_hash.h> 25#include <linux/netfilter/ipset/ip_set_hash.h>
26 26
27#define IPSET_TYPE_REV_MIN 0 27#define IPSET_TYPE_REV_MIN 0
28#define IPSET_TYPE_REV_MAX 0 28#define IPSET_TYPE_REV_MAX 1 /* Forceadd support */
29 29
30MODULE_LICENSE("GPL"); 30MODULE_LICENSE("GPL");
31MODULE_AUTHOR("Vytas Dauksa <vytas.dauksa@smoothwall.net>"); 31MODULE_AUTHOR("Vytas Dauksa <vytas.dauksa@smoothwall.net>");
diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c
index 525a595dd1fe..7597b82a8b03 100644
--- a/net/netfilter/ipset/ip_set_hash_ipport.c
+++ b/net/netfilter/ipset/ip_set_hash_ipport.c
@@ -27,7 +27,8 @@
27#define IPSET_TYPE_REV_MIN 0 27#define IPSET_TYPE_REV_MIN 0
28/* 1 SCTP and UDPLITE support added */ 28/* 1 SCTP and UDPLITE support added */
29/* 2 Counters support added */ 29/* 2 Counters support added */
30#define IPSET_TYPE_REV_MAX 3 /* Comments support added */ 30/* 3 Comments support added */
31#define IPSET_TYPE_REV_MAX 4 /* Forceadd support added */
31 32
32MODULE_LICENSE("GPL"); 33MODULE_LICENSE("GPL");
33MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 34MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c
index f5636631466e..672655ffd573 100644
--- a/net/netfilter/ipset/ip_set_hash_ipportip.c
+++ b/net/netfilter/ipset/ip_set_hash_ipportip.c
@@ -27,7 +27,8 @@
27#define IPSET_TYPE_REV_MIN 0 27#define IPSET_TYPE_REV_MIN 0
28/* 1 SCTP and UDPLITE support added */ 28/* 1 SCTP and UDPLITE support added */
29/* 2 Counters support added */ 29/* 2 Counters support added */
30#define IPSET_TYPE_REV_MAX 3 /* Comments support added */ 30/* 3 Comments support added */
31#define IPSET_TYPE_REV_MAX 4 /* Forceadd support added */
31 32
32MODULE_LICENSE("GPL"); 33MODULE_LICENSE("GPL");
33MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 34MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c
index 5d87fe8a41ff..7308d84f9277 100644
--- a/net/netfilter/ipset/ip_set_hash_ipportnet.c
+++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c
@@ -29,7 +29,8 @@
29/* 2 Range as input support for IPv4 added */ 29/* 2 Range as input support for IPv4 added */
30/* 3 nomatch flag support added */ 30/* 3 nomatch flag support added */
31/* 4 Counters support added */ 31/* 4 Counters support added */
32#define IPSET_TYPE_REV_MAX 5 /* Comments support added */ 32/* 5 Comments support added */
33#define IPSET_TYPE_REV_MAX 6 /* Forceadd support added */
33 34
34MODULE_LICENSE("GPL"); 35MODULE_LICENSE("GPL");
35MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 36MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
diff --git a/net/netfilter/ipset/ip_set_hash_net.c b/net/netfilter/ipset/ip_set_hash_net.c
index 8295cf4f9fdc..4c7d495783a3 100644
--- a/net/netfilter/ipset/ip_set_hash_net.c
+++ b/net/netfilter/ipset/ip_set_hash_net.c
@@ -26,7 +26,8 @@
26/* 1 Range as input support for IPv4 added */ 26/* 1 Range as input support for IPv4 added */
27/* 2 nomatch flag support added */ 27/* 2 nomatch flag support added */
28/* 3 Counters support added */ 28/* 3 Counters support added */
29#define IPSET_TYPE_REV_MAX 4 /* Comments support added */ 29/* 4 Comments support added */
30#define IPSET_TYPE_REV_MAX 5 /* Forceadd support added */
30 31
31MODULE_LICENSE("GPL"); 32MODULE_LICENSE("GPL");
32MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 33MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c
index b827a0f1f351..db2606805b35 100644
--- a/net/netfilter/ipset/ip_set_hash_netiface.c
+++ b/net/netfilter/ipset/ip_set_hash_netiface.c
@@ -27,7 +27,8 @@
27/* 1 nomatch flag support added */ 27/* 1 nomatch flag support added */
28/* 2 /0 support added */ 28/* 2 /0 support added */
29/* 3 Counters support added */ 29/* 3 Counters support added */
30#define IPSET_TYPE_REV_MAX 4 /* Comments support added */ 30/* 4 Comments support added */
31#define IPSET_TYPE_REV_MAX 5 /* Forceadd support added */
31 32
32MODULE_LICENSE("GPL"); 33MODULE_LICENSE("GPL");
33MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 34MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
diff --git a/net/netfilter/ipset/ip_set_hash_netnet.c b/net/netfilter/ipset/ip_set_hash_netnet.c
index 4e7261df8961..3e99987e4bf2 100644
--- a/net/netfilter/ipset/ip_set_hash_netnet.c
+++ b/net/netfilter/ipset/ip_set_hash_netnet.c
@@ -24,7 +24,7 @@
24#include <linux/netfilter/ipset/ip_set_hash.h> 24#include <linux/netfilter/ipset/ip_set_hash.h>
25 25
26#define IPSET_TYPE_REV_MIN 0 26#define IPSET_TYPE_REV_MIN 0
27#define IPSET_TYPE_REV_MAX 0 27#define IPSET_TYPE_REV_MAX 1 /* Forceadd support added */
28 28
29MODULE_LICENSE("GPL"); 29MODULE_LICENSE("GPL");
30MODULE_AUTHOR("Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa>"); 30MODULE_AUTHOR("Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa>");
diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c
index 7097fb0141bf..1c645fbd09c7 100644
--- a/net/netfilter/ipset/ip_set_hash_netport.c
+++ b/net/netfilter/ipset/ip_set_hash_netport.c
@@ -28,7 +28,8 @@
28/* 2 Range as input support for IPv4 added */ 28/* 2 Range as input support for IPv4 added */
29/* 3 nomatch flag support added */ 29/* 3 nomatch flag support added */
30/* 4 Counters support added */ 30/* 4 Counters support added */
31#define IPSET_TYPE_REV_MAX 5 /* Comments support added */ 31/* 5 Comments support added */
32#define IPSET_TYPE_REV_MAX 6 /* Forceadd support added */
32 33
33MODULE_LICENSE("GPL"); 34MODULE_LICENSE("GPL");
34MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 35MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
diff --git a/net/netfilter/ipset/ip_set_hash_netportnet.c b/net/netfilter/ipset/ip_set_hash_netportnet.c
index 703d1192a6a2..c0d2ba73f8b2 100644
--- a/net/netfilter/ipset/ip_set_hash_netportnet.c
+++ b/net/netfilter/ipset/ip_set_hash_netportnet.c
@@ -25,7 +25,8 @@
25#include <linux/netfilter/ipset/ip_set_hash.h> 25#include <linux/netfilter/ipset/ip_set_hash.h>
26 26
27#define IPSET_TYPE_REV_MIN 0 27#define IPSET_TYPE_REV_MIN 0
28#define IPSET_TYPE_REV_MAX 0 /* Comments support added */ 28/* 0 Comments support added */
29#define IPSET_TYPE_REV_MAX 1 /* Forceadd support added */
29 30
30MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
31MODULE_AUTHOR("Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa>"); 32MODULE_AUTHOR("Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa>");