summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2010-06-29 21:14:40 +0200
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2010-06-29 21:14:40 +0200
commit8dd10256cb24ceade8b40bd1604f03ddac8589e2 (patch)
tree9b6e5deae0b5d349122c82b63019d6bb36a66aeb
parent780f6384c5c6639da3f5a6ac8d30653e8a26d6c0 (diff)
ipset 5: Sparc related and compatibility fixesv5.0-pre5
ipset 5 is tested on Sparc, which revealed some compatibility issues and those are fixed. Kernels from 2.6.31 onward are supported. The testsuite checkings are completed to run match/target checks. The README file is updated to reflect the requirements to install and run ipset 5.
-rw-r--r--Make_global.am12
-rw-r--r--Makefile.am5
-rw-r--r--README23
-rwxr-xr-xcheck_const8
-rw-r--r--configure.ac23
-rw-r--r--kernel/Kbuild4
-rw-r--r--kernel/Kconfig.ipset74
-rw-r--r--kernel/include/linux/netfilter/ip_set.h1
-rw-r--r--kernel/include/linux/netfilter/ip_set_kernel.h2
-rw-r--r--kernel/ip_set.c54
-rw-r--r--kernel/ip_set_bitmap_ip.c6
-rw-r--r--kernel/ip_set_bitmap_ipmac.c8
-rw-r--r--kernel/ip_set_bitmap_port.c6
-rw-r--r--kernel/ip_set_hash_ip.c6
-rw-r--r--kernel/ip_set_hash_ipport.c6
-rw-r--r--kernel/ip_set_hash_ipportip.c6
-rw-r--r--kernel/ip_set_hash_ipportnet.c6
-rw-r--r--kernel/ip_set_hash_net.c6
-rw-r--r--kernel/ip_set_list_set.c4
-rw-r--r--kernel/xt_set.c15
-rw-r--r--lib/parse.c14
-rw-r--r--lib/print.c16
-rw-r--r--lib/session.c26
-rw-r--r--lib/types.c2
-rw-r--r--netlink.patch-2.6.31.186
-rw-r--r--tests/bitmap:ip.t14
-rw-r--r--tests/ipmap.t10
-rwxr-xr-xtests/iptables.sh1
-rw-r--r--tests/macipmap.t8
-rw-r--r--tests/portmap.t8
-rwxr-xr-xtests/runtest.sh9
-rw-r--r--tests/setlist.t2
32 files changed, 306 insertions, 165 deletions
diff --git a/Make_global.am b/Make_global.am
index 5b2ec6f..b2e57d6 100644
--- a/Make_global.am
+++ b/Make_global.am
@@ -7,9 +7,7 @@ LIBVERSION = 1:0:0
AM_CPPFLAGS = $(kinclude_CFLAGS) $(all_includes) -I$(top_srcdir)/include \
-I/usr/local/include
-# -Wconversion -> false warnings
-# -Wcast-qual -> false warnings
-# -Wpointer-arith -> we need it
+# -Wconversion -> we need it
# -Wunreachable-code -> fails with ntoh*
if DISABLE_EXTRA_FLAGS
@@ -17,19 +15,24 @@ AM_CFLAGS =
else
AM_CFLAGS = -std=gnu99 \
-Wall \
- -Wextra \
-Waggregate-return \
-Wbad-function-cast \
-Wcast-align \
+ -Wcast-qual \
+ -Wextra \
-Wfloat-equal \
+ -Wformat-nonliteral \
+ -Wformat=2 \
-Winit-self \
-Winline \
-Wmissing-declarations \
-Wmissing-format-attribute \
-Wmissing-prototypes \
-Wnested-externs \
+ -Wno-missing-field-initializers \
-Wold-style-definition \
-Wpacked \
+ -Wpointer-arith \
-Wredundant-decls \
-Wshadow \
-Wsign-compare \
@@ -37,7 +40,6 @@ AM_CFLAGS = -std=gnu99 \
-Wswitch-default \
-Wundef \
-Wwrite-strings \
- -Wno-missing-field-initializers \
-Werror
endif
diff --git a/Makefile.am b/Makefile.am
index e5c1c83..7225f86 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -21,7 +21,10 @@ endif
SUBDIRS = lib src
modules:
- cd kernel; make -C $(KBUILD_OUTPUT) M=`pwd` V=$V IP_SET_MAX=$(IP_SET_MAX) modules
+ cd kernel; make -C $(KBUILD_OUTPUT) M=`pwd` V=$V \
+ IP_SET_MAX=$(IP_SET_MAX) \
+ NETLINK_DUMP_CONST=$(NETLINK_DUMP_CONST) \
+ NFNL_CB_CONST=$(NFNL_CB_CONST) modules
modules_install:
cd kernel; make -C $(KBUILD_OUTPUT) M=`pwd` modules_install
diff --git a/README b/README
index 7838a37..08a22ba 100644
--- a/README
+++ b/README
@@ -1,20 +1,25 @@
This is the ipset source tree. Follow these steps to install ipset:
-0. You need the source tree of your kernel (version >= 2.6.16)
- and it have to be configured, modules compiled.
+0. You need the source tree of your kernel (version >= 2.6.31)
+ and it have to be configured, modules compiled. Please apply
+ the netlink.patch against your kernel tree (with kernel <= 2.6.31.1
+ please use the patch netlink.patch-2.6.31.1). Recompile and
+ install the patched kernel.
-1. Initialize the environment
+1. Initialize the compiling environment for ipset
% ./autogen.sh
2. Run `./configure` and then compile the ipset binary and the kernel
modules.
+ The ipset source code depends on the libmnl library.
+
Configure parameters can be used to to override the default path
to the kernel source tree (/lib/modules/`uname -r`/build),
the maximum number of sets (256), the default hash sizes (1024)
or disable the extra compiler warning flags if your compiler
- does not support all of them.
+ does not support all of them. See `./configure --help`.
% ./configure
% make
@@ -25,7 +30,15 @@ This is the ipset source tree. Follow these steps to install ipset:
# make install
# make modules_install
- After installing the modules, you can run the testsuite as well:
+ After installing the modules, you can run the testsuite as well.
+ Please note, several assumptions must be met for the testsuite:
+
+ - no sets defined
+ - iptables/ip6tables rules are not set up
+ - the destination for kernel logs is /var/log/kern.log
+ - the networks 10.255.255.0/24 and 1002:1002:1002:1002::/64
+ are not in use
+ - sendip utility is installed
# make tests
diff --git a/check_const b/check_const
new file mode 100755
index 0000000..c26b566
--- /dev/null
+++ b/check_const
@@ -0,0 +1,8 @@
+#! /usr/bin/awk -f
+
+# nfnetlink.h && netlink.h
+
+{ if (/^(struct nfnl_callback|extern int netlink_dump)/) { check=1 } }
+{ if (check == 1 && /(^};|...\);)/) { check=0 } }
+
+{ if (check == 1 && /const struct nlmsghdr/) { print "const" } }
diff --git a/configure.ac b/configure.ac
index 658d5f0..f75ef49 100644
--- a/configure.ac
+++ b/configure.ac
@@ -15,10 +15,31 @@ dnl Kernel build directory or source tree
AC_ARG_WITH([kernel],
AS_HELP_STRING([--with-kernel=PATH],
[Path to kernel source/build directory]),
- [KBUILDDOR="$withval";])
+ [KBUILDDIR="$withval";])
AM_CONDITIONAL(WITH_KBUILDDIR, test "$KBUILDDIR" != "")
AC_SUBST(KBUILDDIR)
+dnl Sigh: check kernel version dependencies
+if test "$KBUILDDIR" != ""
+then
+ kbuilddir="$KBUILDDIR"
+else
+ kbuilddir="/lib/modules/`uname -r`/build"
+fi
+
+if test ! -e "$kbuilddir/include/linux/netfilter/nfnetlink.h"
+then
+ AC_MSG_ERROR([Invalid kernel build directory $kbuilddir])
+fi
+
+dnl Check kernel dependencies: nfnetlink.h
+NFNL_CB_CONST="`./check_const $kbuilddir/include/linux/netfilter/nfnetlink.h`"
+AC_SUBST(NFNL_CB_CONST)
+
+dnl Check kernel dependencies: netlink.h
+NETLINK_DUMP_CONST="`./check_const $kbuilddir/include/linux/netlink.h`"
+AC_SUBST(NETLINK_DUMP_CONST)
+
dnl Maximal number of sets supported by the kernel, default 256
AC_ARG_WITH([maxsets],
AS_HELP_STRING([--with-maxsets=256],
diff --git a/kernel/Kbuild b/kernel/Kbuild
index 9c7771a..9875d70 100644
--- a/kernel/Kbuild
+++ b/kernel/Kbuild
@@ -1,5 +1,7 @@
EXTRA_CFLAGS := -I$(M)/include \
- -DCONFIG_IP_SET_MAX=$(IP_SET_MAX)
+ -DCONFIG_IP_SET_MAX=$(IP_SET_MAX) \
+ -DNETLINK_DUMP_CONST=$(NETLINK_DUMP_CONST) \
+ -DNFNL_CB_CONST=$(NFNL_CB_CONST)
obj-m += ip_set.o xt_set.o
obj-m += ip_set_bitmap_ip.o ip_set_bitmap_ipmac.o ip_set_bitmap_port.o
diff --git a/kernel/Kconfig.ipset b/kernel/Kconfig.ipset
index 7f7a34a..527b294 100644
--- a/kernel/Kconfig.ipset
+++ b/kernel/Kconfig.ipset
@@ -20,95 +20,79 @@ config IP_SET_MAX
The value can be overriden by the 'max_sets' module
parameter of the 'ip_set' module.
-config IP_SET_IPMAP
- tristate "ipmap set support"
+config IP_SET_BITMAP_IP
+ tristate "bitmap:ip set support"
depends on IP_SET
help
- This option adds the ipmap set type support.
+ This option adds the bitmap:ip set type support.
To compile it as a module, choose M here. If unsure, say N.
-config IP_SET_MACIPMAP
- tristate "macipmap set support"
+config IP_SET_BITMAP_IPMAC
+ tristate "bitmap:ip,mac set support"
depends on IP_SET
help
- This option adds the macipmap set type support.
+ This option adds the bitmap:ip,mac set type support.
To compile it as a module, choose M here. If unsure, say N.
-config IP_SET_PORTMAP
- tristate "portmap set support"
+config IP_SET_BITMAP_PORT
+ tristate "bitmap:port set support"
depends on IP_SET
help
- This option adds the portmap set type support.
+ This option adds the bitmap:port set type support.
To compile it as a module, choose M here. If unsure, say N.
-config IP_SET_IPHASH
- tristate "iphash set support"
+config IP_SET_HASH_IP
+ tristate "hash:ip set support"
depends on IP_SET
help
- This option adds the iphash set type support.
+ This option adds the hash:ip set type support.
To compile it as a module, choose M here. If unsure, say N.
-config IP_SET_NETHASH
- tristate "nethash set support"
+config IP_SET_HASH_NET
+ tristate "hash:net set support"
depends on IP_SET
help
- This option adds the nethash set type support.
+ This option adds the hash:net set type support.
To compile it as a module, choose M here. If unsure, say N.
-config IP_SET_IPPORTHASH
- tristate "ipporthash set support"
+config IP_SET_HASH_IPPORT
+ tristate "hash:ip,port set support"
depends on IP_SET
help
- This option adds the ipporthash set type support.
+ This option adds the hash:ip,port set type support.
To compile it as a module, choose M here. If unsure, say N.
-config IP_SET_IPPORTIPHASH
- tristate "ipportiphash set support"
+config IP_SET_HASH_IPPORTIP
+ tristate "hash:ip,port,ip set support"
depends on IP_SET
help
- This option adds the ipportiphash set type support.
+ This option adds the hash:ip,port,ip set type support.
To compile it as a module, choose M here. If unsure, say N.
-config IP_SET_IPPORTNETHASH
- tristate "ipportnethash set support"
+config IP_SET_HASH_IPPORTNET
+ tristate "hash:ip,port,net set support"
depends on IP_SET
help
- This option adds the ipportnethash set type support.
+ This option adds the hash:ip,port,net set type support.
To compile it as a module, choose M here. If unsure, say N.
-config IP_SET_IPTREE
- tristate "iptree set support"
+config IP_SET_LIST_SET
+ tristate "list:set set support"
depends on IP_SET
help
- This option adds the iptree set type support.
+ This option adds the list:set set type support.
To compile it as a module, choose M here. If unsure, say N.
-config IP_SET_IPTREEMAP
- tristate "iptreemap set support"
- depends on IP_SET
- help
- This option adds the iptreemap set type support.
-
- To compile it as a module, choose M here. If unsure, say N.
-
-config IP_SET_SETLIST
- tristate "setlist set support"
- depends on IP_SET
- help
- This option adds the setlist set type support.
-
- To compile it as a module, choose M here. If unsure, say N.
-
-config IP_MATCH_SET
+config NETFILTER_XT_MATCH_SET
tristate "set match support"
depends on IP_SET
help
@@ -117,7 +101,7 @@ config IP_MATCH_SET
To compile it as a module, choose M here. If unsure, say N.
-config IP_TARGET_SET
+config NETFILTER_XT_TARGET_SET
tristate "SET target support"
depends on IP_SET
help
diff --git a/kernel/include/linux/netfilter/ip_set.h b/kernel/include/linux/netfilter/ip_set.h
index f306859..b83454a 100644
--- a/kernel/include/linux/netfilter/ip_set.h
+++ b/kernel/include/linux/netfilter/ip_set.h
@@ -155,6 +155,7 @@ enum ipset_adt {
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/netlink.h>
+#include <linux/vmalloc.h>
#include <net/netlink.h>
/* Sets are identified by an index in kernel space. Tweak with ip_set_id_t
diff --git a/kernel/include/linux/netfilter/ip_set_kernel.h b/kernel/include/linux/netfilter/ip_set_kernel.h
index d6e033b..0f04217 100644
--- a/kernel/include/linux/netfilter/ip_set_kernel.h
+++ b/kernel/include/linux/netfilter/ip_set_kernel.h
@@ -10,8 +10,10 @@
#ifdef __KERNEL__
+#ifdef CONFIG_DEBUG_KERNEL
/* Complete debug messages */
#define pr_fmt(fmt) "%s %s[%i]: " fmt "\n", __FILE__, __func__, __LINE__
+#endif
#include <linux/kernel.h>
diff --git a/kernel/ip_set.c b/kernel/ip_set.c
index 9d7093c..74b2e91 100644
--- a/kernel/ip_set.c
+++ b/kernel/ip_set.c
@@ -425,7 +425,7 @@ EXPORT_SYMBOL(ip_set_nfnl_put);
*/
static inline bool
-protocol_failed(const struct nlattr * const tb[])
+protocol_failed(NFNL_CB_CONST struct nlattr * NFNL_CB_CONST tb[])
{
return !tb[IPSET_ATTR_PROTOCOL]
|| nla_get_u8(tb[IPSET_ATTR_PROTOCOL]) != IPSET_PROTOCOL;
@@ -530,8 +530,8 @@ load_type_module(const char *typename)
static int
ip_set_create(struct sock *ctnl, struct sk_buff *skb,
- const struct nlmsghdr *nlh,
- const struct nlattr * const attr[])
+ NFNL_CB_CONST struct nlmsghdr *nlh,
+ NFNL_CB_CONST struct nlattr * NFNL_CB_CONST attr[])
{
struct ip_set *set, *clash;
ip_set_id_t index = IPSET_INVALID_ID;
@@ -669,8 +669,8 @@ ip_set_destroy_set(ip_set_id_t index)
static int
ip_set_destroy(struct sock *ctnl, struct sk_buff *skb,
- const struct nlmsghdr *nlh,
- const struct nlattr * const attr[])
+ NFNL_CB_CONST struct nlmsghdr *nlh,
+ NFNL_CB_CONST struct nlattr * NFNL_CB_CONST attr[])
{
ip_set_id_t i;
@@ -714,8 +714,8 @@ ip_set_flush_set(struct ip_set *set)
static int
ip_set_flush(struct sock *ctnl, struct sk_buff *skb,
- const struct nlmsghdr *nlh,
- const struct nlattr * const attr[])
+ NFNL_CB_CONST struct nlmsghdr *nlh,
+ NFNL_CB_CONST struct nlattr * NFNL_CB_CONST attr[])
{
ip_set_id_t i;
@@ -750,8 +750,8 @@ ip_set_setname2_policy[IPSET_ATTR_CMD_MAX + 1] __read_mostly = {
static int
ip_set_rename(struct sock *ctnl, struct sk_buff *skb,
- const struct nlmsghdr *nlh,
- const struct nlattr * const attr[])
+ NFNL_CB_CONST struct nlmsghdr *nlh,
+ NFNL_CB_CONST struct nlattr * NFNL_CB_CONST attr[])
{
struct ip_set *set;
const char *name2;
@@ -790,8 +790,8 @@ ip_set_rename(struct sock *ctnl, struct sk_buff *skb,
static int
ip_set_swap(struct sock *ctnl, struct sk_buff *skb,
- const struct nlmsghdr *nlh,
- const struct nlattr * const attr[])
+ NFNL_CB_CONST struct nlmsghdr *nlh,
+ NFNL_CB_CONST struct nlattr * NFNL_CB_CONST attr[])
{
struct ip_set *from, *to;
ip_set_id_t from_id, to_id;
@@ -968,8 +968,8 @@ out:
static int
ip_set_dump(struct sock *ctnl, struct sk_buff *skb,
- const struct nlmsghdr *nlh,
- const struct nlattr * const attr[])
+ NFNL_CB_CONST struct nlmsghdr *nlh,
+ NFNL_CB_CONST struct nlattr * NFNL_CB_CONST attr[])
{
ip_set_id_t index;
@@ -1009,7 +1009,7 @@ ip_set_adt_policy[IPSET_ATTR_CMD_MAX + 1] __read_mostly = {
static int
call_ad(struct sock *ctnl, struct sk_buff *skb,
- const struct nlattr * const attr[],
+ NFNL_CB_CONST struct nlattr * NFNL_CB_CONST attr[],
struct ip_set *set, const struct nlattr *nla,
enum ipset_adt adt, u32 flags)
{
@@ -1041,8 +1041,8 @@ call_ad(struct sock *ctnl, struct sk_buff *skb,
static int
ip_set_uadd(struct sock *ctnl, struct sk_buff *skb,
- const struct nlmsghdr *nlh,
- const struct nlattr * const attr[])
+ NFNL_CB_CONST struct nlmsghdr *nlh,
+ NFNL_CB_CONST struct nlattr * NFNL_CB_CONST attr[])
{
struct ip_set *set;
const struct nlattr *nla;
@@ -1085,8 +1085,8 @@ ip_set_uadd(struct sock *ctnl, struct sk_buff *skb,
static int
ip_set_udel(struct sock *ctnl, struct sk_buff *skb,
- const struct nlmsghdr *nlh,
- const struct nlattr * const attr[])
+ NFNL_CB_CONST struct nlmsghdr *nlh,
+ NFNL_CB_CONST struct nlattr * NFNL_CB_CONST attr[])
{
struct ip_set *set;
const struct nlattr *nla;
@@ -1129,8 +1129,8 @@ ip_set_udel(struct sock *ctnl, struct sk_buff *skb,
static int
ip_set_utest(struct sock *ctnl, struct sk_buff *skb,
- const struct nlmsghdr *nlh,
- const struct nlattr * const attr[])
+ NFNL_CB_CONST struct nlmsghdr *nlh,
+ NFNL_CB_CONST struct nlattr * NFNL_CB_CONST attr[])
{
struct ip_set *set;
int ret = 0;
@@ -1162,8 +1162,8 @@ ip_set_utest(struct sock *ctnl, struct sk_buff *skb,
static int
ip_set_header(struct sock *ctnl, struct sk_buff *skb,
- const struct nlmsghdr *nlh,
- const struct nlattr * const attr[])
+ NFNL_CB_CONST struct nlmsghdr *nlh,
+ NFNL_CB_CONST struct nlattr * NFNL_CB_CONST attr[])
{
struct ip_set *set;
struct sk_buff *skb2;
@@ -1220,8 +1220,8 @@ ip_set_type_policy[IPSET_ATTR_CMD_MAX + 1] __read_mostly = {
static int
ip_set_type(struct sock *ctnl, struct sk_buff *skb,
- const struct nlmsghdr *nlh,
- const struct nlattr * const attr[])
+ NFNL_CB_CONST struct nlmsghdr *nlh,
+ NFNL_CB_CONST struct nlattr * NFNL_CB_CONST attr[])
{
struct sk_buff *skb2;
struct nlmsghdr *nlh2;
@@ -1283,8 +1283,8 @@ ip_set_protocol_policy[IPSET_ATTR_CMD_MAX + 1] __read_mostly = {
static int
ip_set_protocol(struct sock *ctnl, struct sk_buff *skb,
- const struct nlmsghdr *nlh,
- const struct nlattr * const attr[])
+ NFNL_CB_CONST struct nlmsghdr *nlh,
+ NFNL_CB_CONST struct nlattr * NFNL_CB_CONST attr[])
{
struct sk_buff *skb2;
struct nlmsghdr *nlh2;
@@ -1525,7 +1525,7 @@ ip_set_init(void)
return ret;
}
- pr_notice("ip_set with protocol version %u loaded", IPSET_PROTOCOL);
+ pr_notice("ip_set: protocol %u", IPSET_PROTOCOL);
return 0;
}
diff --git a/kernel/ip_set_bitmap_ip.c b/kernel/ip_set_bitmap_ip.c
index 27b9665..e63bcda 100644
--- a/kernel/ip_set_bitmap_ip.c
+++ b/kernel/ip_set_bitmap_ip.c
@@ -115,7 +115,7 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *head, int len,
enum ipset_adt adt, u32 *lineno, u32 flags)
{
struct bitmap_ip *map = set->data;
- struct nlattr *tb[IPSET_ATTR_ADT_MAX];
+ struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
u32 ip, ip_to, id;
int ret = 0;
@@ -357,7 +357,7 @@ bitmap_ip_timeout_uadt(struct ip_set *set, struct nlattr *head, int len,
enum ipset_adt adt, u32 *lineno, u32 flags)
{
struct bitmap_ip_timeout *map = set->data;
- struct nlattr *tb[IPSET_ATTR_ADT_MAX];
+ struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
u32 ip, ip_to, id, timeout = map->timeout;
int ret = 0;
@@ -594,7 +594,7 @@ static int
bitmap_ip_create(struct ip_set *set, struct nlattr *head, int len,
u32 flags)
{
- struct nlattr *tb[IPSET_ATTR_CREATE_MAX];
+ struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1];
u32 first_ip, last_ip, hosts, elements;
u8 netmask = 32;
diff --git a/kernel/ip_set_bitmap_ipmac.c b/kernel/ip_set_bitmap_ipmac.c
index 3c94975..5833c77 100644
--- a/kernel/ip_set_bitmap_ipmac.c
+++ b/kernel/ip_set_bitmap_ipmac.c
@@ -61,13 +61,13 @@ struct ipmac {
struct ipmac_elem {
unsigned char ether[ETH_ALEN];
unsigned char match;
-};
+} __attribute__ ((aligned));
struct ipmac_telem {
unsigned char ether[ETH_ALEN];
unsigned char match;
unsigned long timeout;
-};
+} __attribute__ ((aligned));
static inline void *
bitmap_ipmac_elem(const struct bitmap_ipmac *map, u32 id)
@@ -376,7 +376,7 @@ bitmap_ipmac_uadt(struct ip_set *set, struct nlattr *head, int len,
enum ipset_adt adt, u32 *lineno, u32 flags)
{
struct bitmap_ipmac *map = set->data;
- struct nlattr *tb[IPSET_ATTR_ADT_MAX];
+ struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
ipset_adtfn adtfn = set->variant->adt[adt];
struct ipmac data;
u32 timeout = map->timeout;
@@ -570,7 +570,7 @@ static int
bitmap_ipmac_create(struct ip_set *set, struct nlattr *head, int len,
u32 flags)
{
- struct nlattr *tb[IPSET_ATTR_CREATE_MAX];
+ struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1];
u32 first_ip, last_ip, elements;
struct bitmap_ipmac *map;
diff --git a/kernel/ip_set_bitmap_port.c b/kernel/ip_set_bitmap_port.c
index 6517252..c96b06c 100644
--- a/kernel/ip_set_bitmap_port.c
+++ b/kernel/ip_set_bitmap_port.c
@@ -109,7 +109,7 @@ bitmap_port_uadt(struct ip_set *set, struct nlattr *head, int len,
enum ipset_adt adt, u32 *lineno, u32 flags)
{
struct bitmap_port *map = set->data;
- struct nlattr *tb[IPSET_ATTR_ADT_MAX];
+ struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
u32 port; /* wraparound */
u16 id, port_to;
int ret = 0;
@@ -344,7 +344,7 @@ bitmap_port_timeout_uadt(struct ip_set *set, struct nlattr *head, int len,
enum ipset_adt adt, u32 *lineno, u32 flags)
{
const struct bitmap_port_timeout *map = set->data;
- struct nlattr *tb[IPSET_ATTR_ADT_MAX];
+ struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
u16 id, port_to;
u32 port, timeout = map->timeout; /* wraparound */
int ret = 0;
@@ -567,7 +567,7 @@ static int
bitmap_port_create(struct ip_set *set, struct nlattr *head, int len,
u32 flags)
{
- struct nlattr *tb[IPSET_ATTR_CREATE_MAX];
+ struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1];
u16 first_port, last_port;
if (nla_parse(tb, IPSET_ATTR_CREATE_MAX, head, len,
diff --git a/kernel/ip_set_hash_ip.c b/kernel/ip_set_hash_ip.c
index d73a5da..1af96ac 100644
--- a/kernel/ip_set_hash_ip.c
+++ b/kernel/ip_set_hash_ip.c
@@ -148,7 +148,7 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *head, int len,
enum ipset_adt adt, u32 *lineno, u32 flags)
{
struct chash *h = set->data;
- struct nlattr *tb[IPSET_ATTR_ADT_MAX];
+ struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
ipset_adtfn adtfn = set->variant->adt[adt];
u32 ip, nip, ip_to, hosts, timeout = h->timeout;
int ret = 0;
@@ -337,7 +337,7 @@ hash_ip6_uadt(struct ip_set *set, struct nlattr *head, int len,
enum ipset_adt adt, u32 *lineno, u32 flags)
{
struct chash *h = set->data;
- struct nlattr *tb[IPSET_ATTR_ADT_MAX];
+ struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
ipset_adtfn adtfn = set->variant->adt[adt];
union nf_inet_addr *ip;
u32 timeout = h->timeout;
@@ -385,7 +385,7 @@ hash_ip_create_policy[IPSET_ATTR_CREATE_MAX+1] __read_mostly = {
static int
hash_ip_create(struct ip_set *set, struct nlattr *head, int len, u32 flags)
{
- struct nlattr *tb[IPSET_ATTR_CREATE_MAX];
+ struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1];
u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
u8 netmask;
struct chash *h;
diff --git a/kernel/ip_set_hash_ipport.c b/kernel/ip_set_hash_ipport.c
index cb319d2..f0274f9 100644
--- a/kernel/ip_set_hash_ipport.c
+++ b/kernel/ip_set_hash_ipport.c
@@ -171,7 +171,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *head, int len,
enum ipset_adt adt, u32 *lineno, u32 flags)
{
struct chash *h = set->data;
- struct nlattr *tb[IPSET_ATTR_ADT_MAX];
+ struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipport4_elem data = { .proto = h->proto };
u32 timeout = h->timeout;
@@ -365,7 +365,7 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *head, int len,
enum ipset_adt adt, u32 *lineno, u32 flags)
{
struct chash *h = set->data;
- struct nlattr *tb[IPSET_ATTR_ADT_MAX];
+ struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipport6_elem data = { .proto = h->proto };
u32 timeout = h->timeout;
@@ -433,7 +433,7 @@ hash_ipport_create_policy[IPSET_ATTR_CREATE_MAX+1] __read_mostly = {
static int
hash_ipport_create(struct ip_set *set, struct nlattr *head, int len, u32 flags)
{
- struct nlattr *tb[IPSET_ATTR_CREATE_MAX];
+ struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1];
struct chash *h;
u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
u8 proto = IPSET_IPPROTO_TCPUDP; /* Backward compatibility */
diff --git a/kernel/ip_set_hash_ipportip.c b/kernel/ip_set_hash_ipportip.c
index 2c3cf9b..16e6f17 100644
--- a/kernel/ip_set_hash_ipportip.c
+++ b/kernel/ip_set_hash_ipportip.c
@@ -178,7 +178,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *head, int len,
enum ipset_adt adt, u32 *lineno, u32 flags)
{
struct chash *h = set->data;
- struct nlattr *tb[IPSET_ATTR_ADT_MAX];
+ struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipportip4_elem data = { .proto = h->proto };
u32 timeout = h->timeout;
@@ -385,7 +385,7 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *head, int len,
enum ipset_adt adt, u32 *lineno, u32 flags)
{
struct chash *h = set->data;
- struct nlattr *tb[IPSET_ATTR_ADT_MAX];
+ struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipportip6_elem data = { .proto = h->proto };
u32 timeout = h->timeout;
@@ -460,7 +460,7 @@ static int
hash_ipportip_create(struct ip_set *set, struct nlattr *head,
int len, u32 flags)
{
- struct nlattr *tb[IPSET_ATTR_CREATE_MAX];
+ struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1];
struct chash *h;
u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
u8 proto = IPSET_IPPROTO_TCPUDP; /* Backward compatibility */
diff --git a/kernel/ip_set_hash_ipportnet.c b/kernel/ip_set_hash_ipportnet.c
index 4bc44f5..f356a88 100644
--- a/kernel/ip_set_hash_ipportnet.c
+++ b/kernel/ip_set_hash_ipportnet.c
@@ -198,7 +198,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *head, int len,
enum ipset_adt adt, u32 *lineno, u32 flags)
{
struct chash *h = set->data;
- struct nlattr *tb[IPSET_ATTR_ADT_MAX];
+ struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipportnet4_elem data = { .cidr = HOST_MASK,
.proto = h->proto };
@@ -442,7 +442,7 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *head, int len,
enum ipset_adt adt, u32 *lineno, u32 flags)
{
struct chash *h = set->data;
- struct nlattr *tb[IPSET_ATTR_ADT_MAX];
+ struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipportnet6_elem data = { .cidr = HOST_MASK,
.proto = h->proto };
@@ -526,7 +526,7 @@ static int
hash_ipportnet_create(struct ip_set *set, struct nlattr *head,
int len, u32 flags)
{
- struct nlattr *tb[IPSET_ATTR_CREATE_MAX];
+ struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1];
struct chash *h;
u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
u8 proto = IPSET_IPPROTO_TCPUDP; /* Backward compatibility */
diff --git a/kernel/ip_set_hash_net.c b/kernel/ip_set_hash_net.c
index 9be9e2c..42112a2 100644
--- a/kernel/ip_set_hash_net.c
+++ b/kernel/ip_set_hash_net.c
@@ -168,7 +168,7 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *head, int len,
enum ipset_adt adt, u32 *lineno, u32 flags)
{
struct chash *h = set->data;
- struct nlattr *tb[IPSET_ATTR_ADT_MAX];
+ struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_net4_elem data = { .cidr = HOST_MASK };
u32 timeout = h->timeout;
@@ -356,7 +356,7 @@ hash_net6_uadt(struct ip_set *set, struct nlattr *head, int len,
enum ipset_adt adt, u32 *lineno, u32 flags)
{
struct chash *h = set->data;
- struct nlattr *tb[IPSET_ATTR_ADT_MAX];
+ struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_net6_elem data = { .cidr = HOST_MASK };
u32 timeout = h->timeout;
@@ -408,7 +408,7 @@ hash_net_create_policy[IPSET_ATTR_CREATE_MAX+1] __read_mostly = {
static int
hash_net_create(struct ip_set *set, struct nlattr *head, int len, u32 flags)
{
- struct nlattr *tb[IPSET_ATTR_CREATE_MAX];
+ struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1];
u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
struct chash *h;
diff --git a/kernel/ip_set_list_set.c b/kernel/ip_set_list_set.c
index 94c5702..c1e4699 100644
--- a/kernel/ip_set_list_set.c
+++ b/kernel/ip_set_list_set.c
@@ -210,7 +210,7 @@ list_set_uadt(struct ip_set *set, struct nlattr *head, int len,
enum ipset_adt adt, u32 *lineno, u32 flags)
{
struct list_set *map = set->data;
- struct nlattr *tb[IPSET_ATTR_ADT_MAX];
+ struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
bool with_timeout = with_timeout(map->timeout);
int before = 0;
u32 timeout = map->timeout;
@@ -533,7 +533,7 @@ static int
list_set_create(struct ip_set *set, struct nlattr *head, int len,
u32 flags)
{
- struct nlattr *tb[IPSET_ATTR_CREATE_MAX];
+ struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1];
u32 size = IP_SET_LIST_DEFAULT_SIZE;
if (nla_parse(tb, IPSET_ATTR_CREATE_MAX, head, len,
diff --git a/kernel/xt_set.c b/kernel/xt_set.c
index 344d003..3ed8a6a 100644
--- a/kernel/xt_set.c
+++ b/kernel/xt_set.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/skbuff.h>
+#include <linux/version.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_set.h>
@@ -37,6 +38,16 @@ match_set(ip_set_id_t index, const struct sk_buff *skb,
/* Revision 0 interface: backward compatible with netfilter/iptables */
+/* Backward compatibility constrains:
+ * 2.6.24: [NETLINK]: Introduce nested and byteorder flag to netlink attribute
+ * 2.6.31: netfilter: passive OS fingerprint xtables match
+ */
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
+#error "Linux kernel version too old: must be >= 2.6.31"
+#endif
+
static bool
set_match_v0(const struct sk_buff *skb, const struct xt_match_param *par)
{
@@ -93,7 +104,6 @@ set_match_v0_destroy(const struct xt_mtdtor_param *par)
{
struct xt_set_info_match *info = par->matchinfo;
-
ip_set_nfnl_put(info->match_set.index);
}
@@ -200,12 +210,9 @@ set_match_destroy(const struct xt_mtdtor_param *par)
{
struct xt_set_info_match *info = par->matchinfo;
-
ip_set_nfnl_put(info->match_set.index);
}
-/* Set target */
-
static unsigned int
set_target(struct sk_buff *skb, const struct xt_target_param *par)
{
diff --git a/lib/parse.c b/lib/parse.c
index b1fecc7..84b6a3f 100644
--- a/lib/parse.c
+++ b/lib/parse.c
@@ -437,7 +437,7 @@ get_addrinfo##f(struct ipset_session *session, \
struct in##n##_addr **inaddr) \
{ \
struct addrinfo *i; \
- struct sockaddr_in##n *saddr; \
+ struct sockaddr_in##n saddr; \
int found; \
\
if ((*info = get_addrinfo(session, str, family)) == NULL) { \
@@ -447,16 +447,18 @@ get_addrinfo##f(struct ipset_session *session, \
} \
\
for (i = *info, found = 0; i != NULL; i = i->ai_next) { \
- if (i->ai_family != family) \
+ if (i->ai_family != family \
+ || i->ai_addrlen != sizeof(saddr)) \
continue; \
if (found == 0) { \
- saddr = (struct sockaddr_in##n *)i->ai_addr; \
- *inaddr = &saddr->sin##n##_addr; \
- } else if (found == 1) { \
+ /* Workaround: can't cast on Sparc */ \
+ memcpy(&saddr, i->ai_addr, sizeof(saddr)); \
+ *inaddr = &saddr.sin##n##_addr; \
+ } else if (found == 1) { \
ipset_warn(session, \
"%s resolves to multiple addresses: " \
"using only the first one returned by the resolver", \
- str); \
+ str); \
} \
found++; \
} \
diff --git a/lib/print.c b/lib/print.c
index 68f658a..77c283a 100644
--- a/lib/print.c
+++ b/lib/print.c
@@ -220,7 +220,7 @@ ipset_print_ip(char *buf, unsigned int len,
family = ipset_data_family(data);
cidropt = opt == IPSET_OPT_IP ? IPSET_OPT_CIDR : IPSET_OPT_CIDR2;
if (ipset_data_test(data, cidropt)) {
- cidr = *(uint8_t *) ipset_data_get(data, cidropt);
+ cidr = *(const uint8_t *) ipset_data_get(data, cidropt);
D("CIDR: %u", cidr);
} else
cidr = family == AF_INET6 ? 128 : 32;
@@ -287,7 +287,7 @@ ipset_print_ipaddr(char *buf, unsigned int len,
family = ipset_data_family(data);
cidropt = opt == IPSET_OPT_IP ? IPSET_OPT_CIDR : IPSET_OPT_CIDR2;
if (ipset_data_test(data, cidropt))
- cidr = *(uint8_t *) ipset_data_get(data, cidropt);
+ cidr = *(const uint8_t *) ipset_data_get(data, cidropt);
else
cidr = family == AF_INET6 ? 128 : 32;
flags = env & (1 << IPSET_ENV_RESOLVE) ? 0 : NI_NUMERICHOST;
@@ -330,12 +330,12 @@ ipset_print_number(char *buf, unsigned int len,
maxsize = ipset_data_sizeof(opt, AF_INET);
D("opt: %u, maxsize %zu", opt, maxsize);
if (maxsize == sizeof(uint8_t))
- return snprintf(buf, len, "%u", *(uint8_t *) number);
+ return snprintf(buf, len, "%u", *(const uint8_t *) number);
else if (maxsize == sizeof(uint16_t))
- return snprintf(buf, len, "%u", *(uint16_t *) number);
+ return snprintf(buf, len, "%u", *(const uint16_t *) number);
else if (maxsize == sizeof(uint32_t))
return snprintf(buf, len, "%lu",
- (long unsigned) *(uint32_t *) number);
+ (long unsigned) *(const uint32_t *) number);
else
assert(0);
return 0;
@@ -377,8 +377,8 @@ ipset_print_name(char *buf, unsigned int len,
if (ipset_data_test(data, IPSET_OPT_NAMEREF)) {
bool before = false;
if (ipset_data_flags_test(data, IPSET_FLAG(IPSET_OPT_FLAGS))) {
- uint32_t *flags =
- (uint32_t *)ipset_data_get(data, IPSET_OPT_FLAGS);
+ const uint32_t *flags =
+ ipset_data_get(data, IPSET_OPT_FLAGS);
before = (*flags) & IPSET_FLAG_BEFORE;
}
size = snprintf(buf + offset, len,
@@ -460,7 +460,7 @@ ipset_print_proto(char *buf, unsigned int len,
assert(data);
assert(opt == IPSET_OPT_PROTO);
- proto = *(uint8_t *) ipset_data_get(data, IPSET_OPT_PROTO);
+ proto = *(const uint8_t *) ipset_data_get(data, IPSET_OPT_PROTO);
assert(proto);
if (proto == IPSET_IPPROTO_ANY)
diff --git a/lib/session.c b/lib/session.c
index fe1e178..8a0493a 100644
--- a/lib/session.c
+++ b/lib/session.c
@@ -50,7 +50,7 @@ struct ipset_session {
uint8_t envopts; /* Session env opts */
/* Kernel message buffer */
size_t bufsize;
- char buffer[0];
+ void *buffer;
};
/*
@@ -494,7 +494,7 @@ attr2data(struct ipset_session *session, struct nlattr *nla[],
case MNL_TYPE_U32: {
uint32_t value;
- value = ntohl(*(uint32_t *)d);
+ value = ntohl(*(const uint32_t *)d);
d = &value;
break;
@@ -502,7 +502,7 @@ attr2data(struct ipset_session *session, struct nlattr *nla[],
case MNL_TYPE_U16: {
uint16_t value;
- value = ntohs(*(uint16_t *)d);
+ value = ntohs(*(const uint16_t *)d);
d = &value;
break;
@@ -513,13 +513,13 @@ attr2data(struct ipset_session *session, struct nlattr *nla[],
}
#ifdef IPSET_DEBUG
if (type == IPSET_ATTR_TYPENAME)
- D("nla typename %s", (char *) d);
+ D("nla typename %s", (const char *) d);
#endif
ret = ipset_data_set(data, attr->opt, d);
#ifdef IPSET_DEBUG
if (type == IPSET_ATTR_TYPENAME)
D("nla typename %s",
- (char *) ipset_data_get(data, IPSET_OPT_TYPENAME));
+ (const char *) ipset_data_get(data, IPSET_OPT_TYPENAME));
#endif
return ret;
}
@@ -907,7 +907,7 @@ callback_list(struct ipset_session *session, struct nlattr *nla[],
ATTR2DATA(session, nla, IPSET_ATTR_REVISION, cmd_attrs);
D("head: family %u, typename %s",
ipset_data_family(data),
- (char *) ipset_data_get(data, IPSET_OPT_TYPENAME));
+ (const char *) ipset_data_get(data, IPSET_OPT_TYPENAME));
if (mnl_attr_parse_nested(nla[IPSET_ATTR_DATA],
create_attr_cb, cattr) < 0)
FAILURE("Broken %s kernel message: "
@@ -1326,13 +1326,13 @@ rawdata2attr(struct nlmsghdr *nlh,
switch (attr->type) {
case MNL_TYPE_U32: {
- uint32_t value = htonl(*(uint32_t *)d);
+ uint32_t value = htonl(*(const uint32_t *)d);
d = &value;
break;
}
case MNL_TYPE_U16: {
- uint16_t value = htons(*(uint16_t *)d);
+ uint16_t value = htons(*(const uint16_t *)d);
d = &value;
break;
@@ -1415,7 +1415,7 @@ static int
build_send_private_msg(struct ipset_session *session, enum ipset_cmd cmd)
{
char buffer[PRIVATE_MSG_BUFLEN] __attribute__ ((aligned));
- struct nlmsghdr *nlh = (struct nlmsghdr *) buffer;
+ struct nlmsghdr *nlh = (struct nlmsghdr *) (void *) buffer;
struct ipset_data *data = session->data;
int len = PRIVATE_MSG_BUFLEN, ret;
enum ipset_cmd saved = session->cmd;
@@ -1469,7 +1469,10 @@ may_aggregate_ad(struct ipset_session *session, struct ipset_data *data,
&& STREQ(ipset_data_setname(data), session->saved_setname);
}
-static int
+int
+build_msg(struct ipset_session *session, bool aggregate);
+
+int
build_msg(struct ipset_session *session, bool aggregate)
{
struct nlmsghdr *nlh = (struct nlmsghdr *) session->buffer;
@@ -1768,12 +1771,13 @@ ipset_session_init(ipset_outfn outfn)
{
struct ipset_session *session;
size_t bufsize = getpagesize();
-
+
/* Create session object */
session = calloc(1, sizeof(struct ipset_session) + bufsize);
if (session == NULL)
return NULL;
session->bufsize = bufsize;
+ session->buffer = session + 1;
/* The single transport method yet */
session->transport = &ipset_mnl_transport;
diff --git a/lib/types.c b/lib/types.c
index b39a04f..067abcb 100644
--- a/lib/types.c
+++ b/lib/types.c
@@ -404,7 +404,7 @@ ipset_type_check(struct ipset_session *session)
typename = ipset_data_get(data, IPSET_OPT_TYPENAME);
family = ipset_data_family(data);
- revision = *(uint8_t *) ipset_data_get(data, IPSET_OPT_REVISION);
+ revision = *(const uint8_t *) ipset_data_get(data, IPSET_OPT_REVISION);
/* Check registered types */
for (t = typelist; t != NULL && match == NULL; t = t->next) {
diff --git a/netlink.patch-2.6.31.1 b/netlink.patch-2.6.31.1
new file mode 100644
index 0000000..2caed0b
--- /dev/null
+++ b/netlink.patch-2.6.31.1
@@ -0,0 +1,86 @@
+diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
+index 9f00da2..9f51ff6 100644
+--- a/include/linux/netfilter/nfnetlink.h
++++ b/include/linux/netfilter/nfnetlink.h
+@@ -47,7 +47,8 @@ struct nfgenmsg {
+ #define NFNL_SUBSYS_QUEUE 3
+ #define NFNL_SUBSYS_ULOG 4
+ #define NFNL_SUBSYS_OSF 5
+-#define NFNL_SUBSYS_COUNT 6
++#define NFNL_SUBSYS_IPSET 6
++#define NFNL_SUBSYS_COUNT 7
+
+ #ifdef __KERNEL__
+
+diff --git a/include/linux/netlink.h b/include/linux/netlink.h
+index ab5d312..ef8b229 100644
+--- a/include/linux/netlink.h
++++ b/include/linux/netlink.h
+@@ -263,11 +263,14 @@ __nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags)
+ #define NLMSG_PUT(skb, pid, seq, type, len) \
+ NLMSG_NEW(skb, pid, seq, type, len, 0)
+
+-extern int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
+- struct nlmsghdr *nlh,
+- int (*dump)(struct sk_buff *skb, struct netlink_callback*),
+- int (*done)(struct netlink_callback*));
+-
++extern int netlink_dump_init(struct sock *ssk, struct sk_buff *skb,
++ struct nlmsghdr *nlh,
++ int (*dump)(struct sk_buff *skb, struct netlink_callback*),
++ int (*done)(struct netlink_callback*),
++ unsigned char init, ...);
++
++#define netlink_dump_start(ssk, skb, nlh, dump, done) \
++ netlink_dump_init(ssk, skb, nlh, dump, done, 0)
+
+ #define NL_NONROOT_RECV 0x1
+ #define NL_NONROOT_SEND 0x2
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 19e9800..7d85d45 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1714,15 +1714,18 @@ errout:
+ return err;
+ }
+
+-int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
+- struct nlmsghdr *nlh,
+- int (*dump)(struct sk_buff *skb,
+- struct netlink_callback *),
+- int (*done)(struct netlink_callback *))
++int netlink_dump_init(struct sock *ssk, struct sk_buff *skb,
++ struct nlmsghdr *nlh,
++ int (*dump)(struct sk_buff *skb,
++ struct netlink_callback *),
++ int (*done)(struct netlink_callback *),
++ unsigned char init, ...)
+ {
+ struct netlink_callback *cb;
+ struct sock *sk;
+ struct netlink_sock *nlk;
++ va_list args;
++ unsigned char i;
+
+ cb = kzalloc(sizeof(*cb), GFP_KERNEL);
+ if (cb == NULL)
+@@ -1733,6 +1736,10 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
+ cb->nlh = nlh;
+ atomic_inc(&skb->users);
+ cb->skb = skb;
++ va_start(args, init);
++ for (i = 0; i < init; i++)
++ cb->args[i] = va_arg(args, long);
++ va_end(args);
+
+ sk = netlink_lookup(sock_net(ssk), ssk->sk_protocol, NETLINK_CB(skb).pid);
+ if (sk == NULL) {
+@@ -1759,7 +1766,7 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
+ */
+ return -EINTR;
+ }
+-EXPORT_SYMBOL(netlink_dump_start);
++EXPORT_SYMBOL(netlink_dump_init);
+
+ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
+ {
diff --git a/tests/bitmap:ip.t b/tests/bitmap:ip.t
index 03cbe0d..29a1a5a 100644
--- a/tests/bitmap:ip.t
+++ b/tests/bitmap:ip.t
@@ -37,13 +37,13 @@
# Range: List set
0 ipset list test | sed 's/timeout ./timeout x/' > .foo
# Range: Check listing
-0 diff .foo bitmap:ip.t.list4 && rm .foo
+0 diff -I 'Size in memory.*' .foo bitmap:ip.t.list4 && rm .foo
# Sleep 10s so that entries can time out
0 sleep 10s
# Range: List set after timeout
0 ipset list test > .foo
# Range: Check listing
-0 diff .foo bitmap:ip.t.list0 && rm .foo
+0 diff -I 'Size in memory.*' .foo bitmap:ip.t.list0 && rm .foo
# Range: Flush test set
0 ipset flush test
# Range: Delete test set
@@ -79,13 +79,13 @@
# Network: List set
0 ipset list test | sed 's/timeout ./timeout x/' > .foo
# Network: Check listing
-0 diff .foo bitmap:ip.t.list5 && rm .foo
+0 diff -I 'Size in memory.*' .foo bitmap:ip.t.list5 && rm .foo
# Sleep 10s so that entries can time out
0 sleep 10s
# Network: List set
0 ipset list test > .foo
# Network: Check listing
-0 diff .foo bitmap:ip.t.list1 && rm .foo
+0 diff -I 'Size in memory.*' .foo bitmap:ip.t.list1 && rm .foo
# Network: Flush test set
0 ipset flush test
# Network: Delete test set
@@ -121,13 +121,13 @@
# Subnets: List set
0 ipset list test | sed 's/timeout ./timeout x/' > .foo
# Subnets: Check listing
-0 diff .foo bitmap:ip.t.list6 && rm .foo
+0 diff -I 'Size in memory.*' .foo bitmap:ip.t.list6 && rm .foo
# Sleep 10s so that entries can time out
0 sleep 10s
# Subnets: List set
0 ipset list test > .foo
# Subnets: Check listing
-0 diff .foo bitmap:ip.t.list2 && rm .foo
+0 diff -I 'Size in memory.*' .foo bitmap:ip.t.list2 && rm .foo
# Subnets: Flush test set
0 ipset flush test
# Subnets: Delete test set
@@ -147,7 +147,7 @@
# Full: List set
0 ipset list test > .foo
# Full: Check listing
-0 diff .foo bitmap:ip.t.list3 && rm .foo
+0 diff -I 'Size in memory.*' .foo bitmap:ip.t.list3 && rm .foo
# Full: Delete test set
0 ipset destroy test
# eof
diff --git a/tests/ipmap.t b/tests/ipmap.t
index 2373176..f6dd367 100644
--- a/tests/ipmap.t
+++ b/tests/ipmap.t
@@ -49,13 +49,13 @@
# Range: List set
0 ipset -L test > .foo
# Range: Check listing
-0 diff .foo ipmap.t.list0 && rm .foo
+0 diff -I 'Size in memory.*' .foo ipmap.t.list0 && rm .foo
# Range: Delete a range of elements
0 ipset -! -D test 2.0.0.128-2.0.0.132
# Range: List set
0 ipset -L test > .foo
# Range: Check listing
-0 diff .foo ipmap.t.list1 && rm .foo
+0 diff -I 'Size in memory.*' .foo ipmap.t.list1 && rm .foo
# Range: Flush test set
0 ipset -F test
# Range: Delete test set
@@ -91,7 +91,7 @@
# Network: List set
0 ipset -L test > .foo
# Network: Check listing
-0 diff .foo ipmap.t.list2 && rm .foo
+0 diff -I 'Size in memory.*' .foo ipmap.t.list2 && rm .foo
# Network: Flush test set
0 ipset -F test
# Network: Delete test set
@@ -127,7 +127,7 @@
# Subnets: List set
0 ipset -L test > .foo
# Subnets: Check listing
-0 diff .foo ipmap.t.list3 && rm .foo
+0 diff -I 'Size in memory.*' .foo ipmap.t.list3 && rm .foo
# Subnets: FLush test set
0 ipset -F test
# Subnets: Delete test set
@@ -153,7 +153,7 @@
# Full: List set
0 ipset -L test > .foo
# Full: Check listing
-0 diff .foo ipmap.t.list4 && rm .foo
+0 diff -I 'Size in memory.*' .foo ipmap.t.list4 && rm .foo
# Full: Delete test set
0 ipset -X test
# eof
diff --git a/tests/iptables.sh b/tests/iptables.sh
index 935b236..213e748 100755
--- a/tests/iptables.sh
+++ b/tests/iptables.sh
@@ -1,5 +1,6 @@
#!/bin/sh
+# set -x
set -e
# We play with the following networks:
diff --git a/tests/macipmap.t b/tests/macipmap.t
index 90f09ba..7cf0cff 100644
--- a/tests/macipmap.t
+++ b/tests/macipmap.t
@@ -41,7 +41,7 @@
# Range: List set
0 ipset -L test > .foo
# Range: Check listing
-0 diff .foo macipmap.t.list0 && rm .foo
+0 diff -I 'Size in memory.*' .foo macipmap.t.list0 && rm .foo
# Range: Flush test set
0 ipset -F test
# Range: Delete test set
@@ -81,7 +81,7 @@
# Network: List set
0 ipset -L test > .foo
# Network: Check listing
-0 diff .foo macipmap.t.list1 && rm .foo
+0 diff -I 'Size in memory.*' .foo macipmap.t.list1 && rm .foo
# Network: Flush test set
0 ipset -F test
# Network: Delete test set
@@ -121,13 +121,13 @@
# Range: List set
0 ipset -L test | sed 's/timeout ./timeout x/' > .foo
# Range: Check listing
-0 diff .foo macipmap.t.list3 && rm .foo
+0 diff -I 'Size in memory.*' .foo macipmap.t.list3 && rm .foo
# Range: wait 10s so that elements can timeout
0 sleep 10
# Range: List set
0 ipset -L test > .foo
# Range: Check listing
-0 diff .foo macipmap.t.list2 && rm .foo
+0 diff -I 'Size in memory.*' .foo macipmap.t.list2 && rm .foo
# Range: Flush test set
0 ipset -F test
# Range: Delete test set
diff --git a/tests/portmap.t b/tests/portmap.t
index b2ebf55..54fd6f1 100644
--- a/tests/portmap.t
+++ b/tests/portmap.t
@@ -27,7 +27,7 @@
# Range: List set
0 ipset -L test > .foo
# Range: Check listing
-0 diff .foo portmap.t.list0 && rm .foo
+0 diff -I 'Size in memory.*' .foo portmap.t.list0 && rm .foo
# Range: Flush test set
0 ipset -F test
# Range: Delete test set
@@ -47,7 +47,7 @@
# Full: List set
0 ipset -L test > .foo
# Full: Check listing
-0 diff .foo portmap.t.list1 && rm .foo
+0 diff -I 'Size in memory.*' .foo portmap.t.list1 && rm .foo
# Full: Flush test set
0 ipset -F test
# Full: Delete test set
@@ -71,13 +71,13 @@
# Full: List set
0 ipset -L test | sed 's/timeout ./timeout x/' > .foo
# Full: Check listing
-0 diff .foo portmap.t.list3 && rm .foo
+0 diff -I 'Size in memory.*' .foo portmap.t.list3 && rm .foo
# Full: sleep 10s so that elements can timeout
0 sleep 10
# Full: List set
0 ipset -L test > .foo
# Full: Check listing
-# 0 diff .foo portmap.t.list2 && rm .foo
+# 0 diff -I 'Size in memory.*' .foo portmap.t.list2 && rm .foo
# Full: Flush test set
0 ipset -F test
# Full: Delete test set
diff --git a/tests/runtest.sh b/tests/runtest.sh
index 32702c9..cc6678a 100755
--- a/tests/runtest.sh
+++ b/tests/runtest.sh
@@ -19,11 +19,16 @@ add_tests() {
cmd=ip6tables-save
add=match_target6
fi
- modprobe ip_tables
- if [ ! -e /var/log/kern.log -a -z "`grep 'kernel: ip_tables: ' /var/log/kern/log`" ]; then
+ line="`dmesg | tail -1 | cut -d " " -f 2-`"
+ if [ ! -e /var/log/kern.log -o -z "`grep \"$line\" /var/log/kern.log`" ]; then
echo "The destination for kernel log is not /var/log/kern.log, skipping $1 match and target tests"
return
fi
+ c=${cmd%%-save}
+ if [ "`$c -m set -h 2>&1| grep 'cannot open shared object'`" ]; then
+ echo "$c does not support set match, skipping $1 match and target tests"
+ return
+ fi
if [ `$cmd -t filter | wc -l` -eq 7 -a \
`$cmd -t filter | grep ACCEPT | wc -l` -eq 3 ]; then
if [ -z "`which sendip`" ]; then
diff --git a/tests/setlist.t b/tests/setlist.t
index d673e8e..b5e060d 100644
--- a/tests/setlist.t
+++ b/tests/setlist.t
@@ -47,7 +47,7 @@
# List set
0 ipset -L test > .foo
# Check listing
-0 diff .foo setlist.t.list0 && rm .foo
+0 diff -I 'Size in memory.*' .foo setlist.t.list0 && rm .foo
# Flush all sets
0 ipset -F
# Delete all sets