summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--Makefile6
-rw-r--r--ipset.831
-rw-r--r--ipset.c10
-rw-r--r--ipset_ipmap.c2
-rw-r--r--ipset_ipporthash.c16
-rw-r--r--ipset_iptree.c10
-rw-r--r--ipset_iptreemap.c206
-rw-r--r--ipset_macipmap.c12
9 files changed, 273 insertions, 29 deletions
diff --git a/ChangeLog b/ChangeLog
index 63a6e42..ee0154e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2.3.0
+ - jiffies rollover bug in iptree type fixed (reported by Lukasz Nierycho
+ and others)
+ - endiannes bug in iptree type fixed (spotted by Jan Engelhardt)
+ - iptreemap type added (submitted by Sven Wegener)
+ - 2.6.22/23 compatibility fixes (Jeremy Jacque)
+ - typo fixes in ipset (Neville D)
+ - separator changed to ':' from '%' (old one still supported) in ipset
+
2.2.9a
- use correct type (socklen_t) for getsockopt (H. Nakano)
- incorrect return codes fixed (Tomasz Lemiech, Alexey Bortnikov)
diff --git a/Makefile b/Makefile
index 7e206fd..5593e53 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@ ifndef KERNEL_DIR
KERNEL_DIR=/usr/src/linux
endif
-IPSET_VERSION:=2.2.9a
+IPSET_VERSION:=2.3.0
PREFIX:=/usr/local
LIBDIR:=$(PREFIX)/lib
@@ -21,9 +21,9 @@ IPSET_LIB_DIR:=$(LIBDIR)/ipset
RELEASE_DIR:=/tmp
COPT_FLAGS:=-O2
-CFLAGS:=$(COPT_FLAGS) -Wall -Wunused -I$(KERNEL_DIR)/include -I. # -g -DIPSET_DEBUG #-pg # -DIPTC_DEBUG
+CFLAGS:=$(COPT_FLAGS) -Wall -Wunused -I$(KERNEL_DIR)/include -I. -g -DIPSET_DEBUG #-pg # -DIPTC_DEBUG
SH_CFLAGS:=$(CFLAGS) -fPIC
-SETTYPES:=ipmap portmap macipmap iphash nethash iptree ipporthash
+SETTYPES:=ipmap portmap macipmap iphash nethash iptree iptreemap ipporthash
PROGRAMS=ipset
SHARED_LIBS=$(foreach T, $(SETTYPES),libipset_$(T).so)
diff --git a/ipset.8 b/ipset.8
index 89a86ce..8da015c 100644
--- a/ipset.8
+++ b/ipset.8
@@ -231,10 +231,11 @@ 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
up to 65536 (B-class network) IP addresses with MAC.
When adding an entry to a macipmap set, you must specify the entry as
-.I IP%MAC.
+.I IP:MAC.
When deleting or testing macipmap entries, the
-.I %MAC
-part is not mandatory.
+.I :MAC
+part is not mandatory. (The old "%" separation token instead of ":", i.e
+IP%MAC is accepted as well.)
.P
Options to use when creating an macipmap set:
.TP
@@ -307,6 +308,9 @@ When the optional
parameter specified, network addresses will be
stored in the set instead of IP addresses.
.P
+The iphash type of sets can store up to 65535 entries. If a set is full,
+no new entries can be added to it.
+.P
Sets created by zero valued resize parameter won't be resized at all.
The lookup time in an iphash type of set approximately linearly grows with
the value of the
@@ -342,6 +346,9 @@ by double-hashing (default 4).
Increase the hash size by this many percent (default 50) when adding
an IP to the hash could not be performed after
.P
+The nethash type of sets can store up to 65535 entries. If a set is full,
+no new entries can be added to it.
+.P
An IP address will be in a nethash type of set if it is in any of the
netblocks added to the set and the matching always start from the smallest
size of netblock (most specific netmask) to the biggest ones (least
@@ -367,7 +374,8 @@ store up to 65536 (B-class network) IP addresses with all possible port
values. When adding, deleting and testing values in an ipporthash type of
set, the entries must be specified as
.B
-"IP%port".
+"IP:port".
+(Old "IP%port" format accepted as well.)
.P
The ipporthash types of sets evaluates two src/dst parameters of the
.I
@@ -416,7 +424,20 @@ If a set was created with a nonzero valued
.B "--timeout"
parameter then one may add IP addresses to the set with a specific
timeout value using the syntax
-.I IP%timeout-value.
+.I IP:timeout-value.
+Similarly to the hash types, the iptree type of sets can store up to 65535
+entries.
+.SS iptreemap
+The iptreemap set type uses a tree to store IP addresses or networks,
+where the last octet of an IP address are stored in a bitmap.
+As input entry, you can add IP addresses, CIDR blocks or network ranges
+to the set. Network ranges can be specified in the format
+.I IP1:IP2
+.P
+Options to use when creating an iptreemap set:
+.TP
+.BR "--gc " value
+How often the garbage collection should be called, in seconds (default 300)
.SH GENERAL RESTRICTIONS
Setnames starting with colon (:) cannot be defined. Zero valued set
entries cannot be used with hash type of sets.
diff --git a/ipset.c b/ipset.c
index a63b8ec..9d7f78b 100644
--- a/ipset.c
+++ b/ipset.c
@@ -1151,13 +1151,17 @@ static size_t save_set(void *data, int *bindings,
struct settype *settype;
size_t used;
- DP("offset %u, len %u", offset, len);
+ DP("offset %u (%u/%u/%u), len %u", 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)
+ set_save->header_size + set_save->members_size > len)
exit_error(OTHER_PROBLEM,
"Save operation failed, try again later.");
+ DP("index: %u", set_save->index);
if (set_save->index == IP_SET_INVALID_ID) {
/* Marker */
*bindings = 1;
@@ -1633,6 +1637,10 @@ static int set_bind(struct set *set, const char *adt,
/* set may be null: '-U :all: :all:|:default:' */
DP("(%s, %s) -> %s", set ? set->name : IPSET_TOKEN_ALL, adt, binding);
+ /* Ugly */
+ if (strcmp(set->settype->typename, "iptreemap") == 0)
+ exit_error(PARAMETER_PROBLEM,
+ "iptreemap type of sets cannot be used at binding operations\n");
/* Alloc memory for the data to send */
size = sizeof(struct ip_set_req_bind);
if (op != IP_SET_OP_UNBIND_SET && adt[0] == ':')
diff --git a/ipset_ipmap.c b/ipset_ipmap.c
index ed38ec9..df8efbf 100644
--- a/ipset_ipmap.c
+++ b/ipset_ipmap.c
@@ -191,7 +191,7 @@ void create_final(void *data, unsigned int flags)
}
if (range > MAX_RANGE)
exit_error(PARAMETER_PROBLEM,
- "Range to large. Max is %d IPs in range\n",
+ "Range too large. Max is %d IPs in range\n",
MAX_RANGE+1);
}
diff --git a/ipset_ipporthash.c b/ipset_ipporthash.c
index 0548b86..ef527fa 100644
--- a/ipset_ipporthash.c
+++ b/ipset_ipporthash.c
@@ -181,7 +181,7 @@ void create_final(void *data, unsigned int flags)
if (mydata->to - mydata->from > MAX_RANGE)
exit_error(PARAMETER_PROBLEM,
- "Range to large. Max is %d IPs in range\n",
+ "Range too large. Max is %d IPs in range\n",
MAX_RANGE+1);
}
@@ -206,7 +206,7 @@ ip_set_ip_t adt_parser(unsigned cmd, const char *optarg, void *data)
DP("ipporthash: %p %p", optarg, data);
- ptr = strsep(&tmp, "%");
+ ptr = strsep(&tmp, ":%");
parse_ip(ptr, &mydata->ip);
if (tmp)
@@ -262,7 +262,7 @@ void printips(struct set *set, void *data, size_t len, unsigned options)
if (*ipptr) {
ip = (*ipptr>>16) + mysetdata->first_ip;
port = (uint16_t) *ipptr;
- printf("%s%%%s\n",
+ printf("%s:%s\n",
ip_tostring(ip, options),
port_tostring(port, options));
}
@@ -298,7 +298,7 @@ void saveips(struct set *set, void *data, size_t len, unsigned options)
if (*ipptr) {
ip = (*ipptr>>16) + mysetdata->first_ip;
port = (uint16_t) *ipptr;
- printf("-A %s %s%%%s\n", set->name,
+ printf("-A %s %s:%s\n", set->name,
ip_tostring(ip, options),
port_tostring(port, options));
}
@@ -316,7 +316,7 @@ static char * unpack_ipport_tostring(struct set *set, ip_set_ip_t bip, unsigned
ip = (bip>>16) + mysetdata->first_ip;
port = (uint16_t) bip;
- sprintf(buffer, "%s%%%s",
+ sprintf(buffer, "%s:%s",
ip_tostring(ip, options), port_tostring(port, options));
return buffer;
@@ -329,9 +329,9 @@ void usage(void)
" [--hashsize hashsize] [--probes probes ] [--resize resize]\n"
"-N set ipporthash --network IP/mask\n"
" [--hashsize hashsize] [--probes probes ] [--resize resize]\n"
- "-A set IP%%port\n"
- "-D set IP%%port\n"
- "-T set IP%%port\n");
+ "-A set IP:port\n"
+ "-D set IP:port\n"
+ "-T set IP:port\n");
}
static struct settype settype_ipporthash = {
diff --git a/ipset_iptree.c b/ipset_iptree.c
index cce9884..c3678df 100644
--- a/ipset_iptree.c
+++ b/ipset_iptree.c
@@ -84,7 +84,7 @@ ip_set_ip_t adt_parser(unsigned cmd, const char *optarg, void *data)
DP("iptree: %p %p", optarg, data);
- ptr = strsep(&tmp, "%");
+ ptr = strsep(&tmp, ":%");
parse_ip(ptr, &mydata->ip);
if (tmp)
@@ -130,8 +130,8 @@ void printips_sorted(struct set *set, void *data, size_t len, unsigned options)
while (len >= offset + sizeof(struct ip_set_req_iptree)) {
req = (struct ip_set_req_iptree *)(data + offset);
if (mysetdata->timeout)
- printf("%s%%%u\n", ip_tostring(req->ip, options),
- req->timeout);
+ printf("%s:%u\n", ip_tostring(req->ip, options),
+ req->timeout);
else
printf("%s\n", ip_tostring(req->ip, options));
offset += sizeof(struct ip_set_req_iptree);
@@ -164,7 +164,7 @@ void saveips(struct set *set, void *data, size_t len, unsigned options)
while (len >= offset + sizeof(struct ip_set_req_iptree)) {
req = (struct ip_set_req_iptree *)(data + offset);
if (mysetdata->timeout)
- printf("-A %s %s%%%u\n",
+ printf("-A %s %s:%u\n",
set->name,
ip_tostring(req->ip, options),
req->timeout);
@@ -180,7 +180,7 @@ void usage(void)
{
printf
("-N set iptree [--timeout value]\n"
- "-A set IP[%%timeout]\n"
+ "-A set IP[:timeout]\n"
"-D set IP\n"
"-T set IP\n");
}
diff --git a/ipset_iptreemap.c b/ipset_iptreemap.c
new file mode 100644
index 0000000..ccc5ec3
--- /dev/null
+++ b/ipset_iptreemap.c
@@ -0,0 +1,206 @@
+/* Copyright 2007 Sven Wegener <sven.wegener@stealer.net>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <linux/netfilter_ipv4/ip_set_iptreemap.h>
+
+#include "ipset.h"
+
+#define OPT_CREATE_GC 0x1
+
+void
+create_init(void *data)
+{
+ struct ip_set_req_iptreemap_create *mydata = (struct ip_set_req_iptreemap_create *) data;
+
+ mydata->gc_interval = 0;
+}
+
+int
+create_parse(int c, char *argv[], void *data, unsigned int *flags)
+{
+ struct ip_set_req_iptreemap_create *mydata = (struct ip_set_req_iptreemap_create *) data;
+
+ switch (c) {
+ case 'g':
+ string_to_number(optarg, 0, UINT_MAX, &mydata->gc_interval);
+
+ *flags |= OPT_CREATE_GC;
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ return 1;
+}
+
+void
+create_final(void *data, unsigned int flags)
+{
+}
+
+static struct option create_opts[] = {
+ {"gc", 1, 0, 'g'},
+ {0}
+};
+
+ip_set_ip_t
+adt_parser(unsigned int cmd, const char *optarg, void *data)
+{
+ struct ip_set_req_iptreemap *mydata = (struct ip_set_req_iptreemap *) data;
+ ip_set_ip_t mask;
+
+ char *saved = ipset_strdup(optarg);
+ char *ptr, *tmp = saved;
+
+ if (strchr(tmp, '/')) {
+ parse_ipandmask(tmp, &mydata->start, &mask);
+ mydata->end = mydata->start | ~mask;
+ } else {
+ ptr = strsep(&tmp, ":");
+ parse_ip(ptr, &mydata->start);
+
+ if (tmp) {
+ parse_ip(tmp, &mydata->end);
+ } else {
+ mydata->end = mydata->start;
+ }
+ }
+
+ return 1;
+}
+
+void
+initheader(struct set *set, const void *data)
+{
+ struct ip_set_req_iptreemap_create *header = (struct ip_set_req_iptreemap_create *) data;
+ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->settype->header;
+
+ map->gc_interval = header->gc_interval;
+}
+
+void
+printheader(struct set *set, unsigned int options)
+{
+ struct ip_set_iptreemap *mysetdata = (struct ip_set_iptreemap *) set->settype->header;
+
+ if (mysetdata->gc_interval)
+ printf(" gc: %u", mysetdata->gc_interval);
+
+ printf("\n");
+}
+
+void
+printips_sorted(struct set *set, void *data, size_t len, unsigned int options)
+{
+ struct ip_set_req_iptreemap *req;
+ size_t offset = 0;
+
+ while (len >= offset + sizeof(struct ip_set_req_iptreemap)) {
+ req = (struct ip_set_req_iptreemap *) (data + offset);
+
+ printf("%s", ip_tostring(req->start, options));
+ if (req->start != req->end)
+ printf(":%s", ip_tostring(req->end, options));
+ printf("\n");
+
+ offset += sizeof(struct ip_set_req_iptreemap);
+ }
+}
+
+void
+saveheader(struct set *set, unsigned int options)
+{
+ struct ip_set_iptreemap *mysetdata = (struct ip_set_iptreemap *) set->settype->header;
+
+ printf("-N %s %s", set->name, set->settype->typename);
+
+ if (mysetdata->gc_interval)
+ printf(" --gc %u", mysetdata->gc_interval);
+
+ printf("\n");
+}
+
+void
+saveips(struct set *set, void *data, size_t len, unsigned int options)
+{
+ struct ip_set_req_iptreemap *req;
+ size_t offset = 0;
+
+ while (len >= offset + sizeof(struct ip_set_req_iptreemap)) {
+ req = (struct ip_set_req_iptreemap *) (data + offset);
+
+ printf("-A %s %s", set->name, ip_tostring(req->start, options));
+
+ if (req->start != req->end)
+ printf(":%s", ip_tostring(req->end, options));
+
+ printf("\n");
+
+ offset += sizeof(struct ip_set_req_iptreemap);
+ }
+}
+
+void
+usage(void)
+{
+ printf(
+ "-N set iptreemap --gc interval\n"
+ "-A set IP\n"
+ "-D set IP\n"
+ "-T set IP\n"
+ );
+}
+
+static struct settype settype_iptreemap = {
+ .typename = SETTYPE_NAME,
+ .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_opts = create_opts,
+
+ .adt_size = sizeof(struct ip_set_req_iptreemap),
+ .adt_parser = &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,
+};
+
+void
+_init(void)
+{
+ settype_register(&settype_iptreemap);
+}
diff --git a/ipset_macipmap.c b/ipset_macipmap.c
index c14547a..3385f19 100644
--- a/ipset_macipmap.c
+++ b/ipset_macipmap.c
@@ -184,7 +184,7 @@ ip_set_ip_t adt_parser(unsigned cmd, const char *optarg, void *data)
DP("macipmap: %p %p", optarg, data);
- ptr = strsep(&tmp, "%");
+ ptr = strsep(&tmp, ":%");
parse_ip(ptr, &mydata->ip);
if (tmp)
@@ -246,7 +246,7 @@ void printips_sorted(struct set *set, void *data, size_t len, unsigned options)
while (addr <= mysetdata->last_ip) {
if (test_bit(IPSET_MACIP_ISSET,
(void *)&table[addr - mysetdata->first_ip].flags)) {
- printf("%s%%", ip_tostring(addr, options));
+ printf("%s:", ip_tostring(addr, options));
print_mac(table[addr - mysetdata->first_ip].
ethernet);
printf("\n");
@@ -281,7 +281,7 @@ void saveips(struct set *set, void *data, size_t len, unsigned options)
while (addr <= mysetdata->last_ip) {
if (test_bit(IPSET_MACIP_ISSET,
(void *)&table[addr - mysetdata->first_ip].flags)) {
- printf("-A %s %s%%",
+ printf("-A %s %s:",
set->name, ip_tostring(addr, options));
print_mac(table[addr - mysetdata->first_ip].
ethernet);
@@ -296,9 +296,9 @@ void usage(void)
printf
("-N set macipmap --from IP --to IP [--matchunset]\n"
"-N set macipmap --network IP/mask [--matchunset]\n"
- "-A set IP%%MAC\n"
- "-D set IP[%%MAC]\n"
- "-T set IP[%%MAC]\n");
+ "-A set IP:MAC\n"
+ "-D set IP[:MAC]\n"
+ "-T set IP[:MAC]\n");
}
static struct settype settype_macipmap = {