summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/include/linux/netfilter/ipset/ip_set_getport.h2
-rw-r--r--kernel/net/netfilter/ipset/ip_set_getport.c16
-rw-r--r--kernel/net/netfilter/ipset/ip_set_hash_ipport.c2
-rw-r--r--kernel/net/netfilter/ipset/ip_set_hash_ipportip.c2
-rw-r--r--kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c2
-rw-r--r--kernel/net/netfilter/ipset/ip_set_hash_netport.c2
-rw-r--r--lib/parse.c5
-rw-r--r--lib/print.c2
-rw-r--r--lib/types.c28
-rw-r--r--src/ipset.827
-rw-r--r--src/ipset_hash_ipport.c6
-rw-r--r--src/ipset_hash_ipportip.c6
-rw-r--r--src/ipset_hash_ipportnet.c6
-rw-r--r--src/ipset_hash_netport.c5
-rw-r--r--tests/hash:ip,port.t6
15 files changed, 74 insertions, 43 deletions
diff --git a/kernel/include/linux/netfilter/ipset/ip_set_getport.h b/kernel/include/linux/netfilter/ipset/ip_set_getport.h
index 5aebd17..90d0930 100644
--- a/kernel/include/linux/netfilter/ipset/ip_set_getport.h
+++ b/kernel/include/linux/netfilter/ipset/ip_set_getport.h
@@ -22,7 +22,9 @@ static inline bool ip_set_proto_with_ports(u8 proto)
{
switch (proto) {
case IPPROTO_TCP:
+ case IPPROTO_SCTP:
case IPPROTO_UDP:
+ case IPPROTO_UDPLITE:
return true;
}
return false;
diff --git a/kernel/net/netfilter/ipset/ip_set_getport.c b/kernel/net/netfilter/ipset/ip_set_getport.c
index 8d52272..757143b 100644
--- a/kernel/net/netfilter/ipset/ip_set_getport.c
+++ b/kernel/net/netfilter/ipset/ip_set_getport.c
@@ -11,6 +11,7 @@
#include <linux/skbuff.h>
#include <linux/icmp.h>
#include <linux/icmpv6.h>
+#include <linux/sctp.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <net/ip.h>
#include <net/ipv6.h>
@@ -35,7 +36,20 @@ get_port(const struct sk_buff *skb, int protocol, unsigned int protooff,
*port = src ? th->source : th->dest;
break;
}
- case IPPROTO_UDP: {
+ case IPPROTO_SCTP: {
+ sctp_sctphdr_t _sh;
+ const sctp_sctphdr_t *sh;
+
+ sh = skb_header_pointer(skb, protooff, sizeof(_sh), &_sh);
+ if (sh == NULL)
+ /* No choice either */
+ return false;
+
+ *port = src ? sh->source : sh->dest;
+ break;
+ }
+ case IPPROTO_UDP:
+ case IPPROTO_UDPLITE: {
struct udphdr _udph;
const struct udphdr *uh;
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_ipport.c b/kernel/net/netfilter/ipset/ip_set_hash_ipport.c
index b921414..14281b6 100644
--- a/kernel/net/netfilter/ipset/ip_set_hash_ipport.c
+++ b/kernel/net/netfilter/ipset/ip_set_hash_ipport.c
@@ -491,7 +491,7 @@ static struct ip_set_type hash_ipport_type __read_mostly = {
.features = IPSET_TYPE_IP | IPSET_TYPE_PORT,
.dimension = IPSET_DIM_TWO,
.family = AF_UNSPEC,
- .revision = 0,
+ .revision = 1,
.create = hash_ipport_create,
.create_policy = {
[IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_ipportip.c b/kernel/net/netfilter/ipset/ip_set_hash_ipportip.c
index 4642872..401c8a2 100644
--- a/kernel/net/netfilter/ipset/ip_set_hash_ipportip.c
+++ b/kernel/net/netfilter/ipset/ip_set_hash_ipportip.c
@@ -509,7 +509,7 @@ static struct ip_set_type hash_ipportip_type __read_mostly = {
.features = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_TYPE_IP2,
.dimension = IPSET_DIM_THREE,
.family = AF_UNSPEC,
- .revision = 0,
+ .revision = 1,
.create = hash_ipportip_create,
.create_policy = {
[IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c b/kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c
index 2cb84a5..4743e54 100644
--- a/kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c
+++ b/kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c
@@ -574,7 +574,7 @@ static struct ip_set_type hash_ipportnet_type __read_mostly = {
.features = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_TYPE_IP2,
.dimension = IPSET_DIM_THREE,
.family = AF_UNSPEC,
- .revision = 0,
+ .revision = 1,
.create = hash_ipportnet_create,
.create_policy = {
[IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_netport.c b/kernel/net/netfilter/ipset/ip_set_hash_netport.c
index 8598676..d2a4036 100644
--- a/kernel/net/netfilter/ipset/ip_set_hash_netport.c
+++ b/kernel/net/netfilter/ipset/ip_set_hash_netport.c
@@ -526,7 +526,7 @@ static struct ip_set_type hash_netport_type __read_mostly = {
.features = IPSET_TYPE_IP | IPSET_TYPE_PORT,
.dimension = IPSET_DIM_TWO,
.family = AF_UNSPEC,
- .revision = 0,
+ .revision = 1,
.create = hash_netport_create,
.create_policy = {
[IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
diff --git a/lib/parse.c b/lib/parse.c
index cd1ad32..0c15231 100644
--- a/lib/parse.c
+++ b/lib/parse.c
@@ -500,10 +500,9 @@ ipset_parse_proto_port(struct ipset_session *session,
p = *(const uint8_t *) ipset_data_get(data, IPSET_OPT_PROTO);
switch (p) {
case IPPROTO_TCP:
- proto = tmp;
- tmp = a;
- goto parse_port;
+ case IPPROTO_SCTP:
case IPPROTO_UDP:
+ case IPPROTO_UDPLITE:
proto = tmp;
tmp = a;
goto parse_port;
diff --git a/lib/print.c b/lib/print.c
index 5284b0a..66b9c1a 100644
--- a/lib/print.c
+++ b/lib/print.c
@@ -585,7 +585,9 @@ ipset_print_proto_port(char *buf, unsigned int len,
switch (proto) {
case IPPROTO_TCP:
+ case IPPROTO_SCTP:
case IPPROTO_UDP:
+ case IPPROTO_UDPLITE:
break;
case IPPROTO_ICMP:
return ipset_print_icmp(buf + offset, len, data,
diff --git a/lib/types.c b/lib/types.c
index 5eb53c4..f0dbbc9 100644
--- a/lib/types.c
+++ b/lib/types.c
@@ -198,7 +198,7 @@ create_type_get(struct ipset_session *session)
struct ipset_data *data;
const char *typename;
uint8_t family, tmin = 0, tmax = 0;
- const uint8_t *kmin, *kmax;
+ uint8_t kmin, kmax;
int ret;
data = ipset_session_data(session);
@@ -240,32 +240,32 @@ create_type_get(struct ipset_session *session)
if (ret != 0)
return NULL;
- kmax = ipset_data_get(data, IPSET_OPT_REVISION);
+ kmax = *(const uint8_t *)ipset_data_get(data, IPSET_OPT_REVISION);
if (ipset_data_test(data, IPSET_OPT_REVISION_MIN))
- kmin = ipset_data_get(data, IPSET_OPT_REVISION_MIN);
+ kmin = *(const uint8_t *)ipset_data_get(data, IPSET_OPT_REVISION_MIN);
else
kmin = kmax;
- if (MAX(tmin, *kmin) > MIN(tmax, *kmax)) {
- if (*kmin > tmax)
+ if (MAX(tmin, kmin) > MIN(tmax, kmax)) {
+ if (kmin > tmax)
return ipset_errptr(session,
- "Kernel supports %s type with family %s "
- "in minimal revision %u while ipset library "
- "in maximal revision %u. "
- "You need to upgrade your ipset library.",
+ "Kernel supports %s type, family %s "
+ "with minimal revision %u while ipset program "
+ "with maximal revision %u.\n"
+ "You need to upgrade your ipset program.",
typename,
family == AF_INET ? "INET" :
family == AF_INET6 ? "INET6" : "UNSPEC",
- *kmin, tmax);
+ kmin, tmax);
else
return ipset_errptr(session,
- "Kernel supports %s type with family %s "
- "in maximal revision %u while ipset library "
- "in minimal revision %u. "
+ "Kernel supports %s type, family %s "
+ "with maximal revision %u while ipset program "
+ "with minimal revision %u.\n"
"You need to upgrade your kernel.",
typename,
family == AF_INET ? "INET" :
family == AF_INET6 ? "INET6" : "UNSPEC",
- *kmax, tmin);
+ kmax, tmin);
}
match->kernel_check = IPSET_KERNEL_OK;
diff --git a/src/ipset.8 b/src/ipset.8
index b9ca8a5..cad3296 100644
--- a/src/ipset.8
+++ b/src/ipset.8
@@ -330,6 +330,9 @@ Mandatory options to use when creating a \fBbitmap:port\fR type of set:
\fBrange\fP \fIfromport\fP\-\fItoport\fR
Create the set from the specified inclusive port range.
.PP
+The \fBset\fR match and \fBSET\fR target netfilter kernel modules interpret
+the stored numbers as TCP or UDP port numbers.
+.PP
Examples:
.IP
ipset create foo bitmap:port range 0\-1024
@@ -380,9 +383,9 @@ a range or a network:
.PP
Examples:
.IP
-ipset create foo hash:ip netmask 24
+ipset create foo hash:ip netmask 30
.IP
-ipset add foo 192.168.1.1\-192.168.1.2
+ipset add foo 192.168.1.0/24
.IP
ipset test foo 192.168.1.2
.SS hash:net
@@ -414,8 +417,10 @@ correct value.
The maximal number of elements which can be stored in the set, default 65536.
.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, overlapping
-elements are not checked.
+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
@@ -431,7 +436,7 @@ Examples:
.IP
ipset create foo hash:net
.IP
-ipset add foo 192.168.0/24
+ipset add foo 192.168.0.0/24
.IP
ipset add foo 10.1.0.0/16
.IP
@@ -481,8 +486,8 @@ TCP port or range of ports expressed in TCP portname identifiers from /etc/servi
\fIportnumber[\-portnumber]\fR
TCP port or range of ports expressed in TCP port numbers
.TP
-\fBtcp\fR|\fBudp\fR:\fIportname\fR|\fIportnumber\fR[\-\fIportname\fR|\fIportnumber\fR]
-TCP or UDP port or port range expressed in port name(s) or port number(s)
+\fBtcp\fR|\fBsctp\fR|\fBudp\fR|\fBudplite\fR:\fIportname\fR|\fIportnumber\fR[\-\fIportname\fR|\fIportnumber\fR]
+TCP, SCTP, UDP or UDPLITE port or port range expressed in port name(s) or port number(s)
.TP
\fBicmp\fR:\fIcodename\fR|\fItype\fR/\fIcode\fR
ICMP codename or type/code. The supported ICMP codename identifiers can always
@@ -508,7 +513,7 @@ ipset add foo 192.168.1.0/24,80\-82
.IP
ipset add foo 192.168.1.1,udp:53
.IP
-ipset add foo 192.168.1.1,ospf:0
+ipset add foo 192.168.1.1,vrrp:0
.IP
ipset test foo 192.168.1.1,80
.SS hash:net,port
@@ -547,8 +552,10 @@ part of the elements see the description at the
\fBhash:ip,port\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, overlapping
-elements are not checked.
+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
diff --git a/src/ipset_hash_ipport.c b/src/ipset_hash_ipport.c
index 94bda07..3179805 100644
--- a/src/ipset_hash_ipport.c
+++ b/src/ipset_hash_ipport.c
@@ -82,13 +82,13 @@ static const char hash_ipport_usage[] =
" IP is a valid IPv4 or IPv6 address (or hostname).\n"
" Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n"
" is supported for IPv4.\n"
-" Adding/deleting multiple elements with TCP/UDP port range\n"
-" is supported both for IPv4 and IPv6.\n";
+" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
+" port range is supported both for IPv4 and IPv6.\n";
struct ipset_type ipset_hash_ipport0 = {
.name = "hash:ip,port",
.alias = { "ipporthash", NULL },
- .revision = 0,
+ .revision = 1,
.family = AF_INET46,
.dimension = IPSET_DIM_TWO,
.elem = {
diff --git a/src/ipset_hash_ipportip.c b/src/ipset_hash_ipportip.c
index cb90152..944ee81 100644
--- a/src/ipset_hash_ipportip.c
+++ b/src/ipset_hash_ipportip.c
@@ -82,13 +82,13 @@ static const char hash_ipportip_usage[] =
" IP is a valid IPv4 or IPv6 address (or hostname).\n"
" Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n"
" in the first IP component is supported for IPv4.\n"
-" Adding/deleting multiple elements with TCP/UDP port range\n"
-" is supported both for IPv4 and IPv6.\n";
+" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
+" port range is supported both for IPv4 and IPv6.\n";
struct ipset_type ipset_hash_ipportip0 = {
.name = "hash:ip,port,ip",
.alias = { "ipportiphash", NULL },
- .revision = 0,
+ .revision = 1,
.family = AF_INET46,
.dimension = IPSET_DIM_THREE,
.elem = {
diff --git a/src/ipset_hash_ipportnet.c b/src/ipset_hash_ipportnet.c
index ff3a8ec..bd94d12 100644
--- a/src/ipset_hash_ipportnet.c
+++ b/src/ipset_hash_ipportnet.c
@@ -83,13 +83,13 @@ static const char hash_ipportnet_usage[] =
" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n"
" Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n"
" in the first IP component is supported for IPv4.\n"
-" Adding/deleting multiple elements with TCP/UDP port range\n"
-" is supported both for IPv4 and IPv6.\n";
+" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
+" port range is supported both for IPv4 and IPv6.\n";
struct ipset_type ipset_hash_ipportnet0 = {
.name = "hash:ip,port,net",
.alias = { "ipportnethash", NULL },
- .revision = 0,
+ .revision = 1,
.family = AF_INET46,
.dimension = IPSET_DIM_THREE,
.elem = {
diff --git a/src/ipset_hash_netport.c b/src/ipset_hash_netport.c
index 843ef31..8ca77df 100644
--- a/src/ipset_hash_netport.c
+++ b/src/ipset_hash_netport.c
@@ -60,12 +60,13 @@ static const char hash_netport_usage[] =
"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 TCP/UDP port range supported.\n";
+" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
+" port range is supported both for IPv4 and IPv6.\n";
struct ipset_type ipset_hash_netport0 = {
.name = "hash:net,port",
.alias = { "netporthash", NULL },
- .revision = 0,
+ .revision = 1,
.family = AF_INET46,
.dimension = IPSET_DIM_TWO,
.elem = {
diff --git a/tests/hash:ip,port.t b/tests/hash:ip,port.t
index aabd861..020be72 100644
--- a/tests/hash:ip,port.t
+++ b/tests/hash:ip,port.t
@@ -62,6 +62,12 @@
0 ipset add test 2.0.0.1,vrrp:0
# Test element with vrrp
0 ipset test test 2.0.0.1,vrrp:0
+# Add element with sctp
+0 ipset add test 2.0.0.1,sctp:80
+# Test element with sctp
+0 ipset test test 2.0.0.1,sctp:80
+# Delete element with sctp
+0 ipset del test 2.0.0.1,sctp:80
# List set
0 ipset list test > .foo0 && ./sort.sh .foo0
# Check listing