]> granicus.if.org Git - ipset/commitdiff
add hash:ip,mark data type to ipset
authorVytas Dauksa <vytas.dauksa@smoothwall.net>
Tue, 17 Dec 2013 14:01:43 +0000 (14:01 +0000)
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Wed, 8 Jan 2014 20:02:54 +0000 (21:02 +0100)
Introduce packet mark support with new ip,mark hash set. This includes
userspace and kernelspace code, hash:ip,mark set tests and man page
updates.

The intended use of ip,mark set is similar to the ip:port type, but for
protocols which don't use a predictable port number. Instead of port
number it matches a firewall mark determined by a layer 7 filtering
program like opendpi.

As well as allowing or blocking traffic it will also be used for
accounting packets and bytes sent for each protocol.

Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
31 files changed:
Make_global.am
include/libipset/data.h
include/libipset/linux_ip_set.h
include/libipset/parse.h
include/libipset/print.h
kernel/include/linux/netfilter/ipset/ip_set.h
kernel/include/uapi/linux/netfilter/ipset/ip_set.h
kernel/net/netfilter/ipset/Kbuild
kernel/net/netfilter/ipset/Kconfig
kernel/net/netfilter/ipset/ip_set_hash_ipmark.c [new file with mode: 0644]
lib/Makefile.am
lib/data.c
lib/debug.c
lib/ipset_hash_ipmark.c [new file with mode: 0644]
lib/libipset.map
lib/parse.c
lib/print.c
lib/session.c
src/ipset.8
tests/hash:ip,mark.t [new file with mode: 0644]
tests/hash:ip,mark.t.list0 [new file with mode: 0644]
tests/hash:ip,mark.t.list1 [new file with mode: 0644]
tests/hash:ip6,mark.t [new file with mode: 0644]
tests/hash:ip6,mark.t.list0 [new file with mode: 0644]
tests/hash:ip6,mark.t.list1 [new file with mode: 0644]
tests/ipmarkhash.t [new file with mode: 0644]
tests/ipmarkhash.t.list0 [new file with mode: 0644]
tests/ipmarkhash.t.list1 [new file with mode: 0644]
tests/resizet.sh
tests/runtest.sh
tests/setlist_resize.sh

index 33645da6e6be7a7fd2b11cd7c598851e1ecdbb50..f931618486a80a5023bb691ed898b3e801fe9aa6 100644 (file)
@@ -69,7 +69,7 @@
 # interface. 
 
 #            curr:rev:age
-LIBVERSION = 5:0:2
+LIBVERSION = 5:0:3
 
 AM_CPPFLAGS = $(kinclude_CFLAGS) $(all_includes) -I$(top_srcdir)/include \
        -I/usr/local/include
