summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/net/netfilter/ipset/ip_set_hash_gen.h40
-rw-r--r--tests/hash:mac.t18
-rw-r--r--tests/hash:mac.t.list38
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