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>
This commit is contained in:
committed by
Jozsef Kadlecsik
parent
6843bc3c56
commit
07cf8f5ae2
@@ -65,6 +65,7 @@ enum ip_set_extension {
|
|||||||
#define SET_WITH_TIMEOUT(s) ((s)->extensions & IPSET_EXT_TIMEOUT)
|
#define SET_WITH_TIMEOUT(s) ((s)->extensions & IPSET_EXT_TIMEOUT)
|
||||||
#define SET_WITH_COUNTER(s) ((s)->extensions & IPSET_EXT_COUNTER)
|
#define SET_WITH_COUNTER(s) ((s)->extensions & IPSET_EXT_COUNTER)
|
||||||
#define SET_WITH_COMMENT(s) ((s)->extensions & IPSET_EXT_COMMENT)
|
#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 */
|
/* Extension id, in size order */
|
||||||
enum ip_set_ext_id {
|
enum ip_set_ext_id {
|
||||||
@@ -255,6 +256,8 @@ ip_set_put_flags(struct sk_buff *skb, struct ip_set *set)
|
|||||||
cadt_flags |= IPSET_FLAG_WITH_COUNTERS;
|
cadt_flags |= IPSET_FLAG_WITH_COUNTERS;
|
||||||
if (SET_WITH_COMMENT(set))
|
if (SET_WITH_COMMENT(set))
|
||||||
cadt_flags |= IPSET_FLAG_WITH_COMMENT;
|
cadt_flags |= IPSET_FLAG_WITH_COMMENT;
|
||||||
|
if (SET_WITH_FORCEADD(set))
|
||||||
|
cadt_flags |= IPSET_FLAG_WITH_FORCEADD;
|
||||||
|
|
||||||
if (!cadt_flags)
|
if (!cadt_flags)
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -185,13 +185,16 @@ enum ipset_cadt_flags {
|
|||||||
IPSET_FLAG_WITH_COUNTERS = (1 << IPSET_FLAG_BIT_WITH_COUNTERS),
|
IPSET_FLAG_WITH_COUNTERS = (1 << IPSET_FLAG_BIT_WITH_COUNTERS),
|
||||||
IPSET_FLAG_BIT_WITH_COMMENT = 4,
|
IPSET_FLAG_BIT_WITH_COMMENT = 4,
|
||||||
IPSET_FLAG_WITH_COMMENT = (1 << IPSET_FLAG_BIT_WITH_COMMENT),
|
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,
|
IPSET_FLAG_CADT_MAX = 15,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The flag bits which correspond to the non-extension create flags */
|
/* The flag bits which correspond to the non-extension create flags */
|
||||||
enum ipset_create_flags {
|
enum ipset_create_flags {
|
||||||
IPSET_CREATE_FLAG_NONE = 0,
|
IPSET_CREATE_FLAG_BIT_FORCEADD = 0,
|
||||||
IPSET_CREATE_FLAG_MAX = 7,
|
IPSET_CREATE_FLAG_FORCEADD = (1 << IPSET_CREATE_FLAG_BIT_FORCEADD),
|
||||||
|
IPSET_CREATE_FLAG_BIT_MAX = 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Commands with settype-specific attributes */
|
/* Commands with settype-specific attributes */
|
||||||
|
@@ -368,6 +368,8 @@ ip_set_elem_len(struct ip_set *set, struct nlattr *tb[], size_t len)
|
|||||||
|
|
||||||
if (tb[IPSET_ATTR_CADT_FLAGS])
|
if (tb[IPSET_ATTR_CADT_FLAGS])
|
||||||
cadt_flags = ip_set_get_h32(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++) {
|
for (id = 0; id < IPSET_EXT_ID_MAX; id++) {
|
||||||
if (!add_extension(id, cadt_flags, tb))
|
if (!add_extension(id, cadt_flags, tb))
|
||||||
continue;
|
continue;
|
||||||
|
@@ -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;
|
bool flag_exist = flags & IPSET_FLAG_EXIST;
|
||||||
u32 key, multi = 0;
|
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)
|
if (SET_WITH_TIMEOUT(set) && h->elements >= h->maxelem)
|
||||||
/* FIXME: when set is full, we slow down here */
|
/* FIXME: when set is full, we slow down here */
|
||||||
mtype_expire(set, h, NLEN(set->family), set->dsize);
|
mtype_expire(set, h, NLEN(set->family), set->dsize);
|
||||||
|
@@ -25,7 +25,8 @@
|
|||||||
|
|
||||||
#define IPSET_TYPE_REV_MIN 0
|
#define IPSET_TYPE_REV_MIN 0
|
||||||
/* 1 Counters support */
|
/* 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_LICENSE("GPL");
|
||||||
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
|
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
#include <linux/netfilter/ipset/ip_set_hash.h>
|
#include <linux/netfilter/ipset/ip_set_hash.h>
|
||||||
|
|
||||||
#define IPSET_TYPE_REV_MIN 0
|
#define IPSET_TYPE_REV_MIN 0
|
||||||
#define IPSET_TYPE_REV_MAX 0
|
#define IPSET_TYPE_REV_MAX 1 /* Forceadd support */
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_AUTHOR("Vytas Dauksa <vytas.dauksa@smoothwall.net>");
|
MODULE_AUTHOR("Vytas Dauksa <vytas.dauksa@smoothwall.net>");
|
||||||
|
@@ -27,7 +27,8 @@
|
|||||||
#define IPSET_TYPE_REV_MIN 0
|
#define IPSET_TYPE_REV_MIN 0
|
||||||
/* 1 SCTP and UDPLITE support added */
|
/* 1 SCTP and UDPLITE support added */
|
||||||
/* 2 Counters 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_LICENSE("GPL");
|
||||||
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
|
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
|
||||||
|
@@ -27,7 +27,8 @@
|
|||||||
#define IPSET_TYPE_REV_MIN 0
|
#define IPSET_TYPE_REV_MIN 0
|
||||||
/* 1 SCTP and UDPLITE support added */
|
/* 1 SCTP and UDPLITE support added */
|
||||||
/* 2 Counters 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_LICENSE("GPL");
|
||||||
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
|
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
|
||||||
|
@@ -29,7 +29,8 @@
|
|||||||
/* 2 Range as input support for IPv4 added */
|
/* 2 Range as input support for IPv4 added */
|
||||||
/* 3 nomatch flag support added */
|
/* 3 nomatch flag support added */
|
||||||
/* 4 Counters 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_LICENSE("GPL");
|
||||||
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
|
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
|
||||||
|
@@ -26,7 +26,8 @@
|
|||||||
/* 1 Range as input support for IPv4 added */
|
/* 1 Range as input support for IPv4 added */
|
||||||
/* 2 nomatch flag support added */
|
/* 2 nomatch flag support added */
|
||||||
/* 3 Counters 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_LICENSE("GPL");
|
||||||
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
|
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
|
||||||
|
@@ -27,7 +27,8 @@
|
|||||||
/* 1 nomatch flag support added */
|
/* 1 nomatch flag support added */
|
||||||
/* 2 /0 support added */
|
/* 2 /0 support added */
|
||||||
/* 3 Counters 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_LICENSE("GPL");
|
||||||
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
|
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
|
||||||
|
@@ -24,7 +24,7 @@
|
|||||||
#include <linux/netfilter/ipset/ip_set_hash.h>
|
#include <linux/netfilter/ipset/ip_set_hash.h>
|
||||||
|
|
||||||
#define IPSET_TYPE_REV_MIN 0
|
#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_LICENSE("GPL");
|
||||||
MODULE_AUTHOR("Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa>");
|
MODULE_AUTHOR("Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa>");
|
||||||
|
@@ -28,7 +28,8 @@
|
|||||||
/* 2 Range as input support for IPv4 added */
|
/* 2 Range as input support for IPv4 added */
|
||||||
/* 3 nomatch flag support added */
|
/* 3 nomatch flag support added */
|
||||||
/* 4 Counters 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_LICENSE("GPL");
|
||||||
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
|
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
|
||||||
|
@@ -25,7 +25,8 @@
|
|||||||
#include <linux/netfilter/ipset/ip_set_hash.h>
|
#include <linux/netfilter/ipset/ip_set_hash.h>
|
||||||
|
|
||||||
#define IPSET_TYPE_REV_MIN 0
|
#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_LICENSE("GPL");
|
||||||
MODULE_AUTHOR("Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa>");
|
MODULE_AUTHOR("Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa>");
|
||||||
|
Reference in New Issue
Block a user