summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2011-04-18 13:19:59 +0200
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2011-04-18 13:25:13 +0200
commit42d44fcb9c938bac9e144ec862ee00459820f271 (patch)
tree22567ffb331186ae9d946d1806c9aa3c82d10ea4
parent0b6f88e662d54cabf15ef3dbf70e9f0fcdb1412e (diff)
Fix order of listing of sets
A restoreable saving of sets requires that list:set type of sets come last and the code part which should have taken into account the ordering was broken. The patch fixes the listing order. Testsuite entry added which checks the listing order.
-rw-r--r--kernel/net/netfilter/ipset/ip_set_core.c18
-rw-r--r--tests/setlist.t4
-rw-r--r--tests/setlist.t.before1
-rw-r--r--tests/setlist.t.list436
4 files changed, 51 insertions, 8 deletions
diff --git a/kernel/net/netfilter/ipset/ip_set_core.c b/kernel/net/netfilter/ipset/ip_set_core.c
index 72aebae..126d555 100644
--- a/kernel/net/netfilter/ipset/ip_set_core.c
+++ b/kernel/net/netfilter/ipset/ip_set_core.c
@@ -1027,8 +1027,9 @@ ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb)
if (cb->args[1] >= ip_set_max)
goto out;
- pr_debug("args[0]: %ld args[1]: %ld\n", cb->args[0], cb->args[1]);
max = cb->args[0] == DUMP_ONE ? cb->args[1] + 1 : ip_set_max;
+dump_last:
+ pr_debug("args[0]: %ld args[1]: %ld\n", cb->args[0], cb->args[1]);
for (; cb->args[1] < max; cb->args[1]++) {
index = (ip_set_id_t) cb->args[1];
set = ip_set_list[index];
@@ -1043,8 +1044,8 @@ ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb)
* so that lists (unions of sets) are dumped last.
*/
if (cb->args[0] != DUMP_ONE &&
- !((cb->args[0] == DUMP_ALL) ^
- (set->type->features & IPSET_DUMP_LAST)))
+ ((cb->args[0] == DUMP_ALL) ==
+ !!(set->type->features & IPSET_DUMP_LAST)))
continue;
pr_debug("List set: %s\n", set->name);
if (!cb->args[2]) {
@@ -1088,6 +1089,12 @@ ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb)
goto release_refcount;
}
}
+ /* If we dump all sets, continue with dumping last ones */
+ if (cb->args[0] == DUMP_ALL) {
+ cb->args[0] = DUMP_LAST;
+ cb->args[1] = 0;
+ goto dump_last;
+ }
goto out;
nla_put_failure:
@@ -1098,11 +1105,6 @@ release_refcount:
pr_debug("release set %s\n", ip_set_list[index]->name);
ip_set_put_byindex(index);
}
-
- /* If we dump all sets, continue with dumping last ones */
- if (cb->args[0] == DUMP_ALL && cb->args[1] >= max && !cb->args[2])
- cb->args[0] = DUMP_LAST;
-
out:
if (nlh) {
nlmsg_end(skb, nlh);
diff --git a/tests/setlist.t b/tests/setlist.t
index 0430741..90c78f2 100644
--- a/tests/setlist.t
+++ b/tests/setlist.t
@@ -80,6 +80,10 @@
0 ipset list test > .foo
# Check listing
0 diff -u -I 'Size in memory.*' .foo setlist.t.list3
+# List all sets
+0 ipset list > .foo
+# Check listing
+0 diff -u -I 'Size in memory.*' .foo setlist.t.list4
# Flush sets
0 ipset flush
# Destroy sets
diff --git a/tests/setlist.t.before b/tests/setlist.t.before
index 59ee644..64ed849 100644
--- a/tests/setlist.t.before
+++ b/tests/setlist.t.before
@@ -2,3 +2,4 @@ create a hash:ip
create b hash:ip
create c hash:ip
create test list:set
+create d hash:ip
diff --git a/tests/setlist.t.list4 b/tests/setlist.t.list4
new file mode 100644
index 0000000..f867508
--- /dev/null
+++ b/tests/setlist.t.list4
@@ -0,0 +1,36 @@
+Name: a
+Type: hash:ip
+Header: family inet hashsize 1024 maxelem 65536
+Size in memory: 16504
+References: 1
+Members:
+
+Name: b
+Type: hash:ip
+Header: family inet hashsize 1024 maxelem 65536
+Size in memory: 16504
+References: 0
+Members:
+
+Name: c
+Type: hash:ip
+Header: family inet hashsize 1024 maxelem 65536
+Size in memory: 16504
+References: 0
+Members:
+
+Name: d
+Type: hash:ip
+Header: family inet hashsize 1024 maxelem 65536
+Size in memory: 16504
+References: 0
+Members:
+
+Name: test
+Type: list:set
+Header: size 8
+Size in memory: 112
+References: 0
+Members:
+a
+