summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2011-05-30 17:48:01 +0200
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2011-05-30 21:30:10 +0200
commit418a3a4f4d4e38abd1d691f81f2445590f02ecaf (patch)
treea41ed16b366c854786eea8f3da5c80fa50636dc6 /src
parent4e21d6b5ce623f7601a872b94f3b88105356e2d3 (diff)
hash:net,iface type introduced
The hash:net,iface type makes possible to store network address and interface name pairs in a set. It's mostly suitable for egress and ingress filtering. Examples: # ipset create test hash:net,iface # ipset add test 192.168.0.0/16,eth0 # ipset add test 192.168.0.0/24,eth1
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/ipset.871
-rw-r--r--src/ipset.c2
-rw-r--r--src/ipset_hash_netiface.c120
4 files changed, 192 insertions, 2 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 336145a..f3047f0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,6 +12,7 @@ ipset_SOURCES = ipset.c \
ipset_hash_ipportnet.c \
ipset_hash_net.c \
ipset_hash_netport.c \
+ ipset_hash_netiface.c \
ipset_list_set.c \
ui.c
ipset_LDADD = ../lib/libipset.la
diff --git a/src/ipset.8 b/src/ipset.8
index 90914f4..648e935 100644
--- a/src/ipset.8
+++ b/src/ipset.8
@@ -214,8 +214,8 @@ command follows the syntax
where the current list of the methods are
\fBbitmap\fR, \fBhash\fR, and \fBlist\fR and the possible data types
-are \fBip\fR, \fBnet\fR, \fBmac\fR and \fBport\fR. The dimension of a set
-is equal to the number of data types in its type name.
+are \fBip\fR, \fBnet\fR, \fBmac\fR, \fBport\fR and \fBiface\fR.
+The dimension of a set is equal to the number of data types in its type name.
When adding, deleting or testing entries in a set, the same comma separated
data syntax must be used for the entry parameter of the commands, i.e
@@ -711,6 +711,73 @@ ipset add foo 192.168.1,80,10.0.0/24
ipset add foo 192.168.2,25,10.1.0.0/16
.IP
ipset test foo 192.168.1,80.10.0.0/24
+.SS hash:net,iface
+The \fBhash:net,iface\fR set type uses a hash to store different sized IP network
+address and interface name pairs. Network address with zero prefix size is not
+accepted.
+.PP
+\fICREATE\-OPTIONS\fR := [ \fBfamily\fR { \fBinet\fR | \fBinet6\fR } ] | [ \fBhashsize\fR \fIvalue\fR ] [ \fBmaxelem\fR \fIvalue\fR ] [ \fBtimeout\fR \fIvalue\fR ]
+.PP
+\fIADD\-ENTRY\fR := \fInetaddr\fR,[\fBphysdev\fR:]\fIiface\fR
+.PP
+\fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ]
+.PP
+\fIDEL\-ENTRY\fR := \fInetaddr\fR,[\fBphysdev\fR:]\fIiface\fR
+.PP
+\fITEST\-ENTRY\fR := \fInetaddr\fR,[\fBphysdev\fR:]\fIiface\fR
+.PP
+where
+\fInetaddr\fR := \fIip\fR[/\fIcidr\fR]
+.PP
+Optional \fBcreate\fR options:
+.TP
+\fBfamily\fR { \fBinet\fR | \fBinet6\fR }
+The protocol family of the IP addresses to be stored in the set. The default is
+\fBinet\fR, i.e IPv4.
+.TP
+\fBhashsize\fR \fIvalue\fR
+The initial hash size for the set, default is 1024. The hash size must be a power
+of two, the kernel automatically rounds up non power of two hash sizes to the first
+correct value.
+.TP
+\fBmaxelem\fR \fIvalue\fR
+The maximal number of elements which can be stored in the set, default 65536.
+.PP
+For the \fInetaddr\fR part of the elements
+see the description at the \fBhash:net\fR set type.
+.PP
+When adding/deleting/testing entries, if the cidr prefix parameter is not specified,
+then the host prefix value is assumed. When adding/deleting entries, the exact
+element is added/deleted and overlapping elements are not checked by the kernel.
+When testing entries, if a host address is tested, then the kernel tries to match
+the host address in the networks added to the set and reports the result accordingly.
+.PP
+From the \fBset\fR netfilter match point of view the searching for a match
+always starts from the smallest size of netblock (most specific
+prefix) to the largest one (least specific prefix) added to the set.
+When adding/deleting IP
+addresses to the set by the \fBSET\fR netfilter target, it will be
+added/deleted by the most specific prefix which can be found in the
+set, or by the host prefix value if the set is empty.
+.PP
+The second direction parameter of the \fBset\fR match and
+\fBSET\fR target modules corresponds to the incoming/outgoing interface
+: \fBsrc\fR to the incoming, while \fBdst\fR to the outgoing. When
+the interface is flagged with \fBphysdev:\fR, the interface is interpreted
+as the incoming/outgoing bridge port.
+.PP
+The lookup time grows linearly with the number of the different prefix
+values added to the set.
+.PP
+Examples:
+.IP
+ipset create foo hash:net,iface
+.IP
+ipset add foo 192.168.0/24,eth0
+.IP
+ipset add foo 10.1.0.0/16,eth1
+.IP
+ipset test foo 192.168.0/24,eth0
.SS list:set
The \fBlist:set\fR type uses a simple list in which you can store
set names.
diff --git a/src/ipset.c b/src/ipset.c
index 371d851..032564c 100644
--- a/src/ipset.c
+++ b/src/ipset.c
@@ -42,6 +42,7 @@ extern struct ipset_type ipset_hash_net0;
extern struct ipset_type ipset_hash_net1;
extern struct ipset_type ipset_hash_netport1;
extern struct ipset_type ipset_hash_netport2;
+extern struct ipset_type ipset_hash_netiface0;
extern struct ipset_type ipset_hash_ipport1;
extern struct ipset_type ipset_hash_ipportip1;
extern struct ipset_type ipset_hash_ipportnet1;
@@ -729,6 +730,7 @@ main(int argc, char *argv[])
ipset_type_add(&ipset_hash_net1);
ipset_type_add(&ipset_hash_netport1);
ipset_type_add(&ipset_hash_netport2);
+ ipset_type_add(&ipset_hash_netiface0);
ipset_type_add(&ipset_hash_ipport1);
ipset_type_add(&ipset_hash_ipportip1);
ipset_type_add(&ipset_hash_ipportnet1);
diff --git a/src/ipset_hash_netiface.c b/src/ipset_hash_netiface.c
new file mode 100644
index 0000000..bac860b
--- /dev/null
+++ b/src/ipset_hash_netiface.c
@@ -0,0 +1,120 @@
+/* Copyright 2011 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <libipset/data.h> /* IPSET_OPT_* */
+#include <libipset/parse.h> /* parser functions */
+#include <libipset/print.h> /* printing functions */
+#include <libipset/ui.h> /* ipset_port_usage */
+#include <libipset/types.h> /* prototypes */
+
+/* Parse commandline arguments */
+static const struct ipset_arg hash_netiface_create_args[] = {
+ { .name = { "family", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY,
+ .parse = ipset_parse_family, .print = ipset_print_family,
+ },
+ /* Alias: family inet */
+ { .name = { "-4", NULL },
+ .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
+ .parse = ipset_parse_family,
+ },
+ /* Alias: family inet6 */
+ { .name = { "-6", NULL },
+ .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
+ .parse = ipset_parse_family,
+ },
+ { .name = { "hashsize", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE,
+ .parse = ipset_parse_uint32, .print = ipset_print_number,
+ },
+ { .name = { "maxelem", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM,
+ .parse = ipset_parse_uint32, .print = ipset_print_number,
+ },
+ { .name = { "timeout", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
+ .parse = ipset_parse_uint32, .print = ipset_print_number,
+ },
+ { },
+};
+
+static const struct ipset_arg hash_netiface_add_args[] = {
+ { .name = { "timeout", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
+ .parse = ipset_parse_uint32, .print = ipset_print_number,
+ },
+ { },
+};
+
+static const char hash_netiface_usage[] =
+"create SETNAME hash:net,iface\n"
+" [family inet|inet6]\n"
+" [hashsize VALUE] [maxelem VALUE]\n"
+" [timeout VALUE]\n"
+"add SETNAME IP[/CIDR]|FROM-TO,[physdev:]IFACE [timeout VALUE]\n"
+"del SETNAME IP[/CIDR]|FROM-TO,[physdev:]IFACE\n"
+"test SETNAME IP[/CIDR],[physdev:]IFACE\n\n"
+"where depending on the INET family\n"
+" IP is a valid IPv4 or IPv6 address (or hostname),\n"
+" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n"
+" Adding/deleting multiple elements with IPv4 is supported.\n";
+
+struct ipset_type ipset_hash_netiface0 = {
+ .name = "hash:net,iface",
+ .alias = { "netifacehash", NULL },
+ .revision = 0,
+ .family = AF_INET46,
+ .dimension = IPSET_DIM_TWO,
+ .elem = {
+ [IPSET_DIM_ONE] = {
+ .parse = ipset_parse_ip4_net6,
+ .print = ipset_print_ip,
+ .opt = IPSET_OPT_IP
+ },
+ [IPSET_DIM_TWO] = {
+ .parse = ipset_parse_iface,
+ .print = ipset_print_iface,
+ .opt = IPSET_OPT_IFACE
+ },
+ },
+ .args = {
+ [IPSET_CREATE] = hash_netiface_create_args,
+ [IPSET_ADD] = hash_netiface_add_args,
+ },
+ .mandatory = {
+ [IPSET_CREATE] = 0,
+ [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_IFACE),
+ [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_IFACE),
+ [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_IFACE),
+ },
+ .full = {
+ [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE)
+ | IPSET_FLAG(IPSET_OPT_MAXELEM)
+ | IPSET_FLAG(IPSET_OPT_TIMEOUT),
+ [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_CIDR)
+ | IPSET_FLAG(IPSET_OPT_IP_TO)
+ | IPSET_FLAG(IPSET_OPT_IFACE)
+ | IPSET_FLAG(IPSET_OPT_PHYSDEV)
+ | IPSET_FLAG(IPSET_OPT_TIMEOUT),
+ [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_CIDR)
+ | IPSET_FLAG(IPSET_OPT_IP_TO)
+ | IPSET_FLAG(IPSET_OPT_IFACE)
+ | IPSET_FLAG(IPSET_OPT_PHYSDEV),
+ [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_CIDR)
+ | IPSET_FLAG(IPSET_OPT_IP_TO)
+ | IPSET_FLAG(IPSET_OPT_IFACE)
+ | IPSET_FLAG(IPSET_OPT_PHYSDEV),
+ },
+
+ .usage = hash_netiface_usage,
+};
+