From 42d44fcb9c938bac9e144ec862ee00459820f271 Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Mon, 18 Apr 2011 13:19:59 +0200 Subject: [PATCH] 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. --- kernel/net/netfilter/ipset/ip_set_core.c | 18 ++++++------ tests/setlist.t | 4 +++ tests/setlist.t.before | 1 + tests/setlist.t.list4 | 36 ++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 tests/setlist.t.list4 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 + -- 2.40.0