]> granicus.if.org Git - ipset/commitdiff
ipset: add forceadd kernel support for hash set types
authorJosh Hunt <johunt@akamai.com>
Sat, 1 Mar 2014 03:14:57 +0000 (22:14 -0500)
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Tue, 4 Mar 2014 16:35:45 +0000 (17:35 +0100)
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>
14 files changed:
kernel/include/linux/netfilter/ipset/ip_set.h
kernel/include/uapi/linux/netfilter/ipset/ip_set.h
kernel/net/netfilter/ipset/ip_set_core.c
kernel/net/netfilter/ipset/ip_set_hash_gen.h
kernel/net/netfilter/ipset/ip_set_hash_ip.c
kernel/net/netfilter/ipset/ip_set_hash_ipmark.c
kernel/net/netfilter/ipset/ip_set_hash_ipport.c
kernel/net/netfilter/ipset/ip_set_hash_ipportip.c
kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c
kernel/net/netfilter/ipset/ip_set_hash_net.c
kernel/net/netfilter/ipset/ip_set_hash_netiface.c
kernel/net/netfilter/ipset/ip_set_hash_netnet.c
kernel/net/netfilter/ipset/ip_set_hash_netport.c
kernel/net/netfilter/ipset/ip_set_hash_netportnet.c

index 79b13d05f4c08f698830fa6027b2243c734b2ea0..7bb488eaa8379ecd456abcd90763db6e338c3f95 100644 (file)
@@ -66,6 +66,7 @@ enum ip_set_extension {
 #define SET_WITH_TIMEOUT(s)    ((s)->extensions & IPSET_EXT_TIMEOUT)
 #define SET_WITH_COUNTER(s)    ((s)->extensions & IPSET_EXT_COUNTER)
 #define SET_WITH_COMMENT(s)    ((s)->extensions & IPSET_EXT_COMMENT)
+#define SET_WITH_FORCEADD(s)   ((s)->flags & IPSET_CREATE_FLAG_FORCEADD)
 
 /* Extension id, in size order */
 enum ip_set_ext_id {
@@ -256,6 +257,8 @@ ip_set_put_flags(struct sk_buff *skb, struct ip_set *set)
                cadt_flags |= IPSET_FLAG_WITH_COUNTERS;
        if (SET_WITH_COMMENT(set))
                cadt_flags |= IPSET_FLAG_WITH_COMMENT;
+       if (SET_WITH_FORCEADD(set))
+               cadt_flags |= IPSET_FLAG_WITH_FORCEADD;
 
        if (!cadt_flags)
                return 0;
index b8cc49336ba4bc09a7d3317103a2b2a0cd44fb3d..7272b2b17c15daa478f80648402beb6dfdbd8208 100644 (file)
@@ -186,13 +186,16 @@ enum ipset_cadt_flags {
        IPSET_FLAG_WITH_COUNTERS = (1 << IPSET_FLAG_BIT_WITH_COUNTERS),
        IPSET_FLAG_BIT_WITH_COMMENT = 4,
        IPSET_FLAG_WITH_COMMENT = (1 << IPSET_FLAG_BIT_WITH_COMMENT),
+       IPSET_FLAG_BIT_WITH_FORCEADD = 5,
+       IPSET_FLAG_WITH_FORCEADD = (1 << IPSET_FLAG_BIT_WITH_FORCEADD),
        IPSET_FLAG_CADT_MAX     = 15,
 };
 
 /* The flag bits which correspond to the non-extension create flags */
 enum ipset_create_flags {
-       IPSET_CREATE_FLAG_NONE = 0,
-       IPSET_CREATE_FLAG_MAX = 7,
+       IPSET_CREATE_FLAG_BIT_FORCEADD = 0,
+       IPSET_CREATE_FLAG_FORCEADD = (1 << IPSET_CREATE_FLAG_BIT_FORCEADD),
+       IPSET_CREATE_FLAG_BIT_MAX = 7,
 };
 
 /* Commands with settype-specific attributes */
index f67350b65ede9f33ad5db11e5b2592bdcbc4d438..c5cef9444b7a26190fa539ae3d1ea87dd304f8fd 100644 (file)
@@ -374,6 +374,8 @@ ip_set_elem_len(struct ip_set *set, struct nlattr *tb[], size_t len)
 
        if (tb[IPSET_ATTR_CADT_FLAGS])
                cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
+       if (cadt_flags & IPSET_FLAG_WITH_FORCEADD)
+               set->flags |= IPSET_CREATE_FLAG_FORCEADD;
        for (id = 0; id < IPSET_EXT_ID_MAX; id++) {
                if (!add_extension(id, cadt_flags, tb))
                        continue;
index fa259db80dddd30819685251694b5107d53152df..49d36b9b3d265987c68c9818acbf0fa7e988b5b9 100644 (file)
@@ -633,6 +633,18 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
        bool flag_exist = flags & IPSET_FLAG_EXIST;
        u32 key, multi = 0;
 
+       if (h->elements >= h->maxelem && SET_WITH_FORCEADD(set)) {
+               rcu_read_lock_bh();
+               t = rcu_dereference_bh(h->table);
+               key = HKEY(value, h->initval, t->htable_bits);
+               n = hbucket(t,key);
+               if (n->pos) {
+                       /* Choosing the first entry in the array to replace */
+                       j = 0;
+                       goto reuse_slot;
+               }
+               rcu_read_unlock_bh();
+       }
        if (SET_WITH_TIMEOUT(set) && h->elements >= h->maxelem)
                /* FIXME: when set is full, we slow down here */
                mtype_expire(set, h, NLEN(set->family), set->dsize);
index e65fc2423d56dd2b21cee513786eec41ceabefc9..dd40607f878e28e8c5c411a24fb8e36ef7db5d46 100644 (file)
@@ -25,7 +25,8 @@
 
 #define IPSET_TYPE_REV_MIN     0
 /*                             1          Counters support */
-#define IPSET_TYPE_REV_MAX     2       /* Comments support */
+/*                             2          Comments support */
+#define IPSET_TYPE_REV_MAX     3       /* Forceadd support */
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
index 1bf8e8524218ecfdfb6563b9f3a93ba8d891a708..4eff0a29725498045703ac9fc2fc1af042c76386 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/netfilter/ipset/ip_set_hash.h>
 
 #define IPSET_TYPE_REV_MIN     0
-#define IPSET_TYPE_REV_MAX     0
+#define IPSET_TYPE_REV_MAX     1       /* Forceadd support */
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Vytas Dauksa <vytas.dauksa@smoothwall.net>");
index 525a595dd1fe4bf0efe6db7ca9cc06d995c66430..7597b82a8b033bd37c8a5f64dae02e8aa9137a19 100644 (file)
@@ -27,7 +27,8 @@
 #define IPSET_TYPE_REV_MIN     0
 /*                             1    SCTP and UDPLITE support added */
 /*                             2    Counters support added */
-#define IPSET_TYPE_REV_MAX     3 /* Comments support added */
+/*                             3    Comments support added */
+#define IPSET_TYPE_REV_MAX     4 /* Forceadd support added */
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
index f5636631466eb3ee98509e8b832e46da4ad9a417..672655ffd573404b2f2f5bf097b7a8d01f0c4c14 100644 (file)
@@ -27,7 +27,8 @@
 #define IPSET_TYPE_REV_MIN     0
 /*                             1    SCTP and UDPLITE support added */
 /*                             2    Counters support added */
-#define IPSET_TYPE_REV_MAX     3 /* Comments support added */
+/*                             3    Comments support added */
+#define IPSET_TYPE_REV_MAX     4 /* Forceadd support added */
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
index 5d87fe8a41ffa4888a70b6d91897360e30c253bc..7308d84f9277813f16351b692f75218ff1a451b3 100644 (file)
@@ -29,7 +29,8 @@
 /*                             2    Range as input support for IPv4 added */
 /*                             3    nomatch flag support added */
 /*                             4    Counters support added */
-#define IPSET_TYPE_REV_MAX     5 /* Comments support added */
+/*                             5    Comments support added */
+#define IPSET_TYPE_REV_MAX     6 /* Forceadd support added */
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
index 8295cf4f9fdcfdb3d3da4b72792add9fc83156ad..4c7d495783a3aefa9447d4b37114bd3715928b0a 100644 (file)
@@ -26,7 +26,8 @@
 /*                             1    Range as input support for IPv4 added */
 /*                             2    nomatch flag support added */
 /*                             3    Counters support added */
-#define IPSET_TYPE_REV_MAX     4 /* Comments support added */
+/*                             4    Comments support added */
+#define IPSET_TYPE_REV_MAX     5 /* Forceadd support added */
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
index 788825b219aeabc203f0fdc3a1cea7d3e2d2f40d..748c820141455e345de79f14b5582c25e295b29b 100644 (file)
@@ -27,7 +27,8 @@
 /*                             1    nomatch flag support added */
 /*                             2    /0 support added */
 /*                             3    Counters support added */
-#define IPSET_TYPE_REV_MAX     4 /* Comments support added */
+/*                             4    Comments support added */
+#define IPSET_TYPE_REV_MAX     5 /* Forceadd support added */
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
index 4e7261df8961b5fa94b507a4cd6c9b365c7c19b2..3e99987e4bf248f6d6085118dba52a4c24ee108a 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/netfilter/ipset/ip_set_hash.h>
 
 #define IPSET_TYPE_REV_MIN     0
-#define IPSET_TYPE_REV_MAX     0
+#define IPSET_TYPE_REV_MAX     1       /* Forceadd support added */
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa>");
index 7097fb0141bf6e1363ca0b0342451e66c34773b4..1c645fbd09c7d6bcb337b90977ae2536b2ec9ebd 100644 (file)
@@ -28,7 +28,8 @@
 /*                             2    Range as input support for IPv4 added */
 /*                             3    nomatch flag support added */
 /*                             4    Counters support added */
-#define IPSET_TYPE_REV_MAX     5 /* Comments support added */
+/*                             5    Comments support added */
+#define IPSET_TYPE_REV_MAX     6 /* Forceadd support added */
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
index 703d1192a6a225214f1ffd28c6ab926110942c32..c0d2ba73f8b2394995bba3737a833cc47138d581 100644 (file)
@@ -25,7 +25,8 @@
 #include <linux/netfilter/ipset/ip_set_hash.h>
 
 #define IPSET_TYPE_REV_MIN     0
-#define IPSET_TYPE_REV_MAX     0 /* Comments support added */
+/*                             0    Comments support added */
+#define IPSET_TYPE_REV_MAX     1 /* Forceadd support added */
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa>");