]> granicus.if.org Git - ipset/commitdiff
SCTP, UDPLITE support added
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Fri, 18 Mar 2011 16:24:50 +0000 (17:24 +0100)
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Fri, 18 Mar 2011 16:24:50 +0000 (17:24 +0100)
SCTP and UDPLITE port support added to the hash:*port* types.

15 files changed:
kernel/include/linux/netfilter/ipset/ip_set_getport.h
kernel/net/netfilter/ipset/ip_set_getport.c
kernel/net/netfilter/ipset/ip_set_hash_ipport.c
kernel/net/netfilter/ipset/ip_set_hash_ipportip.c
kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c
kernel/net/netfilter/ipset/ip_set_hash_netport.c
lib/parse.c
lib/print.c
lib/types.c
src/ipset.8
src/ipset_hash_ipport.c
src/ipset_hash_ipportip.c
src/ipset_hash_ipportnet.c
src/ipset_hash_netport.c
tests/hash:ip,port.t

index 5aebd170f899f76b9f3231d3aaf5c1066c73870a..90d09300e9541381cffc5aee6a6d7b03e49e607f 100644 (file)
@@ -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;
index 8d52272126867c5637fe644158338a63f98216b6..757143b2240af36395e71f6561e3809f3394e688 100644 (file)
@@ -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;
 
index b9214145d357ff7b4cfd8731f62f21970d7c8463..14281b6b8074142aab9e300b408fc7f4b9b86ae9 100644 (file)
@@ -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 },
index 4642872df6e131818a9486ad99aa215a0b997fc8..401c8a2531dbf471677ba4cb13923fda61e6d7cd 100644 (file)
@@ -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 },
index 2cb84a54b7adbc9d651ed4f8117ad9119419de08..4743e5402522fb6793c2022ade4bed020b240295 100644 (file)
@@ -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 },
index 8598676f2a053724f523d800410f72857700f305..d2a40362dd3aadb6510ff1603a42e132eeeb5c7a 100644 (file)
@@ -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 },
index cd1ad321a22c6469ff3ae7c603d5ba3fcd368d35..0c152319ddfcaa1524b7f0245640ee4990900e9d 100644 (file)
@@ -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;
index 5284b0ab188c4f60d04453d2d3ece10ea9761e95..66b9c1a3a6443c248e79ad206c99d958a24742f7 100644 (file)
@@ -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,
index 5eb53c4f58755d0bf3fb9f01cf8f169195d8b22f..f0dbbc917bc54dce4e7c6ac94352ab40e674507b 100644 (file)
@@ -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;
index b9ca8a563190fbcc5d96d950d0988902537d0992..cad32968425b40e1d9142ac812cc596398d91124 100644 (file)
@@ -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
index 94bda073aba19da1ce001cf4c22b30db176fccc7..3179805190bc64ae9ff941498fc685ff4c86ea9a 100644 (file)
@@ -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 = { 
index cb90152ee0c2a333946abb21c0913e961696d4f1..944ee81879b30f8d8548a0fd0943a160e53f984e 100644 (file)
@@ -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 = { 
index ff3a8ec9c33b4d6da6e6c90b452eb3f85101b914..bd94d12c7090ed135e1475cdf25cfd895d3b29d0 100644 (file)
@@ -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 = { 
index 843ef310f7add8d36692816423b681fbc25d1c4f..8ca77df443580bf54b5cd9ef10a763e18ef0f98b 100644 (file)
@@ -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 = { 
index aabd861c1b15b3ae91d7b86c0020dc1f704652d0..020be72910243f7e3f79a8b401a27ccbf1c82e74 100644 (file)
 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