index cbf30ccd2325899adb1f21ff59c697893c32cbe1..ce6c4c6978a4620ec0b9b9a3209d4497334b6d98 100644 (file)
@@ -22,6 +22,7 @@ enum ipset_opt {
        IPSET_OPT_IP_FROM = IPSET_OPT_IP,
        IPSET_OPT_IP_TO,
        IPSET_OPT_CIDR,
+       IPSET_OPT_MARK,
        IPSET_OPT_PORT,
        IPSET_OPT_PORT_FROM = IPSET_OPT_PORT,
        IPSET_OPT_PORT_TO,
@@ -97,6 +98,7 @@ enum ipset_opt {
        (IPSET_FLAG(IPSET_OPT_IP)       \
        | IPSET_FLAG(IPSET_OPT_IP_TO)   \
        | IPSET_FLAG(IPSET_OPT_CIDR)    \
+       | IPSET_FLAG(IPSET_OPT_MARK)    \
        | IPSET_FLAG(IPSET_OPT_PORT)    \
        | IPSET_FLAG(IPSET_OPT_PORT_TO) \
        | IPSET_FLAG(IPSET_OPT_TIMEOUT) \
index 847bbfff437137d447aa6be3c9ae27af904d9ee2..c57f81e4edf4ab49ad9ad7e80ee9382ebf1f6794 100644 (file)
@@ -83,6 +83,7 @@ enum {
        IPSET_ATTR_PROTO,       /* 7 */
        IPSET_ATTR_CADT_FLAGS,  /* 8 */
        IPSET_ATTR_CADT_LINENO = IPSET_ATTR_LINENO,     /* 9 */
+       IPSET_ATTR_MARK,        /* 10 */
        /* Reserve empty slots */
        IPSET_ATTR_CADT_MAX = 16,
        /* Create-only specific attributes */
index 5c46a885b786493ed325a4fb46f9ea53774025f3..55981f2eb7de3516c5d35c8bb572bf444482a9fc 100644 (file)
@@ -29,6 +29,8 @@ extern int ipset_parse_ether(struct ipset_session *session,
 extern int ipset_parse_port(struct ipset_session *session,
                            enum ipset_opt opt, const char *str,
                            const char *proto);
+extern int ipset_parse_mark(struct ipset_session *session,
+                           enum ipset_opt opt, const char *str);
 extern int ipset_parse_tcpudp_port(struct ipset_session *session,
                                   enum ipset_opt opt, const char *str,
                                   const char *proto);
index f2a6095a456cadb27ade9e3edf5acf23161d03eb..b8fa709ec9da8c8ff1be961077998bc0ea5196ad 100644 (file)
@@ -37,6 +37,9 @@ extern int ipset_print_name(char *buf, unsigned int len,
 extern int ipset_print_port(char *buf, unsigned int len,
                            const struct ipset_data *data,
                            enum ipset_opt opt, uint8_t env);
+extern int ipset_print_mark(char *buf, unsigned int len,
+                           const struct ipset_data *data,
+                           enum ipset_opt opt, uint8_t env);
 extern int ipset_print_iface(char *buf, unsigned int len,
                             const struct ipset_data *data,
                             enum ipset_opt opt, uint8_t env);
index e06411b763b771b19a32458cfd3dd7fab9585016..01c4d4d80fed49e2fbdb73d2b94fbe32d526d4a1 100644 (file)
@@ -40,11 +40,13 @@ enum ip_set_feature {
        IPSET_TYPE_NAME = (1 << IPSET_TYPE_NAME_FLAG),
        IPSET_TYPE_IFACE_FLAG = 5,
        IPSET_TYPE_IFACE = (1 << IPSET_TYPE_IFACE_FLAG),
-       IPSET_TYPE_NOMATCH_FLAG = 6,
+       IPSET_TYPE_MARK_FLAG = 6,
+       IPSET_TYPE_MARK = (1 << IPSET_TYPE_MARK_FLAG),
+       IPSET_TYPE_NOMATCH_FLAG = 7,
        IPSET_TYPE_NOMATCH = (1 << IPSET_TYPE_NOMATCH_FLAG),
        /* Strictly speaking not a feature, but a flag for dumping:
         * this settype must be dumped last */
-       IPSET_DUMP_LAST_FLAG = 7,
+       IPSET_DUMP_LAST_FLAG = 8,
        IPSET_DUMP_LAST = (1 << IPSET_DUMP_LAST_FLAG),
 };
 
@@ -172,8 +174,6 @@ struct ip_set_type {
        char name[IPSET_MAXNAMELEN];
        /* Protocol version */
        u8 protocol;
-       /* Set features to control swapping */
-       u8 features;
        /* Set type dimension */
        u8 dimension;
        /*
@@ -183,6 +183,8 @@ struct ip_set_type {
        u8 family;
        /* Type revisions */
        u8 revision_min, revision_max;
+       /* Set features to control swapping */
+       u16 features;
 
        /* Create set */
        int (*create)(struct net *net, struct ip_set *set,
index 847bbfff437137d447aa6be3c9ae27af904d9ee2..c57f81e4edf4ab49ad9ad7e80ee9382ebf1f6794 100644 (file)
@@ -83,6 +83,7 @@ enum {
        IPSET_ATTR_PROTO,       /* 7 */
        IPSET_ATTR_CADT_FLAGS,  /* 8 */
        IPSET_ATTR_CADT_LINENO = IPSET_ATTR_LINENO,     /* 9 */
+       IPSET_ATTR_MARK,        /* 10 */
        /* Reserve empty slots */
        IPSET_ATTR_CADT_MAX = 16,
        /* Create-only specific attributes */
index 5564cb5e3cca5bce146f4fb1d87002f8c1084054..6495523f27213b66ab48cbdaf96c3ae56583c803 100644 (file)
@@ -5,7 +5,7 @@ ip_set-y := ip_set_core.o ip_set_getport.o pfxlen.o
 obj-m += ip_set.o
 obj-m += ip_set_bitmap_ip.o ip_set_bitmap_ipmac.o ip_set_bitmap_port.o
 obj-m += ip_set_hash_ip.o ip_set_hash_ipport.o ip_set_hash_ipportip.o
-obj-m += ip_set_hash_ipportnet.o
+obj-m += ip_set_hash_ipportnet.o ip_set_hash_ipmark.o
 obj-m += ip_set_hash_net.o ip_set_hash_netport.o ip_set_hash_netiface.o
 obj-m += ip_set_hash_netnet.o ip_set_hash_netportnet.o
 obj-m += ip_set_list_set.o
index a2d6263b6c648e97c663025660ad47320c2c08ff..638faa767d432ea1134945b6f5ec6aed0655c05e 100644 (file)
@@ -61,6 +61,15 @@ config IP_SET_HASH_IP
 
          To compile it as a module, choose M here.  If unsure, say N.
 
+config IP_SET_HASH_IPMARK
+       tristate "hash:ip,mark set support"
+       depends on IP_SET
+       help
+         This option adds the hash:ip,mark set type support, by which one
+         can store IPv4/IPv6 address and mark pairs.
+
+         To compile it as a module, choose M here.  If unsure, say N.
+
 config IP_SET_HASH_IPPORT
        tristate "hash:ip,port set support"
        depends on IP_SET
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_ipmark.c b/kernel/net/netfilter/ipset/ip_set_hash_ipmark.c
new file mode 100644 (file)
index 0000000..e56c0d9
--- /dev/null
@@ -0,0 +1,312 @@
+/* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
+ * Copyright (C) 2013 Smoothwall Ltd. <vytas.dauksa@smoothwall.net>
+ *
+ * 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.
+ */
+
+/* Kernel module implementing an IP set type: the hash:ip,mark type */
+
+#include <linux/jhash.h>
+#include <linux/module.h>
+#include <linux/ip.h>
+#include <linux/skbuff.h>
+#include <linux/errno.h>
+#include <linux/random.h>
+#include <net/ip.h>
+#include <net/ipv6.h>
+#include <net/netlink.h>
+#include <net/tcp.h>
+
+#include <linux/netfilter.h>
+#include <linux/netfilter/ipset/pfxlen.h>
+#include <linux/netfilter/ipset/ip_set.h>
+#include <linux/netfilter/ipset/ip_set_hash.h>
+
+#define IPSET_TYPE_REV_MIN     0
+#define IPSET_TYPE_REV_MAX     0
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Vytas Dauksa <vytas.dauksa@smoothwall.net>");
+IP_SET_MODULE_DESC("hash:ip,mark", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
+MODULE_ALIAS("ip_set_hash:ip,mark");
+
+/* Type specific function prefix */
+#define HTYPE          hash_ipmark
+
+/* IPv4 variant */
+
+/* Member elements */
+struct hash_ipmark4_elem {
+       __be32 ip;
+       __u32 mark;
+};
+
+/* Common functions */
+
+static inline bool
+hash_ipmark4_data_equal(const struct hash_ipmark4_elem *ip1,
+                       const struct hash_ipmark4_elem *ip2,
+                       u32 *multi)
+{
+       return ip1->ip == ip2->ip &&
+              ip1->mark == ip2->mark;
+}
+
+static bool
+hash_ipmark4_data_list(struct sk_buff *skb,
+                      const struct hash_ipmark4_elem *data)
+{
+       if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, data->ip) ||
+           nla_put_net32(skb, IPSET_ATTR_MARK, htonl(data->mark)))
+               goto nla_put_failure;
+       return 0;
+
+nla_put_failure:
+       return 1;
+}
+
+static inline void
+hash_ipmark4_data_next(struct hash_ipmark4_elem *next,
+                      const struct hash_ipmark4_elem *d)
+{
+       next->ip = d->ip;
+}
+
+#define MTYPE           hash_ipmark4
+#define PF              4
+#define HOST_MASK       32
+#define HKEY_DATALEN   sizeof(struct hash_ipmark4_elem)
+#include "ip_set_hash_gen.h"
+
+static int
+hash_ipmark4_kadt(struct ip_set *set, const struct sk_buff *skb,
+                 const struct xt_action_param *par,
+                 enum ipset_adt adt, struct ip_set_adt_opt *opt)
+{
+       ipset_adtfn adtfn = set->variant->adt[adt];
+       struct hash_ipmark4_elem e = { };
+       struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
+
+       e.mark = skb->mark;
+
+       ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip);
+       return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
+}
+
+static int
+hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],
+                 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+{
+       const struct hash_ipmark *h = set->data;
+       ipset_adtfn adtfn = set->variant->adt[adt];
+       struct hash_ipmark4_elem e = { };
+       struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+       u32 ip, ip_to = 0;
+       int ret;
+
+       if (unlikely(!tb[IPSET_ATTR_IP] ||
+                    !ip_set_attr_netorder(tb, IPSET_ATTR_MARK) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
+               return -IPSET_ERR_PROTOCOL;
+
+       if (tb[IPSET_ATTR_LINENO])
+               *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
+
+       ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP], &e.ip) ||
+             ip_set_get_extensions(set, tb, &ext);
+       if (ret)
+               return ret;
+
+       e.mark = ntohl(nla_get_u32(tb[IPSET_ATTR_MARK]));
+
+       if (adt == IPSET_TEST ||
+           !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR])) {
+               ret = adtfn(set, &e, &ext, &ext, flags);
+               return ip_set_eexist(ret, flags) ? 0 : ret;
+       }
+
+       ip_to = ip = ntohl(e.ip);
+       if (tb[IPSET_ATTR_IP_TO]) {
+               ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
+               if (ret)
+                       return ret;
+               if (ip > ip_to)
+                       swap(ip, ip_to);
+       } else if (tb[IPSET_ATTR_CIDR]) {
+               u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
+
+               if (!cidr || cidr > 32)
+                       return -IPSET_ERR_INVALID_CIDR;
+               ip_set_mask_from_to(ip, ip_to, cidr);
+       }
+
+       if (retried)
+               ip = ntohl(h->next.ip);
+       for (; !before(ip_to, ip); ip++) {
+               e.ip = htonl(ip);
+               ret = adtfn(set, &e, &ext, &ext, flags);
+
+               if (ret && !ip_set_eexist(ret, flags))
+                       return ret;
+               else
+                       ret = 0;
+       }
+       return ret;
+}
+
+/* IPv6 variant */
+
+struct hash_ipmark6_elem {
+       union nf_inet_addr ip;
+       __u32 mark;
+};
+
+/* Common functions */
+
+static inline bool
+hash_ipmark6_data_equal(const struct hash_ipmark6_elem *ip1,
+                       const struct hash_ipmark6_elem *ip2,
+                       u32 *multi)
+{
+       return ipv6_addr_equal(&ip1->ip.in6, &ip2->ip.in6) &&
+              ip1->mark == ip2->mark;
+}
+
+static bool
+hash_ipmark6_data_list(struct sk_buff *skb,
+                      const struct hash_ipmark6_elem *data)
+{
+       if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &data->ip.in6) ||
+           nla_put_net32(skb, IPSET_ATTR_MARK, htonl(data->mark)))
+               goto nla_put_failure;
+       return 0;
+
+nla_put_failure:
+       return 1;
+}
+
+static inline void
+hash_ipmark6_data_next(struct hash_ipmark4_elem *next,
+                      const struct hash_ipmark6_elem *d)
+{
+}
+
+#undef MTYPE
+#undef PF
+#undef HOST_MASK
+#undef HKEY_DATALEN
+
+#define MTYPE          hash_ipmark6
+#define PF             6
+#define HOST_MASK      128
+#define HKEY_DATALEN   sizeof(struct hash_ipmark6_elem)
+#define        IP_SET_EMIT_CREATE
+#include "ip_set_hash_gen.h"
+
+
+static int
+hash_ipmark6_kadt(struct ip_set *set, const struct sk_buff *skb,
+                 const struct xt_action_param *par,
+                 enum ipset_adt adt, struct ip_set_adt_opt *opt)
+{
+       ipset_adtfn adtfn = set->variant->adt[adt];
+       struct hash_ipmark6_elem e = { };
+       struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
+
+       e.mark = skb->mark;
+
+       ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip.in6);
+       return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
+}
+
+static int
+hash_ipmark6_uadt(struct ip_set *set, struct nlattr *tb[],
+                 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+{
+       ipset_adtfn adtfn = set->variant->adt[adt];
+       struct hash_ipmark6_elem e = { };
+       struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+       int ret;
+
+       if (unlikely(!tb[IPSET_ATTR_IP] ||
+                    !ip_set_attr_netorder(tb, IPSET_ATTR_MARK) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES) ||
+                    tb[IPSET_ATTR_IP_TO] ||
+                    tb[IPSET_ATTR_CIDR]))
+               return -IPSET_ERR_PROTOCOL;
+
+       if (tb[IPSET_ATTR_LINENO])
+               *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
+
+       ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &e.ip) ||
+             ip_set_get_extensions(set, tb, &ext);
+       if (ret)
+               return ret;
+
+       e.mark = ntohl(nla_get_u32(tb[IPSET_ATTR_MARK]));
+
+       if (adt == IPSET_TEST) {
+               ret = adtfn(set, &e, &ext, &ext, flags);
+               return ip_set_eexist(ret, flags) ? 0 : ret;
+       }
+
+       ret = adtfn(set, &e, &ext, &ext, flags);
+       if (ret && !ip_set_eexist(ret, flags))
+               return ret;
+       else
+               ret = 0;
+
+       return ret;
+}
+
+static struct ip_set_type hash_ipmark_type __read_mostly = {
+       .name           = "hash:ip,mark",
+       .protocol       = IPSET_PROTOCOL,
+       .features       = IPSET_TYPE_IP | IPSET_TYPE_MARK,
+       .dimension      = IPSET_DIM_TWO,
+       .family         = NFPROTO_UNSPEC,
+       .revision_min   = IPSET_TYPE_REV_MIN,
+       .revision_max   = IPSET_TYPE_REV_MAX,
+       .create         = hash_ipmark_create,
+       .create_policy  = {
+               [IPSET_ATTR_HASHSIZE]   = { .type = NLA_U32 },
+               [IPSET_ATTR_MAXELEM]    = { .type = NLA_U32 },
+               [IPSET_ATTR_PROBES]     = { .type = NLA_U8 },
+               [IPSET_ATTR_RESIZE]     = { .type = NLA_U8  },
+               [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
+               [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
+       },
+       .adt_policy     = {
+               [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
+               [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
+               [IPSET_ATTR_MARK]       = { .type = NLA_U32 },
+               [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
+               [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
+               [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
+               [IPSET_ATTR_BYTES]      = { .type = NLA_U64 },
+               [IPSET_ATTR_PACKETS]    = { .type = NLA_U64 },
+               [IPSET_ATTR_COMMENT]    = { .type = NLA_NUL_STRING },
+       },
+       .me             = THIS_MODULE,
+};
+
+static int __init
+hash_ipmark_init(void)
+{
+       return ip_set_type_register(&hash_ipmark_type);
+}
+
+static void __exit
+hash_ipmark_fini(void)
+{
+       ip_set_type_unregister(&hash_ipmark_type);
+}
+
+module_init(hash_ipmark_init);
+module_exit(hash_ipmark_fini);
index 22346703dee4959f4e5108df3d0b2876be032efa..6398be4b1eb5b0eac882725d9a9ad5a2ef4c9572 100644 (file)
@@ -6,6 +6,7 @@ IPSET_SETTYPE_LIST = \
        ipset_bitmap_port.c \
        ipset_hash_ip.c \
        ipset_hash_ipport.c \
+       ipset_hash_ipmark.c \
        ipset_hash_ipportip.c \
        ipset_hash_ipportnet.c \
        ipset_hash_net.c \
index ba4ed57ca735e313c2bdbd06a954e5075994a5dc..1f74cd5ff97930fa918cd83cbc1171cb97c31617 100644 (file)
@@ -41,6 +41,7 @@ struct ipset_data {
        uint32_t timeout;
        union nf_inet_addr ip;
        union nf_inet_addr ip_to;
+       uint32_t mark;
        uint16_t port;
        uint16_t port_to;
        union {
@@ -264,6 +265,9 @@ ipset_data_set(struct ipset_data *data, enum ipset_opt opt, const void *value)
        case IPSET_OPT_CIDR:
                data->cidr = *(const uint8_t *) value;
                break;
+       case IPSET_OPT_MARK:
+               data->mark = *(const uint32_t *) value;
+               break;
        case IPSET_OPT_PORT:
                data->port = *(const uint16_t *) value;
                break;
@@ -448,6 +452,8 @@ ipset_data_get(const struct ipset_data *data, enum ipset_opt opt)
                 return &data->ip_to;
        case IPSET_OPT_CIDR:
                return &data->cidr;
+       case IPSET_OPT_MARK:
+               return &data->mark;
        case IPSET_OPT_PORT:
                return &data->port;
        case IPSET_OPT_PORT_TO:
@@ -542,6 +548,8 @@ ipset_data_sizeof(enum ipset_opt opt, uint8_t family)
        case IPSET_OPT_IP2_TO:
                return family == NFPROTO_IPV4 ? sizeof(uint32_t)
                                         : sizeof(struct in6_addr);
+       case IPSET_OPT_MARK:
+               return sizeof(uint32_t);
        case IPSET_OPT_PORT:
        case IPSET_OPT_PORT_TO:
                return sizeof(uint16_t);
index a204940c0155bbabb035f6f6de72aa3eb5b342bd..9a3c6b8a00db7acb7e7dc1f4e27c458948aadec6 100644 (file)
@@ -51,6 +51,7 @@ static const struct ipset_attrname adtattr2name[] = {
        [IPSET_ATTR_IP]         = { .name = "IP" },
        [IPSET_ATTR_IP_TO]      = { .name = "IP_TO" },
        [IPSET_ATTR_CIDR]       = { .name = "CIDR" },
+       [IPSET_ATTR_MARK]       = { .name = "MARK" },
        [IPSET_ATTR_PORT]       = { .name = "PORT" },
        [IPSET_ATTR_PORT_TO]    = { .name = "PORT_TO" },
        [IPSET_ATTR_TIMEOUT]    = { .name = "TIMEOUT" },
diff --git a/lib/ipset_hash_ipmark.c b/lib/ipset_hash_ipmark.c
new file mode 100644 (file)
index 0000000..6976371
--- /dev/null
@@ -0,0 +1,168 @@
+/* Copyright 2007-2013 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu)
+ * Copyright 2013 Smoothwall Ltd. (vytas.dauksa@smoothwall.net)
+ *
+ * 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/types.h>                    /* prototypes */
+
+/* Parse commandline arguments */
+static const struct ipset_arg hash_ipmark_create_args0[] = {
+       { .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_timeout,         .print = ipset_print_number,
+       },
+       { .name = { "counters", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_COUNTERS,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       { .name = { "comment", NULL },
+         .has_arg = IPSET_NO_ARG,              .opt = IPSET_OPT_CREATE_COMMENT,
+         .parse = ipset_parse_flag,            .print = ipset_print_flag,
+       },
+       /* Backward compatibility */
+       { .name = { "probes", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_PROBES,
+         .parse = ipset_parse_ignored,         .print = ipset_print_number,
+       },
+       { .name = { "resize", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_RESIZE,
+         .parse = ipset_parse_ignored,         .print = ipset_print_number,
+       },
+       { .name = { "from", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_IP,
+         .parse = ipset_parse_ignored,
+       },
+       { .name = { "to", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_IP_TO,
+         .parse = ipset_parse_ignored,
+       },
+       { .name = { "network", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_IP,
+         .parse = ipset_parse_ignored,
+       },
+       { },
+};
+
+static const struct ipset_arg hash_ipmark_add_args0[] = {
+       { .name = { "timeout", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_TIMEOUT,
+         .parse = ipset_parse_timeout,         .print = ipset_print_number,
+       },
+       { .name = { "packets", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_PACKETS,
+         .parse = ipset_parse_uint64,          .print = ipset_print_number,
+       },
+       { .name = { "bytes", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_BYTES,
+         .parse = ipset_parse_uint64,          .print = ipset_print_number,
+       },
+       { .name = { "comment", NULL },
+         .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_ADT_COMMENT,
+         .parse = ipset_parse_comment,         .print = ipset_print_comment,
+       },
+       { },
+};
+
+static const char hash_ipmark_usage0[] =
+"create SETNAME hash:ip,mark\n"
+"              [family inet|inet6]\n"
+"               [hashsize VALUE] [maxelem VALUE]\n"
+"               [timeout VALUE] [counters] [comment]\n"
+"add    SETNAME IP,MARK [timeout VALUE]\n"
+"               [packets VALUE] [bytes VALUE] [comment \"string\"]\n"
+"del    SETNAME IP,MARK\n"
+"test   SETNAME IP,MARK\n\n"
+"where depending on the INET family\n"
+"      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 single mark element\n"
+"      is supported both for IPv4 and IPv6.\n";
+
+static struct ipset_type ipset_hash_ipmark0 = {
+       .name = "hash:ip,mark",
+       .alias = { "ipmarkhash", NULL },
+       .revision = 0,
+       .family = NFPROTO_IPSET_IPV46,
+       .dimension = IPSET_DIM_TWO,
+       .elem = {
+               [IPSET_DIM_ONE - 1] = {
+                       .parse = ipset_parse_ip4_single6,
+                       .print = ipset_print_ip,
+                       .opt = IPSET_OPT_IP
+               },
+               [IPSET_DIM_TWO - 1] = {
+                       .parse = ipset_parse_mark,
+                       .print = ipset_print_mark,
+                       .opt = IPSET_OPT_MARK
+               },
+       },
+       .args = {
+               [IPSET_CREATE] = hash_ipmark_create_args0,
+               [IPSET_ADD] = hash_ipmark_add_args0,
+       },
+       .mandatory = {
+               [IPSET_CREATE] = 0,
+               [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_MARK),
+               [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_MARK),
+               [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_MARK),
+       },
+       .full = {
+               [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE)
+                       | IPSET_FLAG(IPSET_OPT_MAXELEM)
+                       | IPSET_FLAG(IPSET_OPT_TIMEOUT)
+                       | IPSET_FLAG(IPSET_OPT_COUNTERS)
+                       | IPSET_FLAG(IPSET_OPT_CREATE_COMMENT),
+               [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_IP_TO)
+                       | IPSET_FLAG(IPSET_OPT_MARK)
+                       | IPSET_FLAG(IPSET_OPT_TIMEOUT)
+                       | IPSET_FLAG(IPSET_OPT_PACKETS)
+                       | IPSET_FLAG(IPSET_OPT_BYTES)
+                       | IPSET_FLAG(IPSET_OPT_ADT_COMMENT),
+               [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_IP_TO)
+                       | IPSET_FLAG(IPSET_OPT_MARK),
+               [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
+                       | IPSET_FLAG(IPSET_OPT_MARK),
+       },
+
+       .usage = hash_ipmark_usage0,
+       .description = "initial revision",
+};
+
+void _init(void);
+void _init(void)
+{
+       ipset_type_add(&ipset_hash_ipmark0);
+}
index 1080f0d9212fe60d7740eae09688b63f5bee36b0..a035115f33d85854b478c62a292a6f7fb8dfcedf 100644 (file)
@@ -138,3 +138,9 @@ global:
   ipset_print_comment;
   ipset_strlcat;
 } LIBIPSET_4.0;
+
+LIBIPSET_4.2 {
+global:
+  ipset_parse_mark;
+  ipset_print_mark;
+} LIBIPSET_4.1;
index 440ef8f939e7121b1c977f43a8a8cb8a5e8b0b14..f1c1f0e0d9693a3f22c402f23434c3487c9abf6e 100644 (file)
@@ -327,6 +327,36 @@ ipset_parse_port(struct ipset_session *session,
        return err;
 }
 
+/**
+ * ipset_parse_mark - parse a mark
+ * @session: session structure
+ * @opt: option kind of the data
+ * @str: string to parse
+ *
+ * Parse string as a mark. The parsed mark number is
+ * stored in the data blob of the session.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int
+ipset_parse_mark(struct ipset_session *session,
+                enum ipset_opt opt, const char *str)
+{
+       uint32_t mark;
+       int err;
+
+       assert(session);
+       assert(str);
+
+       if ((err = string_to_u32(session, str, &mark)) == 0)
+               err = ipset_session_data_set(session, opt, &mark);
+
+       if (!err)
+               /* No error, so reset false error messages! */
+               ipset_session_report_reset(session);
+       return err;
+}
+
 /**
  * ipset_parse_tcpudp_port - parse TCP/UDP port name, number, or range of them
  * @session: session structure
index 6988fdfc3b9cce39b2f58458154213cc6f123228..3c43443386bc597be2fd66d04ff6542e60d4a761 100644 (file)
@@ -490,6 +490,41 @@ ipset_print_port(char *buf, unsigned int len,
        return offset;
 }
 
+/**
+ * ipset_print_mark - print mark to string
+ * @buf: printing buffer
+ * @len: length of available buffer space
+ * @data: data blob
+ * @opt: the option kind
+ * @env: environment flags
+ *
+ * Print mark to output buffer.
+ *
+ * Return lenght of printed string or error size.
+ */
+int
+ipset_print_mark(char *buf, unsigned int len,
+                  const struct ipset_data *data,
+                  enum ipset_opt opt ASSERT_UNUSED,
+                  uint8_t env UNUSED)
+{
+       const uint32_t *mark;
+       int size, offset = 0;
+
+       assert(buf);
+       assert(len > 0);
+       assert(data);
+       assert(opt == IPSET_OPT_MARK);
+
+       mark = ipset_data_get(data, IPSET_OPT_MARK);
+       assert(mark);
+
+       size = snprintf(buf, len, "%u", *mark);
+       SNPRINTF_FAILURE(size, len, offset);
+
+       return offset;
+}
+
 /**
  * ipset_print_iface - print interface element string
  * @buf: printing buffer
index 6f89281711c34dc40b86e1291f5d0ec724e40d9e..cf65960a39c610557c9433c6b699bf4a882f9bfa 100644 (file)
@@ -424,6 +424,10 @@ static const struct ipset_attr_policy adt_attrs[] = {
                .type = MNL_TYPE_U8,
                .opt = IPSET_OPT_CIDR,
        },
+       [IPSET_ATTR_MARK] = {
+               .type = MNL_TYPE_U32,
+               .opt = IPSET_OPT_MARK,
+       },
        [IPSET_ATTR_PORT] = {
                .type = MNL_TYPE_U16,
                .opt = IPSET_OPT_PORT,
index b5c145c292e1c8c9a6dcf9f96d1331c4cbb7ceff..e2b39fd904ceb79e9a99e21d0bd28d85b6c1a4fa 100644 (file)
@@ -878,6 +878,55 @@ 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:ip,mark
+The \fBhash:ip,mark\fR set type uses a hash to store IP address and packet mark pairs.
+.PP
+\fICREATE\-OPTIONS\fR := [ \fBfamily\fR { \fBinet\fR | \fBinet6\fR } ] | [ \fBhashsize\fR \fIvalue\fR ] [ \fBmaxelem\fR \fIvalue\fR ] [ \fBtimeout\fR \fIvalue\fR ] [ \fBcounters\fP ] [ \fBcomment\fP ]
+.PP
+\fIADD\-ENTRY\fR := \fIipaddr\fR,\fImark\fR
+.PP
+\fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ] [ \fBpackets\fR \fIvalue\fR ] [ \fBbytes\fR \fIvalue\fR ] [ \fBcomment\fR \fIstring\fR ]
+.PP
+\fIDEL\-ENTRY\fR := \fIipaddr\fR,\fImark\fR
+.PP
+\fITEST\-ENTRY\fR := \fIipaddr\fR,\fImark\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 \fBinet\fR family one can add or delete multiple entries by specifying
+a range or a network of IPv4 addresses in the IP address part of the entry:
+.PP
+\fIipaddr\fR := { \fIip\fR | \fIfromaddr\fR\-\fItoaddr\fR | \fIip\fR/\fIcidr\fR }
+.PP
+The
+\fImark\fR
+can be any value between 0 and 4294967295.
+.PP
+The \fBhash:ip,mark\fR type of sets require
+two \fBsrc\fR/\fBdst\fR parameters of the \fBset\fR match and \fBSET\fR
+target kernel modules.
+.PP
+Examples:
+.IP
+ipset create foo hash:ip,mark
+.IP
+ipset add foo 192.168.1.0/24,555
+.IP
+ipset add foo 192.168.1.1,0x63
+.IP
+ipset add foo 192.168.1.1,111236
 .SS hash:net,port,net
 The \fBhash:net,port,net\fR set type behaves similarly to hash:ip,port,net but accepts a
 cidr value for both the first and last parameter. Either subnet is permitted to be a /0
diff --git a/tests/hash:ip,mark.t b/tests/hash:ip,mark.t
new file mode 100644 (file)
index 0000000..bd5c237
--- /dev/null
@@ -0,0 +1,125 @@
+# Create a set with timeout
+0 ipset create test hash:ip,mark timeout 5
+# Add partly zero valued element
+0 ipset add test 2.0.0.1,0
+# Test partly zero valued element
+0 ipset test test 2.0.0.1,0
+# Delete partly zero valued element
+0 ipset del test 2.0.0.1,0
+# Add first random value
+0 ipset add test 2.0.0.1,5
+# Add second random value
+0 ipset add test 2.1.0.0,128
+# Test first random value
+0 ipset test test 2.0.0.1,5
+# Test second random value
+0 ipset test test 2.1.0.0,128
+# Test value not added to the set
+1 ipset test test 2.0.0.1,4
+# Delete value not added to the set
+1 ipset del test 2.0.0.1,6
+# Test value before first random value
+1 ipset test test 2.0.0.0,5
+# Test value after second random value
+1 ipset test test 2.1.0.1,128
+# Try to add value before first random value
+0 ipset add test 2.0.0.0,5
+# Try to add value after second random value
+0 ipset add test 2.1.0.1,128
+# List set
+0 ipset list test | grep -v Revision: | sed 's/timeout ./timeout x/' > .foo0 && ./sort.sh .foo0
+# Check listing
+0 diff -u -I 'Size in memory.*' .foo hash:ip,mark.t.list0
+# Sleep 5s so that elements can time out
+0 sleep 5
+# List set
+0 ipset list test | grep -v Revision: > .foo0 && ./sort.sh .foo0
+# Check listing
+0 diff -u -I 'Size in memory.*' .foo hash:ip,mark.t.list1
+# Flush test set
+0 ipset flush test
+# Add multiple elements in one step
+0 ipset add test 1.1.1.1-1.1.1.18,80
+# Delete multiple elements in one step
+0 ipset del test 1.1.1.2-1.1.1.3,80
+# Check number of elements after multi-add/multi-del
+0 n=`ipset save test|wc -l` && test $n -eq 17
+# Delete test set
+0 ipset destroy test
+# Create set to add a range
+0 ipset new test hash:ip,mark hashsize 64
+# Add a range which forces a resizing
+0 ipset add test 10.0.0.0-10.0.3.255,80
+# Check that correct number of elements are added
+0 n=`ipset list test|grep '^10.0'|wc -l` && test $n -eq 1024
+# Flush set
+0 ipset flush test
+# Add an single element
+0 ipset add test 10.0.0.1,80
+# Check number of elements
+0 n=`ipset save test|wc -l` && test $n -eq 2
+# Delete the single element
+0 ipset del test 10.0.0.1,80
+# Check number of elements
+0 n=`ipset save test|wc -l` && test $n -eq 1
+# Add an IP range
+0 ipset add test 10.0.0.1-10.0.0.10,80
+# Check number of elements
+0 n=`ipset save test|wc -l` && test $n -eq 11
+# Delete the IP range
+0 ipset del test 10.0.0.1-10.0.0.10,80
+# Check number of elements
+0 n=`ipset save test|wc -l` && test $n -eq 1
+# Destroy set
+0 ipset -X test
+# Timeout: Check that resizing keeps timeout values
+0 ./resizet.sh -4 ipmark
+# Counters: create set
+0 ipset n test hash:ip,mark counters
+# Counters: add element with packet, byte counters
+0 ipset a test 2.0.0.1,80 packets 5 bytes 3456
+# Counters: check element
+0 ipset t test 2.0.0.1,80
+# Counters: check counters
+0 ./check_counters test 2.0.0.1 5 3456
+# Counters: delete element
+0 ipset d test 2.0.0.1,80
+# Counters: test deleted element
+1 ipset t test 2.0.0.1,80
+# Counters: add element with packet, byte counters
+0 ipset a test 2.0.0.20,453 packets 12 bytes 9876
+# Counters: check counters
+0 ./check_counters test 2.0.0.20 12 9876
+# Counters: update counters
+0 ipset -! a test 2.0.0.20,453 packets 13 bytes 12479
+# Counters: check counters
+0 ./check_counters test 2.0.0.20 13 12479
+# Counters: destroy set
+0 ipset x test
+# Counters and timeout: create set
+0 ipset n test hash:ip,mark counters timeout 600
+# Counters and timeout: add element with packet, byte counters
+0 ipset a test 2.0.0.1,80 packets 5 bytes 3456
+# Counters and timeout: check element
+0 ipset t test 2.0.0.1,80
+# Counters and timeout: check counters
+0 ./check_extensions test 2.0.0.1 600 5 3456
+# Counters and timeout: delete element
+0 ipset d test 2.0.0.1,80
+# Counters and timeout: test deleted element
+1 ipset t test 2.0.0.1,80
+# Counters and timeout: add element with packet, byte counters
+0 ipset a test 2.0.0.20,453 packets 12 bytes 9876
+# Counters and timeout: check counters
+0 ./check_extensions test 2.0.0.20 600 12 9876
+# Counters and timeout: update counters
+0 ipset -! a test 2.0.0.20,453 packets 13 bytes 12479
+# Counters and timeout: check counters
+0 ./check_extensions test 2.0.0.20 600 13 12479
+# Counters and timeout: update timeout
+0 ipset -! a test 2.0.0.20,453 timeout 700
+# Counters and timeout: check counters
+0 ./check_extensions test 2.0.0.20 700 13 12479
+# Counters and timeout: destroy set
+0 ipset x test
+# eof
diff --git a/tests/hash:ip,mark.t.list0 b/tests/hash:ip,mark.t.list0
new file mode 100644 (file)
index 0000000..378dabe
--- /dev/null
@@ -0,0 +1,10 @@
+Name: test
+Type: hash:ip,mark
+Header: family inet hashsize 1024 maxelem 65536 timeout x
+Size in memory: 8836
+References: 0
+Members:
+2.0.0.0,5 timeout x
+2.0.0.1,5 timeout x
+2.1.0.0,128 timeout x
+2.1.0.1,128 timeout x
diff --git a/tests/hash:ip,mark.t.list1 b/tests/hash:ip,mark.t.list1
new file mode 100644 (file)
index 0000000..af8a38b
--- /dev/null
@@ -0,0 +1,6 @@
+Name: test
+Type: hash:ip,mark
+Header: family inet hashsize 1024 maxelem 65536 timeout 5
+Size in memory: 8836
+References: 0
+Members:
diff --git a/tests/hash:ip6,mark.t b/tests/hash:ip6,mark.t
new file mode 100644 (file)
index 0000000..bc7757b
--- /dev/null
@@ -0,0 +1,227 @@
+# Create a set with timeout
+0 ipset create test hash:ip,mark family inet6 timeout 5
+# Add partly zero valued element
+0 ipset add test 2:0:0::1,0
+# Test partly zero valued element
+0 ipset test test 2:0:0::1,0
+# Delete partly zero valued element
+0 ipset del test 2:0:0::1,0
+# Add first random value
+0 ipset add test 2:0:0::1,5
+# Add second random value
+0 ipset add test 2:1:0::0,128
+# Test first random value
+0 ipset test test 2:0:0::1,5
+# Test second random value
+0 ipset test test 2:1:0::0,128
+# Test value not added to the set
+1 ipset test test 2:0:0::1,4
+# Delete value not added to the set
+1 ipset del test 2:0:0::1,6
+# Test value before first random value
+1 ipset test test 2:0:0::0,5
+# Test value after second random value
+1 ipset test test 2:1:0::1,128
+# Try to add value before first random value
+0 ipset add test 2:0:0::0,5
+# Try to add value after second random value
+0 ipset add test 2:1:0::1,128
+# List set
+0 ipset list test | grep -v Revision: | sed 's/timeout ./timeout x/' > .foo0 && ./sort.sh .foo0
+# Check listing
+0 diff -u -I 'Size in memory.*' .foo hash:ip6,mark.t.list0
+# Sleep 5s so that elements can time out
+0 sleep 5
+# List set
+0 ipset list test | grep -v Revision: > .foo0 && ./sort.sh .foo0
+# Check listing
+0 diff -u -I 'Size in memory.*' .foo hash:ip6,mark.t.list1
+# Delete test set
+0 ipset destroy test
+# Create set to add a range
+0 ipset new test hash:ip,mark -6 hashsize 64
+# Add a random value 1
+0 ipset add test 1::1,800000
+# Add a random value 2
+0 ipset add test 1::1,8900000
+# Add a random value 3
+0 ipset add test 1::3,8900000
+# Add a random value 4
+0 ipset add test 1::4,8900000
+# Add a random value 5
+0 ipset add test 1::5,8900000
+# Add a random value 6
+0 ipset add test 1::6,8900000
+# Add a random value 7
+0 ipset add test 1::7,8900000
+# Add a random value 8
+0 ipset add test 1::8,8900000
+# Add a random value 9
+0 ipset add test 1::9,8900000
+# Add a random value 10
+0 ipset add test 1::101,8900000
+# Add a random value 11
+0 ipset add test 1::11,8900000
+# Add a random value 12
+0 ipset add test 1::12,8900000
+# Add a random value 13
+0 ipset add test 1::13,8900000
+# Add a random value 14
+0 ipset add test 1::14,8900000
+# Add a random value 15
+0 ipset add test 1::15,8900000
+# Add a random value 16
+0 ipset add test 1::16,8900000
+# Add a random value 17
+0 ipset add test 1::17,8900000
+# Add a random value 18
+0 ipset add test 1::18,8900000
+# Add a random value 19
+0 ipset add test 1::19,8900000
+# Add a random value 20
+0 ipset add test 1::20,8900000
+# Add a random value 21
+0 ipset add test 1::21,8900000
+# Add a random value 22
+0 ipset add test 1::22,8900000
+# Add a random value 23
+0 ipset add test 1::23,8900000
+# Add a random value 24
+0 ipset add test 1::24,8900000
+# Add a random value 25
+0 ipset add test 1::25,8900000
+# Add a random value 26
+0 ipset add test 1::26,8900000
+# Add a random value 27
+0 ipset add test 1::27,8900000
+# Add a random value 28
+0 ipset add test 1::28,8900000
+# Add a random value 29
+0 ipset add test 1::29,8900000
+# Add a random value 30
+0 ipset add test 1::301,8900000
+# Add a random value 31
+0 ipset add test 1::31,8900000
+# Add a random value 32
+0 ipset add test 1::32,8900000
+# Add a random value 33
+0 ipset add test 1::33,8900000
+# Add a random value 34
+0 ipset add test 1::34,8900000
+# Add a random value 35
+0 ipset add test 1::35,8900000
+# Add a random value 36
+0 ipset add test 1::36,8900000
+# Add a random value 37
+0 ipset add test 1::37,8900000
+# Add a random value 38
+0 ipset add test 1::38,8900000
+# Add a random value 39
+0 ipset add test 1::39,8900000
+# Add a random value 40
+0 ipset add test 1::401,8900000
+# Add a random value 41
+0 ipset add test 1::41,8900000
+# Add a random value 42
+0 ipset add test 1::42,8900000
+# Add a random value 43
+0 ipset add test 1::43,8900000
+# Add a random value 44
+0 ipset add test 1::44,8900000
+# Add a random value 45
+0 ipset add test 1::45,8900000
+# Add a random value 46
+0 ipset add test 1::46,8900000
+# Add a random value 47
+0 ipset add test 1::47,8900000
+# Add a random value 48
+0 ipset add test 1::48,8900000
+# Add a random value 49
+0 ipset add test 1::49,8900000
+# Add a random value 50
+0 ipset add test 1::501,8900000
+# Add a random value 51
+0 ipset add test 1::51,8900000
+# Add a random value 52
+0 ipset add test 1::52,8900000
+# Add a random value 53
+0 ipset add test 1::53,8900000
+# Add a random value 54
+0 ipset add test 1::54,8900000
+# Add a random value 55
+0 ipset add test 1::55,8900000
+# Add a random value 56
+0 ipset add test 1::56,8900000
+# Add a random value 57
+0 ipset add test 1::57,8900000
+# Add a random value 58
+0 ipset add test 1::58,8900000
+# Add a random value 59
+0 ipset add test 1::59,8900000
+# Add a random value 60
+0 ipset add test 1::601,8900000
+# Add a random value 61
+0 ipset add test 1::61,8900000
+# Add a random value 62
+0 ipset add test 1::62,8900000
+# Add a random value 63
+0 ipset add test 1::63,8900000
+# Add a random value 64
+0 ipset add test 1::64,8900000
+# Add a random value 65, that forces a resizing
+0 ipset add test 1::65,8900000
+# Check that correct number of elements are added
+0 n=`ipset list test|grep 1::|wc -l` && test $n -eq 65
+# Destroy set
+0 ipset -X test
+# Timeout: Check that resizing keeps timeout values
+0 ./resizet.sh -6 ipmark
+# Counters: create set
+0 ipset n test hash:ip,mark -6 counters
+# Counters: add element with packet, byte counters
+0 ipset a test 2:0:0::1,80 packets 5 bytes 3456
+# Counters: check element
+0 ipset t test 2:0:0::1,80
+# Counters: check counters
+0 ./check_counters test 2::1 5 3456
+# Counters: delete element
+0 ipset d test 2:0:0::1,80
+# Counters: test deleted element
+1 ipset t test 2:0:0::1,80
+# Counters: add element with packet, byte counters
+0 ipset a test 2:0:0::20,453 packets 12 bytes 9876
+# Counters: check counters
+0 ./check_counters test 2::20 12 9876
+# Counters: update counters
+0 ipset -! a test 2:0:0::20,453 packets 13 bytes 12479
+# Counters: check counters
+0 ./check_counters test 2::20 13 12479
+# Counters: destroy set
+0 ipset x test
+# Counters and timeout: create set
+0 ipset n test hash:ip,mark -6 counters timeout 600
+# Counters and timeout: add element with packet, byte counters
+0 ipset a test 2:0:0::1,80 packets 5 bytes 3456
+# Counters and timeout: check element
+0 ipset t test 2:0:0::1,80
+# Counters and timeout: check counters
+0 ./check_extensions test 2::1 600 5 3456
+# Counters and timeout: delete element
+0 ipset d test 2:0:0::1,80
+# Counters and timeout: test deleted element
+1 ipset t test 2:0:0::1,80
+# Counters and timeout: add element with packet, byte counters
+0 ipset a test 2:0:0::20,453 packets 12 bytes 9876
+# Counters and timeout: check counters
+0 ./check_extensions test 2::20 600 12 9876
+# Counters and timeout: update counters
+0 ipset -! a test 2:0:0::20,453 packets 13 bytes 12479
+# Counters and timeout: check counters
+0 ./check_extensions test 2::20 600 13 12479
+# Counters and timeout: update timeout
+0 ipset -! a test 2:0:0::20,453 timeout 700
+# Counters and timeout: check counters
+0 ./check_extensions test 2::20 700 13 12479
+# Counters and timeout: destroy set
+0 ipset x test
+# eof
diff --git a/tests/hash:ip6,mark.t.list0 b/tests/hash:ip6,mark.t.list0
new file mode 100644 (file)
index 0000000..3ddc56a
--- /dev/null
@@ -0,0 +1,10 @@
+Name: test
+Type: hash:ip,mark
+Header: family inet6 hashsize 1024 maxelem 65536 timeout x
+Size in memory: 9316
+References: 0
+Members:
+2:1::,128 timeout x
+2:1::1,128 timeout x
+2::,5 timeout x
+2::1,5 timeout x
diff --git a/tests/hash:ip6,mark.t.list1 b/tests/hash:ip6,mark.t.list1
new file mode 100644 (file)
index 0000000..3759448
--- /dev/null
@@ -0,0 +1,6 @@
+Name: test
+Type: hash:ip,mark
+Header: family inet6 hashsize 1024 maxelem 65536 timeout 5
+Size in memory: 9316
+References: 0
+Members:
diff --git a/tests/ipmarkhash.t b/tests/ipmarkhash.t
new file mode 100644 (file)
index 0000000..30301fb
--- /dev/null
@@ -0,0 +1,71 @@
+# Create a set from a range (range ignored)
+0 ipset -N test ipmarkhash --from 2.0.0.1 --to 2.1.0.0
+# Destroy set
+0 ipset -X test
+# Create a set
+0 ipset -N test ipmarkhash
+# Add partly zero valued element
+0 ipset -A test 2.0.0.1,0
+# Test partly zero valued element
+0 ipset -T test 2.0.0.1,0
+# Delete partly zero valued element
+0 ipset -D test 2.0.0.1,0
+# Add first random value
+0 ipset -A test 2.0.0.1,5
+# Add second random value
+0 ipset -A test 2.1.0.0,128
+# Test first random value
+0 ipset -T test 2.0.0.1,5
+# Test second random value
+0 ipset -T test 2.1.0.0,128
+# Test value not added to the set
+1 ipset -T test 2.0.0.1,4
+# Delete value not added to the set
+1 ipset -D test 2.0.0.1,6
+# Test value before first random value
+1 ipset -T test 2.0.0.0,5
+# Test value after second random value
+1 ipset -T test 2.1.0.1,128
+# Try to add value before first random value
+0 ipset -A test 2.0.0.0,5
+# Try to add value after second random value
+0 ipset -A test 2.1.0.1,128
+# List set
+0 ipset -L test | grep -v Revision: > .foo0 && ./sort.sh .foo0
+# Check listing
+0 diff -u -I 'Size in memory.*' .foo ipmarkhash.t.list0
+# Flush test set
+0 ipset -F test
+# Delete test set
+0 ipset -X test
+# Create a set from a network (network ignored)
+0 ipset -N test ipmarkhash --network 2.0.0.0/16
+# Add first random value
+0 ipset -A test 2.0.0.0,5
+# Add second random value
+0 ipset -A test 2.0.255.255,128
+# Test first random value
+0 ipset -T test 2.0.0.0,5
+# Test second random value
+0 ipset -T test 2.0.255.255,128
+# Test value not added to the set
+1 ipset -T test 2.0.0.0,4
+# Delete value not added to the set
+1 ipset -D test 2.0.0.0,6
+# Test value before first random value
+1 ipset -T test 1.255.255.255,5
+# Test value after second random value
+1 ipset -T test 2.1.0.0,128
+# Try to add value before first random value
+0 ipset -A test 1.255.255.255,5
+# Try to add value after second random value
+0 ipset -A test 2.1.0.0,128
+# List set
+0 ipset -L test | grep -v Revision: > .foo0 && ./sort.sh .foo0
+# Check listing
+0 diff -u -I 'Size in memory.*' .foo ipmarkhash.t.list1
+# Flush test set
+0 ipset -F test
+# Delete test set
+0 ipset -X test
+# eof
diff --git a/tests/ipmarkhash.t.list0 b/tests/ipmarkhash.t.list0
new file mode 100644 (file)
index 0000000..201a687
--- /dev/null
@@ -0,0 +1,10 @@
+Name: test
+Type: hash:ip,mark
+Header: family inet hashsize 1024 maxelem 65536
+Size in memory: 8516
+References: 0
+Members:
+2.0.0.0,5
+2.0.0.1,5
+2.1.0.0,128
+2.1.0.1,128
diff --git a/tests/ipmarkhash.t.list1 b/tests/ipmarkhash.t.list1
new file mode 100644 (file)
index 0000000..2b0265b
--- /dev/null
@@ -0,0 +1,10 @@
+Name: test
+Type: hash:ip,mark
+Header: family inet hashsize 1024 maxelem 65536
+Size in memory: 8468
+References: 0
+Members:
+1.255.255.255,5
+2.0.0.0,5
+2.0.255.255,128
+2.1.0.0,128
index c1213573885b79e873159a17296a63695bc7ad59..753c08eaf4b2051d8b341e6d0c76324d9e4cb4fe 100644 (file)
@@ -29,6 +29,14 @@ case "$2" in
            done
        done
        ;;
+    ipmark)
+       $ipset n test hash:ip,mark $1 hashsize 64 timeout 100
+       for x in `seq 0 16`; do
+           for y in `seq 0 255`; do
+               $ipset a test $ip$x$sep$y,1023
+           done
+       done
+       ;;
     ipport)
        $ipset n test hash:ip,port $1 hashsize 64 timeout 100
        for x in `seq 0 16`; do
index a82b802159b4eb65e62f2bab4a1ce0c7b68ebd13..99e5e6cd9418e10a4e5302e7b1e8ce6ad1ceae0d 100755 (executable)
@@ -7,6 +7,7 @@ tests="$tests ipmap bitmap:ip"
 tests="$tests macipmap portmap"
 tests="$tests iphash hash:ip hash:ip6"
 tests="$tests ipporthash hash:ip,port hash:ip6,port"
+tests="$tests ipmarkhash hash:ip,mark hash:ip6,mark"
 tests="$tests ipportiphash hash:ip,port,ip hash:ip6,port,ip6"
 tests="$tests nethash hash:net hash:net6 hash:net,port hash:net6,port"
 tests="$tests hash:ip,port,net hash:ip6,port,net6 hash:net,net hash:net6,net6"
index bdf762b2bb0cbe13565f6311c032d22b9309aa63..7e7ad24929902adb621b27ed3e8ab37f1900fa3d 100755 (executable)
@@ -7,7 +7,7 @@ loop=8
 for x in ip_set_list_set ip_set_hash_netiface ip_set_hash_ipportnet \
         ip_set_hash_netport ip_set_hash_net ip_set_hash_ipportip \
         ip_set_hash_ipport ip_set_hash_ip ip_set_hash_netnet \
-        ip_set_hash_netportnet \
+        ip_set_hash_netportnet ip_set_hash_ipmark \
         ip_set_bitmap_port ip_set_bitmap_ipmac \
         ip_set_bitmap_ip xt_set ip_set; do
     rmmod $x