diff options
-rw-r--r-- | kernel/net/netfilter/ipset/ip_set_hash_gen.h | 40 | ||||
-rw-r--r-- | tests/hash:mac.t | 18 | ||||
-rw-r--r-- | tests/hash:mac.t.list3 | 8 |
3 files changed, 43 insertions, 23 deletions
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_gen.h b/kernel/net/netfilter/ipset/ip_set_hash_gen.h index 1ab3339..a3c9fb4 100644 --- a/kernel/net/netfilter/ipset/ip_set_hash_gen.h +++ b/kernel/net/netfilter/ipset/ip_set_hash_gen.h @@ -633,29 +633,6 @@ 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); - - if (h->elements >= h->maxelem) { - if (net_ratelimit()) - pr_warn("Set %s is full, maxelem %u reached\n", - set->name, h->maxelem); - return -IPSET_ERR_HASH_FULL; - } - rcu_read_lock_bh(); t = rcu_dereference_bh(h->table); key = HKEY(value, h->initval, t->htable_bits); @@ -680,6 +657,23 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext, j != AHASH_MAX(h) + 1) j = i; } + if (h->elements >= h->maxelem && SET_WITH_FORCEADD(set) && n->pos) { + /* Choosing the first entry in the array to replace */ + j = 0; + goto reuse_slot; + } + 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); + + if (h->elements >= h->maxelem) { + if (net_ratelimit()) + pr_warn("Set %s is full, maxelem %u reached\n", + set->name, h->maxelem); + ret = -IPSET_ERR_HASH_FULL; + goto out; + } + reuse_slot: if (j != AHASH_MAX(h) + 1) { /* Fill out reused slot */ diff --git a/tests/hash:mac.t b/tests/hash:mac.t index 25739da..f7023d0 100644 --- a/tests/hash:mac.t +++ b/tests/hash:mac.t @@ -50,4 +50,22 @@ 0 diff -u -I 'Size in memory.*' .foo hash:mac.t.list1 # MAC: Destroy test set 0 ipset -X test +# MAC: Create a set with small maxelem parameter +0 ipset n test hash:mac maxelem 2 skbinfo +# MAC: Add first element +0 ipset a test 1:2:3:4:5:6 skbprio 1:10 +# MAC: Add second element +0 ipset a test 1:2:3:4:5:7 skbprio 1:11 +# MAC: Add third element +1 ipset a test 1:2:3:4:5:8 skbprio 1:12 +# MAC: Add second element again +1 ipset a test 1:2:3:4:5:7 skbprio 1:11 +# MAC: Add second element with another extension value +0 ipset -! a test 1:2:3:4:5:7 skbprio 1:12 skbqueue 8 +# MAC: List set +0 ipset -L test 2>/dev/null | grep -v Revision: > .foo0 && ./sort.sh .foo0 +# MAC: Check listing +0 diff -u -I 'Size in memory.*' .foo hash:mac.t.list3 +# MAC: Destroy test set +0 ipset x test # eof diff --git a/tests/hash:mac.t.list3 b/tests/hash:mac.t.list3 new file mode 100644 index 0000000..2253a34 --- /dev/null +++ b/tests/hash:mac.t.list3 @@ -0,0 +1,8 @@ +Name: test +Type: hash:mac +Header: hashsize 1024 maxelem 2 skbinfo +Size in memory: 16792 +References: 0 +Members: +01:02:03:04:05:06 skbprio 1:10 +01:02:03:04:05:07 skbprio 1:12 skbqueue 8 |