]> granicus.if.org Git - ipset/commitdiff
New release: 2.3.0 (see ChangeLog)
author/C=EU/ST=EU/CN=Jozsef Kadlecsik/emailAddress=kadlec@blackhole.kfki.hu </C=EU/ST=EU/CN=Jozsef Kadlecsik/emailAddress=kadlec@blackhole.kfki.hu>
Tue, 28 Aug 2007 11:23:22 +0000 (11:23 +0000)
committer/C=EU/ST=EU/CN=Jozsef Kadlecsik/emailAddress=kadlec@blackhole.kfki.hu </C=EU/ST=EU/CN=Jozsef Kadlecsik/emailAddress=kadlec@blackhole.kfki.hu>
Tue, 28 Aug 2007 11:23:22 +0000 (11:23 +0000)
ChangeLog
Makefile
ipset.8
ipset.c
ipset_ipmap.c
ipset_ipporthash.c
ipset_iptree.c
ipset_iptreemap.c [new file with mode: 0644]
ipset_macipmap.c

index 63a6e4251c47ba69b737f516fa0e0cf808f64def..ee0154e30796049e01927f3ace04005f9498dfeb 100644 (file)
--- 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)
index 7e206fd5054c2d9887ff5dca3de1312aebb427a9..5593e53ecfb17e868bdcc124a946915763218930 100644 (file)
--- 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 89a86ce859ca2934a1390f645190a1b2307b196e..8da015c59ce31b0194d095efe9a734c722dbf8cb 100644 (file)
--- 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 a63b8ec353dd69f7c2ef50ef2d24bf6a36be3aa4..9d7f78b48d47122d7b6120359fd16e80045cff5a 100644 (file)
--- 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] == ':')
index ed38ec97655047bb227f7e1e0ddc6ca3a93ed9f2..df8efbf7c8d219281ceb17a8481c31b403dd8879 100644 (file)
@@ -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);
 }
 
index 0548b8623e1c420b3a4a75b649b7fb1b036202b5..ef527fa2e147fa67b2aaf44e5771134d57ac7ace 100644 (file)
@@ -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 = {
index cce9884d74631da88e734671f70ef996c2aa2334..c3678df9dbb3e1159916187f094ad6e87d9b5d87 100644 (file)
@@ -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 (file)
index 0000000..ccc5ec3
--- /dev/null
@@ -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);
+}
index c14547adcbedebd860ac6333f8aba755a263bac3..3385f19b540ce93c313330a7de71ffdd8e98d20b 100644 (file)
@@ -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 = {