summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Makefile8
-rw-r--r--ipset.8144
-rw-r--r--ipset.c516
-rw-r--r--ipset.h23
-rw-r--r--ipset_iphash.c53
-rw-r--r--ipset_ipmap.c90
-rw-r--r--ipset_ipporthash.c70
-rw-r--r--ipset_ipportiphash.c50
-rw-r--r--ipset_ipportnethash.c50
-rw-r--r--ipset_iptree.c53
-rw-r--r--ipset_iptreemap.c56
-rw-r--r--ipset_macipmap.c97
-rw-r--r--ipset_nethash.c80
-rw-r--r--ipset_portmap.c97
-rw-r--r--ipset_setlist.c76
-rw-r--r--kernel/ChangeLog8
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set.h67
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_bitmaps.h21
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_compat.h23
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_getport.h6
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_hashes.h16
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_iphash.h2
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_ipmap.h2
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_ipporthash.h2
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_ipportiphash.h2
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_ipportnethash.h2
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_iptree.h2
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_iptreemap.h2
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_macipmap.h2
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_nethash.h2
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_portmap.h2
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_setlist.h2
-rw-r--r--kernel/ip_set.c894
-rw-r--r--kernel/ip_set_iphash.c28
-rw-r--r--kernel/ip_set_ipmap.c48
-rw-r--r--kernel/ip_set_ipporthash.c36
-rw-r--r--kernel/ip_set_ipportiphash.c42
-rw-r--r--kernel/ip_set_ipportnethash.c66
-rw-r--r--kernel/ip_set_iptree.c27
-rw-r--r--kernel/ip_set_iptreemap.c54
-rw-r--r--kernel/ip_set_macipmap.c55
-rw-r--r--kernel/ip_set_nethash.c44
-rw-r--r--kernel/ip_set_portmap.c44
-rw-r--r--kernel/ip_set_setlist.c36
-rw-r--r--tests/iphash.t14
-rw-r--r--tests/iphash.t.list07
-rw-r--r--tests/iphash.t.list17
-rw-r--r--tests/ipmap.t16
-rw-r--r--tests/ipmap.t.list08
-rw-r--r--tests/ipmap.t.list18
-rw-r--r--tests/ipmap.t.list28
-rw-r--r--tests/ipmap.t.list38
-rw-r--r--tests/ipporthash.t8
-rw-r--r--tests/ipporthash.t.list07
-rw-r--r--tests/ipporthash.t.list17
-rw-r--r--tests/ipportiphash.t8
-rw-r--r--tests/ipportiphash.t.list07
-rw-r--r--tests/ipportiphash.t.list17
-rw-r--r--tests/ipportnethash.t8
-rw-r--r--tests/ipportnethash.t.list07
-rw-r--r--tests/ipportnethash.t.list17
-rw-r--r--tests/iptree.t4
-rw-r--r--tests/iptree.t.list08
-rw-r--r--tests/iptreemap.t4
-rw-r--r--tests/iptreemap.t.list011
-rw-r--r--tests/macipmap.t8
-rw-r--r--tests/macipmap.t.list09
-rw-r--r--tests/macipmap.t.list18
-rw-r--r--tests/nethash.t16
-rw-r--r--tests/nethash.t.list07
-rw-r--r--tests/portmap.t8
-rw-r--r--tests/portmap.t.list08
-rw-r--r--tests/portmap.t.list18
-rw-r--r--tests/setlist.t4
-rw-r--r--tests/setlist.t.list08
-rwxr-xr-xtests/sort.sh5
77 files changed, 1357 insertions, 1906 deletions
diff --git a/ChangeLog b/ChangeLog
index ec4899f..9126458 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+4.0
+ - New protocol is introduced to handle aligment issues properly
+ (bug reported by Georg Chini)
+ - Binding support is removed
+
3.1
- Correct format specifiers and change %i to %d (Jan Engelhardt)
diff --git a/Makefile b/Makefile
index 1894679..c8bf0ea 100644
--- a/Makefile
+++ b/Makefile
@@ -20,7 +20,7 @@ ifndef V
V=0
endif
-IPSET_VERSION:=3.2
+IPSET_VERSION:=4.0
PREFIX:=/usr/local
LIBDIR:=$(PREFIX)/lib
@@ -60,11 +60,13 @@ EXTRA_WARN_FLAGS:=\
-Werror
ifndef NO_EXTRA_WARN_FLAGS
-WARN_FLAGS+=$(EXTRA_WARN_FLAGS)
+ WARN_FLAGS+=$(EXTRA_WARN_FLAGS)
endif
-CFLAGS:=$(COPT_FLAGS) $(WARN_FLAGS) -Ikernel/include -I. # -g -DIPSET_DEBUG #-pg
+ABI_FLAGS:=
+CFLAGS:=$(ABI_FLAGS) $(COPT_FLAGS) $(WARN_FLAGS) -Ikernel/include -I. # -g -DIPSET_DEBUG
SH_CFLAGS:=$(CFLAGS) -fPIC
+LDFLAGS:=$(ABI_FLAGS)
SETTYPES:=ipmap portmap macipmap
SETTYPES+=iptree iptreemap
SETTYPES+=iphash nethash ipporthash ipportiphash ipportnethash
diff --git a/ipset.8 b/ipset.8
index 6ef1179..55e5d9b 100644
--- a/ipset.8
+++ b/ipset.8
@@ -26,13 +26,11 @@ ipset \- administration tool for IP sets
.br
.BR "ipset -[EW] " "from-set to-set"
.br
-.BR "ipset -[ADU] " "set entry"
-.br
-.BR "ipset -B " "set entry -b binding"
-.br
-.BR "ipset -T " "set entry [-b binding]"
+.BR "ipset -[ADT] " "set entry"
.br
.BR "ipset -R "
+.br
+.BR "ipset -[Vv] "
.SH DESCRIPTION
.B ipset
is used to set up, maintain and inspect so called IP sets in the Linux
@@ -40,19 +38,9 @@ kernel. Depending on the type, an IP set may store IP addresses, (TCP/UDP)
port numbers or additional informations besides IP addresses: the word IP
means a general term here. See the set type definitions below.
.P
-Any entry in a set can be bound to another set, which forms a relationship
-between a set element and the set it is bound to. In order to define a
-binding it is not required that the entry be already added to the set.
-The sets may have a default binding, which is valid for every set element
-for which there is no binding defined at all.
-.P
-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.
+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.
.SH OPTIONS
The options that are recognized by
.B ipset
@@ -70,21 +58,13 @@ Create a set identified with setname and specified type.
Type-specific options must be supplied.
.TP
.BI "-X, --destroy " "[\fIsetname\fP]"
-Destroy the specified set, or all sets if none or the keyword
-.B
-:all:
-is specified.
-Before destroying the set, all bindings belonging to the
-set elements and the default binding of the set are removed.
+Destroy the specified set or all the sets if none is given.
If the set has got references, nothing is done.
.TP
.BI "-F, --flush " "[\fIsetname\fP]"
-Delete all entries from the specified set, or flush
-all sets if none or the keyword
-.B
-:all:
-is given. Bindings are not affected by the flush operation.
+Delete all entries from the specified set or flush
+all sets if none is given.
.TP
.BI "-E, --rename " "\fIfrom-setname\fP \fIto-setname\fP"
Rename a set. Set identified by to-setname must not exist.
@@ -95,102 +75,63 @@ exchange the name of two sets. The referred sets must exist and
identical type of sets can be swapped only.
.TP
.BI "-L, --list " "[\fIsetname\fP]"
-List the entries and bindings for the specified set, or for
-all sets if none or the keyword
-.B
-:all:
-is given. The
-.B "-n, --numeric"
-option can be used to suppress name lookups and generate numeric
-output. When the
+List the entries for the specified set, or for
+all sets if none is given. The
+.B "-r, --resolve"
+option can be used to force name lookups (which may be slow). When the
.B "-s, --sorted"
option is given, the entries are listed sorted (if the given set
type supports the operation).
.TP
.BI "-S, --save " "[\fIsetname\fP]"
-Save the given set, or all sets if none or the keyword
-.B
-:all:
-is specified to stdout in a format that --restore can read.
+Save the given set, or all sets if none is given
+to stdout in a format that --restore can read.
.TP
.BI "-R, --restore "
Restore a saved session generated by --save. The saved session
can be fed from stdin.
When generating a session file please note that the supported commands
-(create set, add element, bind) must appear in a strict order: first create
+(create set and add element) must appear in a strict order: first create
the set, then add all elements. Then create the next set, add all its elements
-and so on. Finally you can list all binding commands. Also, it is a restore
-operation, so the sets being restored must not exist.
+and so on. Also, it is a restore operation, so the sets being restored must
+not exist.
.TP
.BI "-A, --add " "\fIsetname\fP \fIIP\fP"
-Add an IP to a set.
+Add an IP entry to a set.
.TP
.BI "-D, --del " "\fIsetname\fP \fIIP\fP"
-Delete an IP from a set.
+Delete an IP entry from a set.
.TP
.BI "-T, --test " "\fIsetname\fP \fIIP
-Test wether an IP is in a set or not. Exit status number is zero
+Test wether an IP entry is in a set or not. Exit status number is zero
if the tested IP is in the set and nonzero if it is missing from
the set.
.TP
-.BI "-T, --test " "\fIsetname\fP \fIIP\fP \fI--binding\fP \fIto-setname\fP"
-Test wether the IP belonging to the set points to the specified binding.
-Exit status number is zero if the binding points to the specified set,
-otherwise it is nonzero. The keyword
-.B
-:default:
-can be used to test the default binding of the set.
-.TP
-.BI "-B, --bind " "\fIsetname\fP \fIIP\fP \fI--binding\fP \fIto-setname\fP"
-Bind the IP in setname to to-setname.
-.TP
-.BI "-U, --unbind " "\fIsetname\fP \fIIP\fP"
-Delete the binding belonging to IP in set setname.
-.TP
.BI "-H, --help " "[settype]"
Print help and settype specific help if settype specified.
+.TP
+.BI "-V, -v, --version "
+Print program version and protocol version.
.P
-At the
-.B
--B, -U
-and
-.B
--T
-commands you can use the token
-.B
-:default:
-to bind, unbind or test the default binding of a set instead
-of an IP. At the
-.B
--U
-command you can use the token
-.B
-:all:
-to destroy the bindings of all elements of a set.
.SS "OTHER OPTIONS"
The following additional options can be specified:
.TP
-.B "-b, --binding setname"
-The option specifies the value of the binding for the
-.B "-B"
-binding command, for which it is a mandatory option.
-You can use it in the
-.B "-T"
-test command as well to test bindings.
+.B "-r, --resolve"
+When listing sets, enforce name lookup. The
+program will try to display the IP entries resolved to
+host names or services (whenever applicable), which can trigger
+.B
+slow
+DNS
+lookups.
.TP
.B "-s, --sorted"
Sorted output. When listing sets, entries are listed sorted.
.TP
.B "-n, --numeric"
-Numeric output. When listing sets, bindings, IP addresses and
-port numbers will be printed in numeric format. By default the
-program will try to display them as host names, network names
-or services (whenever applicable), which can trigger
-.B
-slow
-DNS
-lookups.
+Numeric output. When listing sets, IP addresses and
+port numbers will be printed in numeric format. This is the default.
.TP
.B "-q, --quiet"
Suppress any output to stdout and stderr. ipset will still return
@@ -224,6 +165,10 @@ When the optional
parameter specified, network addresses will be
stored in the set instead of IP addresses, and the from-IP parameter
must be a network address. The CIDR-netmask value must be between 1-31.
+.PP
+Example:
+.IP
+ipset \-N test ipmap \-\-network 192.168.0.0/16
.SS macipmap
The macipmap set type uses a memory range, where each 8 bytes
represents one IP and a MAC addresses. A macipmap set type can store
@@ -319,6 +264,10 @@ parameter. In general higher
probe
value results better utilized hash while smaller value
produces larger, sparser hash.
+.PP
+Example:
+.IP
+ipset \-N test iphash \-\-probes 2
.SS nethash
The nethash set type uses a hash to store different size of
network addresses. The
@@ -538,7 +487,7 @@ Options to use when creating a setlist type of set:
.TP
.BR "--size " size
Create a setlist type of set with the given size (default 8).
-.P
+.PP
By the
.I
set
@@ -562,8 +511,9 @@ and
.I
b
are setlist type of sets then in the command
-.TP
-iptables -m set --match-set a src,dst -j SET --add-set b src,dst
+.IP
+iptables \-m set \-\-match\-set a src,dst \-j SET \-\-add-set b src,dst
+.PP
the match and target will skip any set in
.I a
and
@@ -589,6 +539,8 @@ use the iphash set type. If you have got random size of netblocks,
use nethash.
.P
Old separator tokens (':' and '%") are still accepted.
+.P
+Binding support is removed.
.SH DIAGNOSTICS
Various error messages are printed to standard error. The exit code
is 0 for correct functioning. Errors which appear to be caused by
diff --git a/ipset.c b/ipset.c
index 5ff32cf..3b8e248 100644
--- a/ipset.c
+++ b/ipset.c
@@ -32,6 +32,11 @@
char program_name[] = "ipset";
char program_version[] = IPSET_VERSION;
+static int protocol_version = 0;
+
+#define STREQ(a,b) (strncmp(a,b,IP_SET_MAXNAMELEN) == 0)
+#define DONT_ALIGN (protocol_version == IP_SET_PROTOCOL_UNALIGNED)
+#define ALIGNED(len) IPSET_VALIGN(len, DONT_ALIGN)
/* The list of loaded set types */
static struct settype *all_settypes = NULL;
@@ -65,7 +70,7 @@ static unsigned int global_option_offset = 0;
static const char cmdflags[] = { ' ', /* CMD_NONE */
'N', 'X', 'F', 'E', 'W', 'L', 'S', 'R',
- 'A', 'D', 'T', 'B', 'U', 'H', 'V',
+ 'A', 'D', 'T', 'H', 'V',
};
/* Options */
@@ -74,11 +79,10 @@ static const char cmdflags[] = { ' ', /* CMD_NONE */
#define OPT_SORTED 0x0002U /* -s */
#define OPT_QUIET 0x0004U /* -q */
#define OPT_DEBUG 0x0008U /* -z */
-#define OPT_BINDING 0x0010U /* -b */
#define OPT_RESOLVE 0x0020U /* -r */
-#define NUMBER_OF_OPT 6
+#define NUMBER_OF_OPT 5
static const char optflags[] =
- { 'n', 's', 'q', 'z', 'b', 'r' };
+ { 'n', 's', 'q', 'z', 'r' };
static struct option opts_long[] = {
/* set operations */
@@ -97,15 +101,10 @@ static struct option opts_long[] = {
{"del", 1, 0, 'D'},
{"test", 1, 0, 'T'},
- /* binding operations */
- {"bind", 1, 0, 'B'},
- {"unbind", 1, 0, 'U'},
-
/* free options */
{"numeric", 0, 0, 'n'},
{"sorted", 0, 0, 's'},
{"quiet", 0, 0, 'q'},
- {"binding", 1, 0, 'b'},
{"resolve", 0, 0, 'r'},
#ifdef IPSET_DEBUG
@@ -122,7 +121,7 @@ static struct option opts_long[] = {
};
static char opts_short[] =
- "-N:X::F::E:W:L::S::RA:D:T:B:U:nrsqzb:Vh::H::";
+ "-N:X::F::E:W:L::S::RA:D:T:nrsqzvVh::H::";
/* Table of legal combinations of commands and options. If any of the
* given commands make an option legal, that option is legal.
@@ -133,22 +132,20 @@ static char opts_short[] =
*/
static char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] = {
- /* -n -s -q -z -b */
- /*CREATE*/ {'x', 'x', ' ', ' ', 'x', 'x'},
- /*DESTROY*/ {'x', 'x', ' ', ' ', 'x', 'x'},
- /*FLUSH*/ {'x', 'x', ' ', ' ', 'x', 'x'},
- /*RENAME*/ {'x', 'x', ' ', ' ', 'x', 'x'},
- /*SWAP*/ {'x', 'x', ' ', ' ', 'x', 'x'},
- /*LIST*/ {' ', ' ', 'x', ' ', 'x', ' '},
- /*SAVE*/ {'x', 'x', ' ', ' ', 'x', 'x'},
- /*RESTORE*/ {'x', 'x', ' ', ' ', 'x', 'x'},
- /*ADD*/ {'x', 'x', ' ', ' ', 'x', 'x'},
- /*DEL*/ {'x', 'x', ' ', ' ', 'x', 'x'},
- /*TEST*/ {'x', 'x', ' ', ' ', ' ', 'x'},
- /*BIND*/ {'x', 'x', ' ', ' ', '+', 'x'},
- /*UNBIND*/ {'x', 'x', ' ', ' ', 'x', 'x'},
- /*HELP*/ {'x', 'x', 'x', ' ', 'x', 'x'},
- /*VERSION*/ {'x', 'x', 'x', ' ', 'x', 'x'},
+ /* -n -s -q -z -r */
+ /*CREATE*/ {'x', 'x', ' ', ' ', 'x'},
+ /*DESTROY*/ {'x', 'x', ' ', ' ', 'x'},
+ /*FLUSH*/ {'x', 'x', ' ', ' ', 'x'},
+ /*RENAME*/ {'x', 'x', ' ', ' ', 'x'},
+ /*SWAP*/ {'x', 'x', ' ', ' ', 'x'},
+ /*LIST*/ {' ', ' ', 'x', ' ', ' '},
+ /*SAVE*/ {'x', 'x', ' ', ' ', 'x'},
+ /*RESTORE*/ {'x', 'x', ' ', ' ', 'x'},
+ /*ADD*/ {'x', 'x', ' ', ' ', 'x'},
+ /*DEL*/ {'x', 'x', ' ', ' ', 'x'},
+ /*TEST*/ {'x', 'x', ' ', ' ', 'x'},
+ /*HELP*/ {'x', 'x', 'x', ' ', 'x'},
+ /*VERSION*/ {'x', 'x', 'x', ' ', 'x'},
};
/* Main parser function */
@@ -451,25 +448,26 @@ static void check_protocolversion(void)
{
struct ip_set_req_version req_version;
socklen_t size = sizeof(struct ip_set_req_version);
- int sockfd = kernel_getsocket();
int res;
+ if (protocol_version)
+ return;
+
req_version.op = IP_SET_OP_VERSION;
- res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req_version, &size);
+ res = wrapped_getsockopt(&req_version, &size);
- if (res != 0) {
- ipset_printf("I'm of protocol version %u.\n"
- "Kernel module is not loaded in, "
- "cannot verify kernel version.",
- IP_SET_PROTOCOL_VERSION);
- return;
- }
- if (req_version.version != IP_SET_PROTOCOL_VERSION)
+ if (res != 0)
+ exit_error(OTHER_PROBLEM,
+ "Couldn't verify kernel module version!");
+
+ if (!(req_version.version == IP_SET_PROTOCOL_VERSION
+ || req_version.version == IP_SET_PROTOCOL_UNALIGNED))
exit_error(OTHER_PROBLEM,
- "Kernel ipset code is of protocol version %u."
+ "Kernel ip_set module is of protocol version %u."
"I'm of protocol version %u.\n"
"Please upgrade your kernel and/or ipset(8) utillity.",
req_version.version, IP_SET_PROTOCOL_VERSION);
+ protocol_version = req_version.version;
}
static void set_command(int *cmd, int newcmd)
@@ -591,11 +589,6 @@ char *ip_tostring(ip_set_ip_t ip, unsigned options)
return inet_ntoa(addr);
}
-char *binding_ip_tostring(struct set *set UNUSED,
- ip_set_ip_t ip, unsigned options)
-{
- return ip_tostring(ip, options);
-}
char *ip_tostring_numeric(ip_set_ip_t ip)
{
return ip_tostring(ip, OPT_NUMERIC);
@@ -760,8 +753,7 @@ static struct settype *settype_find(const char *typename)
DP("%s", typename);
while (runner != NULL) {
- if (strncmp(runner->typename, typename,
- IP_SET_MAXNAMELEN) == 0)
+ if (STREQ(runner->typename, typename))
return runner;
runner = runner->next;
@@ -883,9 +875,7 @@ struct set *set_find_byname(const char *name)
ip_set_id_t i;
for (i = 0; i < max_sets; i++)
- if (set_list[i]
- && strncmp(set_list[i]->name, name,
- IP_SET_MAXNAMELEN) == 0) {
+ if (set_list[i] != NULL && STREQ(set_list[i]->name, name)) {
set = set_list[i];
break;
}
@@ -903,9 +893,7 @@ static ip_set_id_t set_find_free_index(const char *name)
if (idx == IP_SET_INVALID_ID
&& set_list[i] == NULL)
idx = i;
- if (set_list[i] != NULL
- && strncmp(set_list[i]->name, name,
- IP_SET_MAXNAMELEN) == 0)
+ if (set_list[i] != NULL && STREQ(set_list[i]->name, name))
exit_error(PARAMETER_PROBLEM,
"Set %s is already defined, cannot be restored",
name);
@@ -932,7 +920,7 @@ static void set_create(const char *name, struct settype *settype)
DP("%s %s", name, settype->typename);
req_create.op = IP_SET_OP_CREATE;
- req_create.version = IP_SET_PROTOCOL_VERSION;
+ req_create.version = protocol_version;
strcpy(req_create.name, name);
strcpy(req_create.typename, settype->typename);
@@ -956,14 +944,14 @@ static void set_restore_create(const char *name, struct settype *settype)
{
struct set *set;
- DP("%s %s %u %u %u %u", name, settype->typename,
+ DP("%s %s %zu %zu %u %u", name, settype->typename,
restore_offset, sizeof(struct ip_set_restore),
settype->create_size, restore_size);
/* Sanity checking */
if (restore_offset
- + sizeof(struct ip_set_restore)
- + settype->create_size > restore_size)
+ + ALIGNED(sizeof(struct ip_set_restore))
+ + ALIGNED(settype->create_size) > restore_size)
exit_error(PARAMETER_PROBLEM,
"Giving up, restore file is screwed up!");
@@ -982,11 +970,11 @@ static void set_restore_create(const char *name, struct settype *settype)
DP("name %s, restore index %u", restore_set->name, restore_set->index);
/* Add settype data */
- memcpy(restore_data + restore_offset + sizeof(struct ip_set_restore),
- settype->data, settype->create_size);
+ restore_offset += ALIGNED(sizeof(struct ip_set_restore));
+ memcpy(restore_data + restore_offset, settype->data, settype->create_size);
- restore_offset += sizeof(struct ip_set_restore)
- + settype->create_size;
+ restore_offset += ALIGNED(settype->create_size);
+ DP("restore_offset: %zu", restore_offset);
/* Add set to set_list */
set = ipset_malloc(sizeof(struct set));
@@ -1006,7 +994,7 @@ static void set_destroy(const char *name, unsigned op, unsigned cmd)
DP("%s %s", cmd == CMD_DESTROY ? "destroy" : "flush", name);
req.op = op;
- req.version = IP_SET_PROTOCOL_VERSION;
+ req.version = protocol_version;
strcpy(req.name, name);
kernel_sendto(cmd, &req, sizeof(struct ip_set_req_std));
@@ -1024,7 +1012,7 @@ static void set_rename(const char *name, const char *newname,
name, newname);
req.op = op;
- req.version = IP_SET_PROTOCOL_VERSION;
+ req.version = protocol_version;
strcpy(req.name, name);
strcpy(req.typename, newname);
@@ -1062,7 +1050,7 @@ tryagain:
}
/* Get max_sets */
req_max_sets.op = IP_SET_OP_MAX_SETS;
- req_max_sets.version = IP_SET_PROTOCOL_VERSION;
+ req_max_sets.version = protocol_version;
strcpy(req_max_sets.set.name, name);
size = sizeof(req_max_sets);
kernel_getfrom(CMD_MAX_SETS, &req_max_sets, &size);
@@ -1080,8 +1068,8 @@ tryagain:
return 0;
/* Get setnames */
- size = req_size = sizeof(struct ip_set_req_setnames)
- + req_max_sets.sets * sizeof(struct ip_set_name_list);
+ size = req_size = ALIGNED(sizeof(struct ip_set_req_setnames))
+ + req_max_sets.sets * ALIGNED(sizeof(struct ip_set_name_list));
data = ipset_malloc(size);
((struct ip_set_req_setnames *) data)->op = op;
((struct ip_set_req_setnames *) data)->index = *idx;
@@ -1099,8 +1087,8 @@ tryagain:
}
/* Load in setnames */
- size = sizeof(struct ip_set_req_setnames);
- while (size + sizeof(struct ip_set_name_list) <= req_size) {
+ size = ALIGNED(sizeof(struct ip_set_req_setnames));
+ while (size + ALIGNED(sizeof(struct ip_set_name_list)) <= req_size) {
name_list = (struct ip_set_name_list *)
(data + size);
set = ipset_malloc(sizeof(struct set));
@@ -1111,9 +1099,9 @@ tryagain:
set_list[name_list->index] = set;
DP("loaded %s, type %s, index %u",
set->name, set->settype->typename, set->index);
- size += sizeof(struct ip_set_name_list);
+ size += ALIGNED(sizeof(struct ip_set_name_list));
}
- /* Size to get set members, bindings */
+ /* Size to get set members */
size = ((struct ip_set_req_setnames *)data)->size;
free(data);
@@ -1123,36 +1111,7 @@ tryagain:
/*
* Save operation
*/
-static size_t save_bindings(void *data, size_t offset, size_t len)
-{
- struct ip_set_hash_save *hash =
- (struct ip_set_hash_save *) (data + offset);
- struct set *set;
-
- DP("offset %u, len %u", offset, len);
- if (offset + sizeof(struct ip_set_hash_save) > len)
- exit_error(OTHER_PROBLEM,
- "Save operation failed, try again later.");
-
- set = set_find_byid(hash->id);
- if (!(set && set_list[hash->binding]))
- exit_error(OTHER_PROBLEM,
- "Save binding failed, try again later.");
- if (!set->settype->bindip_tostring)
- exit_error(OTHER_PROBLEM,
- "Internal error, binding is not supported with set %s"
- " of settype %s\n",
- set->name, set->settype->typename);
- printf("-B %s %s -b %s\n",
- set->name,
- set->settype->bindip_tostring(set, hash->ip, OPT_NUMERIC),
- set_list[hash->binding]->name);
-
- return sizeof(struct ip_set_hash_save);
-}
-
-static size_t save_set(void *data, int *bindings,
- size_t offset, size_t len)
+static size_t save_set(void *data, size_t offset, size_t len)
{
struct ip_set_save *set_save =
(struct ip_set_save *) (data + offset);
@@ -1160,12 +1119,12 @@ static size_t save_set(void *data, int *bindings,
struct settype *settype;
size_t used;
- DP("offset %u (%u/%u/%u), len %u", offset,
+ DP("offset %zu (%zu/%u/%u), len %zu", offset,
sizeof(struct ip_set_save),
set_save->header_size, set_save->members_size,
len);
- if (offset + sizeof(struct ip_set_save) > len
- || offset + sizeof(struct ip_set_save)
+ if (offset + ALIGNED(sizeof(struct ip_set_save)) > len
+ || offset + ALIGNED(sizeof(struct ip_set_save))
+ set_save->header_size + set_save->members_size > len)
exit_error(OTHER_PROBLEM,
"Save operation failed, try again later.");
@@ -1173,8 +1132,7 @@ static size_t save_set(void *data, int *bindings,
DP("index: %u", set_save->index);
if (set_save->index == IP_SET_INVALID_ID) {
/* Marker */
- *bindings = 1;
- return sizeof(struct ip_set_save);
+ return ALIGNED(sizeof(struct ip_set_save));
}
set = set_list[set_save->index];
if (!set)
@@ -1183,7 +1141,7 @@ static size_t save_set(void *data, int *bindings,
settype = set->settype;
/* Init set header */
- used = sizeof(struct ip_set_save);
+ used = ALIGNED(sizeof(struct ip_set_save));
settype->initheader(set, data + offset + used);
/* Print create set */
@@ -1192,44 +1150,18 @@ static size_t save_set(void *data, int *bindings,
/* Print add IPs */
used += set_save->header_size;
settype->saveips(set, data + offset + used,
- set_save->members_size, OPT_NUMERIC);
+ set_save->members_size, OPT_NUMERIC,
+ DONT_ALIGN);
return (used + set_save->members_size);
}
-static size_t save_default_bindings(void *data, int *bindings)
-{
- struct ip_set_save *set_save = (struct ip_set_save *) data;
- struct set *set;
-
- if (set_save->index == IP_SET_INVALID_ID) {
- /* Marker */
- *bindings = 1;
- return sizeof(struct ip_set_save);
- }
-
- set = set_list[set_save->index];
- DP("%s, binding %u", set->name, set_save->binding);
- if (set_save->binding != IP_SET_INVALID_ID) {
- if (!set_list[set_save->binding])
- exit_error(OTHER_PROBLEM,
- "Save set failed, try again later.");
-
- printf("-B %s %s -b %s\n",
- set->name, IPSET_TOKEN_DEFAULT,
- set_list[set_save->binding]->name);
- }
- return (sizeof(struct ip_set_save)
- + set_save->header_size
- + set_save->members_size);
-}
-
static int try_save_sets(const char name[IP_SET_MAXNAMELEN])
{
void *data = NULL;
socklen_t size, req_size = 0;
ip_set_id_t idx;
- int res = 0, bindings = 0;
+ int res = 0;
time_t now = time(NULL);
/* Load set_list from kernel */
@@ -1237,15 +1169,17 @@ static int try_save_sets(const char name[IP_SET_MAXNAMELEN])
IP_SET_OP_SAVE_SIZE, CMD_SAVE);
if (size) {
- /* Get sets, bindings and print them */
+ /* Get sets and print them */
/* Take into account marker */
- req_size = (size += sizeof(struct ip_set_save));
+ req_size = (size += ALIGNED(sizeof(struct ip_set_save)));
data = ipset_malloc(size);
((struct ip_set_req_list *) data)->op = IP_SET_OP_SAVE;
((struct ip_set_req_list *) data)->index = idx;
res = kernel_getfrom_handleerrno(CMD_SAVE, data, &size);
if (res != 0 || size != req_size) {
+ DP("Try again: res: %i, size %u, req_size: %u",
+ res, size, req_size);
free(data);
return -EAGAIN;
}
@@ -1255,17 +1189,8 @@ static int try_save_sets(const char name[IP_SET_MAXNAMELEN])
size = 0;
while (size < req_size) {
DP("size: %u, req_size: %u", size, req_size);
- if (bindings)
- size += save_bindings(data, size, req_size);
- else
- size += save_set(data, &bindings, size, req_size);
+ size += save_set(data, size, req_size);
}
- /* Re-read data to save default bindings */
- bindings = 0;
- size = 0;
- while (size < req_size && bindings == 0)
- size += save_default_bindings(data + size, &bindings);
-
printf("COMMIT\n");
now = time(NULL);
printf("# Completed on %s", ctime(&now));
@@ -1363,7 +1288,7 @@ static void set_restore(char *argv0)
char buffer[1024];
char *ptr, *name = NULL;
char cmd = ' ';
- int first_pass, i, bindings = 0;
+ int first_pass, i;
struct settype *settype = NULL;
struct ip_set_req_setnames *header;
ip_set_id_t idx;
@@ -1378,8 +1303,7 @@ static void set_restore(char *argv0)
IP_SET_OP_LIST_SIZE, CMD_RESTORE);
restore_line = 0;
- restore_size = sizeof(struct ip_set_req_setnames)/* header */
- + sizeof(struct ip_set_restore); /* marker */
+ restore_size = ALIGNED(sizeof(struct ip_set_req_setnames)); /* header */
DP("restore_size: %u", restore_size);
/* First pass: calculate required amount of data */
while (fgets(buffer, sizeof(buffer), in)) {
@@ -1426,13 +1350,9 @@ static void set_restore(char *argv0)
exit_error(PARAMETER_PROBLEM,
"Missing settype in line %u\n",
restore_line);
- if (bindings)
- exit_error(PARAMETER_PROBLEM,
- "Invalid line %u: create must precede bindings\n",
- restore_line);
settype = check_set_typename(ptr);
- restore_size += sizeof(struct ip_set_restore)
- + settype->create_size;
+ restore_size += ALIGNED(sizeof(struct ip_set_restore))
+ + ALIGNED(settype->create_size);
DP("restore_size (N): %u", restore_size);
break;
}
@@ -1443,20 +1363,10 @@ static void set_restore(char *argv0)
"Add IP to set %s in line %u without "
"preceding corresponding create set line\n",
ptr, restore_line);
- if (bindings)
- exit_error(PARAMETER_PROBLEM,
- "Invalid line %u: adding entries must precede bindings\n",
- restore_line);
- restore_size += settype->adt_size;
+ restore_size += ALIGNED(settype->adt_size);
DP("restore_size (A): %u", restore_size);
break;
}
- case 'B': {
- bindings = 1;
- restore_size += sizeof(struct ip_set_hash_save);
- DP("restore_size (B): %u", restore_size);
- break;
- }
default: {
exit_error(PARAMETER_PROBLEM,
"Unrecognized restore command in line %u\n",
@@ -1468,12 +1378,13 @@ static void set_restore(char *argv0)
if (!restore)
exit_error(PARAMETER_PROBLEM,
"Missing COMMIT line\n");
+ restore_size += ALIGNED(sizeof(struct ip_set_restore)); /* marker */
DP("restore_size: %u", restore_size);
restore_data = ipset_malloc(restore_size);
header = (struct ip_set_req_setnames *) restore_data;
header->op = IP_SET_OP_RESTORE;
header->size = restore_size;
- restore_offset = sizeof(struct ip_set_req_setnames);
+ restore_offset = ALIGNED(sizeof(struct ip_set_req_setnames));
/* Rewind to scan the file again */
fseek(in, 0L, SEEK_SET);
@@ -1505,17 +1416,15 @@ static void set_restore(char *argv0)
exit_error(PARAMETER_PROBLEM,
"Broken restore file\n");
do_restore:
- if (bindings == 0
- && restore_size ==
- (restore_offset + sizeof(struct ip_set_restore))) {
+ if (restore_size == (restore_offset + ALIGNED(sizeof(struct ip_set_restore)))) {
/* No bindings */
struct ip_set_restore *marker =
(struct ip_set_restore *) (restore_data + restore_offset);
- DP("restore marker");
marker->index = IP_SET_INVALID_ID;
marker->header_size = marker->members_size = 0;
- restore_offset += sizeof(struct ip_set_restore);
+ restore_offset += ALIGNED(sizeof(struct ip_set_restore));
+ DP("restore marker, restore_offset: %zu", restore_offset);
}
if (restore_size != restore_offset)
exit_error(PARAMETER_PROBLEM,
@@ -1547,8 +1456,10 @@ static struct set *set_adt_get(const char *name)
DP("%s", name);
+ check_protocolversion();
+
req_adt_get.op = IP_SET_OP_ADT_GET;
- req_adt_get.version = IP_SET_PROTOCOL_VERSION;
+ req_adt_get.version = protocol_version;
strcpy(req_adt_get.set.name, name);
size = sizeof(struct ip_set_req_adt_get);
@@ -1576,15 +1487,15 @@ static int set_adtip(struct set *set, const char *adt,
DP("%s -> %s", set->name, adt);
/* Alloc memory for the data to send */
- size = sizeof(struct ip_set_req_adt) + set->settype->adt_size ;
- DP("alloc size %d", size);
+ size = ALIGNED(sizeof(struct ip_set_req_adt)) + set->settype->adt_size ;
+ DP("alloc size %zu", size);
data = ipset_malloc(size);
/* Fill out the request */
req_adt = (struct ip_set_req_adt *) data;
req_adt->op = op;
req_adt->index = set->index;
- memcpy(data + sizeof(struct ip_set_req_adt),
+ memcpy(data + ALIGNED(sizeof(struct ip_set_req_adt)),
set->settype->data, set->settype->adt_size);
if (kernel_sendto_handleerrno(cmd, data, size) == -1)
@@ -1622,155 +1533,22 @@ static void set_restore_add(struct set *set, const char *adt UNUSED)
{
DP("%s %s", set->name, adt);
/* Sanity checking */
- if (restore_offset + set->settype->adt_size > restore_size)
+ if (restore_offset + ALIGNED(set->settype->adt_size) > restore_size)
exit_error(PARAMETER_PROBLEM,
"Giving up, restore file is screwed up!");
memcpy(restore_data + restore_offset,
set->settype->data, set->settype->adt_size);
- restore_set->members_size += set->settype->adt_size;
- restore_offset += set->settype->adt_size;
-}
+ restore_set->members_size += ALIGNED(set->settype->adt_size);
+ restore_offset += ALIGNED(set->settype->adt_size);
-/*
- * Send bind/unbind/test binding order to kernel for a set
- */
-static int set_bind(struct set *set, const char *adt,
- const char *binding,
- unsigned op, unsigned cmd)
-{
- struct ip_set_req_bind *req_bind;
- size_t size;
- void *data;
- int res = 0;
-
- /* set may be null: '-U :all: :all:|:default:' */
- DP("(%s, %s) -> %s", set ? set->name : IPSET_TOKEN_ALL, adt, binding);
-
- /* Ugly */
- if (set != NULL
- && ((strcmp(set->settype->typename, "iptreemap") == 0)
- || (strcmp(set->settype->typename, "ipportiphash") == 0)
- || (strcmp(set->settype->typename, "ipportnethash") == 0)
- || (strcmp(set->settype->typename, "setlist") == 0)))
- exit_error(PARAMETER_PROBLEM,
- "%s type of sets cannot be used at binding operations\n",
- set->settype->typename);
- /* Alloc memory for the data to send */
- size = sizeof(struct ip_set_req_bind);
- if (op != IP_SET_OP_UNBIND_SET && adt[0] == ':')
- /* Set default binding */
- size += IP_SET_MAXNAMELEN;
- else if (!(op == IP_SET_OP_UNBIND_SET && set == NULL))
- size += set->settype->adt_size;
- DP("alloc size %d", size);
- data = ipset_malloc(size);
-
- /* Fill out the request */
- req_bind = (struct ip_set_req_bind *) data;
- req_bind->op = op;
- req_bind->index = set ? set->index : IP_SET_INVALID_ID;
- if (adt[0] == ':') {
- /* ':default:' and ':all:' */
- strncpy(req_bind->binding, adt, IP_SET_MAXNAMELEN);
- if (op != IP_SET_OP_UNBIND_SET && adt[0] == ':')
- strncpy(data + sizeof(struct ip_set_req_bind),
- binding, IP_SET_MAXNAMELEN);
- } else {
- strncpy(req_bind->binding, binding, IP_SET_MAXNAMELEN);
- memcpy(data + sizeof(struct ip_set_req_bind),
- set->settype->data, set->settype->adt_size);
- }
-
- if (op == IP_SET_OP_TEST_BIND_SET) {
- if (kernel_sendto_handleerrno(cmd, data, size) == -1) {
- ipset_printf("%s in set %s is bound to %s.",
- adt, set->name, binding);
- res = 0;
- } else {
- ipset_printf("%s in set %s is NOT bound to %s.",
- adt, set->name, binding);
- res = 1;
- }
- } else
- kernel_sendto(cmd, data, size);
- free(data);
-
- return res;
-}
-
-static void set_restore_bind(struct set *set,
- const char *adt,
- const char *binding)
-{
- struct ip_set_hash_save *hash_restore;
-
- if (restore == 1) {
- /* Marker */
- struct ip_set_restore *marker =
- (struct ip_set_restore *) (restore_data + restore_offset);
-
- DP("restore marker");
- if (restore_offset + sizeof(struct ip_set_restore)
- > restore_size)
- exit_error(PARAMETER_PROBLEM,
- "Giving up, restore file is screwed up!");
- marker->index = IP_SET_INVALID_ID;
- marker->header_size = marker->members_size = 0;
- restore_offset += sizeof(struct ip_set_restore);
- restore = 2;
- }
- /* Sanity checking */
- if (restore_offset + sizeof(struct ip_set_hash_save) > restore_size)
- exit_error(PARAMETER_PROBLEM,
- "Giving up, restore file is screwed up!");
-
- hash_restore = (struct ip_set_hash_save *) (restore_data + restore_offset);
- DP("%s -> %s", adt, binding);
- if (strcmp(adt, IPSET_TOKEN_DEFAULT) == 0)
- hash_restore->ip = 0;
- else {
- if (!set->settype->bindip_parse)
- exit_error(OTHER_PROBLEM,
- "Internal error, binding is not supported with set %s"
- " of settype %s\n",
- set->name, set->settype->typename);
- set->settype->bindip_parse(adt, &hash_restore->ip);
- }
- hash_restore->id = set->index;
- hash_restore->binding = (set_find_byname(binding))->index;
- DP("id %u, ip %u, binding %u",
- hash_restore->id, hash_restore->ip, hash_restore->binding);
- restore_offset += sizeof(struct ip_set_hash_save);
+ DP("restore_offset: %zu", restore_offset);
}
/*
* Print operation
*/
-static void print_bindings(struct set *set,
- void *data, size_t size, unsigned options,
- char * (*printip)(struct set *set,
- ip_set_ip_t ip, unsigned options))
-{
- size_t offset = 0;
- struct ip_set_hash_list *hash;
-
- if (offset < size && !printip)
- exit_error(OTHER_PROBLEM,
- "Internal error, binding is not supported with set %s"
- " of settype %s\n",
- set->name, set->settype->typename);
-
- while (offset < size) {
- hash = (struct ip_set_hash_list *) (data + offset);
- printf("%s -> %s\n",
- printip(set, hash->ip, options),
- set_list[hash->binding]->name);
- offset += sizeof(struct ip_set_hash_list);
- }
-}
-
/* Help function to set_list() */
static size_t print_set(void *data, unsigned options)
{
@@ -1780,15 +1558,14 @@ static size_t print_set(void *data, unsigned options)
size_t offset;
/* Pretty print the set */
+ DP("header size: %u, members size: %u",
+ setlist->header_size, setlist->members_size);
printf("Name: %s\n", set->name);
printf("Type: %s\n", settype->typename);
printf("References: %d\n", setlist->ref);
- printf("Default binding: %s\n",
- setlist->binding == IP_SET_INVALID_ID ? ""
- : set_list[setlist->binding]->name);
/* Init header */
- offset = sizeof(struct ip_set_list);
+ offset = ALIGNED(sizeof(struct ip_set_list));
settype->initheader(set, data + offset);
/* Pretty print the type header */
@@ -1798,24 +1575,20 @@ static size_t print_set(void *data, unsigned options)
/* Pretty print all IPs */
printf("Members:\n");
offset += setlist->header_size;
+ DP("Aligned: %u, offset: %zu, members_size %u\n", !DONT_ALIGN, offset,
+ setlist->members_size);
if (options & OPT_SORTED)
settype->printips_sorted(set, data + offset,
- setlist->members_size, options);
+ setlist->members_size, options,
+ DONT_ALIGN);
else
settype->printips(set, data + offset,
- setlist->members_size, options);
-
- /* Print bindings */
- printf("Bindings:\n");
- offset += setlist->members_size;
- if (set->settype->bindip_tostring)
- print_bindings(set,
- data + offset, setlist->bindings_size, options,
- settype->bindip_tostring);
+ setlist->members_size, options,
+ DONT_ALIGN);
printf("\n"); /* One newline between sets */
- return (offset + setlist->bindings_size);
+ return (offset + setlist->members_size);
}
static int try_list_sets(const char name[IP_SET_MAXNAMELEN],
@@ -1886,9 +1659,9 @@ static void set_help(const struct settype *settype)
"Usage: %s -N new-set settype [options]\n"
" %s -[XFLSH] [set] [options]\n"
" %s -[EW] from-set to-set\n"
- " %s -[ADTU] set IP\n"
- " %s -B set IP option\n"
+ " %s -[ADT] set IP\n"
" %s -R\n"
+ " %s -v\n"
" %s -h (print this help information)\n\n",
program_name, program_version,
program_name, program_name, program_name,
@@ -1919,13 +1692,6 @@ static void set_help(const struct settype *settype)
" Deletes an IP from a set\n"
" --test -T setname IP \n"
" Tests if an IP exists in a set.\n"
- " --bind -B setname IP|:default: -b bind-setname\n"
- " Bind the IP in setname to bind-setname.\n"
- " --unbind -U setname IP|:all:|:default:\n"
- " Delete binding belonging to IP,\n"
- " all bindings or default binding of setname.\n"
- " --unbind -U :all: :all:|:default:\n"
- " Delete all bindings or all default bindings.\n"
" --help -H [settype]\n"
" Prints this help, and settype specific help\n"
" --version -V\n"
@@ -1934,8 +1700,7 @@ static void set_help(const struct settype *settype)
" --sorted -s Numeric sort of the IPs in -L\n"
" --numeric -n Numeric output of addresses in a -L (default)\n"
" --resolve -r Try to resolve addresses in a -L\n"
- " --quiet -q Suppress any output to stdout and stderr.\n"
- " --binding -b Specifies the binding for -B\n");
+ " --quiet -q Suppress any output to stdout and stderr.\n");
#ifdef IPSET_DEBUG
printf(" --debug -z Enable debugging\n\n");
#else
@@ -1967,40 +1732,13 @@ static int parse_adt_cmdline(int command,
{
int res = 0;
- /* -U :all: :all:|:default: */
- if (command == CMD_UNBIND) {
- if (strcmp(name, IPSET_TOKEN_ALL) == 0) {
- if (strcmp(adt, IPSET_TOKEN_DEFAULT) == 0
- || strcmp(adt, IPSET_TOKEN_ALL) == 0) {
- *set = NULL;
- *settype = NULL;
- return 1;
- } else
- exit_error(PARAMETER_PROBLEM,
- "-U %s requires %s or %s as binding name",
- IPSET_TOKEN_ALL,
- IPSET_TOKEN_DEFAULT,
- IPSET_TOKEN_ALL);
- }
- }
- *set = restore ? set_find_byname(name)
- : set_adt_get(name);
+ *set = restore ? set_find_byname(name) : set_adt_get(name);
/* Reset space for adt data */
*settype = (*set)->settype;
memset((*settype)->data, 0, (*settype)->adt_size);
- if ((command == CMD_TEST
- || command == CMD_BIND
- || command == CMD_UNBIND)
- && (strcmp(adt, IPSET_TOKEN_DEFAULT) == 0
- || strcmp(adt, IPSET_TOKEN_ALL) == 0))
- res = 1;
- else
- res = (*settype)->adt_parser(
- command,
- adt,
- (*settype)->data);
+ res = (*settype)->adt_parser(command, adt, (*settype)->data);
return res;
}
@@ -2015,9 +1753,8 @@ int parse_commandline(int argc, char *argv[])
char *name = NULL; /* All except -H, -R */
char *newname = NULL; /* -E, -W */
- char *adt = NULL; /* -A, -D, -T, -B, -U */
- char *binding = NULL; /* -B */
- struct set *set = NULL; /* -A, -D, -T, -B, -U */
+ char *adt = NULL; /* -A, -D, -T */
+ struct set *set = NULL; /* -A, -D, -T */
struct settype *settype = NULL; /* -N, -H */
char all_sets[] = IPSET_TOKEN_ALL;
@@ -2051,11 +1788,14 @@ int parse_commandline(int argc, char *argv[])
break;
}
- case 'V':{ /* Version */
- printf("%s v%s Protocol version %u.\n",
+ case 'V':
+ case 'v': { /* Version */
+ printf("%s v%s, protocol version %u.\n",
program_name, program_version,
IP_SET_PROTOCOL_VERSION);
check_protocolversion();
+ printf("Kernel module protocol version %u.\n",
+ protocol_version);
exit(0);
}
@@ -2064,7 +1804,7 @@ int parse_commandline(int argc, char *argv[])
name = check_set_name(optarg);
- /* Protect reserved names (binding) */
+ /* Protect reserved names */
if (name[0] == ':')
exit_error(PARAMETER_PROBLEM,
"setname might not start with colon",
@@ -2139,9 +1879,7 @@ int parse_commandline(int argc, char *argv[])
case 'A': /* Add IP */
case 'D': /* Del IP */
- case 'T': /* Test IP */
- case 'B': /* Bind IP */
- case 'U':{ /* Unbind IP */
+ case 'T':{ /* Test IP */
set_command(&command, find_cmd(c));
name = check_set_name(optarg);
@@ -2194,11 +1932,6 @@ int parse_commandline(int argc, char *argv[])
break;
#endif
- case 'b':
- add_option(&options, OPT_BINDING);
- binding = check_set_name(optarg);
- break;
-
case 1: /* non option */
printf("Bad argument `%s'\n", optarg);
exit_tryhelp(PARAMETER_PROBLEM);
@@ -2245,6 +1978,8 @@ int parse_commandline(int argc, char *argv[])
generic_opt_check(command, options);
DP("cmd: %c", cmd2char(command));
+
+ check_protocolversion();
switch (command) {
case CMD_CREATE:
@@ -2295,26 +2030,7 @@ int parse_commandline(int argc, char *argv[])
break;
case CMD_TEST:
- if (binding)
- res = set_bind(set, adt, binding,
- IP_SET_OP_TEST_BIND_SET, CMD_TEST);
- else
- res = set_adtip(set, adt,
- IP_SET_OP_TEST_IP, CMD_TEST);
- break;
-
- case CMD_BIND:
- fprintf(stderr, "Warning: binding will be removed from the next release.\n"
- "Please replace bindigs with sets of ipportmap and ipportiphash types\n");
- if (restore)
- set_restore_bind(set, adt, binding);
- else
- set_bind(set, adt, binding,
- IP_SET_OP_BIND_SET, CMD_BIND);
- break;
-
- case CMD_UNBIND:
- set_bind(set, adt, "", IP_SET_OP_UNBIND_SET, CMD_UNBIND);
+ res = set_adtip(set, adt, IP_SET_OP_TEST_IP, CMD_TEST);
break;
case CMD_HELP:
diff --git a/ipset.h b/ipset.h
index e47a480..c49418d 100644
--- a/ipset.h
+++ b/ipset.h
@@ -56,8 +56,6 @@ enum set_commands {
CMD_ADD, /* -A */
CMD_DEL, /* -D */
CMD_TEST, /* -T */
- CMD_BIND, /* -B */
- CMD_UNBIND, /* -U */
CMD_HELP, /* -H */
CMD_VERSION, /* -V */
NUMBER_OF_CMD = CMD_VERSION,
@@ -134,22 +132,19 @@ struct settype {
void (*printheader) (struct set *set, unsigned options);
/* Pretty print all IPs */
- void (*printips) (struct set *set, void *data, u_int32_t len, unsigned options);
+ void (*printips) (struct set *set, void *data, u_int32_t len,
+ unsigned options, char dont_align);
/* Pretty print all IPs sorted */
- void (*printips_sorted) (struct set *set, void *data, u_int32_t len, unsigned options);
+ void (*printips_sorted) (struct set *set, void *data, u_int32_t len,
+ unsigned options, char dont_align);
/* Print save arguments for creating the set */
void (*saveheader) (struct set *set, unsigned options);
/* Print save for all IPs */
- void (*saveips) (struct set *set, void *data, u_int32_t len, unsigned options);
-
- /* Conver a single IP (binding) to string */
- char * (*bindip_tostring)(struct set *set, ip_set_ip_t ip, unsigned options);
-
- /* Parse an IP at restoring bindings. FIXME */
- void (*bindip_parse) (const char *str, ip_set_ip_t * ip);
+ void (*saveips) (struct set *set, void *data, u_int32_t len,
+ unsigned options, char dont_align);
/* Print usage */
void (*usage) (void);
@@ -189,12 +184,12 @@ extern struct set *set_find_byid(ip_set_id_t id);
extern unsigned warn_once;
-#define BITS_PER_LONG (8*sizeof(unsigned long))
+#define BITS_PER_LONG (8*sizeof(ip_set_ip_t))
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
-static inline int test_bit(int nr, const unsigned long *addr)
+static inline int test_bit(int nr, const ip_set_ip_t *addr)
{
- return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
+ return 1 & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
}
#define UNUSED __attribute__ ((unused))
diff --git a/ipset_iphash.c b/ipset_iphash.c
index dc9c89b..b352df4 100644
--- a/ipset_iphash.c
+++ b/ipset_iphash.c
@@ -32,7 +32,7 @@
/* Initialize the create. */
static void
-create_init(void *data)
+iphash_create_init(void *data)
{
struct ip_set_req_iphash_create *mydata = data;
@@ -48,7 +48,7 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */
static int
-create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
+iphash_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
{
struct ip_set_req_iphash_create *mydata =
(struct ip_set_req_iphash_create *) data;
@@ -117,7 +117,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */
static void
-create_final(void *data UNUSED, unsigned int flags UNUSED)
+iphash_create_final(void *data UNUSED, unsigned int flags UNUSED)
{
}
@@ -132,7 +132,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */
static ip_set_ip_t
-adt_parser(int cmd UNUSED, const char *arg, void *data)
+iphash_adt_parser(int cmd UNUSED, const char *arg, void *data)
{
struct ip_set_req_iphash *mydata = data;
@@ -149,7 +149,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/
static void
-initheader(struct set *set, const void *data)
+iphash_initheader(struct set *set, const void *data)
{
const struct ip_set_req_iphash_create *header = data;
struct ip_set_iphash *map = set->settype->header;
@@ -178,7 +178,7 @@ mask_to_bits(ip_set_ip_t mask)
}
static void
-printheader(struct set *set, unsigned options UNUSED)
+iphash_printheader(struct set *set, unsigned options UNUSED)
{
struct ip_set_iphash *mysetdata = set->settype->header;
@@ -192,7 +192,8 @@ printheader(struct set *set, unsigned options UNUSED)
}
static void
-printips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
+iphash_printips(struct set *set UNUSED, void *data, u_int32_t len,
+ unsigned options, char dont_align)
{
size_t offset = 0;
ip_set_ip_t *ip;
@@ -201,12 +202,12 @@ printips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
ip = data + offset;
if (*ip)
printf("%s\n", ip_tostring(*ip, options));
- offset += sizeof(ip_set_ip_t);
+ offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
}
}
static void
-saveheader(struct set *set, unsigned options UNUSED)
+iphash_saveheader(struct set *set, unsigned options UNUSED)
{
struct ip_set_iphash *mysetdata = set->settype->header;
@@ -221,7 +222,8 @@ saveheader(struct set *set, unsigned options UNUSED)
/* Print save for an IP */
static void
-saveips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
+iphash_saveips(struct set *set UNUSED, void *data, u_int32_t len,
+ unsigned options, char dont_align)
{
size_t offset = 0;
ip_set_ip_t *ip;
@@ -231,11 +233,12 @@ saveips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
if (*ip)
printf("-A %s %s\n", set->name,
ip_tostring(*ip, options));
- offset += sizeof(ip_set_ip_t);
+ offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
}
}
-static void usage(void)
+static void
+iphash_usage(void)
{
printf
("-N set iphash [--hashsize hashsize] [--probes probes ]\n"
@@ -251,29 +254,25 @@ static struct settype settype_iphash = {
/* Create */
.create_size = sizeof(struct ip_set_req_iphash_create),
- .create_init = &create_init,
- .create_parse = &create_parse,
- .create_final = &create_final,
+ .create_init = iphash_create_init,
+ .create_parse = iphash_create_parse,
+ .create_final = iphash_create_final,
.create_opts = create_opts,
/* Add/del/test */
.adt_size = sizeof(struct ip_set_req_iphash),
- .adt_parser = &adt_parser,
+ .adt_parser = iphash_adt_parser,
/* Printing */
.header_size = sizeof(struct ip_set_iphash),
- .initheader = &initheader,
- .printheader = &printheader,
- .printips = &printips, /* We only have the unsorted version */
- .printips_sorted = &printips,
- .saveheader = &saveheader,
- .saveips = &saveips,
-
- /* Bindings */
- .bindip_tostring = &binding_ip_tostring,
- .bindip_parse = &parse_ip,
+ .initheader = iphash_initheader,
+ .printheader = iphash_printheader,
+ .printips = iphash_printips,
+ .printips_sorted = iphash_printips,
+ .saveheader = iphash_saveheader,
+ .saveips = iphash_saveips,
- .usage = &usage,
+ .usage = iphash_usage,
};
CONSTRUCTOR(iphash)
diff --git a/ipset_ipmap.c b/ipset_ipmap.c
index 992a862..87b8e69 100644
--- a/ipset_ipmap.c
+++ b/ipset_ipmap.c
@@ -35,7 +35,7 @@
/* Initialize the create. */
static void
-create_init(void *data)
+ipmap_create_init(void *data)
{
struct ip_set_req_ipmap_create *mydata = data;
@@ -45,7 +45,7 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */
static int
-create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
+ipmap_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
{
struct ip_set_req_ipmap_create *mydata = data;
unsigned int bits;
@@ -115,7 +115,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */
static void
-create_final(void *data, unsigned int flags)
+ipmap_create_final(void *data, unsigned int flags)
{
struct ip_set_req_ipmap_create *mydata = data;
ip_set_ip_t range;
@@ -188,7 +188,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */
static ip_set_ip_t
-adt_parser(int cmd UNUSED, const char *arg, void *data)
+ipmap_adt_parser(int cmd UNUSED, const char *arg, void *data)
{
struct ip_set_req_ipmap *mydata = data;
@@ -205,7 +205,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/
static void
-initheader(struct set *set, const void *data)
+ipmap_initheader(struct set *set, const void *data)
{
const struct ip_set_req_ipmap_create *header = data;
struct ip_set_ipmap *map = set->settype->header;
@@ -234,7 +234,7 @@ initheader(struct set *set, const void *data)
}
static void
-printheader(struct set *set, unsigned options)
+ipmap_printheader(struct set *set, unsigned options)
{
struct ip_set_ipmap *mysetdata = set->settype->header;
@@ -246,9 +246,9 @@ printheader(struct set *set, unsigned options)
printf(" netmask: %d\n", mask_to_bits(mysetdata->netmask));
}
-static void
-printips_sorted(struct set *set, void *data,
- u_int32_t len UNUSED, unsigned options)
+static inline void
+__ipmap_printips_sorted(struct set *set, void *data,
+ u_int32_t len UNUSED, unsigned options)
{
struct ip_set_ipmap *mysetdata = set->settype->header;
ip_set_ip_t id;
@@ -262,7 +262,26 @@ printips_sorted(struct set *set, void *data,
}
static void
-saveheader(struct set *set, unsigned options)
+ipmap_printips_sorted(struct set *set, void *data,
+ u_int32_t len, unsigned options,
+ char dont_align)
+{
+ ip_set_ip_t *ip;
+ size_t offset = 0;
+
+ if (dont_align)
+ return __ipmap_printips_sorted(set, data, len, options);
+
+ while (offset < len) {
+ DP("offset: %zu, len %u\n", offset, len);
+ ip = data + offset;
+ printf("%s\n", ip_tostring(*ip, options));
+ offset += IPSET_ALIGN(sizeof(ip_set_ip_t));
+ }
+}
+
+static void
+ipmap_saveheader(struct set *set, unsigned options)
{
struct ip_set_ipmap *mysetdata = set->settype->header;
@@ -278,8 +297,9 @@ saveheader(struct set *set, unsigned options)
mask_to_bits(mysetdata->netmask));
}
-static void
-saveips(struct set *set, void *data, u_int32_t len UNUSED, unsigned options)
+static inline void
+__ipmap_saveips(struct set *set, void *data, u_int32_t len UNUSED,
+ unsigned options)
{
struct ip_set_ipmap *mysetdata = set->settype->header;
ip_set_ip_t id;
@@ -294,7 +314,25 @@ saveips(struct set *set, void *data, u_int32_t len UNUSED, unsigned options)
options));
}
-static void usage(void)
+static void
+ipmap_saveips(struct set *set, void *data, u_int32_t len,
+ unsigned options, char dont_align)
+{
+ ip_set_ip_t *ip;
+ size_t offset = 0;
+
+ if (dont_align)
+ return __ipmap_saveips(set, data, len, options);
+
+ while (offset < len) {
+ ip = data + offset;
+ printf("-A %s %s\n", set->name, ip_tostring(*ip, options));
+ offset += IPSET_ALIGN(sizeof(ip_set_ip_t));
+ }
+}
+
+static void
+ipmap_usage(void)
{
printf
("-N set ipmap --from IP --to IP [--netmask CIDR-netmask]\n"
@@ -310,29 +348,25 @@ static struct settype settype_ipmap = {
/* Create */
.create_size = sizeof(struct ip_set_req_ipmap_create),
- .create_init = &create_init,
- .create_parse = &create_parse,
- .create_final = &create_final,
+ .create_init = ipmap_create_init,
+ .create_parse = ipmap_create_parse,
+ .create_final = ipmap_create_final,
.create_opts = create_opts,
/* Add/del/test */
.adt_size = sizeof(struct ip_set_req_ipmap),
- .adt_parser = &adt_parser,
+ .adt_parser = ipmap_adt_parser,
/* Printing */
.header_size = sizeof(struct ip_set_ipmap),
- .initheader = &initheader,
- .printheader = &printheader,
- .printips = &printips_sorted, /* We only have sorted version */
- .printips_sorted = &printips_sorted,
- .saveheader = &saveheader,
- .saveips = &saveips,
+ .initheader = ipmap_initheader,
+ .printheader = ipmap_printheader,
+ .printips = ipmap_printips_sorted,
+ .printips_sorted = ipmap_printips_sorted,
+ .saveheader = ipmap_saveheader,
+ .saveips = ipmap_saveips,
- /* Bindings */
- .bindip_tostring = &binding_ip_tostring,
- .bindip_parse = &parse_ip,
-
- .usage = &usage,
+ .usage = ipmap_usage,
};
CONSTRUCTOR(ipmap)
diff --git a/ipset_ipporthash.c b/ipset_ipporthash.c
index 0073988..ce783ee 100644
--- a/ipset_ipporthash.c
+++ b/ipset_ipporthash.c
@@ -32,7 +32,7 @@
/* Initialize the create. */
static void
-create_init(void *data)
+ipporthash_create_init(void *data)
{
struct ip_set_req_ipporthash_create *mydata = data;
@@ -46,7 +46,8 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */
static int
-create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
+ipporthash_create_parse(int c, char *argv[] UNUSED, void *data,
+ unsigned *flags)
{
struct ip_set_req_ipporthash_create *mydata = data;
ip_set_ip_t value;
@@ -137,7 +138,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */
static void
-create_final(void *data, unsigned int flags)
+ipporthash_create_final(void *data, unsigned int flags)
{
struct ip_set_req_ipporthash_create *mydata = data;
@@ -189,7 +190,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */
static ip_set_ip_t
-adt_parser(int cmd UNUSED, const char *arg, void *data)
+ipporthash_adt_parser(int cmd UNUSED, const char *arg, void *data)
{
struct ip_set_req_ipporthash *mydata = data;
char *saved = ipset_strdup(arg);
@@ -222,7 +223,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/
static void
-initheader(struct set *set, const void *data)
+ipporthash_initheader(struct set *set, const void *data)
{
const struct ip_set_req_ipporthash_create *header = data;
struct ip_set_ipporthash *map = set->settype->header;
@@ -236,7 +237,7 @@ initheader(struct set *set, const void *data)
}
static void
-printheader(struct set *set, unsigned options)
+ipporthash_printheader(struct set *set, unsigned options)
{
struct ip_set_ipporthash *mysetdata = set->settype->header;
@@ -248,7 +249,8 @@ printheader(struct set *set, unsigned options)
}
static void
-printips(struct set *set, void *data, u_int32_t len, unsigned options)
+ipporthash_printips(struct set *set, void *data, u_int32_t len,
+ unsigned options, char dont_align)
{
struct ip_set_ipporthash *mysetdata = set->settype->header;
size_t offset = 0;
@@ -264,12 +266,12 @@ printips(struct set *set, void *data, u_int32_t len, unsigned options)
ip_tostring(ip, options),
port_tostring(port, options));
}
- offset += sizeof(ip_set_ip_t);
+ offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
}
}
static void
-saveheader(struct set *set, unsigned options)
+ipporthash_saveheader(struct set *set, unsigned options)
{
struct ip_set_ipporthash *mysetdata = set->settype->header;
@@ -284,7 +286,8 @@ saveheader(struct set *set, unsigned options)
/* Print save for an IP */
static void
-saveips(struct set *set, void *data, u_int32_t len, unsigned options)
+ipporthash_saveips(struct set *set, void *data, u_int32_t len,
+ unsigned options, char dont_align)
{
struct ip_set_ipporthash *mysetdata = set->settype->header;
size_t offset = 0;
@@ -300,27 +303,12 @@ saveips(struct set *set, void *data, u_int32_t len, unsigned options)
ip_tostring(ip, options),
port_tostring(port, options));
}
- offset += sizeof(ip_set_ip_t);
+ offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
}
}
-static char buffer[22];
-
-static char *
-unpack_ipport_tostring(struct set *set, ip_set_ip_t bip, unsigned options)
-{
- struct ip_set_ipporthash *mysetdata = set->settype->header;
- ip_set_ip_t ip, port;
-
- ip = (bip>>16) + mysetdata->first_ip;
- port = (uint16_t) bip;
- sprintf(buffer, "%s,%s",
- ip_tostring(ip, options), port_tostring(port, options));
-
- return buffer;
-}
-
-static void usage(void)
+static void
+ipporthash_usage(void)
{
printf
("-N set ipporthash --from IP --to IP\n"
@@ -338,29 +326,25 @@ static struct settype settype_ipporthash = {
/* Create */
.create_size = sizeof(struct ip_set_req_ipporthash_create),
- .create_init = &create_init,
- .create_parse = &create_parse,
- .create_final = &create_final,
+ .create_init = ipporthash_create_init,
+ .create_parse = ipporthash_create_parse,
+ .create_final = ipporthash_create_final,
.create_opts = create_opts,
/* Add/del/test */
.adt_size = sizeof(struct ip_set_req_ipporthash),
- .adt_parser = &adt_parser,
+ .adt_parser = ipporthash_adt_parser,
/* Printing */
.header_size = sizeof(struct ip_set_ipporthash),
- .initheader = &initheader,
- .printheader = &printheader,
- .printips = &printips, /* We only have the unsorted version */
- .printips_sorted = &printips,
- .saveheader = &saveheader,
- .saveips = &saveips,
-
- /* Bindings */
- .bindip_tostring = &unpack_ipport_tostring,
- .bindip_parse = &parse_ip,
+ .initheader = ipporthash_initheader,
+ .printheader = ipporthash_printheader,
+ .printips = ipporthash_printips,
+ .printips_sorted = ipporthash_printips,
+ .saveheader = ipporthash_saveheader,
+ .saveips = ipporthash_saveips,
- .usage = &usage,
+ .usage = ipporthash_usage,
};
CONSTRUCTOR(ipporthash)
diff --git a/ipset_ipportiphash.c b/ipset_ipportiphash.c
index 22a92ef..95cbcfd 100644
--- a/ipset_ipportiphash.c
+++ b/ipset_ipportiphash.c
@@ -32,7 +32,7 @@
/* Initialize the create. */
static void
-create_init(void *data)
+ipportiphash_create_init(void *data)
{
struct ip_set_req_ipportiphash_create *mydata = data;
@@ -46,7 +46,8 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */
static int
-create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
+ipportiphash_create_parse(int c, char *argv[] UNUSED, void *data,
+ unsigned *flags)
{
struct ip_set_req_ipportiphash_create *mydata = data;
ip_set_ip_t value;
@@ -137,7 +138,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */
static void
-create_final(void *data, unsigned int flags)
+ipportiphash_create_final(void *data, unsigned int flags)
{
struct ip_set_req_ipportiphash_create *mydata = data;
@@ -189,7 +190,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */
static ip_set_ip_t
-adt_parser(int cmd UNUSED, const char *arg, void *data)
+ipportiphash_adt_parser(int cmd UNUSED, const char *arg, void *data)
{
struct ip_set_req_ipportiphash *mydata = data;
char *saved = ipset_strdup(arg);
@@ -227,7 +228,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/
static void
-initheader(struct set *set, const void *data)
+ipportiphash_initheader(struct set *set, const void *data)
{
const struct ip_set_req_ipportiphash_create *header = data;
struct ip_set_ipportiphash *map = set->settype->header;
@@ -241,7 +242,7 @@ initheader(struct set *set, const void *data)
}
static void
-printheader(struct set *set, unsigned options)
+ipportiphash_printheader(struct set *set, unsigned options)
{
struct ip_set_ipportiphash *mysetdata = set->settype->header;
@@ -253,7 +254,8 @@ printheader(struct set *set, unsigned options)
}
static void
-printips(struct set *set, void *data, u_int32_t len, unsigned options)
+ipportiphash_printips(struct set *set, void *data, u_int32_t len,
+ unsigned options, char dont_align)
{
struct ip_set_ipportiphash *mysetdata = set->settype->header;
size_t offset = 0;
@@ -272,12 +274,12 @@ printips(struct set *set, void *data, u_int32_t len, unsigned options)
printf("%s\n",
ip_tostring(ipptr->ip1, options));
}
- offset += sizeof(struct ipportip);
+ offset += IPSET_VALIGN(sizeof(struct ipportip), dont_align);
}
}
static void
-saveheader(struct set *set, unsigned options)
+ipportiphash_saveheader(struct set *set, unsigned options)
{
struct ip_set_ipportiphash *mysetdata = set->settype->header;
@@ -292,7 +294,8 @@ saveheader(struct set *set, unsigned options)
/* Print save for an IP */
static void
-saveips(struct set *set, void *data, u_int32_t len, unsigned options)
+ipportiphash_saveips(struct set *set, void *data, u_int32_t len,
+ unsigned options, char dont_align)
{
struct ip_set_ipportiphash *mysetdata = set->settype->header;
size_t offset = 0;
@@ -311,11 +314,12 @@ saveips(struct set *set, void *data, u_int32_t len, unsigned options)
printf("%s\n",
ip_tostring(ipptr->ip1, options));
}
- offset += sizeof(struct ipportip);
+ offset += IPSET_VALIGN(sizeof(struct ipportip), dont_align);
}
}
-static void usage(void)
+static void
+ipportiphash_usage(void)
{
printf
("-N set ipportiphash --from IP --to IP\n"
@@ -333,25 +337,25 @@ static struct settype settype_ipportiphash = {
/* Create */
.create_size = sizeof(struct ip_set_req_ipportiphash_create),
- .create_init = &create_init,
- .create_parse = &create_parse,
- .create_final = &create_final,
+ .create_init = ipportiphash_create_init,
+ .create_parse = ipportiphash_create_parse,
+ .create_final = ipportiphash_create_final,
.create_opts = create_opts,
/* Add/del/test */
.adt_size = sizeof(struct ip_set_req_ipportiphash),
- .adt_parser = &adt_parser,
+ .adt_parser = ipportiphash_adt_parser,
/* Printing */
.header_size = sizeof(struct ip_set_ipportiphash),
- .initheader = &initheader,
- .printheader = &printheader,
- .printips = &printips, /* We only have the unsorted version */
- .printips_sorted = &printips,
- .saveheader = &saveheader,
- .saveips = &saveips,
+ .initheader = ipportiphash_initheader,
+ .printheader = ipportiphash_printheader,
+ .printips = ipportiphash_printips,
+ .printips_sorted = ipportiphash_printips,
+ .saveheader = ipportiphash_saveheader,
+ .saveips = ipportiphash_saveips,
- .usage = &usage,
+ .usage = ipportiphash_usage,
};
CONSTRUCTOR(ipportiphash)
diff --git a/ipset_ipportnethash.c b/ipset_ipportnethash.c
index a029343..3485711 100644
--- a/ipset_ipportnethash.c
+++ b/ipset_ipportnethash.c
@@ -32,7 +32,7 @@
/* Initialize the create. */
static void
-create_init(void *data)
+ipportnethash_create_init(void *data)
{
struct ip_set_req_ipportnethash_create *mydata = data;
@@ -46,7 +46,8 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */
static int
-create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
+ipportnethash_create_parse(int c, char *argv[] UNUSED, void *data,
+ unsigned *flags)
{
struct ip_set_req_ipportnethash_create *mydata = data;
ip_set_ip_t value;
@@ -137,7 +138,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */
static void
-create_final(void *data, unsigned int flags)
+ipportnethash_create_final(void *data, unsigned int flags)
{
struct ip_set_req_ipportnethash_create *mydata = data;
@@ -189,7 +190,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */
static ip_set_ip_t
-adt_parser(int cmd, const char *arg, void *data)
+ipportnethash_adt_parser(int cmd, const char *arg, void *data)
{
struct ip_set_req_ipportnethash *mydata = data;
char *saved = ipset_strdup(arg);
@@ -238,7 +239,7 @@ adt_parser(int cmd, const char *arg, void *data)
*/
static void
-initheader(struct set *set, const void *data)
+ipportnethash_initheader(struct set *set, const void *data)
{
const struct ip_set_req_ipportnethash_create *header = data;
struct ip_set_ipportnethash *map = set->settype->header;
@@ -252,7 +253,7 @@ initheader(struct set *set, const void *data)
}
static void
-printheader(struct set *set, unsigned options)
+ipportnethash_printheader(struct set *set, unsigned options)
{
struct ip_set_ipportnethash *mysetdata = set->settype->header;
@@ -318,7 +319,8 @@ unpack_ip_tostring(ip_set_ip_t ip, unsigned options UNUSED)
}
static void
-printips(struct set *set, void *data, u_int32_t len, unsigned options)
+ipportnethash_printips(struct set *set, void *data, u_int32_t len,
+ unsigned options, char dont_align)
{
struct ip_set_ipportnethash *mysetdata = set->settype->header;
size_t offset = 0;
@@ -337,12 +339,12 @@ printips(struct set *set, void *data, u_int32_t len, unsigned options)
printf("%s\n",
unpack_ip_tostring(ipptr->ip1, options));
}
- offset += sizeof(struct ipportip);
+ offset += IPSET_VALIGN(sizeof(struct ipportip), dont_align);
}
}
static void
-saveheader(struct set *set, unsigned options)
+ipportnethash_saveheader(struct set *set, unsigned options)
{
struct ip_set_ipportnethash *mysetdata = set->settype->header;
@@ -357,7 +359,8 @@ saveheader(struct set *set, unsigned options)
/* Print save for an IP */
static void
-saveips(struct set *set, void *data, u_int32_t len, unsigned options)
+ipportnethash_saveips(struct set *set, void *data, u_int32_t len,
+ unsigned options, char dont_align)
{
struct ip_set_ipportnethash *mysetdata = set->settype->header;
size_t offset = 0;
@@ -376,11 +379,12 @@ saveips(struct set *set, void *data, u_int32_t len, unsigned options)
printf("%s\n",
unpack_ip_tostring(ipptr->ip, options));
}
- offset += sizeof(struct ipportip);
+ offset += IPSET_VALIGN(sizeof(struct ipportip), dont_align);
}
}
-static void usage(void)
+static void
+ipportnethash_usage(void)
{
printf
("-N set ipportnethash --from IP --to IP\n"
@@ -398,25 +402,25 @@ static struct settype settype_ipportnethash = {
/* Create */
.create_size = sizeof(struct ip_set_req_ipportnethash_create),
- .create_init = &create_init,
- .create_parse = &create_parse,
- .create_final = &create_final,
+ .create_init = ipportnethash_create_init,
+ .create_parse = ipportnethash_create_parse,
+ .create_final = ipportnethash_create_final,
.create_opts = create_opts,
/* Add/del/test */
.adt_size = sizeof(struct ip_set_req_ipportnethash),
- .adt_parser = &adt_parser,
+ .adt_parser = ipportnethash_adt_parser,
/* Printing */
.header_size = sizeof(struct ip_set_ipportnethash),
- .initheader = &initheader,
- .printheader = &printheader,
- .printips = &printips, /* We only have the unsorted version */
- .printips_sorted = &printips,
- .saveheader = &saveheader,
- .saveips = &saveips,
+ .initheader = ipportnethash_initheader,
+ .printheader = ipportnethash_printheader,
+ .printips = ipportnethash_printips,
+ .printips_sorted = ipportnethash_printips,
+ .saveheader = ipportnethash_saveheader,
+ .saveips = ipportnethash_saveips,
- .usage = &usage,
+ .usage = ipportnethash_usage,
};
CONSTRUCTOR(ipportnethash)
diff --git a/ipset_iptree.c b/ipset_iptree.c
index fbde520..508e67a 100644
--- a/ipset_iptree.c
+++ b/ipset_iptree.c
@@ -29,7 +29,7 @@
/* Initialize the create. */
static void
-create_init(void *data)
+iptree_create_init(void *data)
{
struct ip_set_req_iptree_create *mydata = data;
@@ -39,7 +39,7 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */
static int
-create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
+iptree_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
{
struct ip_set_req_iptree_create *mydata = data;
@@ -63,7 +63,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */
static void
-create_final(void *data UNUSED, unsigned int flags UNUSED)
+iptree_create_final(void *data UNUSED, unsigned int flags UNUSED)
{
}
@@ -75,7 +75,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */
static ip_set_ip_t
-adt_parser(int cmd UNUSED, const char *arg, void *data)
+iptree_adt_parser(int cmd UNUSED, const char *arg, void *data)
{
struct ip_set_req_iptree *mydata = data;
char *saved = ipset_strdup(arg);
@@ -104,7 +104,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/
static void
-initheader(struct set *set, const void *data)
+iptree_initheader(struct set *set, const void *data)
{
const struct ip_set_req_iptree_create *header = data;
struct ip_set_iptree *map = set->settype->header;
@@ -113,7 +113,7 @@ initheader(struct set *set, const void *data)
}
static void
-printheader(struct set *set, unsigned options UNUSED)
+iptree_printheader(struct set *set, unsigned options UNUSED)
{
struct ip_set_iptree *mysetdata = set->settype->header;
@@ -123,7 +123,8 @@ printheader(struct set *set, unsigned options UNUSED)
}
static void
-printips_sorted(struct set *set, void *data, u_int32_t len, unsigned options)
+iptree_printips_sorted(struct set *set, void *data, u_int32_t len,
+ unsigned options, char dont_align)
{
struct ip_set_iptree *mysetdata = set->settype->header;
struct ip_set_req_iptree *req;
@@ -136,12 +137,12 @@ printips_sorted(struct set *set, void *data, u_int32_t len, unsigned options)
req->timeout);
else
printf("%s\n", ip_tostring(req->ip, options));
- offset += sizeof(struct ip_set_req_iptree);
+ offset += IPSET_VALIGN(sizeof(struct ip_set_req_iptree), dont_align);
}
}
static void
-saveheader(struct set *set, unsigned options UNUSED)
+iptree_saveheader(struct set *set, unsigned options UNUSED)
{
struct ip_set_iptree *mysetdata = set->settype->header;
@@ -155,7 +156,8 @@ saveheader(struct set *set, unsigned options UNUSED)
}
static void
-saveips(struct set *set, void *data, u_int32_t len, unsigned options)
+iptree_saveips(struct set *set, void *data, u_int32_t len,
+ unsigned options, char dont_align)
{
struct ip_set_iptree *mysetdata = set->settype->header;
struct ip_set_req_iptree *req;
@@ -174,11 +176,12 @@ saveips(struct set *set, void *data, u_int32_t len, unsigned options)
printf("-A %s %s\n",
set->name,
ip_tostring(req->ip, options));
- offset += sizeof(struct ip_set_req_iptree);
+ offset += IPSET_VALIGN(sizeof(struct ip_set_req_iptree), dont_align);
}
}
-static void usage(void)
+static void
+iptree_usage(void)
{
printf
("-N set iptree [--timeout value]\n"
@@ -193,29 +196,25 @@ static struct settype settype_iptree = {
/* Create */
.create_size = sizeof(struct ip_set_req_iptree_create),
- .create_init = &create_init,
- .create_parse = &create_parse,
- .create_final = &create_final,
+ .create_init = iptree_create_init,
+ .create_parse = iptree_create_parse,
+ .create_final = iptree_create_final,
.create_opts = create_opts,
/* Add/del/test */
.adt_size = sizeof(struct ip_set_req_iptree),
- .adt_parser = &adt_parser,
+ .adt_parser = iptree_adt_parser,
/* Printing */
.header_size = sizeof(struct ip_set_iptree),
- .initheader = &initheader,
- .printheader = &printheader,
- .printips = &printips_sorted, /* We only have sorted version */
- .printips_sorted = &printips_sorted,
- .saveheader = &saveheader,
- .saveips = &saveips,
+ .initheader = iptree_initheader,
+ .printheader = iptree_printheader,
+ .printips = iptree_printips_sorted, /* We only have sorted version */
+ .printips_sorted = iptree_printips_sorted,
+ .saveheader = iptree_saveheader,
+ .saveips = iptree_saveips,
- /* Bindings */
- .bindip_tostring = &binding_ip_tostring,
- .bindip_parse = &parse_ip,
-
- .usage = &usage,
+ .usage = iptree_usage,
};
CONSTRUCTOR(iptree)
diff --git a/ipset_iptreemap.c b/ipset_iptreemap.c
index 21948d4..22bdcb3 100644
--- a/ipset_iptreemap.c
+++ b/ipset_iptreemap.c
@@ -26,7 +26,7 @@
#define OPT_CREATE_GC 0x1
static void
-create_init(void *data)
+iptreemap_create_init(void *data)
{
struct ip_set_req_iptreemap_create *mydata = data;
@@ -34,7 +34,8 @@ create_init(void *data)
}
static int
-create_parse(int c, char *argv[] UNUSED, void *data, unsigned int *flags)
+iptreemap_create_parse(int c, char *argv[] UNUSED, void *data,
+ unsigned int *flags)
{
struct ip_set_req_iptreemap_create *mydata = data;
@@ -53,7 +54,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned int *flags)
}
static void
-create_final(void *data UNUSED, unsigned int flags UNUSED)
+iptreemap_create_final(void *data UNUSED, unsigned int flags UNUSED)
{
}
@@ -63,7 +64,7 @@ static const struct option create_opts[] = {
};
static ip_set_ip_t
-adt_parser(int cmd UNUSED, const char *arg, void *data)
+iptreemap_adt_parser(int cmd UNUSED, const char *arg, void *data)
{
struct ip_set_req_iptreemap *mydata = data;
ip_set_ip_t mask;
@@ -94,7 +95,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
}
static void
-initheader(struct set *set, const void *data)
+iptreemap_initheader(struct set *set, const void *data)
{
const struct ip_set_req_iptreemap_create *header = data;
struct ip_set_iptreemap *map = set->settype->header;
@@ -103,7 +104,7 @@ initheader(struct set *set, const void *data)
}
static void
-printheader(struct set *set, unsigned int options UNUSED)
+iptreemap_printheader(struct set *set, unsigned int options UNUSED)
{
struct ip_set_iptreemap *mysetdata = set->settype->header;
@@ -114,8 +115,8 @@ printheader(struct set *set, unsigned int options UNUSED)
}
static void
-printips_sorted(struct set *set UNUSED, void *data,
- u_int32_t len, unsigned int options)
+iptreemap_printips_sorted(struct set *set UNUSED, void *data,
+ u_int32_t len, unsigned int options, char dont_align)
{
struct ip_set_req_iptreemap *req;
size_t offset = 0;
@@ -128,12 +129,12 @@ printips_sorted(struct set *set UNUSED, void *data,
printf("-%s", ip_tostring(req->end, options));
printf("\n");
- offset += sizeof(struct ip_set_req_iptreemap);
+ offset += IPSET_VALIGN(sizeof(struct ip_set_req_iptreemap), dont_align);
}
}
static void
-saveheader(struct set *set, unsigned int options UNUSED)
+iptreemap_saveheader(struct set *set, unsigned int options UNUSED)
{
struct ip_set_iptreemap *mysetdata = set->settype->header;
@@ -146,8 +147,8 @@ saveheader(struct set *set, unsigned int options UNUSED)
}
static void
-saveips(struct set *set UNUSED, void *data,
- u_int32_t len, unsigned int options)
+iptreemap_saveips(struct set *set UNUSED, void *data,
+ u_int32_t len, unsigned int options, char dont_align)
{
struct ip_set_req_iptreemap *req;
size_t offset = 0;
@@ -162,12 +163,12 @@ saveips(struct set *set UNUSED, void *data,
printf("\n");
- offset += sizeof(struct ip_set_req_iptreemap);
+ offset += IPSET_VALIGN(sizeof(struct ip_set_req_iptreemap), dont_align);
}
}
static void
-usage(void)
+iptreemap_usage(void)
{
printf(
"-N set iptreemap --gc interval\n"
@@ -182,26 +183,23 @@ static struct settype settype_iptreemap = {
.protocol_version = IP_SET_PROTOCOL_VERSION,
.create_size = sizeof(struct ip_set_req_iptreemap_create),
- .create_init = &create_init,
- .create_parse = &create_parse,
- .create_final = &create_final,
+ .create_init = iptreemap_create_init,
+ .create_parse = iptreemap_create_parse,
+ .create_final = iptreemap_create_final,
.create_opts = create_opts,
.adt_size = sizeof(struct ip_set_req_iptreemap),
- .adt_parser = &adt_parser,
+ .adt_parser = iptreemap_adt_parser,
.header_size = sizeof(struct ip_set_iptreemap),
- .initheader = &initheader,
- .printheader = &printheader,
- .printips = &printips_sorted,
- .printips_sorted = &printips_sorted,
- .saveheader = &saveheader,
- .saveips = &saveips,
-
- .bindip_tostring = &binding_ip_tostring,
- .bindip_parse = &parse_ip,
-
- .usage = &usage,
+ .initheader = iptreemap_initheader,
+ .printheader = iptreemap_printheader,
+ .printips = iptreemap_printips_sorted,
+ .printips_sorted = iptreemap_printips_sorted,
+ .saveheader = iptreemap_saveheader,
+ .saveips = iptreemap_saveips,
+
+ .usage = iptreemap_usage,
};
CONSTRUCTOR(iptreemap)
diff --git a/ipset_macipmap.c b/ipset_macipmap.c
index 3a47e59..fb97cae 100644
--- a/ipset_macipmap.c
+++ b/ipset_macipmap.c
@@ -39,7 +39,7 @@
/* Initialize the create. */
static void
-create_init(void *data UNUSED)
+macipmap_create_init(void *data UNUSED)
{
DP("create INIT");
/* Nothing */
@@ -47,7 +47,7 @@ create_init(void *data UNUSED)
/* Function which parses command options; returns true if it ate an option */
static int
-create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
+macipmap_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
{
struct ip_set_req_macipmap_create *mydata = data;
@@ -107,7 +107,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */
static void
-create_final(void *data, unsigned int flags)
+macipmap_create_final(void *data, unsigned int flags)
{
struct ip_set_req_macipmap_create *mydata = data;
@@ -176,7 +176,7 @@ parse_mac(const char *mac, unsigned char *ethernet)
/* Add, del, test parser */
static ip_set_ip_t
-adt_parser(int cmd UNUSED, const char *arg, void *data)
+macipmap_adt_parser(int cmd UNUSED, const char *arg, void *data)
{
struct ip_set_req_macipmap *mydata = data;
char *saved = ipset_strdup(arg);
@@ -209,7 +209,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/
static void
-initheader(struct set *set, const void *data)
+macipmap_initheader(struct set *set, const void *data)
{
const struct ip_set_req_macipmap_create *header = data;
struct ip_set_macipmap *map = set->settype->header;
@@ -221,7 +221,7 @@ initheader(struct set *set, const void *data)
}
static void
-printheader(struct set *set, unsigned options)
+macipmap_printheader(struct set *set, unsigned options)
{
struct ip_set_macipmap *mysetdata = set->settype->header;
@@ -243,9 +243,9 @@ print_mac(unsigned char macaddress[ETH_ALEN])
printf(":%02X", macaddress[i]);
}
-static void
-printips_sorted(struct set *set, void *data,
- u_int32_t len UNUSED, unsigned options)
+static inline void
+__macipmap_printips_sorted(struct set *set, void *data,
+ u_int32_t len UNUSED, unsigned options)
{
struct ip_set_macipmap *mysetdata = set->settype->header;
struct ip_set_macip *table = data;
@@ -263,7 +263,27 @@ printips_sorted(struct set *set, void *data,
}
static void
-saveheader(struct set *set, unsigned options)
+macipmap_printips_sorted(struct set *set, void *data,
+ u_int32_t len, unsigned options,
+ char dont_align)
+{
+ struct ip_set_req_macipmap *d;
+ size_t offset = 0;
+
+ if (dont_align)
+ return __macipmap_printips_sorted(set, data, len, options);
+
+ while (offset < len) {
+ d = data + offset;
+ printf("%s,", ip_tostring(d->ip, options));
+ print_mac(d->ethernet);
+ printf("\n");
+ offset += IPSET_ALIGN(sizeof(struct ip_set_req_macipmap));
+ }
+}
+
+static void
+macipmap_saveheader(struct set *set, unsigned options)
{
struct ip_set_macipmap *mysetdata = set->settype->header;
@@ -277,9 +297,9 @@ saveheader(struct set *set, unsigned options)
printf("\n");
}
-static void
-saveips(struct set *set, void *data,
- u_int32_t len UNUSED, unsigned options)
+static inline void
+__macipmap_saveips(struct set *set, void *data,
+ u_int32_t len UNUSED, unsigned options)
{
struct ip_set_macipmap *mysetdata = set->settype->header;
struct ip_set_macip *table = data;
@@ -297,7 +317,28 @@ saveips(struct set *set, void *data,
}
}
-static void usage(void)
+static void
+macipmap_saveips(struct set *set, void *data,
+ u_int32_t len, unsigned options,
+ char dont_align)
+{
+ struct ip_set_req_macipmap *d;
+ size_t offset = 0;
+
+ if (dont_align)
+ return __macipmap_saveips(set, data, len, options);
+
+ while (offset < len) {
+ d = data + offset;
+ printf("-A %s %s,", set->name, ip_tostring(d->ip, options));
+ print_mac(d->ethernet);
+ printf("\n");
+ offset += IPSET_ALIGN(sizeof(struct ip_set_req_macipmap));
+ }
+}
+
+static void
+macipmap_usage(void)
{
printf
("-N set macipmap --from IP --to IP [--matchunset]\n"
@@ -313,29 +354,25 @@ static struct settype settype_macipmap = {
/* Create */
.create_size = sizeof(struct ip_set_req_macipmap_create),
- .create_init = &create_init,
- .create_parse = &create_parse,
- .create_final = &create_final,
+ .create_init = macipmap_create_init,
+ .create_parse = macipmap_create_parse,
+ .create_final = macipmap_create_final,
.create_opts = create_opts,
/* Add/del/test */
.adt_size = sizeof(struct ip_set_req_macipmap),
- .adt_parser = &adt_parser,
+ .adt_parser = macipmap_adt_parser,
/* Printing */
.header_size = sizeof(struct ip_set_macipmap),
- .initheader = &initheader,
- .printheader = &printheader,
- .printips = &printips_sorted, /* We only have sorted version */
- .printips_sorted = &printips_sorted,
- .saveheader = &saveheader,
- .saveips = &saveips,
-
- /* Bindings */
- .bindip_tostring = &binding_ip_tostring,
- .bindip_parse = &parse_ip,
-
- .usage = &usage,
+ .initheader = macipmap_initheader,
+ .printheader = macipmap_printheader,
+ .printips = macipmap_printips_sorted,
+ .printips_sorted = macipmap_printips_sorted,
+ .saveheader = macipmap_saveheader,
+ .saveips = macipmap_saveips,
+
+ .usage = macipmap_usage,
};
CONSTRUCTOR(macipmap)
diff --git a/ipset_nethash.c b/ipset_nethash.c
index c73e382..50ca1bd 100644
--- a/ipset_nethash.c
+++ b/ipset_nethash.c
@@ -31,7 +31,7 @@
/* Initialize the create. */
static void
-create_init(void *data)
+nethash_create_init(void *data)
{
struct ip_set_req_nethash_create *mydata = data;
@@ -45,7 +45,7 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */
static int
-create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
+nethash_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
{
struct ip_set_req_nethash_create *mydata = data;
ip_set_ip_t value;
@@ -97,7 +97,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */
static void
-create_final(void *data UNUSED, unsigned int flags UNUSED)
+nethash_create_final(void *data UNUSED, unsigned int flags UNUSED)
{
}
@@ -111,7 +111,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */
static ip_set_ip_t
-adt_parser(int cmd, const char *arg, void *data)
+nethash_adt_parser(int cmd, const char *arg, void *data)
{
struct ip_set_req_nethash *mydata = data;
char *saved = ipset_strdup(arg);
@@ -148,7 +148,7 @@ adt_parser(int cmd, const char *arg, void *data)
*/
static void
-initheader(struct set *set, const void *data)
+nethash_initheader(struct set *set, const void *data)
{
const struct ip_set_req_nethash_create *header = data;
struct ip_set_nethash *map = set->settype->header;
@@ -160,7 +160,7 @@ initheader(struct set *set, const void *data)
}
static void
-printheader(struct set *set, unsigned options UNUSED)
+nethash_printheader(struct set *set, unsigned options UNUSED)
{
struct ip_set_nethash *mysetdata = set->settype->header;
@@ -224,7 +224,8 @@ unpack_ip_tostring(ip_set_ip_t ip, unsigned options UNUSED)
}
static void
-printips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
+nethash_printips(struct set *set UNUSED, void *data, u_int32_t len,
+ unsigned options, char dont_align)
{
size_t offset = 0;
ip_set_ip_t *ip;
@@ -233,12 +234,12 @@ printips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
ip = data + offset;
if (*ip)
printf("%s\n", unpack_ip_tostring(*ip, options));
- offset += sizeof(ip_set_ip_t);
+ offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
}
}
static void
-saveheader(struct set *set, unsigned options UNUSED)
+nethash_saveheader(struct set *set, unsigned options UNUSED)
{
struct ip_set_nethash *mysetdata = set->settype->header;
@@ -249,7 +250,8 @@ saveheader(struct set *set, unsigned options UNUSED)
/* Print save for an IP */
static void
-saveips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
+nethash_saveips(struct set *set UNUSED, void *data, u_int32_t len,
+ unsigned options, char dont_align)
{
size_t offset = 0;
ip_set_ip_t *ip;
@@ -259,40 +261,12 @@ saveips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
if (*ip)
printf("-A %s %s\n", set->name,
unpack_ip_tostring(*ip, options));
- offset += sizeof(ip_set_ip_t);
+ offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
}
}
-static char *
-net_tostring(struct set *set UNUSED, ip_set_ip_t ip, unsigned options)
-{
- return unpack_ip_tostring(ip, options);
-}
-
static void
-parse_net(const char *str, ip_set_ip_t *ip)
-{
- char *saved = ipset_strdup(str);
- char *ptr, *tmp = saved;
- ip_set_ip_t cidr;
-
- ptr = strsep(&tmp, "/");
-
- if (tmp == NULL)
- exit_error(PARAMETER_PROBLEM,
- "Missing cidr from `%s'", str);
-
- if (string_to_number(tmp, 1, 31, &cidr))
- exit_error(PARAMETER_PROBLEM,
- "Out of range cidr `%s' specified", str);
-
- parse_ip(ptr, ip);
- ipset_free(saved);
-
- *ip = pack_ip_cidr(*ip, cidr);
-}
-
-static void usage(void)
+nethash_usage(void)
{
printf
("-N set nethash [--hashsize hashsize] [--probes probes ]\n"
@@ -308,29 +282,25 @@ static struct settype settype_nethash = {
/* Create */
.create_size = sizeof(struct ip_set_req_nethash_create),
- .create_init = &create_init,
- .create_parse = &create_parse,
- .create_final = &create_final,
+ .create_init = nethash_create_init,
+ .create_parse = nethash_create_parse,
+ .create_final = nethash_create_final,
.create_opts = create_opts,
/* Add/del/test */
.adt_size = sizeof(struct ip_set_req_nethash),
- .adt_parser = &adt_parser,
+ .adt_parser = nethash_adt_parser,
/* Printing */
.header_size = sizeof(struct ip_set_nethash),
- .initheader = &initheader,
- .printheader = &printheader,
- .printips = &printips, /* We only have the unsorted version */
- .printips_sorted = &printips,
- .saveheader = &saveheader,
- .saveips = &saveips,
+ .initheader = nethash_initheader,
+ .printheader = nethash_printheader,
+ .printips = nethash_printips,
+ .printips_sorted = nethash_printips,
+ .saveheader = nethash_saveheader,
+ .saveips = nethash_saveips,
- /* Bindings */
- .bindip_tostring = &net_tostring,
- .bindip_parse = &parse_net,
-
- .usage = &usage,
+ .usage = nethash_usage,
};
CONSTRUCTOR(nethash)
diff --git a/ipset_portmap.c b/ipset_portmap.c
index 96e87c2..a1065ae 100644
--- a/ipset_portmap.c
+++ b/ipset_portmap.c
@@ -32,7 +32,7 @@
/* Initialize the create. */
static void
-create_init(void *data UNUSED)
+portmap_create_init(void *data UNUSED)
{
DP("create INIT");
/* Nothing */
@@ -40,7 +40,7 @@ create_init(void *data UNUSED)
/* Function which parses command options; returns true if it ate an option */
static int
-create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
+portmap_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
{
struct ip_set_req_portmap_create *mydata = data;
@@ -76,7 +76,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */
static void
-create_final(void *data, unsigned int flags)
+portmap_create_final(void *data, unsigned int flags)
{
struct ip_set_req_portmap_create *mydata = data;
@@ -113,7 +113,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */
static ip_set_ip_t
-adt_parser(int cmd UNUSED, const char *arg, void *data)
+portmap_adt_parser(int cmd UNUSED, const char *arg, void *data)
{
struct ip_set_req_portmap *mydata = data;
@@ -128,7 +128,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/
static void
-initheader(struct set *set, const void *data)
+portmap_initheader(struct set *set, const void *data)
{
const struct ip_set_req_portmap_create *header = data;
struct ip_set_portmap *map = set->settype->header;
@@ -139,7 +139,7 @@ initheader(struct set *set, const void *data)
}
static void
-printheader(struct set *set, unsigned options)
+portmap_printheader(struct set *set, unsigned options)
{
struct ip_set_portmap *mysetdata = set->settype->header;
@@ -147,12 +147,12 @@ printheader(struct set *set, unsigned options)
printf(" to: %s\n", port_tostring(mysetdata->last_ip, options));
}
-static void
-printports_sorted(struct set *set, void *data,
- u_int32_t len UNUSED, unsigned options)
+static inline void
+__portmap_printips_sorted(struct set *set, void *data,
+ u_int32_t len UNUSED, unsigned options)
{
struct ip_set_portmap *mysetdata = set->settype->header;
- u_int32_t addr = mysetdata->first_ip;
+ ip_set_ip_t addr = mysetdata->first_ip;
DP("%u -- %u", mysetdata->first_ip, mysetdata->last_ip);
while (addr <= mysetdata->last_ip) {
@@ -162,15 +162,26 @@ printports_sorted(struct set *set, void *data,
}
}
-static char *
-binding_port_tostring(struct set *set UNUSED,
- ip_set_ip_t ip, unsigned options)
+static void
+portmap_printips_sorted(struct set *set, void *data,
+ u_int32_t len, unsigned options,
+ char dont_align)
{
- return port_tostring(ip, options);
+ ip_set_ip_t *ip;
+ size_t offset = 0;
+
+ if (dont_align)
+ return __portmap_printips_sorted(set, data, len, options);
+
+ while (offset < len) {
+ ip = data + offset;
+ printf("%s\n", port_tostring(*ip, options));
+ offset += IPSET_ALIGN(sizeof(ip_set_ip_t));
+ }
}
static void
-saveheader(struct set *set, unsigned options)
+portmap_saveheader(struct set *set, unsigned options)
{
struct ip_set_portmap *mysetdata = set->settype->header;
@@ -182,14 +193,15 @@ saveheader(struct set *set, unsigned options)
port_tostring(mysetdata->last_ip, options));
}
-static void
-saveports(struct set *set, void *data,
- u_int32_t len UNUSED, unsigned options)
+static inline void
+__portmap_saveips(struct set *set, void *data,
+ u_int32_t len UNUSED, unsigned options)
{
struct ip_set_portmap *mysetdata = set->settype->header;
- u_int32_t addr = mysetdata->first_ip;
+ ip_set_ip_t addr = mysetdata->first_ip;
while (addr <= mysetdata->last_ip) {
+ DP("addr: %lu, last_ip %lu", (long unsigned)addr, (long unsigned)mysetdata->last_ip);
if (test_bit(addr - mysetdata->first_ip, data))
printf("-A %s %s\n",
set->name,
@@ -198,7 +210,26 @@ saveports(struct set *set, void *data,
}
}
-static void usage(void)
+static void
+portmap_saveips(struct set *set, void *data,
+ u_int32_t len, unsigned options,
+ char dont_align)
+{
+ ip_set_ip_t *ip;
+ size_t offset = 0;
+
+ if (dont_align)
+ return __portmap_saveips(set, data, len, options);
+
+ while (offset < len) {
+ ip = data + offset;
+ printf("-A %s %s\n", set->name, port_tostring(*ip, options));
+ offset += IPSET_ALIGN(sizeof(ip_set_ip_t));
+ }
+}
+
+static void
+portmap_usage(void)
{
printf
("-N set portmap --from PORT --to PORT\n"
@@ -213,29 +244,25 @@ static struct settype settype_portmap = {
/* Create */
.create_size = sizeof(struct ip_set_req_portmap_create),
- .create_init = &create_init,
- .create_parse = &create_parse,
- .create_final = &create_final,
+ .create_init = portmap_create_init,
+ .create_parse = portmap_create_parse,
+ .create_final = portmap_create_final,
.create_opts = create_opts,
/* Add/del/test */
.adt_size = sizeof(struct ip_set_req_portmap),
- .adt_parser = &adt_parser,
+ .adt_parser = portmap_adt_parser,
/* Printing */
.header_size = sizeof(struct ip_set_portmap),
- .initheader = &initheader,
- .printheader = &printheader,
- .printips = &printports_sorted, /* We only have sorted version */
- .printips_sorted = &printports_sorted,
- .saveheader = &saveheader,
- .saveips = &saveports,
+ .initheader = portmap_initheader,
+ .printheader = portmap_printheader,
+ .printips = portmap_printips_sorted,
+ .printips_sorted = portmap_printips_sorted,
+ .saveheader = portmap_saveheader,
+ .saveips = portmap_saveips,
- /* Bindings */
- .bindip_tostring = &binding_port_tostring,
- .bindip_parse = &parse_port,
-
- .usage = &usage,
+ .usage = portmap_usage,
};
CONSTRUCTOR(portmap)
diff --git a/ipset_setlist.c b/ipset_setlist.c
index d5d65d7..de16c44 100644
--- a/ipset_setlist.c
+++ b/ipset_setlist.c
@@ -27,7 +27,7 @@
/* Initialize the create. */
static void
-create_init(void *data)
+setlist_create_init(void *data)
{
struct ip_set_req_setlist_create *mydata = data;
@@ -36,7 +36,8 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */
static int
-create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags UNUSED)
+setlist_create_parse(int c, char *argv[] UNUSED, void *data,
+ unsigned *flags UNUSED)
{
struct ip_set_req_setlist_create *mydata = data;
unsigned int size;
@@ -57,7 +58,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags UNUSED)
/* Final check; exit if not ok. */
static void
-create_final(void *data UNUSED, unsigned int flags UNUSED)
+setlist_create_final(void *data UNUSED, unsigned int flags UNUSED)
{
}
@@ -67,7 +68,8 @@ static const struct option create_opts[] = {
{NULL},
};
-static void check_setname(const char *name)
+static void
+check_setname(const char *name)
{
if (strlen(name) > IP_SET_MAXNAMELEN - 1)
exit_error(PARAMETER_PROBLEM,
@@ -77,7 +79,7 @@ static void check_setname(const char *name)
/* Add, del, test parser */
static ip_set_ip_t
-adt_parser(int cmd UNUSED, const char *arg, void *data)
+setlist_adt_parser(int cmd UNUSED, const char *arg, void *data)
{
struct ip_set_req_setlist *mydata = data;
char *saved = ipset_strdup(arg);
@@ -115,7 +117,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/
static void
-initheader(struct set *set, const void *data)
+setlist_initheader(struct set *set, const void *data)
{
const struct ip_set_req_setlist_create *header = data;
struct ip_set_setlist *map = set->settype->header;
@@ -125,7 +127,7 @@ initheader(struct set *set, const void *data)
}
static void
-printheader(struct set *set, unsigned options UNUSED)
+setlist_printheader(struct set *set, unsigned options UNUSED)
{
struct ip_set_setlist *mysetdata = set->settype->header;
@@ -133,25 +135,29 @@ printheader(struct set *set, unsigned options UNUSED)
}
static void
-printips_sorted(struct set *set, void *data,
- u_int32_t len UNUSED, unsigned options UNUSED)
+setlist_printips_sorted(struct set *set, void *data,
+ u_int32_t len UNUSED, unsigned options UNUSED,
+ char dont_align)
{
struct ip_set_setlist *mysetdata = set->settype->header;
- int i;
- ip_set_id_t id;
+ int i, asize;
+ ip_set_id_t *id;
struct set *elem;
+ asize = IPSET_VALIGN(sizeof(ip_set_id_t), dont_align);
for (i = 0; i < mysetdata->size; i++ ) {
- id = *((ip_set_id_t *)data + i);
- if (id == IP_SET_INVALID_ID)
+ DP("Try %u", i);
+ id = (ip_set_id_t *)(data + i * asize);
+ DP("Try %u, check", i);
+ if (*id == IP_SET_INVALID_ID)
return;
- elem = set_find_byid(id);
+ elem = set_find_byid(*id);
printf("%s\n", elem->name);
}
}
static void
-saveheader(struct set *set, unsigned options UNUSED)
+setlist_saveheader(struct set *set, unsigned options UNUSED)
{
struct ip_set_setlist *mysetdata = set->settype->header;
@@ -161,24 +167,26 @@ saveheader(struct set *set, unsigned options UNUSED)
}
static void
-saveips(struct set *set, void *data,
- u_int32_t len UNUSED, unsigned options UNUSED)
+setlist_saveips(struct set *set, void *data,
+ u_int32_t len UNUSED, unsigned options UNUSED, char dont_align)
{
struct ip_set_setlist *mysetdata = set->settype->header;
- int i;
- ip_set_id_t id;
+ int i, asize;
+ ip_set_id_t *id;
struct set *elem;
+ asize = IPSET_VALIGN(sizeof(ip_set_id_t), dont_align);
for (i = 0; i < mysetdata->size; i++ ) {
- id = *((ip_set_id_t *)data + i);
- if (id == IP_SET_INVALID_ID)
+ id = (ip_set_id_t *)(data + i * asize);
+ if (*id == IP_SET_INVALID_ID)
return;
- elem = set_find_byid(id);
+ elem = set_find_byid(*id);
printf("-A %s %s\n", set->name, elem->name);
}
}
-static void usage(void)
+static void
+setlist_usage(void)
{
printf
("-N set setlist --size size\n"
@@ -193,25 +201,25 @@ static struct settype settype_setlist = {
/* Create */
.create_size = sizeof(struct ip_set_req_setlist_create),
- .create_init = &create_init,
- .create_parse = &create_parse,
- .create_final = &create_final,
+ .create_init = setlist_create_init,
+ .create_parse = setlist_create_parse,
+ .create_final = setlist_create_final,
.create_opts = create_opts,
/* Add/del/test */
.adt_size = sizeof(struct ip_set_req_setlist),
- .adt_parser = &adt_parser,
+ .adt_parser = setlist_adt_parser,
/* Printing */
.header_size = sizeof(struct ip_set_setlist),
- .initheader = &initheader,
- .printheader = &printheader,
- .printips = &printips_sorted, /* We only have sorted version */
- .printips_sorted = &printips_sorted,
- .saveheader = &saveheader,
- .saveips = &saveips,
+ .initheader = setlist_initheader,
+ .printheader = setlist_printheader,
+ .printips = setlist_printips_sorted,
+ .printips_sorted = setlist_printips_sorted,
+ .saveheader = setlist_saveheader,
+ .saveips = setlist_saveips,
- .usage = &usage,
+ .usage = setlist_usage,
};
CONSTRUCTOR(setlist)
diff --git a/kernel/ChangeLog b/kernel/ChangeLog
index 849e98e..192f689 100644
--- a/kernel/ChangeLog
+++ b/kernel/ChangeLog
@@ -1,5 +1,13 @@
+4.0
- Compilation of ip_set_iptree.c fails with kernel 2.6.20 due to
missing include of linux/jiffies.h (Jan Engelhardt)
+ - Do not use DECLARE_MUTEX (compatibility fix on 2.6.31-rt, Jan
+ Engelhardt)
+ - Flushing iptreemap type of sets caused high ksoftirqd load due to
+ zeroed out timeout parameter (bug reported by Georg Chini)
+ - New protocol is introduced to handle aligment issues properly
+ (bug reported by Georg Chini)
+ - Binding support is removed
3.2
- Mixed up formats in ip_set_iptree.c (Rob Sterenborg)
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set.h b/kernel/include/linux/netfilter_ipv4/ip_set.h
index 3667352..da17319 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set.h
@@ -40,7 +40,8 @@
/*
* Used so that the kernel module and ipset-binary can match their versions
*/
-#define IP_SET_PROTOCOL_VERSION 3
+#define IP_SET_PROTOCOL_UNALIGNED 3
+#define IP_SET_PROTOCOL_VERSION 4
#define IP_SET_MAXNAMELEN 32 /* set names and set typenames */
@@ -228,7 +229,7 @@ struct ip_set_req_max_sets {
struct ip_set_req_setnames {
unsigned op;
ip_set_id_t index; /* set to list/save */
- u_int32_t size; /* size to get setdata/bindings */
+ u_int32_t size; /* size to get setdata */
/* followed by sets number of struct ip_set_name_list */
};
@@ -302,6 +303,11 @@ static inline int bitmap_bytes(ip_set_ip_t a, ip_set_ip_t b)
/* General limit for the elements in a set */
#define MAX_RANGE 0x0000FFFF
+/* Alignment: 'unsigned long' unsupported */
+#define IPSET_ALIGNTO 4
+#define IPSET_ALIGN(len) (((len) + IPSET_ALIGNTO - 1) & ~(IPSET_ALIGNTO - 1))
+#define IPSET_VALIGN(len, old) ((old) ? (len) : IPSET_ALIGN(len))
+
#ifdef __KERNEL__
#include <linux/netfilter_ipv4/ip_set_compat.h>
#include <linux/netfilter_ipv4/ip_set_malloc.h>
@@ -350,16 +356,13 @@ struct ip_set_type {
*/
int (*testip_kernel) (struct ip_set *set,
const struct sk_buff * skb,
- ip_set_ip_t *ip,
- const u_int32_t *flags,
- unsigned char index);
+ const u_int32_t *flags);
/* test for IP in set (userspace: ipset -T set IP)
* return 0 if not in set, 1 if in set.
*/
int (*testip) (struct ip_set *set,
- const void *data, u_int32_t size,
- ip_set_ip_t *ip);
+ const void *data, u_int32_t size);
/*
* Size of the data structure passed by when
@@ -373,8 +376,7 @@ struct ip_set_type {
* If the address was not already in the set, 0 is returned.
*/
int (*addip) (struct ip_set *set,
- const void *data, u_int32_t size,
- ip_set_ip_t *ip);
+ const void *data, u_int32_t size);
/* Add IP into set (kernel: iptables ... -j SET set src|dst)
* Return -EEXIST if the address is already in the set,
@@ -382,10 +384,8 @@ struct ip_set_type {
* If the address was not already in the set, 0 is returned.
*/
int (*addip_kernel) (struct ip_set *set,
- const struct sk_buff * skb,
- ip_set_ip_t *ip,
- const u_int32_t *flags,
- unsigned char index);
+ const struct sk_buff * skb,
+ const u_int32_t *flags);
/* remove IP from set (userspace: ipset -D set --entry x)
* Return -EEXIST if the address is NOT in the set,
@@ -393,8 +393,7 @@ struct ip_set_type {
* If the address really was in the set, 0 is returned.
*/
int (*delip) (struct ip_set *set,
- const void *data, u_int32_t size,
- ip_set_ip_t *ip);
+ const void *data, u_int32_t size);
/* remove IP from set (kernel: iptables ... -j SET --entry x)
* Return -EEXIST if the address is NOT in the set,
@@ -402,10 +401,8 @@ struct ip_set_type {
* If the address really was in the set, 0 is returned.
*/
int (*delip_kernel) (struct ip_set *set,
- const struct sk_buff * skb,
- ip_set_ip_t *ip,
- const u_int32_t *flags,
- unsigned char index);
+ const struct sk_buff * skb,
+ const u_int32_t *flags);
/* new set creation - allocated type specific items
*/
@@ -443,7 +440,7 @@ struct ip_set_type {
/* Listing: Get the size for the set members
*/
- int (*list_members_size) (const struct ip_set *set);
+ int (*list_members_size) (const struct ip_set *set, char dont_align);
/* Listing: Get the set members
*
@@ -453,7 +450,7 @@ struct ip_set_type {
* correct.
*/
void (*list_members) (const struct ip_set *set,
- void *data);
+ void *data, char dont_align);
char typename[IP_SET_MAXNAMELEN];
unsigned char features;
@@ -471,20 +468,11 @@ struct ip_set {
char name[IP_SET_MAXNAMELEN]; /* the name of the set */
rwlock_t lock; /* lock for concurrency control */
ip_set_id_t id; /* set id for swapping */
- ip_set_id_t binding; /* default binding for the set */
atomic_t ref; /* in kernel and in hash references */
struct ip_set_type *type; /* the set types */
void *data; /* pooltype specific data */
};
-/* Structure to bind set elements to sets */
-struct ip_set_hash {
- struct list_head list; /* list of clashing entries in hash */
- ip_set_ip_t ip; /* ip from set */
- ip_set_id_t id; /* set id */
- ip_set_id_t binding; /* set we bind the element to */
-};
-
/* register and unregister set references */
extern ip_set_id_t ip_set_get_byname(const char name[IP_SET_MAXNAMELEN]);
extern ip_set_id_t ip_set_get_byindex(ip_set_id_t index);
@@ -515,12 +503,11 @@ extern int ip_set_testip_kernel(ip_set_id_t id,
#define UADT0(type, adt, args...) \
static int \
-FNAME(type,_u,adt)(struct ip_set *set, const void *data, u_int32_t size,\
- ip_set_ip_t *hash_ip) \
+FNAME(type,_u,adt)(struct ip_set *set, const void *data, u_int32_t size)\
{ \
const STRUCT(ip_set_req_,type) *req = data; \
\
- return FNAME(type,_,adt)(set, hash_ip , ## args); \
+ return FNAME(type,_,adt)(set , ## args); \
}
#define UADT(type, adt, args...) \
@@ -530,14 +517,12 @@ FNAME(type,_u,adt)(struct ip_set *set, const void *data, u_int32_t size,\
static int \
FNAME(type,_k,adt)(struct ip_set *set, \
const struct sk_buff *skb, \
- ip_set_ip_t *hash_ip, \
- const u_int32_t *flags, \
- unsigned char index) \
+ const u_int32_t *flags) \
{ \
- ip_set_ip_t ip = getfn(skb, flags[index]); \
+ ip_set_ip_t ip = getfn(skb, flags); \
\
KADT_CONDITION \
- return FNAME(type,_,adt)(set, hash_ip, ip , ##args); \
+ return FNAME(type,_,adt)(set, ip , ##args); \
}
#define REGISTER_MODULE(type) \
@@ -559,9 +544,9 @@ module_exit(ip_set_##type##_fini);
/* Common functions */
static inline ip_set_ip_t
-ipaddr(const struct sk_buff *skb, u_int32_t flag)
+ipaddr(const struct sk_buff *skb, const u_int32_t *flags)
{
- return ntohl(flag & IPSET_SRC ? ip_hdr(skb)->saddr : ip_hdr(skb)->daddr);
+ return ntohl(flags[0] & IPSET_SRC ? ip_hdr(skb)->saddr : ip_hdr(skb)->daddr);
}
#define jhash_ip(map, i, ip) jhash_1word(ip, *(map->initval + i))
@@ -571,4 +556,6 @@ ipaddr(const struct sk_buff *skb, u_int32_t flag)
#endif /* __KERNEL__ */
+#define UNUSED __attribute__ ((unused))
+
#endif /*_IP_SET_H*/
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_bitmaps.h b/kernel/include/linux/netfilter_ipv4/ip_set_bitmaps.h
index 90e87e3..da3493f 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_bitmaps.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_bitmaps.h
@@ -77,22 +77,21 @@ type##_list_header(const struct ip_set *set, void *data) \
__##type##_list_header(map, header); \
}
-#define BITMAP_LIST_MEMBERS_SIZE(type) \
+#define BITMAP_LIST_MEMBERS_SIZE(type, dtype, sizeid, testfn) \
static int \
-type##_list_members_size(const struct ip_set *set) \
+type##_list_members_size(const struct ip_set *set, char dont_align) \
{ \
const struct ip_set_##type *map = set->data; \
+ ip_set_ip_t i, elements = 0; \
\
- return map->size; \
-}
-
-#define BITMAP_LIST_MEMBERS(type) \
-static void \
-type##_list_members(const struct ip_set *set, void *data) \
-{ \
- const struct ip_set_##type *map = set->data; \
+ if (dont_align) \
+ return map->size; \
+ \
+ for (i = 0; i < sizeid; i++) \
+ if (testfn) \
+ elements++; \
\
- memcpy(data, map->members, map->size); \
+ return elements * IPSET_ALIGN(sizeof(dtype)); \
}
#define IP_SET_TYPE(type, __features) \
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_compat.h b/kernel/include/linux/netfilter_ipv4/ip_set_compat.h
index 96c2024..9f17397 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_compat.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_compat.h
@@ -65,7 +65,28 @@ static inline void *kzalloc(size_t size, gfp_t flags)
#define KMEM_CACHE_CREATE(name, size) \
kmem_cache_create(name, size, 0, 0, NULL)
#endif
-
+
+#ifndef NIPQUAD
+#define NIPQUAD(addr) \
+ ((unsigned char *)&addr)[0], \
+ ((unsigned char *)&addr)[1], \
+ ((unsigned char *)&addr)[2], \
+ ((unsigned char *)&addr)[3]
+#endif
+
+#ifndef HIPQUAD
+#if defined(__LITTLE_ENDIAN)
+#define HIPQUAD(addr) \
+ ((unsigned char *)&addr)[3], \
+ ((unsigned char *)&addr)[2], \
+ ((unsigned char *)&addr)[1], \
+ ((unsigned char *)&addr)[0]
+#elif defined(__BIG_ENDIAN)
+#define HIPQUAD NIPQUAD
+#else
+#error "Please fix asm/byteorder.h"
+#endif /* __LITTLE_ENDIAN */
+#endif
#endif /* __KERNEL__ */
#endif /* _IP_SET_COMPAT_H */
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_getport.h b/kernel/include/linux/netfilter_ipv4/ip_set_getport.h
index 9e322bf..18ed729 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_getport.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_getport.h
@@ -7,7 +7,7 @@
/* We must handle non-linear skbs */
static inline ip_set_ip_t
-get_port(const struct sk_buff *skb, u_int32_t flags)
+get_port(const struct sk_buff *skb, const u_int32_t *flags)
{
struct iphdr *iph = ip_hdr(skb);
u_int16_t offset = ntohs(iph->frag_off) & IP_OFFSET;
@@ -23,7 +23,7 @@ get_port(const struct sk_buff *skb, u_int32_t flags)
/* No choice either */
return INVALID_PORT;
- return ntohs(flags & IPSET_SRC ?
+ return ntohs(flags[0] & IPSET_SRC ?
tcph.source : tcph.dest);
}
case IPPROTO_UDP: {
@@ -36,7 +36,7 @@ get_port(const struct sk_buff *skb, u_int32_t flags)
/* No choice either */
return INVALID_PORT;
- return ntohs(flags & IPSET_SRC ?
+ return ntohs(flags[0] & IPSET_SRC ?
udph.source : udph.dest);
}
default:
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_hashes.h b/kernel/include/linux/netfilter_ipv4/ip_set_hashes.h
index f7d6a69..f62ae37 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_hashes.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_hashes.h
@@ -182,30 +182,31 @@ type##_list_header(const struct ip_set *set, void *data) \
#define HASH_LIST_MEMBERS_SIZE(type, dtype) \
static int \
-type##_list_members_size(const struct ip_set *set) \
+type##_list_members_size(const struct ip_set *set, char dont_align) \
{ \
const struct ip_set_##type *map = set->data; \
\
- return (map->hashsize * sizeof(dtype)); \
+ return (map->hashsize * IPSET_VALIGN(sizeof(dtype), dont_align));\
}
#define HASH_LIST_MEMBERS(type, dtype) \
static void \
-type##_list_members(const struct ip_set *set, void *data) \
+type##_list_members(const struct ip_set *set, void *data, char dont_align)\
{ \
const struct ip_set_##type *map = set->data; \
- dtype *elem; \
+ dtype *elem, *d; \
uint32_t i; \
\
for (i = 0; i < map->hashsize; i++) { \
elem = HARRAY_ELEM(map->members, dtype *, i); \
- ((dtype *)data)[i] = *elem; \
+ d = data + i * IPSET_VALIGN(sizeof(dtype), dont_align); \
+ *d = *elem; \
} \
}
#define HASH_LIST_MEMBERS_MEMCPY(type, dtype) \
static void \
-type##_list_members(const struct ip_set *set, void *data) \
+type##_list_members(const struct ip_set *set, void *data, char dont_align)\
{ \
const struct ip_set_##type *map = set->data; \
dtype *elem; \
@@ -213,7 +214,8 @@ type##_list_members(const struct ip_set *set, void *data) \
\
for (i = 0; i < map->hashsize; i++) { \
elem = HARRAY_ELEM(map->members, dtype *, i); \
- memcpy((((dtype *)data)+i), elem, sizeof(dtype)); \
+ memcpy(data + i * IPSET_VALIGN(sizeof(dtype), dont_align),\
+ elem, sizeof(dtype)); \
} \
}
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_iphash.h b/kernel/include/linux/netfilter_ipv4/ip_set_iphash.h
index 277bc8c..0a0c7e8 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_iphash.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_iphash.h
@@ -4,7 +4,7 @@
#include <linux/netfilter_ipv4/ip_set.h>
#include <linux/netfilter_ipv4/ip_set_hashes.h>
-#define SETTYPE_NAME "iphash"
+#define SETTYPE_NAME "iphash"
struct ip_set_iphash {
ip_set_ip_t *members; /* the iphash proper */
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_ipmap.h b/kernel/include/linux/netfilter_ipv4/ip_set_ipmap.h
index ce4b29b..d16c0ae 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_ipmap.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_ipmap.h
@@ -4,7 +4,7 @@
#include <linux/netfilter_ipv4/ip_set.h>
#include <linux/netfilter_ipv4/ip_set_bitmaps.h>
-#define SETTYPE_NAME "ipmap"
+#define SETTYPE_NAME "ipmap"
struct ip_set_ipmap {
void *members; /* the ipmap proper */
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_ipporthash.h b/kernel/include/linux/netfilter_ipv4/ip_set_ipporthash.h
index b5db5f5..a3b781a 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_ipporthash.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_ipporthash.h
@@ -4,7 +4,7 @@
#include <linux/netfilter_ipv4/ip_set.h>
#include <linux/netfilter_ipv4/ip_set_hashes.h>
-#define SETTYPE_NAME "ipporthash"
+#define SETTYPE_NAME "ipporthash"
struct ip_set_ipporthash {
ip_set_ip_t *members; /* the ipporthash proper */
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_ipportiphash.h b/kernel/include/linux/netfilter_ipv4/ip_set_ipportiphash.h
index eb6cf55..2202c51 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_ipportiphash.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_ipportiphash.h
@@ -4,7 +4,7 @@
#include <linux/netfilter_ipv4/ip_set.h>
#include <linux/netfilter_ipv4/ip_set_hashes.h>
-#define SETTYPE_NAME "ipportiphash"
+#define SETTYPE_NAME "ipportiphash"
struct ipportip {
ip_set_ip_t ip;
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_ipportnethash.h b/kernel/include/linux/netfilter_ipv4/ip_set_ipportnethash.h
index 951da92..73b2430 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_ipportnethash.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_ipportnethash.h
@@ -4,7 +4,7 @@
#include <linux/netfilter_ipv4/ip_set.h>
#include <linux/netfilter_ipv4/ip_set_hashes.h>
-#define SETTYPE_NAME "ipportnethash"
+#define SETTYPE_NAME "ipportnethash"
struct ipportip {
ip_set_ip_t ip;
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_iptree.h b/kernel/include/linux/netfilter_ipv4/ip_set_iptree.h
index de5cf47..36bf5ac 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_iptree.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_iptree.h
@@ -3,7 +3,7 @@
#include <linux/netfilter_ipv4/ip_set.h>
-#define SETTYPE_NAME "iptree"
+#define SETTYPE_NAME "iptree"
struct ip_set_iptreed {
unsigned long expires[256]; /* x.x.x.ADDR */
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_iptreemap.h b/kernel/include/linux/netfilter_ipv4/ip_set_iptreemap.h
index a58bc4e..6ea771a 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_iptreemap.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_iptreemap.h
@@ -3,7 +3,7 @@
#include <linux/netfilter_ipv4/ip_set.h>
-#define SETTYPE_NAME "iptreemap"
+#define SETTYPE_NAME "iptreemap"
#ifdef __KERNEL__
struct ip_set_iptreemap_d {
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_macipmap.h b/kernel/include/linux/netfilter_ipv4/ip_set_macipmap.h
index 19418f3..0615e9f 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_macipmap.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_macipmap.h
@@ -4,7 +4,7 @@
#include <linux/netfilter_ipv4/ip_set.h>
#include <linux/netfilter_ipv4/ip_set_bitmaps.h>
-#define SETTYPE_NAME "macipmap"
+#define SETTYPE_NAME "macipmap"
/* general flags */
#define IPSET_MACIP_MATCHUNSET 1
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_nethash.h b/kernel/include/linux/netfilter_ipv4/ip_set_nethash.h
index b2d006f..cf0b794 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_nethash.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_nethash.h
@@ -4,7 +4,7 @@
#include <linux/netfilter_ipv4/ip_set.h>
#include <linux/netfilter_ipv4/ip_set_hashes.h>
-#define SETTYPE_NAME "nethash"
+#define SETTYPE_NAME "nethash"
struct ip_set_nethash {
ip_set_ip_t *members; /* the nethash proper */
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_portmap.h b/kernel/include/linux/netfilter_ipv4/ip_set_portmap.h
index 8ea6ba2..37f411e 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_portmap.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_portmap.h
@@ -4,7 +4,7 @@
#include <linux/netfilter_ipv4/ip_set.h>
#include <linux/netfilter_ipv4/ip_set_bitmaps.h>
-#define SETTYPE_NAME "portmap"
+#define SETTYPE_NAME "portmap"
struct ip_set_portmap {
void *members; /* the portmap proper */
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_setlist.h b/kernel/include/linux/netfilter_ipv4/ip_set_setlist.h
index ca044d8..7cc6ed0 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_setlist.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_setlist.h
@@ -3,7 +3,7 @@
#include <linux/netfilter_ipv4/ip_set.h>
-#define SETTYPE_NAME "setlist"
+#define SETTYPE_NAME "setlist"
#define IP_SET_SETLIST_ADD_AFTER 0
#define IP_SET_SETLIST_ADD_BEFORE 1
diff --git a/kernel/ip_set.c b/kernel/ip_set.c
index c836d85..30185c5 100644
--- a/kernel/ip_set.c
+++ b/kernel/ip_set.c
@@ -39,19 +39,18 @@
static struct list_head set_type_list; /* all registered sets */
static struct ip_set **ip_set_list; /* all individual sets */
static DEFINE_RWLOCK(ip_set_lock); /* protects the lists and the hash */
-static DECLARE_MUTEX(ip_set_app_mutex); /* serializes user access */
+static struct semaphore ip_set_app_mutex; /* serializes user access */
static ip_set_id_t ip_set_max = CONFIG_IP_NF_SET_MAX;
-static ip_set_id_t ip_set_bindings_hash_size = CONFIG_IP_NF_SET_HASHSIZE;
-static struct list_head *ip_set_hash; /* hash of bindings */
-static unsigned int ip_set_hash_random; /* random seed */
+static int protocol_version = IP_SET_PROTOCOL_VERSION;
-#define SETNAME_EQ(a,b) (strncmp(a,b,IP_SET_MAXNAMELEN) == 0)
+#define STREQ(a,b) (strncmp(a,b,IP_SET_MAXNAMELEN) == 0)
+#define DONT_ALIGN (protocol_version == IP_SET_PROTOCOL_UNALIGNED)
+#define ALIGNED(len) IPSET_VALIGN(len, DONT_ALIGN)
/*
* Sets are identified either by the index in ip_set_list or by id.
- * The id never changes and is used to find a key in the hash.
- * The index may change by swapping and used at all other places
- * (set/SET netfilter modules, binding value, etc.)
+ * The id never changes. The index may change by swapping and used
+ * by external references (set/SET netfilter modules, etc.)
*
* Userspace requests are serialized by ip_set_mutex and sets can
* be deleted only from userspace. Therefore ip_set_list locking
@@ -73,166 +72,25 @@ __ip_set_put(ip_set_id_t index)
atomic_dec(&ip_set_list[index]->ref);
}
-/*
- * Binding routines
- */
-
-static inline struct ip_set_hash *
-__ip_set_find(u_int32_t key, ip_set_id_t id, ip_set_ip_t ip)
-{
- struct ip_set_hash *set_hash;
-
- list_for_each_entry(set_hash, &ip_set_hash[key], list)
- if (set_hash->id == id && set_hash->ip == ip)
- return set_hash;
-
- return NULL;
-}
-
-static ip_set_id_t
-ip_set_find_in_hash(ip_set_id_t id, ip_set_ip_t ip)
-{
- u_int32_t key = jhash_2words(id, ip, ip_set_hash_random)
- % ip_set_bindings_hash_size;
- struct ip_set_hash *set_hash;
-
- ASSERT_READ_LOCK(&ip_set_lock);
- IP_SET_ASSERT(ip_set_list[id]);
- DP("set: %s, ip: %u.%u.%u.%u", ip_set_list[id]->name, HIPQUAD(ip));
-
- set_hash = __ip_set_find(key, id, ip);
-
- DP("set: %s, ip: %u.%u.%u.%u, binding: %s", ip_set_list[id]->name,
- HIPQUAD(ip),
- set_hash != NULL ? ip_set_list[set_hash->binding]->name : "");
-
- return (set_hash != NULL ? set_hash->binding : IP_SET_INVALID_ID);
-}
-
-static inline void
-__set_hash_del(struct ip_set_hash *set_hash)
-{
- ASSERT_WRITE_LOCK(&ip_set_lock);
- IP_SET_ASSERT(ip_set_list[set_hash->binding]);
-
- __ip_set_put(set_hash->binding);
- list_del(&set_hash->list);
- kfree(set_hash);
-}
-
-static int
-ip_set_hash_del(ip_set_id_t id, ip_set_ip_t ip)
-{
- u_int32_t key = jhash_2words(id, ip, ip_set_hash_random)
- % ip_set_bindings_hash_size;
- struct ip_set_hash *set_hash;
-
- IP_SET_ASSERT(ip_set_list[id]);
- DP("set: %s, ip: %u.%u.%u.%u", ip_set_list[id]->name, HIPQUAD(ip));
- write_lock_bh(&ip_set_lock);
- set_hash = __ip_set_find(key, id, ip);
- DP("set: %s, ip: %u.%u.%u.%u, binding: %s", ip_set_list[id]->name,
- HIPQUAD(ip),
- set_hash != NULL ? ip_set_list[set_hash->binding]->name : "");
-
- if (set_hash != NULL)
- __set_hash_del(set_hash);
- write_unlock_bh(&ip_set_lock);
- return 0;
-}
-
-static int
-ip_set_hash_add(ip_set_id_t id, ip_set_ip_t ip, ip_set_id_t binding)
-{
- u_int32_t key = jhash_2words(id, ip, ip_set_hash_random)
- % ip_set_bindings_hash_size;
- struct ip_set_hash *set_hash;
- int ret = 0;
-
- IP_SET_ASSERT(ip_set_list[id]);
- IP_SET_ASSERT(ip_set_list[binding]);
- DP("set: %s, ip: %u.%u.%u.%u, binding: %s", ip_set_list[id]->name,
- HIPQUAD(ip), ip_set_list[binding]->name);
- write_lock_bh(&ip_set_lock);
- set_hash = __ip_set_find(key, id, ip);
- if (!set_hash) {
- set_hash = kmalloc(sizeof(struct ip_set_hash), GFP_ATOMIC);
- if (!set_hash) {
- ret = -ENOMEM;
- goto unlock;
- }
- INIT_LIST_HEAD(&set_hash->list);
- set_hash->id = id;
- set_hash->ip = ip;
- list_add(&set_hash->list, &ip_set_hash[key]);
- } else {
- IP_SET_ASSERT(ip_set_list[set_hash->binding]);
- DP("overwrite binding: %s",
- ip_set_list[set_hash->binding]->name);
- __ip_set_put(set_hash->binding);
- }
- set_hash->binding = binding;
- __ip_set_get(set_hash->binding);
- DP("stored: key %u, id %u (%s), ip %u.%u.%u.%u, binding %u (%s)",
- key, id, ip_set_list[id]->name,
- HIPQUAD(ip), binding, ip_set_list[binding]->name);
- unlock:
- write_unlock_bh(&ip_set_lock);
- return ret;
-}
-
-#define FOREACH_HASH_DO(fn, args...) \
-({ \
- ip_set_id_t __key; \
- struct ip_set_hash *__set_hash; \
- \
- for (__key = 0; __key < ip_set_bindings_hash_size; __key++) { \
- list_for_each_entry(__set_hash, &ip_set_hash[__key], list) \
- fn(__set_hash , ## args); \
- } \
-})
-
-#define FOREACH_HASH_RW_DO(fn, args...) \
-({ \
- ip_set_id_t __key; \
- struct ip_set_hash *__set_hash, *__n; \
- \
- ASSERT_WRITE_LOCK(&ip_set_lock); \
- for (__key = 0; __key < ip_set_bindings_hash_size; __key++) { \
- list_for_each_entry_safe(__set_hash, __n, &ip_set_hash[__key], list)\
- fn(__set_hash , ## args); \
- } \
-})
-
/* Add, del and test set entries from kernel */
-#define follow_bindings(index, set, ip) \
-((index = ip_set_find_in_hash((set)->id, ip)) != IP_SET_INVALID_ID \
- || (index = (set)->binding) != IP_SET_INVALID_ID)
-
int
ip_set_testip_kernel(ip_set_id_t index,
const struct sk_buff *skb,
const u_int32_t *flags)
{
struct ip_set *set;
- ip_set_ip_t ip;
int res;
- unsigned char i = 0;
-
- IP_SET_ASSERT(flags[i]);
+
read_lock_bh(&ip_set_lock);
- do {
- set = ip_set_list[index];
- IP_SET_ASSERT(set);
- DP("set %s, index %u", set->name, index);
- read_lock_bh(&set->lock);
- res = set->type->testip_kernel(set, skb, &ip, flags, i++);
- read_unlock_bh(&set->lock);
- i += !!(set->type->features & IPSET_DATA_DOUBLE);
- } while (res > 0
- && flags[i]
- && follow_bindings(index, set, ip));
+ set = ip_set_list[index];
+ IP_SET_ASSERT(set);
+ DP("set %s, index %u", set->name, index);
+
+ read_lock_bh(&set->lock);
+ res = set->type->testip_kernel(set, skb, flags);
+ read_unlock_bh(&set->lock);
+
read_unlock_bh(&ip_set_lock);
return (res < 0 ? 0 : res);
@@ -244,26 +102,20 @@ ip_set_addip_kernel(ip_set_id_t index,
const u_int32_t *flags)
{
struct ip_set *set;
- ip_set_ip_t ip;
int res;
- unsigned char i = 0;
- IP_SET_ASSERT(flags[i]);
retry:
read_lock_bh(&ip_set_lock);
- do {
- set = ip_set_list[index];
- IP_SET_ASSERT(set);
- DP("set %s, index %u", set->name, index);
- write_lock_bh(&set->lock);
- res = set->type->addip_kernel(set, skb, &ip, flags, i++);
- write_unlock_bh(&set->lock);
- i += !!(set->type->features & IPSET_DATA_DOUBLE);
- } while ((res == 0 || res == -EEXIST)
- && flags[i]
- && follow_bindings(index, set, ip));
- read_unlock_bh(&ip_set_lock);
+ set = ip_set_list[index];
+ IP_SET_ASSERT(set);
+ DP("set %s, index %u", set->name, index);
+ write_lock_bh(&set->lock);
+ res = set->type->addip_kernel(set, skb, flags);
+ write_unlock_bh(&set->lock);
+
+ read_unlock_bh(&ip_set_lock);
+ /* Retry function called without holding any lock */
if (res == -EAGAIN
&& set->type->retry
&& (res = set->type->retry(set)) == 0)
@@ -278,23 +130,17 @@ ip_set_delip_kernel(ip_set_id_t index,
const u_int32_t *flags)
{
struct ip_set *set;
- ip_set_ip_t ip;
int res;
- unsigned char i = 0;
- IP_SET_ASSERT(flags[i]);
read_lock_bh(&ip_set_lock);
- do {
- set = ip_set_list[index];
- IP_SET_ASSERT(set);
- DP("set %s, index %u", set->name, index);
- write_lock_bh(&set->lock);
- res = set->type->delip_kernel(set, skb, &ip, flags, i++);
- write_unlock_bh(&set->lock);
- i += !!(set->type->features & IPSET_DATA_DOUBLE);
- } while ((res == 0 || res == -EEXIST)
- && flags[i]
- && follow_bindings(index, set, ip));
+ set = ip_set_list[index];
+ IP_SET_ASSERT(set);
+ DP("set %s, index %u", set->name, index);
+
+ write_lock_bh(&set->lock);
+ res = set->type->delip_kernel(set, skb, flags);
+ write_unlock_bh(&set->lock);
+
read_unlock_bh(&ip_set_lock);
return res;
@@ -308,7 +154,7 @@ find_set_type(const char *name)
struct ip_set_type *set_type;
list_for_each_entry(set_type, &set_type_list, list)
- if (!strncmp(set_type->typename, name, IP_SET_MAXNAMELEN - 1))
+ if (STREQ(set_type->typename, name))
return set_type;
return NULL;
}
@@ -369,7 +215,7 @@ __ip_set_get_byname(const char *name, struct ip_set **set)
for (i = 0; i < ip_set_max; i++) {
if (ip_set_list[i] != NULL
- && SETNAME_EQ(ip_set_list[i]->name, name)) {
+ && STREQ(ip_set_list[i]->name, name)) {
__ip_set_get(i);
index = i;
*set = ip_set_list[i];
@@ -379,7 +225,8 @@ __ip_set_get_byname(const char *name, struct ip_set **set)
return index;
}
-void __ip_set_put_byindex(ip_set_id_t index)
+void
+__ip_set_put_byindex(ip_set_id_t index)
{
if (ip_set_list[index])
__ip_set_put(index);
@@ -402,7 +249,7 @@ ip_set_get_byname(const char *name)
down(&ip_set_app_mutex);
for (i = 0; i < ip_set_max; i++) {
if (ip_set_list[i] != NULL
- && SETNAME_EQ(ip_set_list[i]->name, name)) {
+ && STREQ(ip_set_list[i]->name, name)) {
__ip_set_get(i);
index = i;
break;
@@ -453,7 +300,8 @@ ip_set_id(ip_set_id_t index)
* reference count by 1. The caller shall not assume the index
* to be valid, after calling this function.
*/
-void ip_set_put_byindex(ip_set_id_t index)
+void
+ip_set_put_byindex(ip_set_id_t index)
{
down(&ip_set_app_mutex);
if (ip_set_list[index])
@@ -469,7 +317,7 @@ ip_set_find_byname(const char *name)
for (i = 0; i < ip_set_max; i++) {
if (ip_set_list[i] != NULL
- && SETNAME_EQ(ip_set_list[i]->name, name)) {
+ && STREQ(ip_set_list[i]->name, name)) {
index = i;
break;
}
@@ -487,37 +335,18 @@ ip_set_find_byindex(ip_set_id_t index)
}
/*
- * Add, del, test, bind and unbind
+ * Add, del and test
*/
-static inline int
-__ip_set_testip(struct ip_set *set,
- const void *data,
- u_int32_t size,
- ip_set_ip_t *ip)
-{
- int res;
-
- read_lock_bh(&set->lock);
- res = set->type->testip(set, data, size, ip);
- read_unlock_bh(&set->lock);
-
- return res;
-}
-
static int
-__ip_set_addip(ip_set_id_t index,
- const void *data,
- u_int32_t size)
+ip_set_addip(struct ip_set *set, const void *data, u_int32_t size)
{
- struct ip_set *set = ip_set_list[index];
- ip_set_ip_t ip;
int res;
IP_SET_ASSERT(set);
do {
write_lock_bh(&set->lock);
- res = set->type->addip(set, data, size, &ip);
+ res = set->type->addip(set, data, size);
write_unlock_bh(&set->lock);
} while (res == -EAGAIN
&& set->type->retry
@@ -527,289 +356,33 @@ __ip_set_addip(ip_set_id_t index,
}
static int
-ip_set_addip(ip_set_id_t index,
- const void *data,
- u_int32_t size)
-{
- struct ip_set *set = ip_set_list[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 %zu)",
- (long unsigned)set->type->reqsize,
- size - sizeof(struct ip_set_req_adt));
- return -EINVAL;
- }
- return __ip_set_addip(index,
- data + sizeof(struct ip_set_req_adt),
- size - sizeof(struct ip_set_req_adt));
-}
-
-static int
-ip_set_delip(ip_set_id_t index,
- const void *data,
- u_int32_t size)
+ip_set_delip(struct ip_set *set, const void *data, u_int32_t size)
{
- struct ip_set *set = ip_set_list[index];
- ip_set_ip_t ip;
int res;
IP_SET_ASSERT(set);
- if (size - sizeof(struct ip_set_req_adt) != set->type->reqsize) {
- ip_set_printk("data length wrong (want %lu, have %zu)",
- (long unsigned)set->type->reqsize,
- size - sizeof(struct ip_set_req_adt));
- return -EINVAL;
- }
write_lock_bh(&set->lock);
- res = set->type->delip(set,
- data + sizeof(struct ip_set_req_adt),
- size - sizeof(struct ip_set_req_adt),
- &ip);
+ res = set->type->delip(set, data, size);
write_unlock_bh(&set->lock);
return res;
}
static int
-ip_set_testip(ip_set_id_t index,
- const void *data,
- u_int32_t size)
+ip_set_testip(struct ip_set *set, const void *data, u_int32_t size)
{
- struct ip_set *set = ip_set_list[index];
- ip_set_ip_t ip;
int res;
IP_SET_ASSERT(set);
- if (size - sizeof(struct ip_set_req_adt) != set->type->reqsize) {
- ip_set_printk("data length wrong (want %lu, have %zu)",
- (long unsigned)set->type->reqsize,
- size - sizeof(struct ip_set_req_adt));
- return -EINVAL;
- }
- res = __ip_set_testip(set,
- data + sizeof(struct ip_set_req_adt),
- size - sizeof(struct ip_set_req_adt),
- &ip);
+ read_lock_bh(&set->lock);
+ res = set->type->testip(set, data, size);
+ read_unlock_bh(&set->lock);
return (res > 0 ? -EEXIST : res);
}
-static int
-ip_set_bindip(ip_set_id_t index,
- const void *data,
- u_int32_t size)
-{
- struct ip_set *set = ip_set_list[index];
- const struct ip_set_req_bind *req_bind;
- ip_set_id_t binding;
- ip_set_ip_t ip;
- int res;
-
- IP_SET_ASSERT(set);
- if (size < sizeof(struct ip_set_req_bind))
- return -EINVAL;
-
- req_bind = data;
-
- if (SETNAME_EQ(req_bind->binding, IPSET_TOKEN_DEFAULT)) {
- /* Default binding of a set */
- const char *binding_name;
-
- if (size != sizeof(struct ip_set_req_bind) + IP_SET_MAXNAMELEN)
- return -EINVAL;
-
- binding_name = data + sizeof(struct ip_set_req_bind);
-
- binding = ip_set_find_byname(binding_name);
- if (binding == IP_SET_INVALID_ID)
- return -ENOENT;
-
- write_lock_bh(&ip_set_lock);
- /* Sets as binding values are referenced */
- if (set->binding != IP_SET_INVALID_ID)
- __ip_set_put(set->binding);
- set->binding = binding;
- __ip_set_get(set->binding);
- write_unlock_bh(&ip_set_lock);
-
- return 0;
- }
- binding = ip_set_find_byname(req_bind->binding);
- if (binding == IP_SET_INVALID_ID)
- return -ENOENT;
-
- res = __ip_set_testip(set,
- data + sizeof(struct ip_set_req_bind),
- size - sizeof(struct ip_set_req_bind),
- &ip);
- DP("set %s, ip: %u.%u.%u.%u, binding %s",
- set->name, HIPQUAD(ip), ip_set_list[binding]->name);
-
- if (res >= 0)
- res = ip_set_hash_add(set->id, ip, binding);
-
- return res;
-}
-
-#define FOREACH_SET_DO(fn, args...) \
-({ \
- ip_set_id_t __i; \
- struct ip_set *__set; \
- \
- for (__i = 0; __i < ip_set_max; __i++) { \
- __set = ip_set_list[__i]; \
- if (__set != NULL) \
- fn(__set , ##args); \
- } \
-})
-
-static inline void
-__set_hash_del_byid(struct ip_set_hash *set_hash, ip_set_id_t id)
-{
- if (set_hash->id == id)
- __set_hash_del(set_hash);
-}
-
-static inline void
-__unbind_default(struct ip_set *set)
-{
- if (set->binding != IP_SET_INVALID_ID) {
- /* Sets as binding values are referenced */
- __ip_set_put(set->binding);
- set->binding = IP_SET_INVALID_ID;
- }
-}
-
-static int
-ip_set_unbindip(ip_set_id_t index,
- const void *data,
- u_int32_t size)
-{
- struct ip_set *set;
- const struct ip_set_req_bind *req_bind;
- ip_set_ip_t ip;
- int res;
-
- DP("");
- if (size < sizeof(struct ip_set_req_bind))
- return -EINVAL;
-
- req_bind = data;
-
- DP("%u %s", index, req_bind->binding);
- if (index == IP_SET_INVALID_ID) {
- /* unbind :all: */
- if (SETNAME_EQ(req_bind->binding, IPSET_TOKEN_DEFAULT)) {
- /* Default binding of sets */
- write_lock_bh(&ip_set_lock);
- FOREACH_SET_DO(__unbind_default);
- write_unlock_bh(&ip_set_lock);
- return 0;
- } else if (SETNAME_EQ(req_bind->binding, IPSET_TOKEN_ALL)) {
- /* Flush all bindings of all sets*/
- write_lock_bh(&ip_set_lock);
- FOREACH_HASH_RW_DO(__set_hash_del);
- write_unlock_bh(&ip_set_lock);
- return 0;
- }
- DP("unreachable reached!");
- return -EINVAL;
- }
-
- set = ip_set_list[index];
- IP_SET_ASSERT(set);
- if (SETNAME_EQ(req_bind->binding, IPSET_TOKEN_DEFAULT)) {
- /* Default binding of set */
- ip_set_id_t binding = ip_set_find_byindex(set->binding);
-
- if (binding == IP_SET_INVALID_ID)
- return -ENOENT;
-
- write_lock_bh(&ip_set_lock);
- /* Sets in hash values are referenced */
- __ip_set_put(set->binding);
- set->binding = IP_SET_INVALID_ID;
- write_unlock_bh(&ip_set_lock);
-
- return 0;
- } else if (SETNAME_EQ(req_bind->binding, IPSET_TOKEN_ALL)) {
- /* Flush all bindings */
-
- write_lock_bh(&ip_set_lock);
- FOREACH_HASH_RW_DO(__set_hash_del_byid, set->id);
- write_unlock_bh(&ip_set_lock);
- return 0;
- }
-
- res = __ip_set_testip(set,
- data + sizeof(struct ip_set_req_bind),
- size - sizeof(struct ip_set_req_bind),
- &ip);
-
- DP("set %s, ip: %u.%u.%u.%u", set->name, HIPQUAD(ip));
- if (res >= 0)
- res = ip_set_hash_del(set->id, ip);
-
- return res;
-}
-
-static int
-ip_set_testbind(ip_set_id_t index,
- const void *data,
- u_int32_t size)
-{
- struct ip_set *set = ip_set_list[index];
- const struct ip_set_req_bind *req_bind;
- ip_set_id_t binding;
- ip_set_ip_t ip;
- int res;
-
- IP_SET_ASSERT(set);
- if (size < sizeof(struct ip_set_req_bind))
- return -EINVAL;
-
- req_bind = data;
-
- if (SETNAME_EQ(req_bind->binding, IPSET_TOKEN_DEFAULT)) {
- /* Default binding of set */
- const char *binding_name;
-
- if (size != sizeof(struct ip_set_req_bind) + IP_SET_MAXNAMELEN)
- return -EINVAL;
-
- binding_name = data + sizeof(struct ip_set_req_bind);
-
- binding = ip_set_find_byname(binding_name);
- if (binding == IP_SET_INVALID_ID)
- return -ENOENT;
-
- res = (set->binding == binding) ? -EEXIST : 0;
-
- return res;
- }
- binding = ip_set_find_byname(req_bind->binding);
- if (binding == IP_SET_INVALID_ID)
- return -ENOENT;
-
-
- res = __ip_set_testip(set,
- data + sizeof(struct ip_set_req_bind),
- size - sizeof(struct ip_set_req_bind),
- &ip);
- DP("set %s, ip: %u.%u.%u.%u, binding %s",
- set->name, HIPQUAD(ip), ip_set_list[binding]->name);
-
- if (res >= 0)
- res = (ip_set_find_in_hash(set->id, ip) == binding)
- ? -EEXIST : 0;
-
- return res;
-}
-
static struct ip_set_type *
find_set_type_rlock(const char *typename)
{
@@ -835,7 +408,7 @@ find_free_id(const char *name,
if (ip_set_list[i] == NULL) {
if (*id == IP_SET_INVALID_ID)
*id = *index = i;
- } else if (SETNAME_EQ(name, ip_set_list[i]->name))
+ } else if (STREQ(name, ip_set_list[i]->name))
/* Name clash */
return -EEXIST;
}
@@ -879,7 +452,6 @@ ip_set_create(const char *name,
return -ENOMEM;
rwlock_init(&set->lock);
strncpy(set->name, name, IP_SET_MAXNAMELEN);
- set->binding = IP_SET_INVALID_ID;
atomic_set(&set->ref, 0);
/*
@@ -978,9 +550,6 @@ ip_set_destroy_set(ip_set_id_t index)
IP_SET_ASSERT(set);
DP("set: %s", set->name);
write_lock_bh(&ip_set_lock);
- FOREACH_HASH_RW_DO(__set_hash_del_byid, set->id);
- if (set->binding != IP_SET_INVALID_ID)
- __ip_set_put(set->binding);
ip_set_list[index] = NULL;
write_unlock_bh(&ip_set_lock);
@@ -1038,8 +607,13 @@ ip_set_flush(ip_set_id_t index)
if (index != IP_SET_INVALID_ID) {
IP_SET_ASSERT(ip_set_list[index]);
ip_set_flush_set(ip_set_list[index]);
- } else
- FOREACH_SET_DO(ip_set_flush_set);
+ } else {
+ ip_set_id_t i;
+
+ for (i = 0; i < ip_set_max; i++)
+ if (ip_set_list[i] != NULL)
+ ip_set_flush_set(ip_set_list[i]);
+ }
return 0;
}
@@ -1056,7 +630,7 @@ ip_set_rename(ip_set_id_t index, const char *name)
write_lock_bh(&ip_set_lock);
for (i = 0; i < ip_set_max; i++) {
if (ip_set_list[i] != NULL
- && SETNAME_EQ(ip_set_list[i]->name, name)) {
+ && STREQ(ip_set_list[i]->name, name)) {
res = -EEXIST;
goto unlock;
}
@@ -1107,39 +681,8 @@ ip_set_swap(ip_set_id_t from_index, ip_set_id_t to_index)
* List set data
*/
-static inline void
-__set_hash_bindings_size_list(struct ip_set_hash *set_hash,
- ip_set_id_t id, u_int32_t *size)
-{
- if (set_hash->id == id)
- *size += sizeof(struct ip_set_hash_list);
-}
-
-static inline void
-__set_hash_bindings_size_save(struct ip_set_hash *set_hash,
- ip_set_id_t id, u_int32_t *size)
-{
- if (set_hash->id == id)
- *size += sizeof(struct ip_set_hash_save);
-}
-
-static inline void
-__set_hash_bindings(struct ip_set_hash *set_hash,
- ip_set_id_t id, void *data, int *used)
-{
- if (set_hash->id == id) {
- struct ip_set_hash_list *hash_list = data + *used;
-
- hash_list->ip = set_hash->ip;
- hash_list->binding = set_hash->binding;
- *used += sizeof(struct ip_set_hash_list);
- }
-}
-
-static int ip_set_list_set(ip_set_id_t index,
- void *data,
- int *used,
- int len)
+static int
+ip_set_list_set(ip_set_id_t index, void *data, int *used, int len)
{
struct ip_set *set = ip_set_list[index];
struct ip_set_list *set_list;
@@ -1147,22 +690,22 @@ static int ip_set_list_set(ip_set_id_t index,
/* Pointer to our header */
set_list = data + *used;
- DP("set: %s, used: %d %p %p", set->name, *used, data, data + *used);
+ DP("set: %s, used: %d len %u %p %p", set->name, *used, len, data, data + *used);
/* Get and ensure header size */
- if (*used + sizeof(struct ip_set_list) > len)
+ if (*used + ALIGNED(sizeof(struct ip_set_list)) > len)
goto not_enough_mem;
- *used += sizeof(struct ip_set_list);
+ *used += ALIGNED(sizeof(struct ip_set_list));
read_lock_bh(&set->lock);
/* Get and ensure set specific header size */
- set_list->header_size = set->type->header_size;
+ set_list->header_size = ALIGNED(set->type->header_size);
if (*used + set_list->header_size > len)
goto unlock_set;
/* Fill in the header */
set_list->index = index;
- set_list->binding = set->binding;
+ set_list->binding = IP_SET_INVALID_ID;
set_list->ref = atomic_read(&set->ref);
/* Fill in set spefific header data */
@@ -1170,27 +713,18 @@ static int ip_set_list_set(ip_set_id_t index,
*used += set_list->header_size;
/* Get and ensure set specific members size */
- set_list->members_size = set->type->list_members_size(set);
+ set_list->members_size = set->type->list_members_size(set, DONT_ALIGN);
if (*used + set_list->members_size > len)
goto unlock_set;
/* Fill in set spefific members data */
- set->type->list_members(set, data + *used);
+ set->type->list_members(set, data + *used, DONT_ALIGN);
*used += set_list->members_size;
read_unlock_bh(&set->lock);
/* Bindings */
-
- /* Get and ensure set specific bindings size */
set_list->bindings_size = 0;
- FOREACH_HASH_DO(__set_hash_bindings_size_list,
- set->id, &set_list->bindings_size);
- if (*used + set_list->bindings_size > len)
- goto not_enough_mem;
- /* Fill in set spefific bindings data */
- FOREACH_HASH_DO(__set_hash_bindings, set->id, data, used);
-
return 0;
unlock_set:
@@ -1203,10 +737,28 @@ static int ip_set_list_set(ip_set_id_t index,
/*
* Save sets
*/
-static int ip_set_save_set(ip_set_id_t index,
- void *data,
- int *used,
- int len)
+static inline int
+ip_set_save_marker(void *data, int *used, int len)
+{
+ struct ip_set_save *set_save;
+
+ DP("used %u, len %u", *used, len);
+ /* Get and ensure header size */
+ if (*used + ALIGNED(sizeof(struct ip_set_save)) > len)
+ return -ENOMEM;
+
+ /* Marker: just for backward compatibility */
+ set_save = data + *used;
+ set_save->index = IP_SET_INVALID_ID;
+ set_save->header_size = 0;
+ set_save->members_size = 0;
+ *used += ALIGNED(sizeof(struct ip_set_save));
+
+ return 0;
+}
+
+static int
+ip_set_save_set(ip_set_id_t index, void *data, int *used, int len)
{
struct ip_set *set;
struct ip_set_save *set_save;
@@ -1215,9 +767,9 @@ static int ip_set_save_set(ip_set_id_t index,
set_save = data + *used;
/* Get and ensure header size */
- if (*used + sizeof(struct ip_set_save) > len)
+ if (*used + ALIGNED(sizeof(struct ip_set_save)) > len)
goto not_enough_mem;
- *used += sizeof(struct ip_set_save);
+ *used += ALIGNED(sizeof(struct ip_set_save));
set = ip_set_list[index];
DP("set: %s, used: %d(%d) %p %p", set->name, *used, len,
@@ -1225,13 +777,13 @@ static int ip_set_save_set(ip_set_id_t index,
read_lock_bh(&set->lock);
/* Get and ensure set specific header size */
- set_save->header_size = set->type->header_size;
+ set_save->header_size = ALIGNED(set->type->header_size);
if (*used + set_save->header_size > len)
goto unlock_set;
/* Fill in the header */
set_save->index = index;
- set_save->binding = set->binding;
+ set_save->binding = IP_SET_INVALID_ID;
/* Fill in set spefific header data */
set->type->list_header(set, data + *used);
@@ -1240,12 +792,12 @@ static int ip_set_save_set(ip_set_id_t index,
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);
+ set_save->members_size = set->type->list_members_size(set, DONT_ALIGN);
if (*used + set_save->members_size > len)
goto unlock_set;
/* Fill in set spefific members data */
- set->type->list_members(set, data + *used);
+ set->type->list_members(set, data + *used, DONT_ALIGN);
*used += set_save->members_size;
read_unlock_bh(&set->lock);
DP("set members filled: %s, used: %d(%lu) %p %p", set->name, *used,
@@ -1259,69 +811,15 @@ static int ip_set_save_set(ip_set_id_t index,
return -EAGAIN;
}
-static inline void
-__set_hash_save_bindings(struct ip_set_hash *set_hash,
- ip_set_id_t id,
- void *data,
- int *used,
- int len,
- int *res)
-{
- if (*res == 0
- && (id == IP_SET_INVALID_ID || set_hash->id == id)) {
- struct ip_set_hash_save *hash_save = data + *used;
- /* Ensure bindings size */
- if (*used + sizeof(struct ip_set_hash_save) > len) {
- *res = -ENOMEM;
- return;
- }
- hash_save->id = set_hash->id;
- hash_save->ip = set_hash->ip;
- hash_save->binding = set_hash->binding;
- *used += sizeof(struct ip_set_hash_save);
- }
-}
-
-static int ip_set_save_bindings(ip_set_id_t index,
- void *data,
- int *used,
- int len)
-{
- int res = 0;
- struct ip_set_save *set_save;
-
- DP("used %u, len %u", *used, len);
- /* Get and ensure header size */
- if (*used + sizeof(struct ip_set_save) > len)
- return -ENOMEM;
-
- /* Marker */
- set_save = data + *used;
- set_save->index = IP_SET_INVALID_ID;
- set_save->header_size = 0;
- set_save->members_size = 0;
- *used += sizeof(struct ip_set_save);
-
- DP("marker added used %u, len %u", *used, len);
- /* Fill in bindings data */
- if (index != IP_SET_INVALID_ID)
- /* Sets are identified by id in hash */
- index = ip_set_list[index]->id;
- FOREACH_HASH_DO(__set_hash_save_bindings, index, data, used, len, &res);
-
- return res;
-}
-
/*
* Restore sets
*/
-static int ip_set_restore(void *data,
- int len)
+static int
+ip_set_restore(void *data, int len)
{
int res = 0;
int line = 0, used = 0, members_size;
struct ip_set *set;
- struct ip_set_hash_save *hash_save;
struct ip_set_restore *set_restore;
ip_set_id_t index;
@@ -1329,12 +827,12 @@ static int ip_set_restore(void *data,
while (1) {
line++;
- DP("%d %zu %d", used, sizeof(struct ip_set_restore), len);
+ DP("%d %zu %d", used, ALIGNED(sizeof(struct ip_set_restore)), len);
/* Get and ensure header size */
- if (used + sizeof(struct ip_set_restore) > len)
+ if (used + ALIGNED(sizeof(struct ip_set_restore)) > len)
return line;
set_restore = data + used;
- used += sizeof(struct ip_set_restore);
+ used += ALIGNED(sizeof(struct ip_set_restore));
/* Ensure data size */
if (used
@@ -1345,7 +843,7 @@ static int ip_set_restore(void *data,
/* Check marker */
if (set_restore->index == IP_SET_INVALID_ID) {
line--;
- goto bindings;
+ goto finish;
}
/* Try to create the set */
@@ -1358,7 +856,7 @@ static int ip_set_restore(void *data,
if (res != 0)
return line;
- used += set_restore->header_size;
+ used += ALIGNED(set_restore->header_size);
index = ip_set_find_byindex(set_restore->index);
DP("index %u, restore_index %u", index, set_restore->index);
@@ -1370,16 +868,16 @@ static int ip_set_restore(void *data,
DP("members_size %lu reqsize %lu",
(unsigned long)set_restore->members_size,
(unsigned long)set->type->reqsize);
- while (members_size + set->type->reqsize <=
+ while (members_size + ALIGNED(set->type->reqsize) <=
set_restore->members_size) {
line++;
DP("members: %d, line %d", members_size, line);
- res = __ip_set_addip(index,
+ res = ip_set_addip(set,
data + used + members_size,
set->type->reqsize);
if (!(res == 0 || res == -EEXIST))
return line;
- members_size += set->type->reqsize;
+ members_size += ALIGNED(set->type->reqsize);
}
DP("members_size %lu %d",
@@ -1389,45 +887,7 @@ static int ip_set_restore(void *data,
used += set_restore->members_size;
}
- bindings:
- /* Loop to restore bindings */
- while (used < len) {
- line++;
-
- DP("restore binding, line %u", line);
- /* Get and ensure size */
- if (used + sizeof(struct ip_set_hash_save) > len)
- return line;
- hash_save = data + used;
- used += sizeof(struct ip_set_hash_save);
-
- /* hash_save->id is used to store the index */
- index = ip_set_find_byindex(hash_save->id);
- DP("restore binding index %u, id %u, %u -> %u",
- index, hash_save->id, hash_save->ip, hash_save->binding);
- if (index != hash_save->id)
- return line;
- if (ip_set_find_byindex(hash_save->binding) == IP_SET_INVALID_ID) {
- DP("corrupt binding set index %u", hash_save->binding);
- return line;
- }
- set = ip_set_list[hash_save->id];
- /* Null valued IP means default binding */
- if (hash_save->ip)
- res = ip_set_hash_add(set->id,
- hash_save->ip,
- hash_save->binding);
- else {
- IP_SET_ASSERT(set->binding == IP_SET_INVALID_ID);
- write_lock_bh(&ip_set_lock);
- set->binding = hash_save->binding;
- __ip_set_get(set->binding);
- write_unlock_bh(&ip_set_lock);
- DP("default binding: %u", set->binding);
- }
- if (res != 0)
- return line;
- }
+ finish:
if (used != len)
return line;
@@ -1439,17 +899,17 @@ ip_set_sockfn_set(struct sock *sk, int optval, void *user, unsigned int len)
{
void *data;
int res = 0; /* Assume OK */
+ size_t offset;
unsigned *op;
struct ip_set_req_adt *req_adt;
ip_set_id_t index = IP_SET_INVALID_ID;
- int (*adtfn)(ip_set_id_t index,
+ int (*adtfn)(struct ip_set *set,
const void *data, u_int32_t size);
struct fn_table {
- int (*fn)(ip_set_id_t index,
+ int (*fn)(struct ip_set *set,
const void *data, u_int32_t size);
} adtfn_table[] =
- { { ip_set_addip }, { ip_set_delip }, { ip_set_testip},
- { ip_set_bindip}, { ip_set_unbindip }, { ip_set_testbind },
+ { { ip_set_addip }, { ip_set_delip }, { ip_set_testip},
};
DP("optval=%d, user=%p, len=%d", optval, user, len);
@@ -1482,19 +942,22 @@ ip_set_sockfn_set(struct sock *sk, int optval, void *user, unsigned int len)
if (*op < IP_SET_OP_VERSION) {
/* Check the version at the beginning of operations */
struct ip_set_req_version *req_version = data;
- if (req_version->version != IP_SET_PROTOCOL_VERSION) {
+ if (!(req_version->version == IP_SET_PROTOCOL_UNALIGNED
+ || req_version->version == IP_SET_PROTOCOL_VERSION)) {
res = -EPROTO;
goto done;
}
+ protocol_version = req_version->version;
}
switch (*op) {
case IP_SET_OP_CREATE:{
struct ip_set_req_create *req_create = data;
+ offset = ALIGNED(sizeof(struct ip_set_req_create));
- if (len < sizeof(struct ip_set_req_create)) {
+ if (len < offset) {
ip_set_printk("short CREATE data (want >=%zu, got %u)",
- sizeof(struct ip_set_req_create), len);
+ offset, len);
res = -EINVAL;
goto done;
}
@@ -1503,8 +966,8 @@ ip_set_sockfn_set(struct sock *sk, int optval, void *user, unsigned int len)
res = ip_set_create(req_create->name,
req_create->typename,
IP_SET_INVALID_ID,
- data + sizeof(struct ip_set_req_create),
- len - sizeof(struct ip_set_req_create));
+ data + offset,
+ len - offset);
goto done;
}
case IP_SET_OP_DESTROY:{
@@ -1516,7 +979,7 @@ ip_set_sockfn_set(struct sock *sk, int optval, void *user, unsigned int len)
res = -EINVAL;
goto done;
}
- if (SETNAME_EQ(req_destroy->name, IPSET_TOKEN_ALL)) {
+ if (STREQ(req_destroy->name, IPSET_TOKEN_ALL)) {
/* Destroy all sets */
index = IP_SET_INVALID_ID;
} else {
@@ -1541,7 +1004,7 @@ ip_set_sockfn_set(struct sock *sk, int optval, void *user, unsigned int len)
res = -EINVAL;
goto done;
}
- if (SETNAME_EQ(req_flush->name, IPSET_TOKEN_ALL)) {
+ if (STREQ(req_flush->name, IPSET_TOKEN_ALL)) {
/* Flush all sets */
index = IP_SET_INVALID_ID;
} else {
@@ -1609,30 +1072,40 @@ ip_set_sockfn_set(struct sock *sk, int optval, void *user, unsigned int len)
}
/* There we may have add/del/test/bind/unbind/test_bind operations */
- if (*op < IP_SET_OP_ADD_IP || *op > IP_SET_OP_TEST_BIND_SET) {
+ if (*op < IP_SET_OP_ADD_IP || *op > IP_SET_OP_TEST_IP) {
res = -EBADMSG;
goto done;
}
adtfn = adtfn_table[*op - IP_SET_OP_ADD_IP].fn;
- if (len < sizeof(struct ip_set_req_adt)) {
+ if (len < ALIGNED(sizeof(struct ip_set_req_adt))) {
ip_set_printk("short data in adt request (want >=%zu, got %u)",
- sizeof(struct ip_set_req_adt), len);
+ ALIGNED(sizeof(struct ip_set_req_adt)), len);
res = -EINVAL;
goto done;
}
req_adt = data;
- /* -U :all: :all:|:default: uses IP_SET_INVALID_ID */
- if (!(*op == IP_SET_OP_UNBIND_SET
- && req_adt->index == IP_SET_INVALID_ID)) {
- index = ip_set_find_byindex(req_adt->index);
- if (index == IP_SET_INVALID_ID) {
- res = -ENOENT;
+ index = ip_set_find_byindex(req_adt->index);
+ if (index == IP_SET_INVALID_ID) {
+ res = -ENOENT;
+ goto done;
+ }
+ do {
+ struct ip_set *set = ip_set_list[index];
+ size_t offset = ALIGNED(sizeof(struct ip_set_req_adt));
+
+ IP_SET_ASSERT(set);
+
+ if (len - offset != set->type->reqsize) {
+ ip_set_printk("data length wrong (want %lu, have %zu)",
+ (long unsigned)set->type->reqsize,
+ len - offset);
+ res = -EINVAL;
goto done;
}
- }
- res = adtfn(index, data, len);
+ res = adtfn(set, data + offset, len - offset);
+ } while (0);
done:
up(&ip_set_app_mutex);
@@ -1682,10 +1155,12 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
if (*op < IP_SET_OP_VERSION) {
/* Check the version at the beginning of operations */
struct ip_set_req_version *req_version = data;
- if (req_version->version != IP_SET_PROTOCOL_VERSION) {
+ if (!(req_version->version == IP_SET_PROTOCOL_UNALIGNED
+ || req_version->version == IP_SET_PROTOCOL_VERSION)) {
res = -EPROTO;
goto done;
}
+ protocol_version = req_version->version;
}
switch (*op) {
@@ -1768,7 +1243,7 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
goto done;
}
- if (SETNAME_EQ(req_max_sets->set.name, IPSET_TOKEN_ALL)) {
+ if (STREQ(req_max_sets->set.name, IPSET_TOKEN_ALL)) {
req_max_sets->set.index = IP_SET_INVALID_ID;
} else {
req_max_sets->set.name[IP_SET_MAXNAMELEN - 1] = '\0';
@@ -1795,20 +1270,21 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
ip_set_id_t i;
int used;
- if (*len < sizeof(struct ip_set_req_setnames)) {
+ if (*len < ALIGNED(sizeof(struct ip_set_req_setnames))) {
ip_set_printk("short LIST_SIZE (want >=%zu, got %d)",
- sizeof(struct ip_set_req_setnames), *len);
+ ALIGNED(sizeof(struct ip_set_req_setnames)),
+ *len);
res = -EINVAL;
goto done;
}
req_setnames->size = 0;
- used = sizeof(struct ip_set_req_setnames);
+ used = ALIGNED(sizeof(struct ip_set_req_setnames));
for (i = 0; i < ip_set_max; i++) {
if (ip_set_list[i] == NULL)
continue;
name_list = data + used;
- used += sizeof(struct ip_set_name_list);
+ used += ALIGNED(sizeof(struct ip_set_name_list));
if (used > copylen) {
res = -EAGAIN;
goto done;
@@ -1830,27 +1306,12 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
|| req_setnames->index == i))
continue;
/* Update size */
- switch (*op) {
- case IP_SET_OP_LIST_SIZE: {
- req_setnames->size += sizeof(struct ip_set_list)
- + set->type->header_size
- + set->type->list_members_size(set);
- /* Sets are identified by id in the hash */
- FOREACH_HASH_DO(__set_hash_bindings_size_list,
- set->id, &req_setnames->size);
- break;
- }
- case IP_SET_OP_SAVE_SIZE: {
- req_setnames->size += sizeof(struct ip_set_save)
- + set->type->header_size
- + set->type->list_members_size(set);
- FOREACH_HASH_DO(__set_hash_bindings_size_save,
- set->id, &req_setnames->size);
- break;
- }
- default:
- break;
- }
+ req_setnames->size +=
+ (*op == IP_SET_OP_LIST_SIZE ?
+ ALIGNED(sizeof(struct ip_set_list)) :
+ ALIGNED(sizeof(struct ip_set_save)))
+ + ALIGNED(set->type->header_size)
+ + set->type->list_members_size(set, DONT_ALIGN);
}
if (copylen != used) {
res = -EAGAIN;
@@ -1933,7 +1394,7 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
res = ip_set_save_set(index, data, &used, *len);
}
if (res == 0)
- res = ip_set_save_bindings(index, data, &used, *len);
+ res = ip_set_save_marker(data, &used, *len);
if (res != 0)
goto done;
@@ -1945,17 +1406,16 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
}
case IP_SET_OP_RESTORE: {
struct ip_set_req_setnames *req_restore = data;
+ size_t offset = ALIGNED(sizeof(struct ip_set_req_setnames));
int line;
- if (*len < sizeof(struct ip_set_req_setnames)
- || *len != req_restore->size) {
+ if (*len < offset || *len != req_restore->size) {
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));
+ line = ip_set_restore(data + offset, req_restore->size - offset);
DP("ip_set_restore: %d", line);
if (line != 0) {
res = -EAGAIN;
@@ -2001,40 +1461,32 @@ static struct nf_sockopt_ops so_set = {
#endif
};
-static int max_sets, hash_size;
+static int max_sets;
module_param(max_sets, int, 0600);
MODULE_PARM_DESC(max_sets, "maximal number of sets");
-module_param(hash_size, int, 0600);
-MODULE_PARM_DESC(hash_size, "hash size for bindings");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
MODULE_DESCRIPTION("module implementing core IP set support");
-static int __init ip_set_init(void)
+static int __init
+ip_set_init(void)
{
int res;
- ip_set_id_t i;
- get_random_bytes(&ip_set_hash_random, 4);
+ init_MUTEX(&ip_set_app_mutex);
+
if (max_sets)
ip_set_max = max_sets;
+ if (ip_set_max >= IP_SET_INVALID_ID)
+ ip_set_max = IP_SET_INVALID_ID - 1;
+
ip_set_list = vmalloc(sizeof(struct ip_set *) * ip_set_max);
if (!ip_set_list) {
printk(KERN_ERR "Unable to create ip_set_list\n");
return -ENOMEM;
}
memset(ip_set_list, 0, sizeof(struct ip_set *) * ip_set_max);
- if (hash_size)
- ip_set_bindings_hash_size = hash_size;
- ip_set_hash = vmalloc(sizeof(struct list_head) * ip_set_bindings_hash_size);
- if (!ip_set_hash) {
- printk(KERN_ERR "Unable to create ip_set_hash\n");
- vfree(ip_set_list);
- return -ENOMEM;
- }
- for (i = 0; i < ip_set_bindings_hash_size; i++)
- INIT_LIST_HEAD(&ip_set_hash[i]);
INIT_LIST_HEAD(&set_type_list);
@@ -2042,19 +1494,19 @@ static int __init ip_set_init(void)
if (res != 0) {
ip_set_printk("SO_SET registry failed: %d", res);
vfree(ip_set_list);
- vfree(ip_set_hash);
return res;
}
-
+
+ printk("ip_set version %u loaded\n", IP_SET_PROTOCOL_VERSION);
return 0;
}
-static void __exit ip_set_fini(void)
+static void __exit
+ip_set_fini(void)
{
/* There can't be any existing set or binding */
nf_unregister_sockopt(&so_set);
vfree(ip_set_list);
- vfree(ip_set_hash);
DP("these are the famous last words");
}
diff --git a/kernel/ip_set_iphash.c b/kernel/ip_set_iphash.c
index aac3eec..1accbe3 100644
--- a/kernel/ip_set_iphash.c
+++ b/kernel/ip_set_iphash.c
@@ -25,22 +25,21 @@
static int limit = MAX_RANGE;
static inline __u32
-iphash_id(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
+iphash_id(struct ip_set *set, ip_set_ip_t ip)
{
struct ip_set_iphash *map = set->data;
__u32 id;
u_int16_t i;
ip_set_ip_t *elem;
- *hash_ip = ip & map->netmask;
- DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u, %u.%u.%u.%u",
- set->name, HIPQUAD(ip), HIPQUAD(*hash_ip), HIPQUAD(map->netmask));
-
+
+ ip &= map->netmask;
+ DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(ip));
for (i = 0; i < map->probes; i++) {
- id = jhash_ip(map, i, *hash_ip) % map->hashsize;
+ id = jhash_ip(map, i, ip) % map->hashsize;
DP("hash key: %u", id);
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
- if (*elem == *hash_ip)
+ if (*elem == ip)
return id;
/* No shortcut - there can be deleted entries. */
}
@@ -48,9 +47,9 @@ iphash_id(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
}
static inline int
-iphash_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
+iphash_test(struct ip_set *set, ip_set_ip_t ip)
{
- return (ip && iphash_id(set, hash_ip, ip) != UINT_MAX);
+ return (ip && iphash_id(set, ip) != UINT_MAX);
}
#define KADT_CONDITION
@@ -84,16 +83,15 @@ __iphash_add(struct ip_set_iphash *map, ip_set_ip_t *ip)
}
static inline int
-iphash_add(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
+iphash_add(struct ip_set *set, ip_set_ip_t ip)
{
struct ip_set_iphash *map = set->data;
if (!ip || map->elements >= limit)
return -ERANGE;
- *hash_ip = ip & map->netmask;
-
- return __iphash_add(map, hash_ip);
+ ip &= map->netmask;
+ return __iphash_add(map, &ip);
}
UADT(iphash, add)
@@ -108,7 +106,7 @@ __iphash_retry(struct ip_set_iphash *tmp, struct ip_set_iphash *map)
HASH_RETRY(iphash, ip_set_ip_t)
static inline int
-iphash_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
+iphash_del(struct ip_set *set, ip_set_ip_t ip)
{
struct ip_set_iphash *map = set->data;
ip_set_ip_t id, *elem;
@@ -116,7 +114,7 @@ iphash_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
if (!ip)
return -ERANGE;
- id = iphash_id(set, hash_ip, ip);
+ id = iphash_id(set, ip);
if (id == UINT_MAX)
return -EEXIST;
diff --git a/kernel/ip_set_ipmap.c b/kernel/ip_set_ipmap.c
index 442f0d3..be3c538 100644
--- a/kernel/ip_set_ipmap.c
+++ b/kernel/ip_set_ipmap.c
@@ -22,21 +22,19 @@
static inline ip_set_ip_t
ip_to_id(const struct ip_set_ipmap *map, ip_set_ip_t ip)
{
- return (ip - map->first_ip)/map->hosts;
+ return ((ip & map->netmask) - map->first_ip)/map->hosts;
}
static inline int
-ipmap_test(const struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
+ipmap_test(const struct ip_set *set, ip_set_ip_t ip)
{
const struct ip_set_ipmap *map = set->data;
if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE;
- *hash_ip = ip & map->netmask;
- DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u",
- set->name, HIPQUAD(ip), HIPQUAD(*hash_ip));
- return !!test_bit(ip_to_id(map, *hash_ip), map->members);
+ DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(ip));
+ return !!test_bit(ip_to_id(map, ip), map->members);
}
#define KADT_CONDITION
@@ -45,16 +43,15 @@ UADT(ipmap, test)
KADT(ipmap, test, ipaddr)
static inline int
-ipmap_add(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
+ipmap_add(struct ip_set *set, ip_set_ip_t ip)
{
struct ip_set_ipmap *map = set->data;
if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE;
- *hash_ip = ip & map->netmask;
- DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip));
- if (test_and_set_bit(ip_to_id(map, *hash_ip), map->members))
+ DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(ip));
+ if (test_and_set_bit(ip_to_id(map, ip), map->members))
return -EEXIST;
return 0;
@@ -64,16 +61,15 @@ UADT(ipmap, add)
KADT(ipmap, add, ipaddr)
static inline int
-ipmap_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
+ipmap_del(struct ip_set *set, ip_set_ip_t ip)
{
struct ip_set_ipmap *map = set->data;
if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE;
- *hash_ip = ip & map->netmask;
- DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip));
- if (!test_and_clear_bit(ip_to_id(map, *hash_ip), map->members))
+ DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(ip));
+ if (!test_and_clear_bit(ip_to_id(map, ip), map->members))
return -EEXIST;
return 0;
@@ -130,8 +126,28 @@ __ipmap_list_header(const struct ip_set_ipmap *map,
}
BITMAP_LIST_HEADER(ipmap)
-BITMAP_LIST_MEMBERS_SIZE(ipmap)
-BITMAP_LIST_MEMBERS(ipmap)
+BITMAP_LIST_MEMBERS_SIZE(ipmap, ip_set_ip_t, map->sizeid,
+ test_bit(i, map->members))
+
+static void
+ipmap_list_members(const struct ip_set *set, void *data, char dont_align)
+{
+ const struct ip_set_ipmap *map = set->data;
+ uint32_t i, n = 0;
+ ip_set_ip_t *d;
+
+ if (dont_align) {
+ memcpy(data, map->members, map->size);
+ return;
+ }
+
+ for (i = 0; i < map->sizeid; i++)
+ if (test_bit(i, map->members)) {
+ d = data + n * IPSET_ALIGN(sizeof(ip_set_ip_t));
+ *d = map->first_ip + i * map->hosts;
+ n++;
+ }
+}
IP_SET_TYPE(ipmap, IPSET_TYPE_IP | IPSET_DATA_SINGLE)
diff --git a/kernel/ip_set_ipporthash.c b/kernel/ip_set_ipporthash.c
index c41c0a8..36e68b0 100644
--- a/kernel/ip_set_ipporthash.c
+++ b/kernel/ip_set_ipporthash.c
@@ -28,26 +28,23 @@
static int limit = MAX_RANGE;
static inline __u32
-ipporthash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
- ip_set_ip_t ip, ip_set_ip_t port)
+ipporthash_id(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port)
{
struct ip_set_ipporthash *map = set->data;
__u32 id;
u_int16_t i;
ip_set_ip_t *elem;
- *hash_ip = pack_ip_port(map, ip, port);
+ ip = pack_ip_port(map, ip, port);
- DP("set: %s, ipport:%u.%u.%u.%u:%u, %u.%u.%u.%u",
- set->name, HIPQUAD(ip), port, HIPQUAD(*hash_ip));
- if (!*hash_ip)
+ if (!ip)
return UINT_MAX;
for (i = 0; i < map->probes; i++) {
- id = jhash_ip(map, i, *hash_ip) % map->hashsize;
+ id = jhash_ip(map, i, ip) % map->hashsize;
DP("hash key: %u", id);
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
- if (*elem == *hash_ip)
+ if (*elem == ip)
return id;
/* No shortcut - there can be deleted entries. */
}
@@ -55,24 +52,23 @@ ipporthash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
}
static inline int
-ipporthash_test(struct ip_set *set, ip_set_ip_t *hash_ip,
- ip_set_ip_t ip, ip_set_ip_t port)
+ipporthash_test(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port)
{
struct ip_set_ipporthash *map = set->data;
if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE;
- return (ipporthash_id(set, hash_ip, ip, port) != UINT_MAX);
+ return (ipporthash_id(set, ip, port) != UINT_MAX);
}
#define KADT_CONDITION \
ip_set_ip_t port; \
\
- if (flags[index+1] == 0) \
+ if (flags[1] == 0) \
return 0; \
\
- port = get_port(skb, flags[index+1]); \
+ port = get_port(skb, flags++); \
\
if (port == INVALID_PORT) \
return 0;
@@ -106,8 +102,7 @@ __ipporthash_add(struct ip_set_ipporthash *map, ip_set_ip_t *ip)
}
static inline int
-ipporthash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
- ip_set_ip_t ip, ip_set_ip_t port)
+ipporthash_add(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port)
{
struct ip_set_ipporthash *map = set->data;
if (map->elements > limit)
@@ -115,12 +110,12 @@ ipporthash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE;
- *hash_ip = pack_ip_port(map, ip, port);
+ ip = pack_ip_port(map, ip, port);
- if (!*hash_ip)
+ if (!ip)
return -ERANGE;
- return __ipporthash_add(map, hash_ip);
+ return __ipporthash_add(map, &ip);
}
UADT(ipporthash, add, req->port)
@@ -137,8 +132,7 @@ __ipporthash_retry(struct ip_set_ipporthash *tmp,
HASH_RETRY(ipporthash, ip_set_ip_t)
static inline int
-ipporthash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
- ip_set_ip_t ip, ip_set_ip_t port)
+ipporthash_del(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port)
{
struct ip_set_ipporthash *map = set->data;
ip_set_ip_t id;
@@ -147,7 +141,7 @@ ipporthash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE;
- id = ipporthash_id(set, hash_ip, ip, port);
+ id = ipporthash_id(set, ip, port);
if (id == UINT_MAX)
return -EEXIST;
diff --git a/kernel/ip_set_ipportiphash.c b/kernel/ip_set_ipportiphash.c
index 166bec4..5fe00f1 100644
--- a/kernel/ip_set_ipportiphash.c
+++ b/kernel/ip_set_ipportiphash.c
@@ -31,7 +31,7 @@ static int limit = MAX_RANGE;
jhash_2words(ipport, ip1, *(map->initval + i))
static inline __u32
-ipportiphash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
+ipportiphash_id(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
{
struct ip_set_ipportiphash *map = set->data;
@@ -39,17 +39,15 @@ ipportiphash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
u_int16_t i;
struct ipportip *elem;
- *hash_ip = pack_ip_port(map, ip, port);
- DP("set: %s, ipport:%u.%u.%u.%u:%u, %u.%u.%u.%u",
- set->name, HIPQUAD(ip), port, HIPQUAD(*hash_ip));
- if (!(*hash_ip || ip1))
+ ip = pack_ip_port(map, ip, port);
+ if (!(ip || ip1))
return UINT_MAX;
for (i = 0; i < map->probes; i++) {
- id = jhash_ip2(map, i, *hash_ip, ip1) % map->hashsize;
+ id = jhash_ip2(map, i, ip, ip1) % map->hashsize;
DP("hash key: %u", id);
elem = HARRAY_ELEM(map->members, struct ipportip *, id);
- if (elem->ip == *hash_ip && elem->ip1 == ip1)
+ if (elem->ip == ip && elem->ip1 == ip1)
return id;
/* No shortcut - there can be deleted entries. */
}
@@ -57,7 +55,7 @@ ipportiphash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
}
static inline int
-ipportiphash_test(struct ip_set *set, ip_set_ip_t *hash_ip,
+ipportiphash_test(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
{
struct ip_set_ipportiphash *map = set->data;
@@ -65,17 +63,17 @@ ipportiphash_test(struct ip_set *set, ip_set_ip_t *hash_ip,
if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE;
- return (ipportiphash_id(set, hash_ip, ip, port, ip1) != UINT_MAX);
+ return (ipportiphash_id(set, ip, port, ip1) != UINT_MAX);
}
#define KADT_CONDITION \
ip_set_ip_t port, ip1; \
\
- if (flags[index+2] == 0) \
+ if (flags[2] == 0) \
return 0; \
\
- port = get_port(skb, flags[index+1]); \
- ip1 = ipaddr(skb, flags[index+2]); \
+ port = get_port(skb, flags++); \
+ ip1 = ipaddr(skb, flags++); \
\
if (port == INVALID_PORT) \
return 0;
@@ -85,23 +83,23 @@ KADT(ipportiphash, test, ipaddr, port, ip1)
static inline int
__ipportip_add(struct ip_set_ipportiphash *map,
- ip_set_ip_t hash_ip, ip_set_ip_t ip1)
+ ip_set_ip_t ip, ip_set_ip_t ip1)
{
__u32 probe;
u_int16_t i;
struct ipportip *elem, *slot = NULL;
for (i = 0; i < map->probes; i++) {
- probe = jhash_ip2(map, i, hash_ip, ip1) % map->hashsize;
+ probe = jhash_ip2(map, i, ip, ip1) % map->hashsize;
elem = HARRAY_ELEM(map->members, struct ipportip *, probe);
- if (elem->ip == hash_ip && elem->ip1 == ip1)
+ if (elem->ip == ip && elem->ip1 == ip1)
return -EEXIST;
if (!(slot || elem->ip || elem->ip1))
slot = elem;
/* There can be deleted entries, must check all slots */
}
if (slot) {
- slot->ip = hash_ip;
+ slot->ip = ip;
slot->ip1 = ip1;
map->elements++;
return 0;
@@ -118,7 +116,7 @@ __ipportiphash_add(struct ip_set_ipportiphash *map,
}
static inline int
-ipportiphash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
+ipportiphash_add(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
{
struct ip_set_ipportiphash *map = set->data;
@@ -128,11 +126,11 @@ ipportiphash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE;
- *hash_ip = pack_ip_port(map, ip, port);
- if (!(*hash_ip || ip1))
+ ip = pack_ip_port(map, ip, port);
+ if (!(ip || ip1))
return -ERANGE;
- return __ipportip_add(map, *hash_ip, ip1);
+ return __ipportip_add(map, ip, ip1);
}
UADT(ipportiphash, add, req->port, req->ip1)
@@ -149,7 +147,7 @@ __ipportiphash_retry(struct ip_set_ipportiphash *tmp,
HASH_RETRY2(ipportiphash, struct ipportip)
static inline int
-ipportiphash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
+ipportiphash_del(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
{
struct ip_set_ipportiphash *map = set->data;
@@ -159,7 +157,7 @@ ipportiphash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE;
- id = ipportiphash_id(set, hash_ip, ip, port, ip1);
+ id = ipportiphash_id(set, ip, port, ip1);
if (id == UINT_MAX)
return -EEXIST;
diff --git a/kernel/ip_set_ipportnethash.c b/kernel/ip_set_ipportnethash.c
index 45e53ed..9179184 100644
--- a/kernel/ip_set_ipportnethash.c
+++ b/kernel/ip_set_ipportnethash.c
@@ -31,7 +31,7 @@ static int limit = MAX_RANGE;
jhash_2words(ipport, ip1, *(map->initval + i))
static inline __u32
-ipportnethash_id_cidr(struct ip_set *set, ip_set_ip_t *hash_ip,
+ipportnethash_id_cidr(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port,
ip_set_ip_t ip1, uint8_t cidr)
{
@@ -40,18 +40,16 @@ ipportnethash_id_cidr(struct ip_set *set, ip_set_ip_t *hash_ip,
u_int16_t i;
struct ipportip *elem;
- *hash_ip = pack_ip_port(map, ip, port);
- DP("set: %s, ipport:%u.%u.%u.%u:%u, %u.%u.%u.%u",
- set->name, HIPQUAD(ip), port, HIPQUAD(*hash_ip));
+ ip = pack_ip_port(map, ip, port);
ip1 = pack_ip_cidr(ip1, cidr);
- if (!(*hash_ip || ip1))
+ if (!(ip || ip1))
return UINT_MAX;
for (i = 0; i < map->probes; i++) {
- id = jhash_ip2(map, i, *hash_ip, ip1) % map->hashsize;
+ id = jhash_ip2(map, i, ip, ip1) % map->hashsize;
DP("hash key: %u", id);
elem = HARRAY_ELEM(map->members, struct ipportip *, id);
- if (elem->ip == *hash_ip && elem->ip1 == ip1)
+ if (elem->ip == ip && elem->ip1 == ip1)
return id;
/* No shortcut - there can be deleted entries. */
}
@@ -59,7 +57,7 @@ ipportnethash_id_cidr(struct ip_set *set, ip_set_ip_t *hash_ip,
}
static inline __u32
-ipportnethash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
+ipportnethash_id(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
{
struct ip_set_ipportnethash *map = set->data;
@@ -67,8 +65,7 @@ ipportnethash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
int i;
for (i = 0; i < 30 && map->cidr[i]; i++) {
- id = ipportnethash_id_cidr(set, hash_ip, ip, port, ip1,
- map->cidr[i]);
+ id = ipportnethash_id_cidr(set, ip, port, ip1, map->cidr[i]);
if (id != UINT_MAX)
break;
}
@@ -76,7 +73,7 @@ ipportnethash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
}
static inline int
-ipportnethash_test_cidr(struct ip_set *set, ip_set_ip_t *hash_ip,
+ipportnethash_test_cidr(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port,
ip_set_ip_t ip1, uint8_t cidr)
{
@@ -85,12 +82,11 @@ ipportnethash_test_cidr(struct ip_set *set, ip_set_ip_t *hash_ip,
if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE;
- return (ipportnethash_id_cidr(set, hash_ip, ip, port, ip1,
- cidr) != UINT_MAX);
+ return (ipportnethash_id_cidr(set, ip, port, ip1, cidr) != UINT_MAX);
}
static inline int
-ipportnethash_test(struct ip_set *set, ip_set_ip_t *hash_ip,
+ipportnethash_test(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
{
struct ip_set_ipportnethash *map = set->data;
@@ -98,32 +94,30 @@ ipportnethash_test(struct ip_set *set, ip_set_ip_t *hash_ip,
if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE;
- return (ipportnethash_id(set, hash_ip, ip, port, ip1) != UINT_MAX);
+ return (ipportnethash_id(set, ip, port, ip1) != UINT_MAX);
}
static int
-ipportnethash_utest(struct ip_set *set, const void *data, u_int32_t size,
- ip_set_ip_t *hash_ip)
+ipportnethash_utest(struct ip_set *set, const void *data, u_int32_t size)
{
const struct ip_set_req_ipportnethash *req = data;
if (req->cidr <= 0 || req->cidr > 32)
return -EINVAL;
return (req->cidr == 32
- ? ipportnethash_test(set, hash_ip, req->ip, req->port,
- req->ip1)
- : ipportnethash_test_cidr(set, hash_ip, req->ip, req->port,
+ ? ipportnethash_test(set, req->ip, req->port, req->ip1)
+ : ipportnethash_test_cidr(set, req->ip, req->port,
req->ip1, req->cidr));
}
#define KADT_CONDITION \
ip_set_ip_t port, ip1; \
\
- if (flags[index+2] == 0) \
+ if (flags[2] == 0) \
return 0; \
\
- port = get_port(skb, flags[index+1]); \
- ip1 = ipaddr(skb, flags[index+2]); \
+ port = get_port(skb, flags++); \
+ ip1 = ipaddr(skb, flags++); \
\
if (port == INVALID_PORT) \
return 0;
@@ -132,23 +126,23 @@ KADT(ipportnethash, test, ipaddr, port, ip1)
static inline int
__ipportnet_add(struct ip_set_ipportnethash *map,
- ip_set_ip_t hash_ip, ip_set_ip_t ip1)
+ ip_set_ip_t ip, ip_set_ip_t ip1)
{
__u32 probe;
u_int16_t i;
struct ipportip *elem, *slot = NULL;
for (i = 0; i < map->probes; i++) {
- probe = jhash_ip2(map, i, hash_ip, ip1) % map->hashsize;
+ probe = jhash_ip2(map, i, ip, ip1) % map->hashsize;
elem = HARRAY_ELEM(map->members, struct ipportip *, probe);
- if (elem->ip == hash_ip && elem->ip1 == ip1)
+ if (elem->ip == ip && elem->ip1 == ip1)
return -EEXIST;
if (!(slot || elem->ip || elem->ip1))
slot = elem;
/* There can be deleted entries, must check all slots */
}
if (slot) {
- slot->ip = hash_ip;
+ slot->ip = ip;
slot->ip1 = ip1;
map->elements++;
return 0;
@@ -165,7 +159,7 @@ __ipportnethash_add(struct ip_set_ipportnethash *map,
}
static inline int
-ipportnethash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
+ipportnethash_add(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port,
ip_set_ip_t ip1, uint8_t cidr)
{
@@ -182,12 +176,12 @@ ipportnethash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
if (map->nets[cidr-1] == UINT16_MAX)
return -ERANGE;
- *hash_ip = pack_ip_port(map, ip, port);
+ ip = pack_ip_port(map, ip, port);
ip1 = pack_ip_cidr(ip1, cidr);
- if (!(*hash_ip || ip1))
+ if (!(ip || ip1))
return -ERANGE;
- ret =__ipportnet_add(map, *hash_ip, ip1);
+ ret =__ipportnet_add(map, ip, ip1);
if (ret == 0) {
if (!map->nets[cidr-1]++)
add_cidr_size(map->cidr, cidr);
@@ -202,11 +196,11 @@ ipportnethash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
uint8_t cidr = map->cidr[0] ? map->cidr[0] : 31; \
ip_set_ip_t port, ip1; \
\
- if (flags[index+2] == 0) \
+ if (flags[2] == 0) \
return 0; \
\
- port = get_port(skb, flags[index+1]); \
- ip1 = ipaddr(skb, flags[index+2]); \
+ port = get_port(skb, flags++); \
+ ip1 = ipaddr(skb, flags++); \
\
if (port == INVALID_PORT) \
return 0;
@@ -227,7 +221,7 @@ __ipportnethash_retry(struct ip_set_ipportnethash *tmp,
HASH_RETRY2(ipportnethash, struct ipportip)
static inline int
-ipportnethash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
+ipportnethash_del(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port,
ip_set_ip_t ip1, uint8_t cidr)
{
@@ -242,7 +236,7 @@ ipportnethash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
if (cidr <= 0 || cidr >= 32)
return -EINVAL;
- id = ipportnethash_id_cidr(set, hash_ip, ip, port, ip1, cidr);
+ id = ipportnethash_id_cidr(set, ip, port, ip1, cidr);
if (id == UINT_MAX)
return -EEXIST;
diff --git a/kernel/ip_set_iptree.c b/kernel/ip_set_iptree.c
index cdb3404..77eb180 100644
--- a/kernel/ip_set_iptree.c
+++ b/kernel/ip_set_iptree.c
@@ -62,7 +62,7 @@ static __KMEM_CACHE_T__ *leaf_cachep;
} while (0)
static inline int
-iptree_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
+iptree_test(struct ip_set *set, ip_set_ip_t ip)
{
struct ip_set_iptree *map = set->data;
struct ip_set_iptreeb *btree;
@@ -73,8 +73,7 @@ iptree_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
if (!ip)
return -ERANGE;
- *hash_ip = ip;
- ABCD(a, b, c, d, hash_ip);
+ ABCD(a, b, c, d, &ip);
DP("%u %u %u %u timeout %u", a, b, c, d, map->timeout);
TESTIP_WALK(map, a, btree);
TESTIP_WALK(btree, b, ctree);
@@ -106,8 +105,7 @@ KADT(iptree, test, ipaddr)
} while (0)
static inline int
-iptree_add(struct ip_set *set, ip_set_ip_t *hash_ip,
- ip_set_ip_t ip, unsigned int timeout)
+iptree_add(struct ip_set *set, ip_set_ip_t ip, unsigned int timeout)
{
struct ip_set_iptree *map = set->data;
struct ip_set_iptreeb *btree;
@@ -121,8 +119,7 @@ iptree_add(struct ip_set *set, ip_set_ip_t *hash_ip,
* but it's probably overkill */
return -ERANGE;
- *hash_ip = ip;
- ABCD(a, b, c, d, hash_ip);
+ ABCD(a, b, c, d, &ip);
DP("%u %u %u %u timeout %u", a, b, c, d, timeout);
ADDIP_WALK(map, a, btree, struct ip_set_iptreeb, branch_cachep);
ADDIP_WALK(btree, b, ctree, struct ip_set_iptreec, branch_cachep);
@@ -153,7 +150,7 @@ KADT(iptree, add, ipaddr, 0)
} while (0)
static inline int
-iptree_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
+iptree_del(struct ip_set *set, ip_set_ip_t ip)
{
struct ip_set_iptree *map = set->data;
struct ip_set_iptreeb *btree;
@@ -164,8 +161,7 @@ iptree_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
if (!ip)
return -ERANGE;
- *hash_ip = ip;
- ABCD(a, b, c, d, hash_ip);
+ ABCD(a, b, c, d, &ip);
DELIP_WALK(map, a, btree);
DELIP_WALK(btree, b, ctree);
DELIP_WALK(ctree, c, dtree);
@@ -364,7 +360,7 @@ iptree_list_header(const struct ip_set *set, void *data)
}
static int
-iptree_list_members_size(const struct ip_set *set)
+iptree_list_members_size(const struct ip_set *set, char dont_align)
{
const struct ip_set_iptree *map = set->data;
struct ip_set_iptreeb *btree;
@@ -386,20 +382,21 @@ iptree_list_members_size(const struct ip_set *set)
LOOP_WALK_END;
DP("members %u", count);
- return (count * sizeof(struct ip_set_req_iptree));
+ return (count * IPSET_VALIGN(sizeof(struct ip_set_req_iptree), dont_align));
}
static void
-iptree_list_members(const struct ip_set *set, void *data)
+iptree_list_members(const struct ip_set *set, void *data, char dont_align)
{
const struct ip_set_iptree *map = set->data;
struct ip_set_iptreeb *btree;
struct ip_set_iptreec *ctree;
struct ip_set_iptreed *dtree;
unsigned int a,b,c,d;
- size_t offset = 0;
+ size_t offset = 0, datasize;
struct ip_set_req_iptree *entry;
+ datasize = IPSET_VALIGN(sizeof(struct ip_set_req_iptree), dont_align);
LOOP_WALK_BEGIN(map, a, btree);
LOOP_WALK_BEGIN(btree, b, ctree);
LOOP_WALK_BEGIN(ctree, c, dtree);
@@ -410,7 +407,7 @@ iptree_list_members(const struct ip_set *set, void *data)
entry->ip = ((a << 24) | (b << 16) | (c << 8) | d);
entry->timeout = !map->timeout ? 0
: (dtree->expires[d] - jiffies)/HZ;
- offset += sizeof(struct ip_set_req_iptree);
+ offset += datasize;
}
}
LOOP_WALK_END;
diff --git a/kernel/ip_set_iptreemap.c b/kernel/ip_set_iptreemap.c
index 7c8c517..02f657e 100644
--- a/kernel/ip_set_iptreemap.c
+++ b/kernel/ip_set_iptreemap.c
@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/ip.h>
+#include <linux/jiffies.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/delay.h>
@@ -250,7 +251,7 @@ free_b(struct ip_set_iptreemap_b *map)
}
static inline int
-iptreemap_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
+iptreemap_test(struct ip_set *set, ip_set_ip_t ip)
{
struct ip_set_iptreemap *map = set->data;
struct ip_set_iptreemap_b *btree;
@@ -258,9 +259,7 @@ iptreemap_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
struct ip_set_iptreemap_d *dtree;
unsigned char a, b, c, d;
- *hash_ip = ip;
-
- ABCD(a, b, c, d, hash_ip);
+ ABCD(a, b, c, d, &ip);
TESTIP_WALK(map, a, btree, fullbitmap_b);
TESTIP_WALK(btree, b, ctree, fullbitmap_c);
@@ -275,7 +274,7 @@ UADT(iptreemap, test)
KADT(iptreemap, test, ipaddr)
static inline int
-__addip_single(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
+__addip_single(struct ip_set *set, ip_set_ip_t ip)
{
struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data;
struct ip_set_iptreemap_b *btree;
@@ -283,9 +282,7 @@ __addip_single(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
struct ip_set_iptreemap_d *dtree;
unsigned char a, b, c, d;
- *hash_ip = ip;
-
- ABCD(a, b, c, d, hash_ip);
+ ABCD(a, b, c, d, &ip);
ADDIP_WALK(map, a, btree, struct ip_set_iptreemap_b, cachep_b, fullbitmap_b);
ADDIP_WALK(btree, b, ctree, struct ip_set_iptreemap_c, cachep_c, fullbitmap_c);
@@ -300,8 +297,7 @@ __addip_single(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
}
static inline int
-iptreemap_add(struct ip_set *set, ip_set_ip_t *hash_ip,
- ip_set_ip_t start, ip_set_ip_t end)
+iptreemap_add(struct ip_set *set, ip_set_ip_t start, ip_set_ip_t end)
{
struct ip_set_iptreemap *map = set->data;
struct ip_set_iptreemap_b *btree;
@@ -312,9 +308,7 @@ iptreemap_add(struct ip_set *set, ip_set_ip_t *hash_ip,
unsigned char a2, b2, c2, d2;
if (start == end)
- return __addip_single(set, hash_ip, start);
-
- *hash_ip = start;
+ return __addip_single(set, start);
ABCD(a1, b1, c1, d1, &start);
ABCD(a2, b2, c2, d2, &end);
@@ -337,8 +331,7 @@ UADT0(iptreemap, add, min(req->ip, req->end), max(req->ip, req->end))
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, gfp_t flags)
+__delip_single(struct ip_set *set, ip_set_ip_t ip, gfp_t flags)
{
struct ip_set_iptreemap *map = set->data;
struct ip_set_iptreemap_b *btree;
@@ -346,9 +339,7 @@ __delip_single(struct ip_set *set, ip_set_ip_t *hash_ip,
struct ip_set_iptreemap_d *dtree;
unsigned char a,b,c,d;
- *hash_ip = ip;
-
- ABCD(a, b, c, d, hash_ip);
+ ABCD(a, b, c, d, &ip);
DELIP_WALK(map, a, btree, cachep_b, fullbitmap_b, flags);
DELIP_WALK(btree, b, ctree, cachep_c, fullbitmap_c, flags);
@@ -363,7 +354,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,
+iptreemap_del(struct ip_set *set,
ip_set_ip_t start, ip_set_ip_t end, gfp_t flags)
{
struct ip_set_iptreemap *map = set->data;
@@ -375,9 +366,7 @@ iptreemap_del(struct ip_set *set, ip_set_ip_t *hash_ip,
unsigned char a2, b2, c2, d2;
if (start == end)
- return __delip_single(set, hash_ip, start, flags);
-
- *hash_ip = start;
+ return __delip_single(set, start, flags);
ABCD(a1, b1, c1, d1, &start);
ABCD(a2, b2, c2, d2, &end);
@@ -517,6 +506,7 @@ static void
iptreemap_flush(struct ip_set *set)
{
struct ip_set_iptreemap *map = set->data;
+ unsigned int gc_interval = map->gc_interval;
while (!del_timer(&map->gc))
msleep(IPTREEMAP_DESTROY_SLEEP);
@@ -524,6 +514,7 @@ iptreemap_flush(struct ip_set *set)
__flush(map);
memset(map, 0, sizeof(*map));
+ map->gc_interval = gc_interval;
init_gc_timer(set);
}
@@ -538,7 +529,7 @@ iptreemap_list_header(const struct ip_set *set, void *data)
}
static int
-iptreemap_list_members_size(const struct ip_set *set)
+iptreemap_list_members_size(const struct ip_set *set, char dont_align)
{
struct ip_set_iptreemap *map = set->data;
struct ip_set_iptreemap_b *btree;
@@ -564,31 +555,30 @@ iptreemap_list_members_size(const struct ip_set *set)
if (inrange)
count++;
- return (count * sizeof(struct ip_set_req_iptreemap));
+ return (count * IPSET_VALIGN(sizeof(struct ip_set_req_iptreemap), dont_align));
}
-static inline u_int32_t
+static inline void
add_member(void *data, size_t offset, ip_set_ip_t start, ip_set_ip_t end)
{
struct ip_set_req_iptreemap *entry = data + offset;
entry->ip = start;
entry->end = end;
-
- return sizeof(*entry);
}
static void
-iptreemap_list_members(const struct ip_set *set, void *data)
+iptreemap_list_members(const struct ip_set *set, void *data, char dont_align)
{
struct ip_set_iptreemap *map = set->data;
struct ip_set_iptreemap_b *btree;
struct ip_set_iptreemap_c *ctree;
struct ip_set_iptreemap_d *dtree;
unsigned int a, b, c, d, inrange = 0;
- size_t offset = 0;
+ size_t offset = 0, datasize;
ip_set_ip_t start = 0, end = 0, ip;
+ datasize = IPSET_VALIGN(sizeof(struct ip_set_req_iptreemap), dont_align);
LOOP_WALK_BEGIN(map, a, btree) {
LOOP_WALK_BEGIN(btree, b, ctree) {
LOOP_WALK_BEGIN(ctree, c, dtree) {
@@ -599,12 +589,14 @@ iptreemap_list_members(const struct ip_set *set, void *data)
inrange = 1;
start = ip;
} else if (end < ip - 1) {
- offset += add_member(data, offset, start, end);
+ add_member(data, offset, start, end);
+ offset += datasize;
start = ip;
}
end = ip;
} else if (inrange) {
- offset += add_member(data, offset, start, end);
+ add_member(data, offset, start, end);
+ offset += datasize;
inrange = 0;
}
}
diff --git a/kernel/ip_set_macipmap.c b/kernel/ip_set_macipmap.c
index 464106e..89e907b 100644
--- a/kernel/ip_set_macipmap.c
+++ b/kernel/ip_set_macipmap.c
@@ -22,8 +22,7 @@
#include <linux/netfilter_ipv4/ip_set_macipmap.h>
static int
-macipmap_utest(struct ip_set *set, const void *data, u_int32_t size,
- ip_set_ip_t *hash_ip)
+macipmap_utest(struct ip_set *set, const void *data, u_int32_t size)
{
const struct ip_set_macipmap *map = set->data;
const struct ip_set_macip *table = map->members;
@@ -32,9 +31,7 @@ macipmap_utest(struct ip_set *set, const void *data, u_int32_t size,
if (req->ip < map->first_ip || req->ip > map->last_ip)
return -ERANGE;
- *hash_ip = req->ip;
- DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u",
- set->name, HIPQUAD(req->ip), HIPQUAD(*hash_ip));
+ DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(req->ip));
if (table[req->ip - map->first_ip].match) {
return (memcmp(req->ethernet,
&table[req->ip - map->first_ip].ethernet,
@@ -47,22 +44,18 @@ macipmap_utest(struct ip_set *set, const void *data, u_int32_t size,
static int
macipmap_ktest(struct ip_set *set,
const struct sk_buff *skb,
- ip_set_ip_t *hash_ip,
- const u_int32_t *flags,
- unsigned char index)
+ const u_int32_t *flags)
{
const struct ip_set_macipmap *map = set->data;
const struct ip_set_macip *table = map->members;
ip_set_ip_t ip;
- ip = ipaddr(skb, flags[index]);
+ ip = ipaddr(skb, flags);
if (ip < map->first_ip || ip > map->last_ip)
return 0;
- *hash_ip = ip;
- DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u",
- set->name, HIPQUAD(ip), HIPQUAD(*hash_ip));
+ DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(ip));
if (table[ip - map->first_ip].match) {
/* Is mac pointer valid?
* If so, compare... */
@@ -78,7 +71,7 @@ macipmap_ktest(struct ip_set *set,
/* returns 0 on success */
static inline int
-macipmap_add(struct ip_set *set, ip_set_ip_t *hash_ip,
+macipmap_add(struct ip_set *set,
ip_set_ip_t ip, const unsigned char *ethernet)
{
struct ip_set_macipmap *map = set->data;
@@ -89,8 +82,7 @@ macipmap_add(struct ip_set *set, ip_set_ip_t *hash_ip,
if (table[ip - map->first_ip].match)
return -EEXIST;
- *hash_ip = ip;
- DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip));
+ DP("set: %s, ip: %u.%u.%u.%u", set->name, HIPQUAD(ip));
memcpy(&table[ip - map->first_ip].ethernet, ethernet, ETH_ALEN);
table[ip - map->first_ip].match = IPSET_MACIP_ISSET;
return 0;
@@ -105,7 +97,7 @@ UADT(macipmap, add, req->ethernet)
KADT(macipmap, add, ipaddr, eth_hdr(skb)->h_source)
static inline int
-macipmap_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
+macipmap_del(struct ip_set *set, ip_set_ip_t ip)
{
struct ip_set_macipmap *map = set->data;
struct ip_set_macip *table = map->members;
@@ -115,9 +107,8 @@ macipmap_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
if (!table[ip - map->first_ip].match)
return -EEXIST;
- *hash_ip = ip;
table[ip - map->first_ip].match = 0;
- DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip));
+ DP("set: %s, ip: %u.%u.%u.%u", set->name, HIPQUAD(ip));
return 0;
}
@@ -152,8 +143,32 @@ __macipmap_list_header(const struct ip_set_macipmap *map,
}
BITMAP_LIST_HEADER(macipmap)
-BITMAP_LIST_MEMBERS_SIZE(macipmap)
-BITMAP_LIST_MEMBERS(macipmap)
+BITMAP_LIST_MEMBERS_SIZE(macipmap, struct ip_set_req_macipmap,
+ (map->last_ip - map->first_ip + 1),
+ ((const struct ip_set_macip *)map->members)[i].match)
+
+
+static void
+macipmap_list_members(const struct ip_set *set, void *data, char dont_align)
+{
+ const struct ip_set_macipmap *map = set->data;
+ const struct ip_set_macip *table = map->members;
+ uint32_t i, n = 0;
+ struct ip_set_req_macipmap *d;
+
+ if (dont_align) {
+ memcpy(data, map->members, map->size);
+ return;
+ }
+
+ for (i = 0; i < map->last_ip - map->first_ip + 1; i++)
+ if (table[i].match) {
+ d = data + n * IPSET_ALIGN(sizeof(struct ip_set_req_macipmap));
+ d->ip = map->first_ip + i;
+ memcpy(d->ethernet, &table[i].ethernet, ETH_ALEN);
+ n++;
+ }
+}
IP_SET_TYPE(macipmap, IPSET_TYPE_IP | IPSET_DATA_SINGLE)
diff --git a/kernel/ip_set_nethash.c b/kernel/ip_set_nethash.c
index d68a015..bf87f5c 100644
--- a/kernel/ip_set_nethash.c
+++ b/kernel/ip_set_nethash.c
@@ -26,7 +26,6 @@ static int limit = MAX_RANGE;
static inline __u32
nethash_id_cidr(const struct ip_set_nethash *map,
- ip_set_ip_t *hash_ip,
ip_set_ip_t ip,
uint8_t cidr)
{
@@ -34,15 +33,15 @@ nethash_id_cidr(const struct ip_set_nethash *map,
u_int16_t i;
ip_set_ip_t *elem;
- *hash_ip = pack_ip_cidr(ip, cidr);
- if (!*hash_ip)
+ ip = pack_ip_cidr(ip, cidr);
+ if (!ip)
return MAX_RANGE;
for (i = 0; i < map->probes; i++) {
- id = jhash_ip(map, i, *hash_ip) % map->hashsize;
+ id = jhash_ip(map, i, ip) % map->hashsize;
DP("hash key: %u", id);
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
- if (*elem == *hash_ip)
+ if (*elem == ip)
return id;
/* No shortcut - there can be deleted entries. */
}
@@ -50,14 +49,14 @@ nethash_id_cidr(const struct ip_set_nethash *map,
}
static inline __u32
-nethash_id(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
+nethash_id(struct ip_set *set, ip_set_ip_t ip)
{
const struct ip_set_nethash *map = set->data;
__u32 id = UINT_MAX;
int i;
for (i = 0; i < 30 && map->cidr[i]; i++) {
- id = nethash_id_cidr(map, hash_ip, ip, map->cidr[i]);
+ id = nethash_id_cidr(map, ip, map->cidr[i]);
if (id != UINT_MAX)
break;
}
@@ -65,30 +64,28 @@ nethash_id(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
}
static inline int
-nethash_test_cidr(struct ip_set *set, ip_set_ip_t *hash_ip,
- ip_set_ip_t ip, uint8_t cidr)
+nethash_test_cidr(struct ip_set *set, ip_set_ip_t ip, uint8_t cidr)
{
const struct ip_set_nethash *map = set->data;
- return (nethash_id_cidr(map, hash_ip, ip, cidr) != UINT_MAX);
+ return (nethash_id_cidr(map, ip, cidr) != UINT_MAX);
}
static inline int
-nethash_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
+nethash_test(struct ip_set *set, ip_set_ip_t ip)
{
- return (nethash_id(set, hash_ip, ip) != UINT_MAX);
+ return (nethash_id(set, ip) != UINT_MAX);
}
static int
-nethash_utest(struct ip_set *set, const void *data, u_int32_t size,
- ip_set_ip_t *hash_ip)
+nethash_utest(struct ip_set *set, const void *data, u_int32_t size)
{
const struct ip_set_req_nethash *req = data;
if (req->cidr <= 0 || req->cidr > 32)
return -EINVAL;
- return (req->cidr == 32 ? nethash_test(set, hash_ip, req->ip)
- : nethash_test_cidr(set, hash_ip, req->ip, req->cidr));
+ return (req->cidr == 32 ? nethash_test(set, req->ip)
+ : nethash_test_cidr(set, req->ip, req->cidr));
}
#define KADT_CONDITION
@@ -121,8 +118,7 @@ __nethash_add(struct ip_set_nethash *map, ip_set_ip_t *ip)
}
static inline int
-nethash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
- ip_set_ip_t ip, uint8_t cidr)
+nethash_add(struct ip_set *set, ip_set_ip_t ip, uint8_t cidr)
{
struct ip_set_nethash *map = set->data;
int ret;
@@ -132,12 +128,11 @@ nethash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
if (cidr <= 0 || cidr >= 32)
return -EINVAL;
- *hash_ip = pack_ip_cidr(ip, cidr);
- DP("%u.%u.%u.%u/%u, %u.%u.%u.%u", HIPQUAD(ip), cidr, HIPQUAD(*hash_ip));
- if (!*hash_ip)
+ ip = pack_ip_cidr(ip, cidr);
+ if (!ip)
return -ERANGE;
- ret = __nethash_add(map, hash_ip);
+ ret = __nethash_add(map, &ip);
if (ret == 0) {
if (!map->nets[cidr-1]++)
add_cidr_size(map->cidr, cidr);
@@ -165,8 +160,7 @@ __nethash_retry(struct ip_set_nethash *tmp, struct ip_set_nethash *map)
HASH_RETRY(nethash, ip_set_ip_t)
static inline int
-nethash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
- ip_set_ip_t ip, uint8_t cidr)
+nethash_del(struct ip_set *set, ip_set_ip_t ip, uint8_t cidr)
{
struct ip_set_nethash *map = set->data;
ip_set_ip_t id, *elem;
@@ -174,7 +168,7 @@ nethash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
if (cidr <= 0 || cidr >= 32)
return -EINVAL;
- id = nethash_id_cidr(map, hash_ip, ip, cidr);
+ id = nethash_id_cidr(map, ip, cidr);
if (id == UINT_MAX)
return -EEXIST;
diff --git a/kernel/ip_set_portmap.c b/kernel/ip_set_portmap.c
index 8b0ec0a..8bb6e76 100644
--- a/kernel/ip_set_portmap.c
+++ b/kernel/ip_set_portmap.c
@@ -23,16 +23,14 @@
#include <linux/netfilter_ipv4/ip_set_getport.h>
static inline int
-portmap_test(const struct ip_set *set, ip_set_ip_t *hash_port,
- ip_set_ip_t port)
+portmap_test(const struct ip_set *set, ip_set_ip_t port)
{
const struct ip_set_portmap *map = set->data;
if (port < map->first_ip || port > map->last_ip)
return -ERANGE;
- *hash_port = port;
- DP("set: %s, port:%u, %u", set->name, port, *hash_port);
+ DP("set: %s, port: %u", set->name, port);
return !!test_bit(port - map->first_ip, map->members);
}
@@ -44,7 +42,7 @@ UADT(portmap, test)
KADT(portmap, test, get_port)
static inline int
-portmap_add(struct ip_set *set, ip_set_ip_t *hash_port, ip_set_ip_t port)
+portmap_add(struct ip_set *set, ip_set_ip_t port)
{
struct ip_set_portmap *map = set->data;
@@ -52,9 +50,8 @@ portmap_add(struct ip_set *set, ip_set_ip_t *hash_port, ip_set_ip_t port)
return -ERANGE;
if (test_and_set_bit(port - map->first_ip, map->members))
return -EEXIST;
-
- *hash_port = port;
- DP("port %u", port);
+
+ DP("set: %s, port %u", set->name, port);
return 0;
}
@@ -62,7 +59,7 @@ UADT(portmap, add)
KADT(portmap, add, get_port)
static inline int
-portmap_del(struct ip_set *set, ip_set_ip_t *hash_port, ip_set_ip_t port)
+portmap_del(struct ip_set *set, ip_set_ip_t port)
{
struct ip_set_portmap *map = set->data;
@@ -70,9 +67,8 @@ portmap_del(struct ip_set *set, ip_set_ip_t *hash_port, ip_set_ip_t port)
return -ERANGE;
if (!test_and_clear_bit(port - map->first_ip, map->members))
return -EEXIST;
-
- *hash_port = port;
- DP("port %u", port);
+
+ DP("set: %s, port %u", set->name, port);
return 0;
}
@@ -102,8 +98,28 @@ __portmap_list_header(const struct ip_set_portmap *map,
}
BITMAP_LIST_HEADER(portmap)
-BITMAP_LIST_MEMBERS_SIZE(portmap)
-BITMAP_LIST_MEMBERS(portmap)
+BITMAP_LIST_MEMBERS_SIZE(portmap, ip_set_ip_t, (map->last_ip - map->first_ip + 1),
+ test_bit(i, map->members))
+
+static void
+portmap_list_members(const struct ip_set *set, void *data, char dont_align)
+{
+ const struct ip_set_portmap *map = set->data;
+ uint32_t i, n = 0;
+ ip_set_ip_t *d;
+
+ if (dont_align) {
+ memcpy(data, map->members, map->size);
+ return;
+ }
+
+ for (i = 0; i < map->last_ip - map->first_ip + 1; i++)
+ if (test_bit(i, map->members)) {
+ d = data + n * IPSET_ALIGN(sizeof(ip_set_ip_t));
+ *d = map->first_ip + i;
+ n++;
+ }
+}
IP_SET_TYPE(portmap, IPSET_TYPE_PORT | IPSET_DATA_SINGLE)
diff --git a/kernel/ip_set_setlist.c b/kernel/ip_set_setlist.c
index 2b1c6b6..3cfdae8 100644
--- a/kernel/ip_set_setlist.c
+++ b/kernel/ip_set_setlist.c
@@ -28,8 +28,7 @@ next_index_eq(const struct ip_set_setlist *map, int i, ip_set_id_t index)
}
static int
-setlist_utest(struct ip_set *set, const void *data, u_int32_t size,
- ip_set_ip_t *hash_ip)
+setlist_utest(struct ip_set *set, const void *data, u_int32_t size)
{
const struct ip_set_setlist *map = set->data;
const struct ip_set_req_setlist *req = data;
@@ -72,10 +71,8 @@ finish:
static int
setlist_ktest(struct ip_set *set,
- const struct sk_buff *skb,
- ip_set_ip_t *hash_ip,
- const u_int32_t *flags,
- unsigned char index)
+ const struct sk_buff *skb,
+ const u_int32_t *flags)
{
struct ip_set_setlist *map = set->data;
int i, res = 0;
@@ -107,8 +104,7 @@ insert_setlist(struct ip_set_setlist *map, int i, ip_set_id_t index)
}
static int
-setlist_uadd(struct ip_set *set, const void *data, u_int32_t size,
- ip_set_ip_t *hash_ip)
+setlist_uadd(struct ip_set *set, const void *data, u_int32_t size)
{
struct ip_set_setlist *map = set->data;
const struct ip_set_req_setlist *req = data;
@@ -156,9 +152,7 @@ finish:
static int
setlist_kadd(struct ip_set *set,
const struct sk_buff *skb,
- ip_set_ip_t *hash_ip,
- const u_int32_t *flags,
- unsigned char index)
+ const u_int32_t *flags)
{
struct ip_set_setlist *map = set->data;
int i, res = -EINVAL;
@@ -182,8 +176,7 @@ unshift_setlist(struct ip_set_setlist *map, int i)
}
static int
-setlist_udel(struct ip_set *set, const void *data, u_int32_t size,
- ip_set_ip_t *hash_ip)
+setlist_udel(struct ip_set *set, const void *data, u_int32_t size)
{
struct ip_set_setlist *map = set->data;
const struct ip_set_req_setlist *req = data;
@@ -234,9 +227,7 @@ finish:
static int
setlist_kdel(struct ip_set *set,
const struct sk_buff *skb,
- ip_set_ip_t *hash_ip,
- const u_int32_t *flags,
- unsigned char index)
+ const u_int32_t *flags)
{
struct ip_set_setlist *map = set->data;
int i, res = -EINVAL;
@@ -304,21 +295,24 @@ setlist_list_header(const struct ip_set *set, void *data)
}
static int
-setlist_list_members_size(const struct ip_set *set)
+setlist_list_members_size(const struct ip_set *set, char dont_align)
{
const struct ip_set_setlist *map = set->data;
- return map->size * sizeof(ip_set_id_t);
+ return map->size * IPSET_VALIGN(sizeof(ip_set_id_t), dont_align);
}
static void
-setlist_list_members(const struct ip_set *set, void *data)
+setlist_list_members(const struct ip_set *set, void *data, char dont_align)
{
struct ip_set_setlist *map = set->data;
+ ip_set_id_t *d;
int i;
- for (i = 0; i < map->size; i++)
- *((ip_set_id_t *)data + i) = ip_set_id(map->index[i]);
+ for (i = 0; i < map->size; i++) {
+ d = data + i * IPSET_VALIGN(sizeof(ip_set_id_t), dont_align);
+ *d = ip_set_id(map->index[i]);
+ }
}
IP_SET_TYPE(setlist, IPSET_TYPE_SETNAME | IPSET_DATA_SINGLE)
diff --git a/tests/iphash.t b/tests/iphash.t
index 4c33ce3..7a3ce1f 100644
--- a/tests/iphash.t
+++ b/tests/iphash.t
@@ -14,6 +14,10 @@
0 ipset -T test 192.168.68.69
# IP: Test value not added to the set
1 ipset -T test 2.0.0.2
+# IP: List set
+0 ipset -L test > .foo0 && ./sort.sh .foo0
+# IP: Check listing
+0 diff .foo iphash.t.list0 && rm .foo
# IP: Flush test set
0 ipset -F test
# IP: Delete test set
@@ -28,11 +32,11 @@
0 ipset -X test
# Network: Create a set
0 ipset -N test iphash --hashsize 128 --netmask 24
-# Range: Add zero valued element
+# Network: Add zero valued element
2 ipset -A test 0.0.0.0
-# Range: Test zero valued element
+# Network: Test zero valued element
2 ipset -T test 0.0.0.0
-# Range: Delete zero valued element
+# Network: Delete zero valued element
2 ipset -D test 0.0.0.0
# Network: Add first random network
0 ipset -A test 2.0.0.1
@@ -44,6 +48,10 @@
0 ipset -T test 192.168.68.95
# Network: Test value not added to the set
1 ipset -T test 2.0.1.0
+# Network: List set
+0 ipset -L test > .foo0 && ./sort.sh .foo0
+# Network: Check listing
+0 diff .foo iphash.t.list1 && rm .foo
# Network: Flush test set
0 ipset -F test
# Network: Delete test set
diff --git a/tests/iphash.t.list0 b/tests/iphash.t.list0
new file mode 100644
index 0000000..93d51c2
--- /dev/null
+++ b/tests/iphash.t.list0
@@ -0,0 +1,7 @@
+Name: test
+Type: iphash
+References: 0
+Header: hashsize: 128 probes: 8 resize: 50
+Members:
+192.168.68.69
+2.0.0.1
diff --git a/tests/iphash.t.list1 b/tests/iphash.t.list1
new file mode 100644
index 0000000..7f13c1c
--- /dev/null
+++ b/tests/iphash.t.list1
@@ -0,0 +1,7 @@
+Name: test
+Type: iphash
+References: 0
+Header: hashsize: 128 probes: 8 resize: 50 netmask: 24
+Members:
+192.168.68.0
+2.0.0.0
diff --git a/tests/ipmap.t b/tests/ipmap.t
index 58b913a..239cef9 100644
--- a/tests/ipmap.t
+++ b/tests/ipmap.t
@@ -20,6 +20,10 @@
1 ipset -A test 2.0.0.0
# Range: Try to add value after upper boundary
1 ipset -A test 2.1.0.1
+# Range: List set
+0 ipset -L test > .foo
+# Range: Check listing
+0 diff .foo ipmap.t.list0 && rm .foo
# Range: Flush test set
0 ipset -F test
# Range: Delete test set
@@ -46,6 +50,10 @@
1 ipset -A test 1.255.255.255
# Network: Try to add value after upper boundary
1 ipset -A test 2.1.0.0
+# Network: List set
+0 ipset -L test > .foo
+# Network: Check listing
+0 diff .foo ipmap.t.list1 && rm .foo
# Network: Flush test set
0 ipset -F test
# Network: Delete test set
@@ -70,6 +78,10 @@
1 ipset -A test 9.255.255.255
# Subnets: Try to add value after upper boundary
1 ipset -A test 11.0.0.0
+# Subnets: List set
+0 ipset -L test > .foo
+# Subnets: Check listing
+0 diff .foo ipmap.t.list2 && rm .foo
# Subnets: FLush test set
0 ipset -F test
# Subnets: Delete test set
@@ -86,6 +98,10 @@
0 ipset -T test 255.255.255.255
# Full: Test value not added to the set
1 ipset -T test 0.1.0.0
+# Full: List set
+0 ipset -L test > .foo
+# Full: Check listing
+0 diff .foo ipmap.t.list3 && rm .foo
# Full: Delete test set
0 ipset -X test
# eof
diff --git a/tests/ipmap.t.list0 b/tests/ipmap.t.list0
new file mode 100644
index 0000000..aeaa4fb
--- /dev/null
+++ b/tests/ipmap.t.list0
@@ -0,0 +1,8 @@
+Name: test
+Type: ipmap
+References: 0
+Header: from: 2.0.0.1 to: 2.1.0.0
+Members:
+2.0.0.1
+2.1.0.0
+
diff --git a/tests/ipmap.t.list1 b/tests/ipmap.t.list1
new file mode 100644
index 0000000..53b76b6
--- /dev/null
+++ b/tests/ipmap.t.list1
@@ -0,0 +1,8 @@
+Name: test
+Type: ipmap
+References: 0
+Header: from: 2.0.0.0 to: 2.0.255.255
+Members:
+2.0.0.0
+2.0.255.255
+
diff --git a/tests/ipmap.t.list2 b/tests/ipmap.t.list2
new file mode 100644
index 0000000..695254b
--- /dev/null
+++ b/tests/ipmap.t.list2
@@ -0,0 +1,8 @@
+Name: test
+Type: ipmap
+References: 0
+Header: from: 10.0.0.0 to: 10.255.255.255 netmask: 24
+Members:
+10.0.0.0
+10.255.255.0
+
diff --git a/tests/ipmap.t.list3 b/tests/ipmap.t.list3
new file mode 100644
index 0000000..3d95091
--- /dev/null
+++ b/tests/ipmap.t.list3
@@ -0,0 +1,8 @@
+Name: test
+Type: ipmap
+References: 0
+Header: from: 0.0.0.0 to: 255.255.255.255 netmask: 16
+Members:
+0.0.0.0
+255.255.0.0
+
diff --git a/tests/ipporthash.t b/tests/ipporthash.t
index 74fed1a..7c622bb 100644
--- a/tests/ipporthash.t
+++ b/tests/ipporthash.t
@@ -28,6 +28,10 @@
1 ipset -A test 2.0.0.0,5
# Range: Try to add value after upper boundary
1 ipset -A test 2.1.0.1,128
+# Range: List set
+0 ipset -L test > .foo0 && ./sort.sh .foo0
+# Range: Check listing
+0 diff .foo ipporthash.t.list0 && rm .foo
# Range: Flush test set
0 ipset -F test
# Range: Delete test set
@@ -56,6 +60,10 @@
1 ipset -A test 1.255.255.255,5
# Network: Try to add value after upper boundary
1 ipset -A test 2.1.0.0,128
+# Network: List set
+0 ipset -L test > .foo0 && ./sort.sh .foo0
+# Network: Check listing
+0 diff .foo ipporthash.t.list1 && rm .foo
# Network: Flush test set
0 ipset -F test
# Network: Delete test set
diff --git a/tests/ipporthash.t.list0 b/tests/ipporthash.t.list0
new file mode 100644
index 0000000..b840a94
--- /dev/null
+++ b/tests/ipporthash.t.list0
@@ -0,0 +1,7 @@
+Name: test
+Type: ipporthash
+References: 0
+Header: from: 2.0.0.1 to: 2.1.0.0 hashsize: 1024 probes: 8 resize: 50
+Members:
+2.0.0.1,5
+2.1.0.0,128
diff --git a/tests/ipporthash.t.list1 b/tests/ipporthash.t.list1
new file mode 100644
index 0000000..be86cda
--- /dev/null
+++ b/tests/ipporthash.t.list1
@@ -0,0 +1,7 @@
+Name: test
+Type: ipporthash
+References: 0
+Header: from: 2.0.0.0 to: 2.0.255.255 hashsize: 1024 probes: 8 resize: 50
+Members:
+2.0.0.0,5
+2.0.255.255,128
diff --git a/tests/ipportiphash.t b/tests/ipportiphash.t
index c7c25e5..860d5a6 100644
--- a/tests/ipportiphash.t
+++ b/tests/ipportiphash.t
@@ -36,6 +36,10 @@
1 ipset -A test 2.0.0.0,5,1.1.1.1
# Range: Try to add value after upper boundary
1 ipset -A test 2.1.0.1,128,2.2.2.2
+# Range: List set
+0 ipset -L test > .foo0 && ./sort.sh .foo0
+# Range: Check listing
+0 diff .foo ipportiphash.t.list0 && rm .foo
# Range: Flush test set
0 ipset -F test
# Range: Delete test set
@@ -64,6 +68,10 @@
1 ipset -A test 1.255.255.255,5,1.1.1.1
# Network: Try to add value after upper boundary
1 ipset -A test 2.1.0.0,128,2.2.2.2
+# Network: List set
+0 ipset -L test > .foo0 && ./sort.sh .foo0
+# Network: Check listing
+0 diff .foo ipportiphash.t.list1 && rm .foo
# Network: Flush test set
0 ipset -F test
# Network: Delete test set
diff --git a/tests/ipportiphash.t.list0 b/tests/ipportiphash.t.list0
new file mode 100644
index 0000000..acb1041
--- /dev/null
+++ b/tests/ipportiphash.t.list0
@@ -0,0 +1,7 @@
+Name: test
+Type: ipportiphash
+References: 0
+Header: from: 2.0.0.1 to: 2.1.0.0 hashsize: 1024 probes: 8 resize: 50
+Members:
+2.0.0.1,5,1.1.1.1
+2.1.0.0,128,2.2.2.2
diff --git a/tests/ipportiphash.t.list1 b/tests/ipportiphash.t.list1
new file mode 100644
index 0000000..5545078
--- /dev/null
+++ b/tests/ipportiphash.t.list1
@@ -0,0 +1,7 @@
+Name: test
+Type: ipportiphash
+References: 0
+Header: from: 2.0.0.0 to: 2.0.255.255 hashsize: 1024 probes: 8 resize: 50
+Members:
+2.0.0.0,5,1.1.1.1
+2.0.255.255,128,2.2.2.2
diff --git a/tests/ipportnethash.t b/tests/ipportnethash.t
index 0b87dad..93369ef 100644
--- a/tests/ipportnethash.t
+++ b/tests/ipportnethash.t
@@ -36,6 +36,10 @@
1 ipset -A test 2.0.0.0,5,1.1.1.1/24
# Range: Try to add value after upper boundary
1 ipset -A test 2.1.0.1,128,2.2.2.2/12
+# Range: List set
+0 ipset -L test > .foo0 && ./sort.sh .foo0
+# Range: Check listing
+0 diff .foo ipportnethash.t.list0 && rm .foo
# Range: Flush test set
0 ipset -F test
# Range: Delete test set
@@ -64,6 +68,10 @@
1 ipset -A test 1.255.255.255,5,1.1.1.1/24
# Network: Try to add value after upper boundary
1 ipset -A test 2.1.0.0,128,2.2.2.2/12
+# Network: List set
+0 ipset -L test > .foo0 && ./sort.sh .foo0
+# Network: Check listing
+0 diff .foo ipportnethash.t.list1 && rm .foo
# Network: Flush test set
0 ipset -F test
# Network: Delete test set
diff --git a/tests/ipportnethash.t.list0 b/tests/ipportnethash.t.list0
new file mode 100644
index 0000000..9727d20
--- /dev/null
+++ b/tests/ipportnethash.t.list0
@@ -0,0 +1,7 @@
+Name: test
+Type: ipportnethash
+References: 0
+Header: from: 2.0.0.1 to: 2.1.0.0 hashsize: 1024 probes: 8 resize: 50
+Members:
+2.0.0.1,5,1.1.1.0/24
+2.1.0.0,128,2.0.0.0/12
diff --git a/tests/ipportnethash.t.list1 b/tests/ipportnethash.t.list1
new file mode 100644
index 0000000..ad861d4
--- /dev/null
+++ b/tests/ipportnethash.t.list1
@@ -0,0 +1,7 @@
+Name: test
+Type: ipportnethash
+References: 0
+Header: from: 2.0.0.0 to: 2.0.255.255 hashsize: 1024 probes: 8 resize: 50
+Members:
+2.0.0.0,5,1.1.1.0/24
+2.0.255.255,128,2.0.0.0/12
diff --git a/tests/iptree.t b/tests/iptree.t
index 746baed..3cb0e00 100644
--- a/tests/iptree.t
+++ b/tests/iptree.t
@@ -12,6 +12,10 @@
1 ipset -T test 2.0.0.2
# Static: Test value not added to the set
1 ipset -T test 192.168.68.70
+# Static: List set
+0 ipset -L test > .foo
+# Static: Check listing
+0 diff .foo iptree.t.list0 && rm .foo
# Static: Flush test set
0 ipset -F test
# Static: Delete test set
diff --git a/tests/iptree.t.list0 b/tests/iptree.t.list0
new file mode 100644
index 0000000..07433b9
--- /dev/null
+++ b/tests/iptree.t.list0
@@ -0,0 +1,8 @@
+Name: test
+Type: iptree
+References: 0
+Header:
+Members:
+2.0.0.1
+192.168.68.69
+
diff --git a/tests/iptreemap.t b/tests/iptreemap.t
index b563522..2e9fce7 100644
--- a/tests/iptreemap.t
+++ b/tests/iptreemap.t
@@ -46,6 +46,10 @@
0 ipset -T test 192.168.68.67
# Test element after upper bound of deleted network
0 ipset -T test 192.168.68.72
+# List set
+0 ipset -L test > .foo
+# Check listing
+0 diff .foo iptreemap.t.list0 && rm .foo
# Flush test set
0 ipset -F test
# Delete test set
diff --git a/tests/iptreemap.t.list0 b/tests/iptreemap.t.list0
new file mode 100644
index 0000000..6e783a0
--- /dev/null
+++ b/tests/iptreemap.t.list0
@@ -0,0 +1,11 @@
+Name: test
+Type: iptreemap
+References: 0
+Header: gc: 300
+Members:
+2.0.0.1
+3.0.0.0
+3.0.0.2
+192.168.68.64-192.168.68.67
+192.168.68.72-192.168.68.95
+
diff --git a/tests/macipmap.t b/tests/macipmap.t
index a498a4f..d088958 100644
--- a/tests/macipmap.t
+++ b/tests/macipmap.t
@@ -26,6 +26,10 @@
1 ipset -T test 2.0.0.2,00:11:22:33:44:56
# Range: Test value with valid MAC
0 ipset -T test 2.0.0.2,00:11:22:33:44:55
+# Range: List set
+0 ipset -L test > .foo
+# Range: Check listing
+0 diff .foo macipmap.t.list0 && rm .foo
# Range: Flush test set
0 ipset -F test
# Range: Delete test set
@@ -52,6 +56,10 @@
1 ipset -A test 1.255.255.255
# Network: Try to add value after upper boundary
1 ipset -A test 2.1.0.0
+# Network: List set
+0 ipset -L test > .foo
+# Network: Check listing
+0 diff .foo macipmap.t.list1 && rm .foo
# Network: Flush test set
0 ipset -F test
# Network: Delete test set
diff --git a/tests/macipmap.t.list0 b/tests/macipmap.t.list0
new file mode 100644
index 0000000..157ba53
--- /dev/null
+++ b/tests/macipmap.t.list0
@@ -0,0 +1,9 @@
+Name: test
+Type: macipmap
+References: 0
+Header: from: 2.0.0.1 to: 2.1.0.0
+Members:
+2.0.0.1,00:00:00:00:00:00
+2.0.0.2,00:11:22:33:44:55
+2.1.0.0,00:00:00:00:00:00
+
diff --git a/tests/macipmap.t.list1 b/tests/macipmap.t.list1
new file mode 100644
index 0000000..dc0dc75
--- /dev/null
+++ b/tests/macipmap.t.list1
@@ -0,0 +1,8 @@
+Name: test
+Type: macipmap
+References: 0
+Header: from: 2.0.0.0 to: 2.0.255.255
+Members:
+2.0.0.0,00:00:00:00:00:00
+2.0.255.255,00:00:00:00:00:00
+
diff --git a/tests/nethash.t b/tests/nethash.t
index b2f234e..cedcfde 100644
--- a/tests/nethash.t
+++ b/tests/nethash.t
@@ -16,18 +16,22 @@
0 ipset -T test 0.0.0.0/1
# Range: Delete almost zero valued element
0 ipset -D test 0.0.0.0/1
-# Add first random network
+# Range: Add first random network
0 ipset -A test 2.0.0.1/24
-# Add second random network
+# Range: Add second random network
0 ipset -A test 192.168.68.69/27
-# Test first random value
+# Range: Test first random value
0 ipset -T test 2.0.0.255
-# Test second random value
+# Range: Test second random value
0 ipset -T test 192.168.68.95
-# Test value not added to the set
+# Range: Test value not added to the set
1 ipset -T test 2.0.1.0
-# Try to add IP address
+# Range: Try to add IP address
2 ipset -A test 2.0.0.1
+# Range: List set
+0 ipset -L test > .foo0 && ./sort.sh .foo0
+# Range: Check listing
+0 diff .foo nethash.t.list0 && rm .foo
# Flush test set
0 ipset -F test
# Delete test set
diff --git a/tests/nethash.t.list0 b/tests/nethash.t.list0
new file mode 100644
index 0000000..0b008b8
--- /dev/null
+++ b/tests/nethash.t.list0
@@ -0,0 +1,7 @@
+Name: test
+Type: nethash
+References: 0
+Header: hashsize: 128 probes: 4 resize: 50
+Members:
+192.168.68.64/27
+2.0.0.0/24
diff --git a/tests/portmap.t b/tests/portmap.t
index 299877a..12cdc1f 100644
--- a/tests/portmap.t
+++ b/tests/portmap.t
@@ -18,6 +18,10 @@
1 ipset -A test 0
# Range: Try to add value after upper boundary
1 ipset -A test 1025
+# Range: List set
+0 ipset -L test > .foo
+# Range: Check listing
+0 diff .foo portmap.t.list0 && rm .foo
# Range: Flush test set
0 ipset -F test
# Range: Delete test set
@@ -34,6 +38,10 @@
0 ipset -T test 65535
# Full: Test value not added to the set
1 ipset -T test 1
+# Full: List set
+0 ipset -L test > .foo
+# Full: Check listing
+0 diff .foo portmap.t.list1 && rm .foo
# Full: Flush test set
0 ipset -F test
# Full: Delete test set
diff --git a/tests/portmap.t.list0 b/tests/portmap.t.list0
new file mode 100644
index 0000000..809ffe1
--- /dev/null
+++ b/tests/portmap.t.list0
@@ -0,0 +1,8 @@
+Name: test
+Type: portmap
+References: 0
+Header: from: 1 to: 1024
+Members:
+1
+1024
+
diff --git a/tests/portmap.t.list1 b/tests/portmap.t.list1
new file mode 100644
index 0000000..9c9b38d
--- /dev/null
+++ b/tests/portmap.t.list1
@@ -0,0 +1,8 @@
+Name: test
+Type: portmap
+References: 0
+Header: from: 0 to: 65535
+Members:
+0
+65535
+
diff --git a/tests/setlist.t b/tests/setlist.t
index d677863..ed21396 100644
--- a/tests/setlist.t
+++ b/tests/setlist.t
@@ -38,6 +38,10 @@
0 ipset -X
# Setlist: Restore saved sets
0 ipset -R < setlist.t.restore
+# Setlist: List set
+0 ipset -L test > .foo
+# Setlist: Check listing
+0 diff .foo setlist.t.list0 && rm .foo
# Setlist: Flush all sets
0 ipset -F
# Setlist: Delete all sets
diff --git a/tests/setlist.t.list0 b/tests/setlist.t.list0
new file mode 100644
index 0000000..9b70446
--- /dev/null
+++ b/tests/setlist.t.list0
@@ -0,0 +1,8 @@
+Name: test
+Type: setlist
+References: 0
+Header: size: 8
+Members:
+foo
+bar
+
diff --git a/tests/sort.sh b/tests/sort.sh
new file mode 100755
index 0000000..a01d066
--- /dev/null
+++ b/tests/sort.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+awk '/^[A-Za-z]+:/ { print $0 }' $1 > .foo
+awk '!/^[A-Za-z]+:/ && !/inding/ { print $0 }' | sort >> .foo
+rm $1