From d19f4ca4451f02add0e8edfcb69882d5b3e0cc9e Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Tue, 18 Aug 2009 19:52:26 +0200 Subject: ipset 3.1 release A few minor bugs fixed and cleanups: - Nonexistent sets were reported as existing sets when testing from userspace in setlist type of sets (bug reported by Victor A. Safronov) - When saving sets, setlist type of sets must come last in order to satisfy the dependency from the elements (bug reported by Marty B.) - Sparse insists that the flags argument to kmalloc() is gfp_t (Stephen Hemminger) - Correct format specifiers and change %i to %d (Jan Engelhardt) - Fix the definition of 'bool' for kernels <= 2.6.18 (Jan Engelhardt) --- ChangeLog | 3 ++ Makefile | 2 +- ipset.8 | 3 ++ ipset.c | 4 +-- ipset_ipmap.c | 4 +-- kernel/ChangeLog | 11 +++++++ .../include/linux/netfilter_ipv4/ip_set_bitmaps.h | 2 +- .../include/linux/netfilter_ipv4/ip_set_hashes.h | 8 ++--- .../include/linux/netfilter_ipv4/ip_set_malloc.h | 4 +-- kernel/ip_set.c | 38 ++++++++++++++-------- kernel/ip_set_iptree.c | 4 +-- kernel/ip_set_iptreemap.c | 4 +-- kernel/ip_set_setlist.c | 13 ++++---- libipt_set.h | 2 +- tests/setlist.t | 12 +++++++ 15 files changed, 76 insertions(+), 38 deletions(-) diff --git a/ChangeLog b/ChangeLog index 228925a..ec4899f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +3.1 + - Correct format specifiers and change %i to %d (Jan Engelhardt) + 3.0 - New kernel-userspace protocol release - Bigendian and 64/32bit fixes (Stefan Gula, bugzilla id 593) diff --git a/Makefile b/Makefile index c3d8385..eae8b20 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ ifndef V V=0 endif -IPSET_VERSION:=3.0 +IPSET_VERSION:=3.1 PREFIX:=/usr/local LIBDIR:=$(PREFIX)/lib diff --git a/ipset.8 b/ipset.8 index 522608e..6ef1179 100644 --- a/ipset.8 +++ b/ipset.8 @@ -50,6 +50,9 @@ IP set bindings pointing to sets and iptables matches and targets referring to sets creates references, which protects the given sets in the kernel. A set cannot be removed (destroyed) while there is a single reference pointing to it. +.P +.B +Please note, binding sets is a deprecated feature and will be removed in a later release. Switch to the multidata type of sets from using bindings. .SH OPTIONS The options that are recognized by .B ipset diff --git a/ipset.c b/ipset.c index de6a4ec..5ff32cf 100644 --- a/ipset.c +++ b/ipset.c @@ -1577,7 +1577,7 @@ static int set_adtip(struct set *set, const char *adt, /* Alloc memory for the data to send */ size = sizeof(struct ip_set_req_adt) + set->settype->adt_size ; - DP("alloc size %i", size); + DP("alloc size %d", size); data = ipset_malloc(size); /* Fill out the request */ @@ -1663,7 +1663,7 @@ static int set_bind(struct set *set, const char *adt, size += IP_SET_MAXNAMELEN; else if (!(op == IP_SET_OP_UNBIND_SET && set == NULL)) size += set->settype->adt_size; - DP("alloc size %i", size); + DP("alloc size %d", size); data = ipset_malloc(size); /* Fill out the request */ diff --git a/ipset_ipmap.c b/ipset_ipmap.c index 287b057..992a862 100644 --- a/ipset_ipmap.c +++ b/ipset_ipmap.c @@ -225,12 +225,12 @@ initheader(struct set *set, const void *data) mask = range_to_mask(header->from, header->to, &mask_bits); netmask_bits = mask_to_bits(header->netmask); - DP("bits: %i %i", mask_bits, netmask_bits); + DP("bits: %d %d", mask_bits, netmask_bits); map->hosts = 2 << (32 - netmask_bits - 1); map->sizeid = 2 << (netmask_bits - mask_bits - 1); } - DP("%i %i", map->hosts, map->sizeid ); + DP("%d %d", map->hosts, map->sizeid ); } static void diff --git a/kernel/ChangeLog b/kernel/ChangeLog index f8414e1..fd440ef 100644 --- a/kernel/ChangeLog +++ b/kernel/ChangeLog @@ -1,3 +1,14 @@ +3.1 + - Nonexistent sets were reported as existing sets when testing + from userspace in setlist type of sets (bug reported by Victor A. + Safronov) + - When saving sets, setlist type of sets must come last in order + to satisfy the dependency from the elements (bug reported by Marty B.) + - Sparse insists that the flags argument to kmalloc() is gfp_t + (Stephen Hemminger) + - Correct format specifiers and change %i to %d (Jan Engelhardt) + - Fix the definition of 'bool' for kernels <= 2.6.18 (Jan Engelhardt) + 3.0 - New kernel-userspace protocol release - Bigendian and 64/32bit fixes (Stefan Gula, bugzilla id 593) diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_bitmaps.h b/kernel/include/linux/netfilter_ipv4/ip_set_bitmaps.h index d537639..90e87e3 100644 --- a/kernel/include/linux/netfilter_ipv4/ip_set_bitmaps.h +++ b/kernel/include/linux/netfilter_ipv4/ip_set_bitmaps.h @@ -19,7 +19,7 @@ type##_create(struct ip_set *set, const void *data, u_int32_t size) \ \ map = kmalloc(sizeof(struct ip_set_##type), GFP_KERNEL); \ if (!map) { \ - DP("out of memory for %lu bytes", \ + DP("out of memory for %zu bytes", \ sizeof(struct ip_set_##type)); \ return -ENOMEM; \ } \ diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_hashes.h b/kernel/include/linux/netfilter_ipv4/ip_set_hashes.h index 4ca8431..f7d6a69 100644 --- a/kernel/include/linux/netfilter_ipv4/ip_set_hashes.h +++ b/kernel/include/linux/netfilter_ipv4/ip_set_hashes.h @@ -36,14 +36,14 @@ type##_retry(struct ip_set *set) \ tmp = kmalloc(sizeof(struct ip_set_##type) \ + map->probes * sizeof(initval_t), GFP_ATOMIC); \ if (!tmp) { \ - DP("out of memory for %lu bytes", \ + DP("out of memory for %zu bytes", \ sizeof(struct ip_set_##type) \ + map->probes * sizeof(initval_t)); \ return -ENOMEM; \ } \ tmp->members = harray_malloc(hashsize, sizeof(dtype), GFP_ATOMIC);\ if (!tmp->members) { \ - DP("out of memory for %lu bytes", hashsize * sizeof(dtype));\ + DP("out of memory for %zu bytes", hashsize * sizeof(dtype));\ kfree(tmp); \ return -ENOMEM; \ } \ @@ -109,7 +109,7 @@ type##_create(struct ip_set *set, const void *data, u_int32_t size) \ map = kmalloc(sizeof(struct ip_set_##type) \ + req->probes * sizeof(initval_t), GFP_KERNEL); \ if (!map) { \ - DP("out of memory for %lu bytes", \ + DP("out of memory for %zu bytes", \ sizeof(struct ip_set_##type) \ + req->probes * sizeof(initval_t)); \ return -ENOMEM; \ @@ -126,7 +126,7 @@ type##_create(struct ip_set *set, const void *data, u_int32_t size) \ } \ map->members = harray_malloc(map->hashsize, sizeof(dtype), GFP_KERNEL);\ if (!map->members) { \ - DP("out of memory for %lu bytes", map->hashsize * sizeof(dtype));\ + DP("out of memory for %zu bytes", map->hashsize * sizeof(dtype));\ kfree(map); \ return -ENOMEM; \ } \ diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_malloc.h b/kernel/include/linux/netfilter_ipv4/ip_set_malloc.h index 8bce667..2a80443 100644 --- a/kernel/include/linux/netfilter_ipv4/ip_set_malloc.h +++ b/kernel/include/linux/netfilter_ipv4/ip_set_malloc.h @@ -40,7 +40,7 @@ struct harray { }; static inline void * -__harray_malloc(size_t hashsize, size_t typesize, int flags) +__harray_malloc(size_t hashsize, size_t typesize, gfp_t flags) { struct harray *harray; size_t max_elements, size, i, j; @@ -88,7 +88,7 @@ __harray_malloc(size_t hashsize, size_t typesize, int flags) } static inline void * -harray_malloc(size_t hashsize, size_t typesize, int flags) +harray_malloc(size_t hashsize, size_t typesize, gfp_t flags) { void *harray; diff --git a/kernel/ip_set.c b/kernel/ip_set.c index f94d0e0..c836d85 100644 --- a/kernel/ip_set.c +++ b/kernel/ip_set.c @@ -536,7 +536,7 @@ ip_set_addip(ip_set_id_t index, IP_SET_ASSERT(set); if (size - sizeof(struct ip_set_req_adt) != set->type->reqsize) { - ip_set_printk("data length wrong (want %lu, have %lu)", + ip_set_printk("data length wrong (want %lu, have %zu)", (long unsigned)set->type->reqsize, size - sizeof(struct ip_set_req_adt)); return -EINVAL; @@ -558,7 +558,7 @@ ip_set_delip(ip_set_id_t index, IP_SET_ASSERT(set); if (size - sizeof(struct ip_set_req_adt) != set->type->reqsize) { - ip_set_printk("data length wrong (want %lu, have %lu)", + ip_set_printk("data length wrong (want %lu, have %zu)", (long unsigned)set->type->reqsize, size - sizeof(struct ip_set_req_adt)); return -EINVAL; @@ -585,7 +585,7 @@ ip_set_testip(ip_set_id_t index, IP_SET_ASSERT(set); if (size - sizeof(struct ip_set_req_adt) != set->type->reqsize) { - ip_set_printk("data length wrong (want %lu, have %lu)", + ip_set_printk("data length wrong (want %lu, have %zu)", (long unsigned)set->type->reqsize, size - sizeof(struct ip_set_req_adt)); return -EINVAL; @@ -1220,7 +1220,7 @@ static int ip_set_save_set(ip_set_id_t index, *used += sizeof(struct ip_set_save); set = ip_set_list[index]; - DP("set: %s, used: %i(%i) %p %p", set->name, *used, len, + DP("set: %s, used: %d(%d) %p %p", set->name, *used, len, data, data + *used); read_lock_bh(&set->lock); @@ -1237,7 +1237,7 @@ static int ip_set_save_set(ip_set_id_t index, set->type->list_header(set, data + *used); *used += set_save->header_size; - DP("set header filled: %s, used: %i(%lu) %p %p", set->name, *used, + DP("set header filled: %s, used: %d(%lu) %p %p", set->name, *used, (unsigned long)set_save->header_size, data, data + *used); /* Get and ensure set specific members size */ set_save->members_size = set->type->list_members_size(set); @@ -1248,7 +1248,7 @@ static int ip_set_save_set(ip_set_id_t index, set->type->list_members(set, data + *used); *used += set_save->members_size; read_unlock_bh(&set->lock); - DP("set members filled: %s, used: %i(%lu) %p %p", set->name, *used, + DP("set members filled: %s, used: %d(%lu) %p %p", set->name, *used, (unsigned long)set_save->members_size, data, data + *used); return 0; @@ -1329,7 +1329,7 @@ static int ip_set_restore(void *data, while (1) { line++; - DP("%i %lu %i", used, sizeof(struct ip_set_restore), len); + DP("%d %zu %d", used, sizeof(struct ip_set_restore), len); /* Get and ensure header size */ if (used + sizeof(struct ip_set_restore) > len) return line; @@ -1373,7 +1373,7 @@ static int ip_set_restore(void *data, while (members_size + set->type->reqsize <= set_restore->members_size) { line++; - DP("members: %i, line %i", members_size, line); + DP("members: %d, line %d", members_size, line); res = __ip_set_addip(index, data + used + members_size, set->type->reqsize); @@ -1382,7 +1382,7 @@ static int ip_set_restore(void *data, members_size += set->type->reqsize; } - DP("members_size %lu %i", + DP("members_size %lu %d", (unsigned long)set_restore->members_size, members_size); if (members_size != set_restore->members_size) return line++; @@ -1911,13 +1911,23 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len) res = -ENOENT; goto done; } + +#define SETLIST(set) (strcmp(set->type->typename, "setlist") == 0) + used = 0; if (index == IP_SET_INVALID_ID) { - /* Save all sets */ + /* Save all sets: ugly setlist type dependency */ + int setlist = 0; + setlists: for (i = 0; i < ip_set_max && res == 0; i++) { - if (ip_set_list[i] != NULL) + if (ip_set_list[i] != NULL + && !(setlist ^ SETLIST(ip_set_list[i]))) res = ip_set_save_set(i, data, &used, *len); } + if (!setlist) { + setlist = 1; + goto setlists; + } } else { /* Save an individual set */ res = ip_set_save_set(index, data, &used, *len); @@ -1939,14 +1949,14 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len) if (*len < sizeof(struct ip_set_req_setnames) || *len != req_restore->size) { - ip_set_printk("invalid RESTORE (want =%lu, got %u)", + ip_set_printk("invalid RESTORE (want =%lu, got %d)", (long unsigned)req_restore->size, *len); res = -EINVAL; goto done; } line = ip_set_restore(data + sizeof(struct ip_set_req_setnames), req_restore->size - sizeof(struct ip_set_req_setnames)); - DP("ip_set_restore: %u", line); + DP("ip_set_restore: %d", line); if (line != 0) { res = -EAGAIN; req_restore->size = line; @@ -1961,7 +1971,7 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len) } /* end of switch(op) */ copy: - DP("set %s, copylen %u", index != IP_SET_INVALID_ID + DP("set %s, copylen %d", index != IP_SET_INVALID_ID && ip_set_list[index] ? ip_set_list[index]->name : ":all:", copylen); diff --git a/kernel/ip_set_iptree.c b/kernel/ip_set_iptree.c index 08b9118..f7d64b7 100644 --- a/kernel/ip_set_iptree.c +++ b/kernel/ip_set_iptree.c @@ -282,7 +282,7 @@ iptree_create(struct ip_set *set, const void *data, u_int32_t size) struct ip_set_iptree *map; if (size != sizeof(struct ip_set_req_iptree_create)) { - ip_set_printk("data length wrong (want %lu, have %lu)", + ip_set_printk("data length wrong (want %lu, have %zu)", sizeof(struct ip_set_req_iptree_create), (unsigned long)size); return -EINVAL; @@ -290,7 +290,7 @@ iptree_create(struct ip_set *set, const void *data, u_int32_t size) map = kmalloc(sizeof(struct ip_set_iptree), GFP_KERNEL); if (!map) { - DP("out of memory for %lu bytes", + DP("out of memory for %zu bytes", sizeof(struct ip_set_iptree)); return -ENOMEM; } diff --git a/kernel/ip_set_iptreemap.c b/kernel/ip_set_iptreemap.c index f62ed19..7c8c517 100644 --- a/kernel/ip_set_iptreemap.c +++ b/kernel/ip_set_iptreemap.c @@ -338,7 +338,7 @@ KADT(iptreemap, add, ipaddr, ip) static inline int __delip_single(struct ip_set *set, ip_set_ip_t *hash_ip, - ip_set_ip_t ip, unsigned int __nocast flags) + ip_set_ip_t ip, gfp_t flags) { struct ip_set_iptreemap *map = set->data; struct ip_set_iptreemap_b *btree; @@ -364,7 +364,7 @@ __delip_single(struct ip_set *set, ip_set_ip_t *hash_ip, static inline int iptreemap_del(struct ip_set *set, ip_set_ip_t *hash_ip, - ip_set_ip_t start, ip_set_ip_t end, unsigned int __nocast flags) + ip_set_ip_t start, ip_set_ip_t end, gfp_t flags) { struct ip_set_iptreemap *map = set->data; struct ip_set_iptreemap_b *btree; diff --git a/kernel/ip_set_setlist.c b/kernel/ip_set_setlist.c index 15a67ba..612f81f 100644 --- a/kernel/ip_set_setlist.c +++ b/kernel/ip_set_setlist.c @@ -16,8 +16,9 @@ #include #include -#ifndef bool -#define bool int +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) +typedef _Bool bool; +enum { false = 0, true = 1, }; #endif /* @@ -42,17 +43,15 @@ setlist_utest(struct ip_set *set, const void *data, u_int32_t size, struct ip_set *s; if (req->before && req->ref[0] == '\0') - return -EINVAL; + return 0; index = __ip_set_get_byname(req->name, &s); if (index == IP_SET_INVALID_ID) - return -EEXIST; + return 0; if (req->ref[0] != '\0') { ref = __ip_set_get_byname(req->ref, &s); - if (ref == IP_SET_INVALID_ID) { - res = -EEXIST; + if (ref == IP_SET_INVALID_ID) goto finish; - } } for (i = 0; i < map->size && map->index[i] != IP_SET_INVALID_ID; i++) { diff --git a/libipt_set.h b/libipt_set.h index 0521251..771a0fe 100644 --- a/libipt_set.h +++ b/libipt_set.h @@ -36,7 +36,7 @@ parse_bindings(const char *optarg, struct ipt_set_info *info) if (tmp) exit_error(PARAMETER_PROBLEM, - "Can't follow bindings deeper than %i.", + "Can't follow bindings deeper than %d.", IP_SET_MAX_BINDINGS); free(saved); diff --git a/tests/setlist.t b/tests/setlist.t index 183a7ab..d677863 100644 --- a/tests/setlist.t +++ b/tests/setlist.t @@ -8,6 +8,8 @@ 0 ipset -A test foo # Setlist: Test foo set in setlist 0 ipset -T test foo +# Setlist: Test nonexistent set in setlist +1 ipset -T test nonexistent # Setlist: Try to delete foo set 1 ipset -X foo # Setlist: Add bar set to setlist, after foo @@ -20,6 +22,8 @@ 1 ipset -T test bar,before,foo # Setlist: Test foo,after,bar 1 ipset -T test foo,after,bar +# Setlist: Save sets +0 ipset -S > setlist.t.restore # Setlist: Delete bar,before,foo 1 ipset -D test bar,before,foo # Setlist: Delete foo,after,bar @@ -30,4 +34,12 @@ 0 ipset -F test # Setlist: Delete test set 0 ipset -X test +# Setlist: Delete all sets +0 ipset -X +# Setlist: Restore saved sets +0 ipset -R < setlist.t.restore +# Setlist: Flush all sets +0 ipset -F +# Setlist: Delete all sets +0 ipset -X && rm setlist.t.restore # eof -- cgit v1.2.3