]> granicus.if.org Git - ipset/commitdiff
Fix order of listing of sets
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Mon, 18 Apr 2011 11:19:59 +0000 (13:19 +0200)
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Mon, 18 Apr 2011 11:25:13 +0000 (13:25 +0200)
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.

kernel/net/netfilter/ipset/ip_set_core.c
tests/setlist.t
tests/setlist.t.before
tests/setlist.t.list4 [new file with mode: 0644]

index 72aebae40887cf8308e7ff652026e9de4f9fcf44..126d5550bd0471e4d0f8098546790e1d7c8b4905 100644 (file)
@@ -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);
index 043074136bd8b37ef14cc2b4668aa12744c08c7c..90c78f2603a5f568b9e7842366e4744adb03a5eb 100644 (file)
 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
index 59ee6444012ec098c619b16a6721b937a66927ee..64ed8493c8611bc5c118049823166133287364da 100644 (file)
@@ -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 (file)
index 0000000..f867508
--- /dev/null
@@ -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
+