]> git.ipfire.org Git - thirdparty/xtables-addons.git/commitdiff
ipset: update to 5.4.1
authorJan Engelhardt <jengelh@medozas.de>
Sat, 22 Jan 2011 14:55:08 +0000 (15:55 +0100)
committerJan Engelhardt <jengelh@medozas.de>
Sat, 22 Jan 2011 14:56:44 +0000 (15:56 +0100)
22 files changed:
doc/changelog.txt
extensions/ipset-5/Kbuild
extensions/ipset-5/ip_set.h
extensions/ipset-5/ip_set_ahash.h
extensions/ipset-5/ip_set_bitmap_ip.c
extensions/ipset-5/ip_set_bitmap_ipmac.c
extensions/ipset-5/ip_set_bitmap_port.c
extensions/ipset-5/ip_set_core.c
extensions/ipset-5/ip_set_getport.c [new file with mode: 0644]
extensions/ipset-5/ip_set_getport.h
extensions/ipset-5/ip_set_hash_ip.c
extensions/ipset-5/ip_set_hash_ipport.c
extensions/ipset-5/ip_set_hash_ipportip.c
extensions/ipset-5/ip_set_hash_ipportnet.c
extensions/ipset-5/ip_set_hash_net.c
extensions/ipset-5/ip_set_hash_netport.c
extensions/ipset-5/ip_set_kernel.h [deleted file]
extensions/ipset-5/ip_set_list_set.c
extensions/ipset-5/ip_set_timeout.h
extensions/ipset-5/pfxlen.c
extensions/ipset-5/pfxlen.h
extensions/ipset-5/xt_set.c

index 9d9ca970ebfe2e2ac0cd171b113ea3b37e345d69..049c11d05e32c26536ab72cd229a6b2de391cc7e 100644 (file)
@@ -9,6 +9,10 @@ Enhancements:
 - Update to ipset 5.3
   * make IPv4 and IPv6 address handling similar
   * show correct line numbers in restore output for parser errors
+- Update to ipset 5.4
+  * fixed ICMP and ICMPv6 handling
+  * fixed trailing whitespaces and pr_* messages
+  * fixed module loading at create/header commands
 
 
 v1.32 (2011-01-04)
index b84b49979b430b8a3a30495c254c57b831355ae1..1ec5c40cc36771d1640e25daa2d8c20a5cf1693c 100644 (file)
@@ -6,6 +6,6 @@ obj-m += ip_set_bitmap_port.o ip_set_hash_ip.o ip_set_hash_ipport.o
 obj-m += ip_set_hash_ipportip.o ip_set_hash_ipportnet.o ip_set_hash_net.o
 obj-m += ip_set_hash_netport.o ip_set_list_set.o
 
-ip_set-y := ip_set_core.o pfxlen.o
+ip_set-y := ip_set_core.o ip_set_getport.o pfxlen.o
 
 EXTRA_CFLAGS += -DLCONFIG_IP_SET_MAX=256
index 7003c78b06b9278e3bcae71318a54643b80b2d08..9d4b9614cc940fca49bcf4ba3aaa8326311efb1f 100644 (file)
@@ -11,6 +11,8 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/netlink.h>
+
 /* The protocol version */
 #define IPSET_PROTOCOL         5
 
@@ -292,7 +294,7 @@ struct ip_set {
        /* References to the set */
        atomic_t ref;
        /* The core set type */
-       const struct ip_set_type *type;
+       struct ip_set_type *type;
        /* The type variant doing the real job */
        const struct ip_set_type_variant *variant;
        /* The actual INET family of the set */
@@ -317,37 +319,22 @@ extern int ip_set_del(ip_set_id_t id, const struct sk_buff *skb,
 extern int ip_set_test(ip_set_id_t id, const struct sk_buff *skb,
                       u8 family, u8 dim, u8 flags);
 
-/* Allocate members */
-static inline void *
-ip_set_alloc(size_t size, gfp_t gfp_mask)
-{
-       void *members = NULL;
-
-       if (size < KMALLOC_MAX_SIZE)
-               members = kzalloc(size, gfp_mask | __GFP_NOWARN);
-
-       if (members) {
-               pr_debug("%p: allocated with kmalloc", members);
-               return members;
-       }
-
-       members = __vmalloc(size, gfp_mask | __GFP_ZERO, PAGE_KERNEL);
-       if (!members)
-               return NULL;
-       pr_debug("%p: allocated with vmalloc", members);
+/* Utility functions */
+extern void * ip_set_alloc(size_t size, gfp_t gfp_mask);
+extern void ip_set_free(void *members);
+extern int ip_set_get_ipaddr4(struct nlattr *nla,  __be32 *ipaddr);
+extern int ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr);
 
-       return members;
-}
-
-static inline void
-ip_set_free(void *members)
+static inline int
+ip_set_get_hostipaddr4(struct nlattr *nla, u32 *ipaddr)
 {
-       pr_debug("%p: free with %s", members,
-                is_vmalloc_addr(members) ? "vfree" : "kfree");
-       if (is_vmalloc_addr(members))
-               vfree(members);
-       else
-               kfree(members);
+       __be32 ip;
+       int ret = ip_set_get_ipaddr4(nla, &ip);
+       
+       if (ret)
+               return ret;
+       *ipaddr = ntohl(ip);
+       return 0;
 }
 
 /* Ignore IPSET_ERR_EXIST errors if asked to do so? */
@@ -357,92 +344,47 @@ ip_set_eexist(int ret, u32 flags)
        return ret == -IPSET_ERR_EXIST && (flags & IPSET_FLAG_EXIST);
 }
 
-/* Useful converters */
-static inline u32
-ip_set_get_h32(const struct nlattr *attr)
+/* Check the NLA_F_NET_BYTEORDER flag */
+static inline bool
+ip_set_attr_netorder(struct nlattr *tb[], int type)
 {
-       u32 value = nla_get_u32(attr);
-
-       return attr->nla_type & NLA_F_NET_BYTEORDER ? ntohl(value) : value;
+       return tb[type] && (tb[type]->nla_type & NLA_F_NET_BYTEORDER);
 }
 
-static inline u16
-ip_set_get_h16(const struct nlattr *attr)
+static inline bool
+ip_set_optattr_netorder(struct nlattr *tb[], int type)
 {
-       u16 value = nla_get_u16(attr);
-
-       return attr->nla_type & NLA_F_NET_BYTEORDER ? ntohs(value) : value;
+       return !tb[type] || (tb[type]->nla_type & NLA_F_NET_BYTEORDER);
 }
 
+/* Useful converters */
 static inline u32
-ip_set_get_n32(const struct nlattr *attr)
+ip_set_get_h32(const struct nlattr *attr)
 {
-       u32 value = nla_get_u32(attr);
-
-       return attr->nla_type & NLA_F_NET_BYTEORDER ? value : htonl(value);
+       return ntohl(nla_get_be32(attr));
 }
 
 static inline u16
-ip_set_get_n16(const struct nlattr *attr)
-{
-       u16 value = nla_get_u16(attr);
-
-       return attr->nla_type & NLA_F_NET_BYTEORDER ? value : htons(value);
-}
-
-static const struct nla_policy ipaddr_policy[IPSET_ATTR_IPADDR_MAX + 1] = {
-       [IPSET_ATTR_IPADDR_IPV4]        = { .type = NLA_U32 },
-       [IPSET_ATTR_IPADDR_IPV6]        = { .type = NLA_BINARY,
-                                           .len = sizeof(struct in6_addr) },
-};
-
-static inline int
-ip_set_get_ipaddr4(struct nlattr *attr[], int type, u32 *ipaddr)
-{
-       struct nlattr *tb[IPSET_ATTR_IPADDR_MAX+1] = {};
-
-       if (!attr[type])
-               return -IPSET_ERR_PROTOCOL;
-
-       if (nla_parse(tb, IPSET_ATTR_IPADDR_MAX,
-                     nla_data(attr[type]), nla_len(attr[type]),
-                     ipaddr_policy))
-               return -IPSET_ERR_PROTOCOL;
-       if (!tb[IPSET_ATTR_IPADDR_IPV4])
-               return -IPSET_ERR_IPADDR_IPV4;
-
-       *ipaddr = ip_set_get_n32(tb[IPSET_ATTR_IPADDR_IPV4]);
-       return 0;
-}
-
-static inline int
-ip_set_get_ipaddr6(struct nlattr *attr[], int type, union nf_inet_addr *ipaddr)
+ip_set_get_h16(const struct nlattr *attr)
 {
-       struct nlattr *tb[IPSET_ATTR_IPADDR_MAX+1] = {};
-
-       if (!attr[type])
-               return -IPSET_ERR_PROTOCOL;
-
-       if (nla_parse(tb, IPSET_ATTR_IPADDR_MAX,
-                     nla_data(attr[type]), nla_len(attr[type]),
-                     ipaddr_policy))
-               return -IPSET_ERR_PROTOCOL;
-       if (!tb[IPSET_ATTR_IPADDR_IPV6])
-               return -IPSET_ERR_IPADDR_IPV6;
-
-       memcpy(ipaddr, nla_data(tb[IPSET_ATTR_IPADDR_IPV6]),
-               sizeof(struct in6_addr));
-       return 0;
+       return ntohs(nla_get_be16(attr));
 }
 
 #define ipset_nest_start(skb, attr) nla_nest_start(skb, attr | NLA_F_NESTED)
 #define ipset_nest_end(skb, start)  nla_nest_end(skb, start)
 
-#define NLA_PUT_NET32(skb, type, value)        \
-       NLA_PUT_BE32(skb, type | NLA_F_NET_BYTEORDER, value)
-
-#define NLA_PUT_NET16(skb, type, value)        \
-       NLA_PUT_BE16(skb, type | NLA_F_NET_BYTEORDER, value)
+#ifndef NLA_PUT_NET16
+#define NLA_PUT_NET16(skb, attrtype, value) \
+       NLA_PUT_BE16(skb, attrtype | NLA_F_NET_BYTEORDER, value)
+#endif
+#ifndef NLA_PUT_NET32
+#define NLA_PUT_NET32(skb, attrtype, value) \
+       NLA_PUT_BE32(skb, attrtype | NLA_F_NET_BYTEORDER, value)
+#endif
+#ifndef NLA_PUT_NET64
+#define NLA_PUT_NET64(skb, attrtype, value) \
+       NLA_PUT_BE64(skb, attrtype | NLA_F_NET_BYTEORDER, value)
+#endif
 
 #define NLA_PUT_IPADDR4(skb, type, ipaddr)                     \
 do {                                                           \
@@ -466,14 +408,14 @@ do {                                                              \
 } while (0)
 
 /* Get address from skbuff */
-static inline u32
+static inline __be32
 ip4addr(const struct sk_buff *skb, bool src)
 {
        return src ? ip_hdr(skb)->saddr : ip_hdr(skb)->daddr;
 }
 
 static inline void
-ip4addrptr(const struct sk_buff *skb, bool src, u32 *addr)
+ip4addrptr(const struct sk_buff *skb, bool src, __be32 *addr)
 {
        *addr = src ? ip_hdr(skb)->saddr : ip_hdr(skb)->daddr;
 }
index 7c36f63d634f33c05f10cd1f1fec31b6df9e1608..2f4bb3affb388a8691762ee0b6c71df54f9f1ab3 100644 (file)
@@ -63,7 +63,7 @@ struct ip_set_hash {
 };
 
 /* Compute htable_bits from the user input parameter hashsize */
-static inline u8
+static u8
 htable_bits(u32 hashsize)
 {
        /* Assume that hashsize == 2^htable_bits */
@@ -81,14 +81,14 @@ htable_bits(u32 hashsize)
 
 /* Network cidr size book keeping when the hash stores different
  * sized networks */
-static inline void
+static void
 add_cidr(struct ip_set_hash *h, u8 cidr, u8 host_mask)
 {
        u8 i;
 
        ++h->nets[cidr-1].nets;
 
-       pr_debug("add_cidr added %u: %u", cidr, h->nets[cidr-1].nets);
+       pr_debug("add_cidr added %u: %u\n", cidr, h->nets[cidr-1].nets);
 
        if (h->nets[cidr-1].nets > 1)
                return;
@@ -103,14 +103,14 @@ add_cidr(struct ip_set_hash *h, u8 cidr, u8 host_mask)
                h->nets[i].cidr = cidr;
 }
 
-static inline void
+static void
 del_cidr(struct ip_set_hash *h, u8 cidr, u8 host_mask)
 {
        u8 i;
 
        --h->nets[cidr-1].nets;
 
-       pr_debug("del_cidr deleted %u: %u", cidr, h->nets[cidr-1].nets);
+       pr_debug("del_cidr deleted %u: %u\n", cidr, h->nets[cidr-1].nets);
 
        if (h->nets[cidr-1].nets != 0)
                return;
@@ -142,7 +142,7 @@ ahash_destroy(struct htable *t)
 }
 
 /* Calculate the actual memory size of the set data */
-static inline size_t
+static size_t
 ahash_memsize(const struct ip_set_hash *h, size_t dsize, u8 host_mask)
 {
        u32 i;
@@ -340,7 +340,7 @@ retry:
        /* Give time to other readers of the set */
        synchronize_rcu_bh();
 
-       pr_debug("set %s resized from %u (%p) to %u (%p)", set->name,
+       pr_debug("set %s resized from %u (%p) to %u (%p)\n", set->name,
                 orig->htable_bits, orig, t->htable_bits, t);
        ahash_destroy(orig);
 
@@ -436,7 +436,7 @@ type_pf_del(struct ip_set *set, void *value, u32 timeout)
 
 /* Special test function which takes into account the different network
  * sizes added to the set */
-static inline int
+static int
 type_pf_test_cidrs(struct ip_set *set, struct type_pf_elem *d, u32 timeout)
 {
        struct ip_set_hash *h = set->data;
@@ -447,7 +447,7 @@ type_pf_test_cidrs(struct ip_set *set, struct type_pf_elem *d, u32 timeout)
        u32 key;
        u8 host_mask = SET_HOST_MASK(set->family);
 
-       pr_debug("test by nets");
+       pr_debug("test by nets\n");
        for (; j < host_mask && h->nets[j].cidr; j++) {
                type_pf_data_netmask(d, h->nets[j].cidr);
                key = HKEY(d, h->initval, t->htable_bits);
@@ -546,14 +546,14 @@ type_pf_list(const struct ip_set *set,
        atd = ipset_nest_start(skb, IPSET_ATTR_ADT);
        if (!atd)
                return -EFAULT;
-       pr_debug("list hash set %s", set->name);
+       pr_debug("list hash set %s\n", set->name);
        for (; cb->args[2] < jhash_size(t->htable_bits); cb->args[2]++) {
                incomplete = skb_tail_pointer(skb);
                n = hbucket(t, cb->args[2]);
-               pr_debug("cb->args[2]: %lu, t %p n %p", cb->args[2], t, n); 
+               pr_debug("cb->args[2]: %lu, t %p n %p\n", cb->args[2], t, n);
                for (i = 0; i < n->pos; i++) {
                        data = ahash_data(n, i);
-                       pr_debug("list hash %lu hbucket %p i %u, data %p",
+                       pr_debug("list hash %lu hbucket %p i %u, data %p\n",
                                 cb->args[2], n, i, data);
                        nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
                        if (!nested) {
@@ -686,7 +686,7 @@ type_pf_expire(struct ip_set_hash *h)
                for (j = 0; j < n->pos; j++) {
                        data = ahash_tdata(n, j);
                        if (type_pf_data_expired(data)) {
-                               pr_debug("expired %u/%u", i, j);
+                               pr_debug("expired %u/%u\n", i, j);
 #ifdef IP_SET_HASH_WITH_NETS
                                del_cidr(h, data->cidr, HOST_MASK);
 #endif
@@ -701,7 +701,7 @@ type_pf_expire(struct ip_set_hash *h)
                if (n->pos + AHASH_INIT_SIZE < n->size) {
                        void *tmp = kzalloc((n->size - AHASH_INIT_SIZE)
                                            * sizeof(struct type_pf_telem),
-                                           GFP_KERNEL);
+                                           GFP_ATOMIC);
                        if (!tmp)
                                /* Still try to delete expired elements */
                                continue;
@@ -807,8 +807,8 @@ type_pf_tadd(struct ip_set *set, void *value, u32 timeout)
                                ret = -IPSET_ERR_EXIST;
                                goto out;
                        }
-               } else if (j == AHASH_MAX_SIZE + 1 
-                        && type_pf_data_expired(data))
+               } else if (j == AHASH_MAX_SIZE + 1 &&
+                          type_pf_data_expired(data))
                        j = i;
        }
        if (j != AHASH_MAX_SIZE + 1) {
@@ -881,7 +881,7 @@ type_pf_tdel(struct ip_set *set, void *value, u32 timeout)
 }
 
 #ifdef IP_SET_HASH_WITH_NETS
-static inline int
+static int
 type_pf_ttest_cidrs(struct ip_set *set, struct type_pf_elem *d, u32 timeout)
 {
        struct ip_set_hash *h = set->data;
@@ -952,10 +952,10 @@ type_pf_tlist(const struct ip_set *set,
                n = hbucket(t, cb->args[2]);
                for (i = 0; i < n->pos; i++) {
                        data = ahash_tdata(n, i);
-                       pr_debug("list %p %u", n, i);
+                       pr_debug("list %p %u\n", n, i);
                        if (type_pf_data_expired(data))
                                continue;
-                       pr_debug("do list %p %u", n, i);
+                       pr_debug("do list %p %u\n", n, i);
                        nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
                        if (!nested) {
                                if (cb->args[2] == first) {
@@ -1008,7 +1008,7 @@ type_pf_gc(unsigned long ul_set)
        struct ip_set *set = (struct ip_set *) ul_set;
        struct ip_set_hash *h = set->data;
 
-       pr_debug("called");
+       pr_debug("called\n");
        write_lock_bh(&set->lock);
        type_pf_expire(h);
        write_unlock_bh(&set->lock);
@@ -1017,7 +1017,7 @@ type_pf_gc(unsigned long ul_set)
        add_timer(&h->gc);
 }
 
-static inline void
+static void
 type_pf_gc_init(struct ip_set *set)
 {
        struct ip_set_hash *h = set->data;
@@ -1027,7 +1027,7 @@ type_pf_gc_init(struct ip_set *set)
        h->gc.function = type_pf_gc;
        h->gc.expires = jiffies + IPSET_GC_PERIOD(h->timeout) * HZ;
        add_timer(&h->gc);
-       pr_debug("gc initialized, run in every %u",
+       pr_debug("gc initialized, run in every %u\n",
                 IPSET_GC_PERIOD(h->timeout));
 }
 
index b44bdc73a52c56c7b6c001909ea6e24bcb861a31..e0118649dea4de805d0d9910da5cdcade7122539 100644 (file)
@@ -9,7 +9,6 @@
 
 /* Kernel module implementing an IP set type: the bitmap:ip type */
 
-#include "ip_set_kernel.h"
 #include <linux/module.h>
 #include <linux/ip.h>
 #include <linux/skbuff.h>
@@ -47,9 +46,9 @@ struct bitmap_ip {
 };
 
 static inline u32
-ip_to_id(const struct bitmap_ip *map, u32 ip)
+ip_to_id(const struct bitmap_ip *m, u32 ip)
 {
-       return ((ip & HOSTMASK(map->netmask)) - map->first_ip)/map->hosts;
+       return ((ip & ip_set_hostmask(m->netmask)) - m->first_ip)/m->hosts;
 }
 
 static inline int
@@ -122,13 +121,15 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *head, int len,
                      bitmap_ip_adt_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!tb[IPSET_ATTR_IP]))
+               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, &ip);
+       ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip);
        if (ret)
                return ret;
-       ip = ntohl(ip);
 
        if (ip < map->first_ip || ip > map->last_ip)
                return -IPSET_ERR_BITMAP_RANGE;
@@ -142,10 +143,9 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *head, int len,
                return bitmap_ip_test(map, ip_to_id(map, ip));
 
        if (tb[IPSET_ATTR_IP_TO]) {
-               ret = ip_set_get_ipaddr4(tb, IPSET_ATTR_IP_TO, &ip_to);
+               ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
                if (ret)
                        return ret;
-               ip_to = ntohl(ip_to);
                if (ip > ip_to) {
                        swap(ip, ip_to);
                        if (ip < map->first_ip)
@@ -156,8 +156,8 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *head, int len,
 
                if (cidr > 32)
                        return -IPSET_ERR_INVALID_CIDR;
-               ip &= HOSTMASK(cidr);
-               ip_to = ip | ~HOSTMASK(cidr);
+               ip &= ip_set_hostmask(cidr);
+               ip_to = ip | ~ip_set_hostmask(cidr);
        } else
                ip_to = ip;
 
@@ -264,9 +264,9 @@ bitmap_ip_same_set(const struct ip_set *a, const struct ip_set *b)
        const struct bitmap_ip *x = a->data;
        const struct bitmap_ip *y = b->data;
 
-       return x->first_ip == y->first_ip
-              && x->last_ip == y->last_ip
-              && x->netmask == y->netmask;
+       return x->first_ip == y->first_ip &&
+              x->last_ip == y->last_ip &&
+              x->netmask == y->netmask;
 }
 
 static const struct ip_set_type_variant bitmap_ip = {
@@ -362,13 +362,16 @@ bitmap_ip_timeout_uadt(struct ip_set *set, struct nlattr *head, int len,
                      bitmap_ip_adt_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!tb[IPSET_ATTR_IP] ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               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, &ip);
+       ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip);
        if (ret)
                return ret;
-       ip = ntohl(ip);
 
        if (ip < map->first_ip || ip > map->last_ip)
                return -IPSET_ERR_BITMAP_RANGE;
@@ -378,10 +381,9 @@ bitmap_ip_timeout_uadt(struct ip_set *set, struct nlattr *head, int len,
                                ip_to_id((const struct bitmap_ip *)map, ip));
 
        if (tb[IPSET_ATTR_IP_TO]) {
-               ret = ip_set_get_ipaddr4(tb, IPSET_ATTR_IP_TO, &ip_to);
+               ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
                if (ret)
                        return ret;
-               ip_to = ntohl(ip_to);
                if (ip > ip_to) {
                        swap(ip, ip_to);
                        if (ip < map->first_ip)
@@ -392,8 +394,8 @@ bitmap_ip_timeout_uadt(struct ip_set *set, struct nlattr *head, int len,
 
                if (cidr > 32)
                        return -IPSET_ERR_INVALID_CIDR;
-               ip &= HOSTMASK(cidr);
-               ip_to = ip | ~HOSTMASK(cidr);
+               ip &= ip_set_hostmask(cidr);
+               ip_to = ip | ~ip_set_hostmask(cidr);
        } else
                ip_to = ip;
 
@@ -511,10 +513,10 @@ bitmap_ip_timeout_same_set(const struct ip_set *a, const struct ip_set *b)
        const struct bitmap_ip_timeout *x = a->data;
        const struct bitmap_ip_timeout *y = b->data;
 
-       return x->first_ip == y->first_ip
-              && x->last_ip == y->last_ip
-              && x->netmask == y->netmask
-              && x->timeout == y->timeout;
+       return x->first_ip == y->first_ip &&
+              x->last_ip == y->last_ip &&
+              x->netmask == y->netmask &&
+              x->timeout == y->timeout;
 }
 
 static const struct ip_set_type_variant bitmap_ip_timeout = {
@@ -547,7 +549,7 @@ bitmap_ip_gc(unsigned long ul_set)
        add_timer(&map->gc);
 }
 
-static inline void
+static void
 bitmap_ip_gc_init(struct ip_set *set)
 {
        struct bitmap_ip_timeout *map = set->data;
@@ -603,16 +605,18 @@ bitmap_ip_create(struct ip_set *set, struct nlattr *head, int len,
                      bitmap_ip_create_policy))
                return -IPSET_ERR_PROTOCOL;
 
-       ret = ip_set_get_ipaddr4(tb, IPSET_ATTR_IP, &first_ip);
+       if (unlikely(!tb[IPSET_ATTR_IP] ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               return -IPSET_ERR_PROTOCOL;
+
+       ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &first_ip);
        if (ret)
                return ret;
-       first_ip = ntohl(first_ip);
 
        if (tb[IPSET_ATTR_IP_TO]) {
-               ret = ip_set_get_ipaddr4(tb, IPSET_ATTR_IP_TO, &last_ip);
+               ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &last_ip);
                if (ret)
                        return ret;
-               last_ip = htonl(last_ip);
                if (first_ip > last_ip) {
                        u32 tmp = first_ip;
 
@@ -624,7 +628,7 @@ bitmap_ip_create(struct ip_set *set, struct nlattr *head, int len,
 
                if (cidr >= 32)
                        return -IPSET_ERR_INVALID_CIDR;
-               last_ip = first_ip | ~HOSTMASK(cidr);
+               last_ip = first_ip | ~ip_set_hostmask(cidr);
        } else
                return -IPSET_ERR_PROTOCOL;
 
@@ -634,8 +638,8 @@ bitmap_ip_create(struct ip_set *set, struct nlattr *head, int len,
                if (netmask > 32)
                        return -IPSET_ERR_INVALID_NETMASK;
 
-               first_ip &= HOSTMASK(netmask);
-               last_ip |= ~HOSTMASK(netmask);
+               first_ip &= ip_set_hostmask(netmask);
+               last_ip |= ~ip_set_hostmask(netmask);
        }
 
        if (netmask == 32) {
@@ -647,18 +651,18 @@ bitmap_ip_create(struct ip_set *set, struct nlattr *head, int len,
 
                mask = range_to_mask(first_ip, last_ip, &mask_bits);
 
-               if ((!mask && (first_ip || last_ip != 0xFFFFFFFF))
-                   || netmask <= mask_bits)
+               if ((!mask && (first_ip || last_ip != 0xFFFFFFFF)) ||
+                   netmask <= mask_bits)
                        return -IPSET_ERR_BITMAP_RANGE;
 
-               pr_debug("mask_bits %u, netmask %u", mask_bits, netmask);
+               pr_debug("mask_bits %u, netmask %u\n", mask_bits, netmask);
                hosts = 2 << (32 - netmask - 1);
                elements = 2 << (netmask - mask_bits - 1);
        }
        if (elements > IPSET_BITMAP_MAX_RANGE + 1)
                return -IPSET_ERR_BITMAP_RANGE_SIZE;
 
-       pr_debug("hosts %u, elements %u", hosts, elements);
+       pr_debug("hosts %u, elements %u\n", hosts, elements);
 
        if (tb[IPSET_ATTR_TIMEOUT]) {
                struct bitmap_ip_timeout *map;
index 4c36d1dc6d699141b856909867d15e6a9a985c49..736352794985153818d65e467bad4db14a1125f5 100644 (file)
@@ -10,7 +10,6 @@
 
 /* Kernel module implementing an IP set type: the bitmap:ip,mac type */
 
-#include "ip_set_kernel.h"
 #include <linux/module.h>
 #include <linux/ip.h>
 #include <linux/etherdevice.h>
@@ -95,9 +94,9 @@ bitmap_expired(const struct bitmap_ipmac *map, u32 id)
 static inline int
 bitmap_ipmac_exist(const struct ipmac_telem *elem)
 {
-       return elem->match == MAC_UNSET
-               || (elem->match == MAC_FILLED
-                   && !ip_set_timeout_expired(elem->timeout));
+       return elem->match == MAC_UNSET ||
+              (elem->match == MAC_FILLED &&
+               !ip_set_timeout_expired(elem->timeout));
 }
 
 /* Base variant */
@@ -114,8 +113,8 @@ bitmap_ipmac_test(struct ip_set *set, void *value, u32 timeout)
                /* Trigger kernel to fill out the ethernet address */
                return -EAGAIN;
        case MAC_FILLED:
-               return data->ether == NULL
-                      || compare_ether_addr(data->ether, elem->ether) == 0;
+               return data->ether == NULL ||
+                      compare_ether_addr(data->ether, elem->ether) == 0;
        }
        return 0;
 }
@@ -223,9 +222,9 @@ bitmap_ipmac_ttest(struct ip_set *set, void *value, u32 timeout)
                /* Trigger kernel to fill out the ethernet address */
                return -EAGAIN;
        case MAC_FILLED:
-               return (data->ether == NULL
-                       || compare_ether_addr(data->ether, elem->ether) == 0)
-                      && !bitmap_expired(map, data->id);
+               return (data->ether == NULL ||
+                       compare_ether_addr(data->ether, elem->ether) == 0) &&
+                      !bitmap_expired(map, data->id);
        }
        return 0;
 }
@@ -348,8 +347,8 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
                return -IPSET_ERR_BITMAP_RANGE;
 
        /* Backward compatibility: we don't check the second flag */
-       if (skb_mac_header(skb) < skb->head
-           || (skb_mac_header(skb) + ETH_HLEN) > skb->data)
+       if (skb_mac_header(skb) < skb->head ||
+           (skb_mac_header(skb) + ETH_HLEN) > skb->data)
                return -EINVAL;
 
        data.id -= map->first_ip;
@@ -381,13 +380,16 @@ bitmap_ipmac_uadt(struct ip_set *set, struct nlattr *head, int len,
                      bitmap_ipmac_adt_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!tb[IPSET_ATTR_IP] ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               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, &data.id);
+       ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &data.id);
        if (ret)
                return ret;
-       data.id = ntohl(data.id);
 
        if (data.id < map->first_ip || data.id > map->last_ip)
                return -IPSET_ERR_BITMAP_RANGE;
@@ -464,12 +466,12 @@ bitmap_ipmac_same_set(const struct ip_set *a, const struct ip_set *b)
        const struct bitmap_ipmac *x = a->data;
        const struct bitmap_ipmac *y = b->data;
 
-       return x->first_ip == y->first_ip
-              && x->last_ip == y->last_ip
-              && x->timeout == y->timeout;
+       return x->first_ip == y->first_ip &&
+              x->last_ip == y->last_ip &&
+              x->timeout == y->timeout;
 }
 
-const struct ip_set_type_variant bitmap_ipmac = {
+static const struct ip_set_type_variant bitmap_ipmac = {
        .kadt   = bitmap_ipmac_kadt,
        .uadt   = bitmap_ipmac_uadt,
        .adt    = {
@@ -484,7 +486,7 @@ const struct ip_set_type_variant bitmap_ipmac = {
        .same_set = bitmap_ipmac_same_set,
 };
 
-const struct ip_set_type_variant bitmap_tipmac = {
+static const struct ip_set_type_variant bitmap_tipmac = {
        .kadt   = bitmap_ipmac_kadt,
        .uadt   = bitmap_ipmac_uadt,
        .adt    = {
@@ -512,8 +514,8 @@ bitmap_ipmac_gc(unsigned long ul_set)
        read_lock_bh(&set->lock);
        for (id = 0; id <= last; id++) {
                elem = bitmap_ipmac_elem(map, id);
-               if (elem->match == MAC_FILLED
-                   && ip_set_timeout_expired(elem->timeout))
+               if (elem->match == MAC_FILLED &&
+                   ip_set_timeout_expired(elem->timeout))
                        elem->match = MAC_EMPTY;
        }
        read_unlock_bh(&set->lock);
@@ -522,7 +524,7 @@ bitmap_ipmac_gc(unsigned long ul_set)
        add_timer(&map->gc);
 }
 
-static inline void
+static void
 bitmap_ipmac_gc_init(struct ip_set *set)
 {
        struct bitmap_ipmac *map = set->data;
@@ -540,6 +542,7 @@ static const struct nla_policy
 bitmap_ipmac_create_policy[IPSET_ATTR_CREATE_MAX+1] = {
        [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
        [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
+       [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
        [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
 };
 
@@ -574,16 +577,18 @@ bitmap_ipmac_create(struct ip_set *set, struct nlattr *head, int len,
                      bitmap_ipmac_create_policy))
                return -IPSET_ERR_PROTOCOL;
 
-       ret = ip_set_get_ipaddr4(tb, IPSET_ATTR_IP, &first_ip);
+       if (unlikely(!tb[IPSET_ATTR_IP] ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               return -IPSET_ERR_PROTOCOL;
+
+       ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &first_ip);
        if (ret)
                return ret;
-       first_ip = ntohl(first_ip);
 
        if (tb[IPSET_ATTR_IP_TO]) {
-               ret = ip_set_get_ipaddr4(tb, IPSET_ATTR_IP_TO, &last_ip);
+               ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &last_ip);
                if (ret)
                        return ret;
-               last_ip = ntohl(last_ip);
                if (first_ip > last_ip) {
                        u32 tmp = first_ip;
 
@@ -595,7 +600,7 @@ bitmap_ipmac_create(struct ip_set *set, struct nlattr *head, int len,
 
                if (cidr >= 32)
                        return -IPSET_ERR_INVALID_CIDR;
-               last_ip = first_ip | ~HOSTMASK(cidr);
+               last_ip = first_ip | ~ip_set_hostmask(cidr);
        } else
                return -IPSET_ERR_PROTOCOL;
 
@@ -634,7 +639,7 @@ bitmap_ipmac_create(struct ip_set *set, struct nlattr *head, int len,
        return 0;
 }
 
-struct ip_set_type bitmap_ipmac_type = {
+static struct ip_set_type bitmap_ipmac_type = {
        .name           = "bitmap:ip,mac",
        .protocol       = IPSET_PROTOCOL,
        .features       = IPSET_TYPE_IP | IPSET_TYPE_MAC,
index 9cf71549faadbc26fdc98c2634f3d11304b9007d..5c5c6f393ce91058f864bb87e931b71548275a8b 100644 (file)
@@ -7,7 +7,6 @@
 
 /* Kernel module implementing an IP set type: the bitmap:port type */
 
-#include "ip_set_kernel.h"
 #include <linux/module.h>
 #include <linux/ip.h>
 #include <linux/tcp.h>
@@ -71,12 +70,13 @@ bitmap_port_kadt(struct ip_set *set, const struct sk_buff *skb,
                 enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
 {
        struct bitmap_port *map = set->data;
+       __be16 __port;
        u16 port = 0;
 
-       if (!get_ip_port(skb, pf, flags & IPSET_DIM_ONE_SRC, &port))
+       if (!ip_set_get_ip_port(skb, pf, flags & IPSET_DIM_ONE_SRC, &__port))
                return -EINVAL;
 
-       port = ntohs(port);
+       port = ntohs(__port);
 
        if (port < map->first_port || port > map->last_port)
                return -IPSET_ERR_BITMAP_RANGE;
@@ -116,14 +116,14 @@ bitmap_port_uadt(struct ip_set *set, struct nlattr *head, int len,
                      bitmap_port_adt_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO)))
+               return -IPSET_ERR_PROTOCOL;
+
        if (tb[IPSET_ATTR_LINENO])
                *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
-       if (tb[IPSET_ATTR_PORT])
-               port = ip_set_get_h16(tb[IPSET_ATTR_PORT]);
-       else
-               return -IPSET_ERR_PROTOCOL;
-
+       port = ip_set_get_h16(tb[IPSET_ATTR_PORT]);
        if (port < map->first_port || port > map->last_port)
                return -IPSET_ERR_BITMAP_RANGE;
 
@@ -246,11 +246,11 @@ bitmap_port_same_set(const struct ip_set *a, const struct ip_set *b)
        const struct bitmap_port *x = a->data;
        const struct bitmap_port *y = b->data;
 
-       return x->first_port == y->first_port
-              && x->last_port == y->last_port;
+       return x->first_port == y->first_port &&
+              x->last_port == y->last_port;
 }
 
-const struct ip_set_type_variant bitmap_port = {
+static const struct ip_set_type_variant bitmap_port = {
        .kadt   = bitmap_port_kadt,
        .uadt   = bitmap_port_uadt,
        .destroy = bitmap_port_destroy,
@@ -308,12 +308,13 @@ bitmap_port_timeout_kadt(struct ip_set *set, const struct sk_buff *skb,
                         enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
 {
        struct bitmap_port_timeout *map = set->data;
+       __be16 __port;
        u16 port = 0;
 
-       if (!get_ip_port(skb, pf, flags & IPSET_DIM_ONE_SRC, &port))
+       if (!ip_set_get_ip_port(skb, pf, flags & IPSET_DIM_ONE_SRC, &__port))
                return -EINVAL;
 
-       port = ntohs(port);
+       port = ntohs(__port);
 
        if (port < map->first_port || port > map->last_port)
                return -IPSET_ERR_BITMAP_RANGE;
@@ -346,14 +347,15 @@ bitmap_port_timeout_uadt(struct ip_set *set, struct nlattr *head, int len,
                      bitmap_port_adt_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               return -IPSET_ERR_PROTOCOL;
+
        if (tb[IPSET_ATTR_LINENO])
                *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
-       if (tb[IPSET_ATTR_PORT])
-               port = ip_set_get_h16(tb[IPSET_ATTR_PORT]);
-       else
-               return -IPSET_ERR_PROTOCOL;
-
+       port = ip_set_get_h16(tb[IPSET_ATTR_PORT]);
        if (port < map->first_port || port > map->last_port)
                return -IPSET_ERR_BITMAP_RANGE;
 
@@ -483,12 +485,12 @@ bitmap_port_timeout_same_set(const struct ip_set *a, const struct ip_set *b)
        const struct bitmap_port_timeout *x = a->data;
        const struct bitmap_port_timeout *y = b->data;
 
-       return x->first_port == y->first_port
-              && x->last_port == y->last_port
-              && x->timeout == y->timeout;
+       return x->first_port == y->first_port &&
+              x->last_port == y->last_port &&
+              x->timeout == y->timeout;
 }
 
-const struct ip_set_type_variant bitmap_port_timeout = {
+static const struct ip_set_type_variant bitmap_port_timeout = {
        .kadt   = bitmap_port_timeout_kadt,
        .uadt   = bitmap_port_timeout_uadt,
        .destroy = bitmap_port_timeout_destroy,
@@ -519,7 +521,7 @@ bitmap_port_gc(unsigned long ul_set)
        add_timer(&map->gc);
 }
 
-static inline void
+static void
 bitmap_port_gc_init(struct ip_set *set)
 {
        struct bitmap_port_timeout *map = set->data;
@@ -567,21 +569,19 @@ bitmap_port_create(struct ip_set *set, struct nlattr *head, int len,
                      bitmap_port_create_policy))
                return -IPSET_ERR_PROTOCOL;
 
-       if (tb[IPSET_ATTR_PORT])
-               first_port = ip_set_get_h16(tb[IPSET_ATTR_PORT]);
-       else
+       if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+                    !ip_set_attr_netorder(tb, IPSET_ATTR_PORT_TO) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
                return -IPSET_ERR_PROTOCOL;
 
-       if (tb[IPSET_ATTR_PORT_TO]) {
-               last_port = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
-               if (first_port > last_port) {
-                       u16 tmp = first_port;
+       first_port = ip_set_get_h16(tb[IPSET_ATTR_PORT]);
+       last_port = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
+       if (first_port > last_port) {
+               u16 tmp = first_port;
 
-                       first_port = last_port;
-                       last_port = tmp;
-               }
-       } else
-               return -IPSET_ERR_PROTOCOL;
+               first_port = last_port;
+               last_port = tmp;
+       }
 
        if (tb[IPSET_ATTR_TIMEOUT]) {
                struct bitmap_port_timeout *map;
@@ -611,7 +611,7 @@ bitmap_port_create(struct ip_set *set, struct nlattr *head, int len,
                        return -ENOMEM;
 
                map->memsize = bitmap_bytes(0, last_port - first_port);
-               pr_debug("memsize: %zu", map->memsize);
+               pr_debug("memsize: %zu\n", map->memsize);
                if (!init_map_port(set, map, first_port, last_port)) {
                        kfree(map);
                        return -ENOMEM;
@@ -622,7 +622,7 @@ bitmap_port_create(struct ip_set *set, struct nlattr *head, int len,
        return 0;
 }
 
-struct ip_set_type bitmap_port_type = {
+static struct ip_set_type bitmap_port_type = {
        .name           = "bitmap:port",
        .protocol       = IPSET_PROTOCOL,
        .features       = IPSET_TYPE_PORT,
index 3af992fd47851ce007f1c50243055c5669a82330..d17cffec16a09871c8c5bcca500687d29ff3cc7b 100644 (file)
@@ -9,7 +9,6 @@
 
 /* Kernel module for IP set management */
 
-#include "ip_set_kernel.h"
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -26,7 +25,7 @@
 #include <net/genetlink.h>
 #define GENLMSG_DEFAULT_SIZE (NLMSG_DEFAULT_SIZE - GENL_HDRLEN)
 
-static struct list_head ip_set_type_list;      /* all registered set types */
+static LIST_HEAD(ip_set_type_list);            /* all registered set types */
 static DEFINE_MUTEX(ip_set_type_mutex);                /* protects ip_set_type_list */
 
 static struct ip_set **ip_set_list;            /* all individual sets */
@@ -34,7 +33,7 @@ static ip_set_id_t ip_set_max = LCONFIG_IP_SET_MAX; /* max number of sets */
 
 #define STREQ(a, b)    (strncmp(a, b, IPSET_MAXNAMELEN) == 0)
 
-static int max_sets;
+static unsigned int max_sets;
 
 module_param(max_sets, int, 0600);
 MODULE_PARM_DESC(max_sets, "maximal number of sets");
@@ -64,60 +63,77 @@ ip_set_type_unlock(void)
 
 /* Register and deregister settype */
 
-static inline struct ip_set_type *
+static struct ip_set_type *
 find_set_type(const char *name, u8 family, u8 revision)
 {
        struct ip_set_type *type;
 
        list_for_each_entry_rcu(type, &ip_set_type_list, list)
-               if (STREQ(type->name, name)
-                   && (type->family == family || type->family == AF_UNSPEC)
-                   && type->revision == revision)
+               if (STREQ(type->name, name) &&
+                   (type->family == family || type->family == AF_UNSPEC) &&
+                   type->revision == revision)
                        return type;
        return NULL;
 }
 
-/* Find a set type so that rcu_read_lock() is called by the function.
- * If we succeeded, the RCU lock is NOT released and the caller
- * must release it later.
- */
-static struct ip_set_type *
-find_set_type_rcu(const char *name, u8 family, u8 revision)
+/* Unlock, try to load a set type module and lock again */
+static int
+try_to_load_type(const char *name)
 {
-       struct ip_set_type *type;
+       nfnl_unlock();
+       pr_debug("try to load ip_set_%s\n", name);
+       if (request_module("ip_set_%s", name) < 0) {
+               pr_warning("Can't find ip_set type %s\n", name);
+               nfnl_lock();
+               return -IPSET_ERR_FIND_TYPE;
+       }
+       nfnl_lock();
+       return -EAGAIN;
+}
 
+/* Find a set type and reference it */
+static int
+find_set_type_get(const char *name, u8 family, u8 revision,
+                 struct ip_set_type **found)
+{
        rcu_read_lock();
-       type = find_set_type(name, family, revision);
-       if (type == NULL)
+       *found = find_set_type(name, family, revision);
+       if (*found) {
+               int err = !try_module_get((*found)->me);
                rcu_read_unlock();
+               return err ? -EFAULT : 0;
+       }
+       rcu_read_unlock();
 
-       return type;
+       return try_to_load_type(name);
 }
 
 /* Find a given set type by name and family.
  * If we succeeded, the supported minimal and maximum revisions are
  * filled out.
  */
-static bool
+static int
 find_set_type_minmax(const char *name, u8 family, u8 *min, u8 *max)
 {
        struct ip_set_type *type;
-       bool ret = false;
+       bool found = false;
 
        *min = *max = 0;
        rcu_read_lock();
        list_for_each_entry_rcu(type, &ip_set_type_list, list)
-               if (STREQ(type->name, name)
-                   && (type->family == family || type->family == AF_UNSPEC)) {
-                       ret = true;
+               if (STREQ(type->name, name) &&
+                   (type->family == family || type->family == AF_UNSPEC)) {
+                       found = true;
                        if (type->revision < *min)
                                *min = type->revision;
                        else if (type->revision > *max)
                                *max = type->revision;
                }
        rcu_read_unlock();
+       if (found)
+               return 0;
 
-       return ret;
+       return try_to_load_type(name);
 }
 
 #define family_name(f) ((f) == AF_INET ? "inet" : \
@@ -149,7 +165,7 @@ ip_set_type_register(struct ip_set_type *type)
                goto unlock;
        }
        list_add_rcu(&type->list, &ip_set_type_list);
-       pr_debug("type %s, family %s, revision %u registered.",
+       pr_debug("type %s, family %s, revision %u registered.\n",
                 type->name, family_name(type->family), type->revision);
 unlock:
        ip_set_type_unlock();
@@ -169,7 +185,7 @@ ip_set_type_unregister(struct ip_set_type *type)
                goto unlock;
        }
        list_del_rcu(&type->list);
-       pr_debug("type %s, family %s, revision %u unregistered.",
+       pr_debug("type %s, family %s, revision %u unregistered.\n",
                 type->name, family_name(type->family), type->revision);
 unlock:
        ip_set_type_unlock();
@@ -178,6 +194,92 @@ unlock:
 }
 EXPORT_SYMBOL_GPL(ip_set_type_unregister);
 
+/* Utility functions */
+void *
+ip_set_alloc(size_t size, gfp_t gfp_mask)
+{
+       void *members = NULL;
+
+       if (size < KMALLOC_MAX_SIZE)
+               members = kzalloc(size, gfp_mask | __GFP_NOWARN);
+
+       if (members) {
+               pr_debug("%p: allocated with kmalloc\n", members);
+               return members;
+       }
+
+       members = __vmalloc(size, gfp_mask | __GFP_ZERO | __GFP_HIGHMEM,
+                           PAGE_KERNEL);
+       if (!members)
+               return NULL;
+       pr_debug("%p: allocated with vmalloc\n", members);
+
+       return members;
+}
+EXPORT_SYMBOL_GPL(ip_set_alloc);
+
+void
+ip_set_free(void *members)
+{
+       pr_debug("%p: free with %s\n", members,
+                is_vmalloc_addr(members) ? "vfree" : "kfree");
+       if (is_vmalloc_addr(members))
+               vfree(members);
+       else
+               kfree(members);
+}
+EXPORT_SYMBOL_GPL(ip_set_free);
+
+static inline bool
+flag_nested(const struct nlattr *nla)
+{
+       return nla->nla_type & NLA_F_NESTED;
+}
+
+static const struct nla_policy ipaddr_policy[IPSET_ATTR_IPADDR_MAX + 1] = {
+       [IPSET_ATTR_IPADDR_IPV4]        = { .type = NLA_U32 },
+       [IPSET_ATTR_IPADDR_IPV6]        = { .type = NLA_BINARY,
+                                           .len = sizeof(struct in6_addr) },
+};
+
+int
+ip_set_get_ipaddr4(struct nlattr *nla,  __be32 *ipaddr)
+{
+       struct nlattr *tb[IPSET_ATTR_IPADDR_MAX+1];
+
+       if (unlikely(!flag_nested(nla)))
+               return -IPSET_ERR_PROTOCOL;
+       if (nla_parse(tb, IPSET_ATTR_IPADDR_MAX, nla_data(nla), nla_len(nla),
+                     ipaddr_policy))
+               return -IPSET_ERR_PROTOCOL;
+       if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_IPADDR_IPV4)))
+               return -IPSET_ERR_PROTOCOL;
+
+       *ipaddr = nla_get_be32(tb[IPSET_ATTR_IPADDR_IPV4]);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ip_set_get_ipaddr4);
+
+int
+ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr)
+{
+       struct nlattr *tb[IPSET_ATTR_IPADDR_MAX+1];
+
+       if (unlikely(!flag_nested(nla)))
+               return -IPSET_ERR_PROTOCOL;
+
+       if (nla_parse(tb, IPSET_ATTR_IPADDR_MAX, nla_data(nla), nla_len(nla),
+                     ipaddr_policy))
+               return -IPSET_ERR_PROTOCOL;
+       if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_IPADDR_IPV6)))
+               return -IPSET_ERR_PROTOCOL;
+
+       memcpy(ipaddr, nla_data(tb[IPSET_ATTR_IPADDR_IPV6]),
+               sizeof(struct in6_addr));
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ip_set_get_ipaddr6);
+
 /*
  * Creating/destroying/renaming/swapping affect the existence and
  * the properties of a set. All of these can be executed from userspace
@@ -216,10 +318,10 @@ ip_set_test(ip_set_id_t index, const struct sk_buff *skb,
        int ret = 0;
 
        BUG_ON(set == NULL || atomic_read(&set->ref) == 0);
-       pr_debug("set %s, index %u", set->name, index);
+       pr_debug("set %s, index %u\n", set->name, index);
 
-       if (dim < set->type->dimension
-           || !(family == set->family || set->family == AF_UNSPEC))
+       if (dim < set->type->dimension ||
+           !(family == set->family || set->family == AF_UNSPEC))
                return 0;
 
        read_lock_bh(&set->lock);
@@ -228,7 +330,7 @@ ip_set_test(ip_set_id_t index, const struct sk_buff *skb,
 
        if (ret == -EAGAIN) {
                /* Type requests element to be completed */
-               pr_debug("element must be competed, ADD is triggered");
+               pr_debug("element must be competed, ADD is triggered\n");
                write_lock_bh(&set->lock);
                set->variant->kadt(set, skb, IPSET_ADD, family, dim, flags);
                write_unlock_bh(&set->lock);
@@ -248,10 +350,10 @@ ip_set_add(ip_set_id_t index, const struct sk_buff *skb,
        int ret;
 
        BUG_ON(set == NULL || atomic_read(&set->ref) == 0);
-       pr_debug("set %s, index %u", set->name, index);
+       pr_debug("set %s, index %u\n", set->name, index);
 
-       if (dim < set->type->dimension
-           || !(family == set->family || set->family == AF_UNSPEC))
+       if (dim < set->type->dimension ||
+           !(family == set->family || set->family == AF_UNSPEC))
                return 0;
 
        write_lock_bh(&set->lock);
@@ -270,10 +372,10 @@ ip_set_del(ip_set_id_t index, const struct sk_buff *skb,
        int ret = 0;
 
        BUG_ON(set == NULL || atomic_read(&set->ref) == 0);
-       pr_debug("set %s, index %u", set->name, index);
+       pr_debug("set %s, index %u\n", set->name, index);
 
-       if (dim < set->type->dimension
-           || !(family == set->family || set->family == AF_UNSPEC))
+       if (dim < set->type->dimension ||
+           !(family == set->family || set->family == AF_UNSPEC))
                return 0;
 
        write_lock_bh(&set->lock);
@@ -423,8 +525,8 @@ EXPORT_SYMBOL_GPL(ip_set_nfnl_put);
 static inline bool
 protocol_failed(struct nlattr *const *tb)
 {
-       return !tb[IPSET_ATTR_PROTOCOL]
-              || nla_get_u8(tb[IPSET_ATTR_PROTOCOL]) != IPSET_PROTOCOL;
+       return !tb[IPSET_ATTR_PROTOCOL] ||
+              nla_get_u8(tb[IPSET_ATTR_PROTOCOL]) != IPSET_PROTOCOL;
 }
 
 static inline u32
@@ -433,13 +535,7 @@ flag_exist(const struct genlmsghdr *ghdr)
        return ghdr->reserved & NLM_F_EXCL ? 0 : IPSET_FLAG_EXIST;
 }
 
-static inline bool
-flag_nested(const struct nlattr *nla)
-{
-       return nla->nla_type & NLA_F_NESTED;
-}
-
-static void *
+static struct nlmsghdr *
 start_msg(struct sk_buff *skb, u32 pid, u32 seq, unsigned int flags,
          enum ipset_cmd cmd)
 {
@@ -508,13 +604,6 @@ find_free_id(const char *name, ip_set_id_t *index, struct ip_set **set)
        return 0;
 }
 
-static inline void
-load_type_module(const char *typename)
-{
-       pr_debug("try to load ip_set_%s", typename);
-       request_module("ip_set_%s", typename);
-}
-
 static int
 ip_set_create(struct sk_buff *skb, struct genl_info *info)
 {
@@ -527,20 +616,20 @@ ip_set_create(struct sk_buff *skb, struct genl_info *info)
        u32 flags = flag_exist(info->genlhdr);
        int ret = 0, len;
 
-       if (unlikely(protocol_failed(attr)
-                    || attr[IPSET_ATTR_SETNAME] == NULL
-                    || attr[IPSET_ATTR_TYPENAME] == NULL
-                    || attr[IPSET_ATTR_REVISION] == NULL
-                    || attr[IPSET_ATTR_FAMILY] == NULL
-                    || (attr[IPSET_ATTR_DATA] != NULL
-                        && !flag_nested(attr[IPSET_ATTR_DATA]))))
+       if (unlikely(protocol_failed(attr) ||
+                    attr[IPSET_ATTR_SETNAME] == NULL ||
+                    attr[IPSET_ATTR_TYPENAME] == NULL ||
+                    attr[IPSET_ATTR_REVISION] == NULL ||
+                    attr[IPSET_ATTR_FAMILY] == NULL ||
+                    (attr[IPSET_ATTR_DATA] != NULL &&
+                     !flag_nested(attr[IPSET_ATTR_DATA]))))
                return -IPSET_ERR_PROTOCOL;
 
        name = nla_data(attr[IPSET_ATTR_SETNAME]);
        typename = nla_data(attr[IPSET_ATTR_TYPENAME]);
        family = nla_get_u8(attr[IPSET_ATTR_FAMILY]);
        revision = nla_get_u8(attr[IPSET_ATTR_REVISION]);
-       pr_debug("setname: %s, typename: %s, family: %s, revision: %u",
+       pr_debug("setname: %s, typename: %s, family: %s, revision: %u\n",
                 name, typename, family_name(family), revision);
 
        /*
@@ -563,32 +652,15 @@ ip_set_create(struct sk_buff *skb, struct genl_info *info)
         * After referencing the type, we try to create the type
         * specific part of the set without holding any locks.
         */
-       set->type = find_set_type_rcu(typename, family, revision);
-       if (set->type == NULL) {
-               /* Try loading the module */
-               load_type_module(typename);
-               set->type = find_set_type_rcu(typename, family, revision);
-               if (set->type == NULL) {
-                       pr_warning("Can't find ip_set type %s, family %s, "
-                                  "revision %u: set '%s' not created",
-                                  typename, family_name(family), revision,
-                                  name);
-                       ret = -IPSET_ERR_FIND_TYPE;
-                       goto out;
-               }
-       }
-       if (!try_module_get(set->type->me)) {
-               rcu_read_unlock();
-               ret = -EFAULT;
+       ret = find_set_type_get(typename, family, revision, &(set->type));
+       if (ret)
                goto out;
-       }
-       rcu_read_unlock();
 
        /*
         * Without holding any locks, create private part.
         */
        len = attr[IPSET_ATTR_DATA] ? nla_len(attr[IPSET_ATTR_DATA]) : 0;
-       pr_debug("data len: %u", len);
+       pr_debug("data len: %u\n", len);
        ret = set->type->create(set, attr[IPSET_ATTR_DATA] ?
                                nla_data(attr[IPSET_ATTR_DATA]) : NULL, len,
                                flags);
@@ -604,12 +676,12 @@ ip_set_create(struct sk_buff *skb, struct genl_info *info)
         */
        if ((ret = find_free_id(set->name, &index, &clash)) != 0) {
                /* If this is the same set and requested, ignore error */
-               if (ret == -EEXIST
-                   && (flags & IPSET_FLAG_EXIST)
-                   && STREQ(set->type->name, clash->type->name)
-                   && set->type->family == clash->type->family
-                   && set->type->revision == clash->type->revision
-                   && set->variant->same_set(set, clash))
+               if (ret == -EEXIST &&
+                   (flags & IPSET_FLAG_EXIST) &&
+                   STREQ(set->type->name, clash->type->name) &&
+                   set->type->family == clash->type->family &&
+                   set->type->revision == clash->type->revision &&
+                   set->variant->same_set(set, clash))
                        ret = 0;
                goto cleanup;
        }
@@ -617,7 +689,7 @@ ip_set_create(struct sk_buff *skb, struct genl_info *info)
        /*
         * Finally! Add our shiny new set to the list, and be done.
         */
-       pr_debug("create: '%s' created with index %u!", set->name, index);
+       pr_debug("create: '%s' created with index %u!\n", set->name, index);
        ip_set_list[index] = set;
 
        return ret;
@@ -640,12 +712,12 @@ ip_set_setname_policy[IPSET_ATTR_CMD_MAX + 1] = {
                                    .len = IPSET_MAXNAMELEN - 1 },
 };
 
-static inline void
+static void
 ip_set_destroy_set(ip_set_id_t index)
 {
        struct ip_set *set = ip_set_list[index];
 
-       pr_debug("set: %s",  set->name);
+       pr_debug("set: %s\n",  set->name);
        ip_set_list[index] = NULL;
 
        /* Must call it without holding any lock */
@@ -666,8 +738,8 @@ ip_set_destroy(struct sk_buff *skb, struct genl_info *info)
        /* References are protected by the nfnl mutex */
        if (!attr[IPSET_ATTR_SETNAME]) {
                for (i = 0; i < ip_set_max; i++) {
-                       if (ip_set_list[i] != NULL
-                           && (atomic_read(&ip_set_list[i]->ref)))
+                       if (ip_set_list[i] != NULL &&
+                           (atomic_read(&ip_set_list[i]->ref)))
                                return -IPSET_ERR_BUSY;
                }
                for (i = 0; i < ip_set_max; i++) {
@@ -688,10 +760,10 @@ ip_set_destroy(struct sk_buff *skb, struct genl_info *info)
 
 /* Flush sets */
 
-static inline void
+static void
 ip_set_flush_set(struct ip_set *set)
 {
-       pr_debug("set: %s",  set->name);
+       pr_debug("set: %s\n",  set->name);
 
        write_lock_bh(&set->lock);
        set->variant->flush(set);
@@ -741,9 +813,9 @@ ip_set_rename(struct sk_buff *skb, struct genl_info *info)
        const char *name2;
        ip_set_id_t i;
 
-       if (unlikely(protocol_failed(attr)
-                    || attr[IPSET_ATTR_SETNAME] == NULL
-                    || attr[IPSET_ATTR_SETNAME2] == NULL))
+       if (unlikely(protocol_failed(attr) ||
+                    attr[IPSET_ATTR_SETNAME] == NULL ||
+                    attr[IPSET_ATTR_SETNAME2] == NULL))
                return -IPSET_ERR_PROTOCOL;
 
        set = find_set(nla_data(attr[IPSET_ATTR_SETNAME]));
@@ -754,8 +826,8 @@ ip_set_rename(struct sk_buff *skb, struct genl_info *info)
 
        name2 = nla_data(attr[IPSET_ATTR_SETNAME2]);
        for (i = 0; i < ip_set_max; i++) {
-               if (ip_set_list[i] != NULL
-                   && STREQ(ip_set_list[i]->name, name2))
+               if (ip_set_list[i] != NULL &&
+                   STREQ(ip_set_list[i]->name, name2))
                        return -IPSET_ERR_EXIST_SETNAME2;
        }
        strncpy(set->name, name2, IPSET_MAXNAMELEN);
@@ -781,9 +853,9 @@ ip_set_swap(struct sk_buff *skb, struct genl_info *info)
        char from_name[IPSET_MAXNAMELEN];
        u32 from_ref;
 
-       if (unlikely(protocol_failed(attr)
-                    || attr[IPSET_ATTR_SETNAME] == NULL
-                    || attr[IPSET_ATTR_SETNAME2] == NULL))
+       if (unlikely(protocol_failed(attr) ||
+                    attr[IPSET_ATTR_SETNAME] == NULL ||
+                    attr[IPSET_ATTR_SETNAME2] == NULL))
                return -IPSET_ERR_PROTOCOL;
 
        from_id = find_set_id(nla_data(attr[IPSET_ATTR_SETNAME]));
@@ -800,8 +872,8 @@ ip_set_swap(struct sk_buff *skb, struct genl_info *info)
        /* Features must not change.
         * Not an artifical restriction anymore, as we must prevent
         * possible loops created by swapping in setlist type of sets. */
-       if (!(from->type->features == to->type->features
-             && from->type->family == to->type->family))
+       if (!(from->type->features == to->type->features &&
+             from->type->family == to->type->family))
                return -IPSET_ERR_TYPE_MISMATCH;
 
        /* No magic here: ref munging protected by the nfnl_lock */
@@ -830,7 +902,7 @@ static int
 ip_set_dump_done(struct netlink_callback *cb)
 {
        if (cb->args[2]) {
-               pr_debug("release set %s", ip_set_list[cb->args[1]]->name);
+               pr_debug("release set %s\n", ip_set_list[cb->args[1]]->name);
                __ip_set_put((ip_set_id_t) cb->args[1]);
        }
        return 0;
@@ -843,14 +915,13 @@ dump_attrs(void *phdr)
        const struct nlmsghdr *nlh = phdr - GENL_HDRLEN - NLMSG_HDRLEN;
        int rem;
 
-       pr_debug("nlmsg_len: %u", nlh->nlmsg_len);
-       pr_debug("dump nlmsg");
+       pr_debug("dump nlmsg\n");
        nlmsg_for_each_attr(attr, nlh, sizeof(struct genlmsghdr), rem) {
-               pr_debug("type: %u, len %u", nla_type(attr), attr->nla_len);
+               pr_debug("type: %u, len %u\n", nla_type(attr), attr->nla_len);
        }
 }
 
-static inline int
+static int
 dump_init(struct netlink_callback *cb)
 {
        struct nlmsghdr *nlh = nlmsg_hdr(cb->skb);
@@ -919,14 +990,14 @@ ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb)
                /* When dumping all sets, we must dump "sorted"
                 * so that lists (unions of sets) are dumped last.
                 */
-               if (cb->args[0] != DUMP_ONE
-                   && !((cb->args[0] == DUMP_ALL)
-                        ^ (set->type->features & IPSET_DUMP_LAST)))
+               if (cb->args[0] != DUMP_ONE &&
+                   !((cb->args[0] == DUMP_ALL) ^
+                     (set->type->features & IPSET_DUMP_LAST)))
                        continue;
-               pr_debug("List set: %s", set->name);
+               pr_debug("List set: %s\n", set->name);
                if (!cb->args[2]) {
                        /* Start listing: make sure set won't be destroyed */
-                       pr_debug("reference set");
+                       pr_debug("reference set\n");
                        __ip_set_get(index);
                }
                nlh = start_msg(skb, NETLINK_CB(cb->skb).pid,
@@ -972,7 +1043,7 @@ nla_put_failure:
 release_refcount:
        /* If there was an error or set is done, release set */
        if (ret || !cb->args[2]) {
-               pr_debug("release set %s", ip_set_list[index]->name);
+               pr_debug("release set %s\n", ip_set_list[index]->name);
                __ip_set_put(index);
        }
 
@@ -983,6 +1054,7 @@ release_refcount:
 out:
        if (nlh) {
                genlmsg_end(skb, nlh);
+               pr_debug("nlmsg_len: %u\n", skb->len);
                dump_attrs(nlh);
        }
 
@@ -1034,9 +1106,9 @@ call_ad(struct sk_buff *skb, struct nlattr *const attr[],
                ret = set->variant->uadt(set, head, len, adt,
                                         &lineno, flags);
                write_unlock_bh(&set->lock);
-       } while (ret == -EAGAIN
-                && set->variant->resize
-                && (ret = set->variant->resize(set, retried++)) == 0);
+       } while (ret == -EAGAIN &&
+                set->variant->resize &&
+                (ret = set->variant->resize(set, retried++)) == 0);
 
        if (!ret || (ret == -IPSET_ERR_EXIST && eexist))
                return 0;
@@ -1060,15 +1132,15 @@ ip_set_uadd(struct sk_buff *skb, struct genl_info *info)
        u32 flags = flag_exist(info->genlhdr);
        int ret = 0;
 
-       if (unlikely(protocol_failed(attr)
-                    || attr[IPSET_ATTR_SETNAME] == NULL
-                    || !((attr[IPSET_ATTR_DATA] != NULL)
-                         ^ (attr[IPSET_ATTR_ADT] != NULL))
-                    || (attr[IPSET_ATTR_DATA] != NULL
-                        && !flag_nested(attr[IPSET_ATTR_DATA]))
-                    || (attr[IPSET_ATTR_ADT] != NULL
-                        && (!flag_nested(attr[IPSET_ATTR_ADT])
-                            || attr[IPSET_ATTR_LINENO] == NULL))))
+       if (unlikely(protocol_failed(attr) ||
+                    attr[IPSET_ATTR_SETNAME] == NULL ||
+                    !((attr[IPSET_ATTR_DATA] != NULL) ^
+                      (attr[IPSET_ATTR_ADT] != NULL)) ||
+                    (attr[IPSET_ATTR_DATA] != NULL &&
+                     !flag_nested(attr[IPSET_ATTR_DATA])) ||
+                    (attr[IPSET_ATTR_ADT] != NULL &&
+                     (!flag_nested(attr[IPSET_ATTR_ADT]) ||
+                      attr[IPSET_ATTR_LINENO] == NULL))))
                return -IPSET_ERR_PROTOCOL;
 
        set = find_set(nla_data(attr[IPSET_ATTR_SETNAME]));
@@ -1082,8 +1154,8 @@ ip_set_uadd(struct sk_buff *skb, struct genl_info *info)
                int nla_rem;
 
                nla_for_each_nested(nla, attr[IPSET_ATTR_ADT], nla_rem) {
-                       if (nla_type(nla) != IPSET_ATTR_DATA
-                           || !flag_nested(nla))
+                       if (nla_type(nla) != IPSET_ATTR_DATA ||
+                           !flag_nested(nla))
                                return -IPSET_ERR_PROTOCOL;
                        ret = call_ad(skb, attr,
                                       set, nla, IPSET_ADD, flags);
@@ -1104,15 +1176,15 @@ ip_set_udel(struct sk_buff *skb, struct genl_info *info)
        u32 flags = flag_exist(info->genlhdr);
        int ret = 0;
 
-       if (unlikely(protocol_failed(attr)
-                    || attr[IPSET_ATTR_SETNAME] == NULL
-                    || !((attr[IPSET_ATTR_DATA] != NULL)
-                         ^ (attr[IPSET_ATTR_ADT] != NULL))
-                    || (attr[IPSET_ATTR_DATA] != NULL
-                        && !flag_nested(attr[IPSET_ATTR_DATA]))
-                    || (attr[IPSET_ATTR_ADT] != NULL
-                        && (!flag_nested(attr[IPSET_ATTR_ADT])
-                           || attr[IPSET_ATTR_LINENO] == NULL))))
+       if (unlikely(protocol_failed(attr) ||
+                    attr[IPSET_ATTR_SETNAME] == NULL ||
+                    !((attr[IPSET_ATTR_DATA] != NULL) ^
+                      (attr[IPSET_ATTR_ADT] != NULL)) ||
+                    (attr[IPSET_ATTR_DATA] != NULL &&
+                     !flag_nested(attr[IPSET_ATTR_DATA])) ||
+                    (attr[IPSET_ATTR_ADT] != NULL &&
+                     (!flag_nested(attr[IPSET_ATTR_ADT]) ||
+                      attr[IPSET_ATTR_LINENO] == NULL))))
                return -IPSET_ERR_PROTOCOL;
 
        set = find_set(nla_data(attr[IPSET_ATTR_SETNAME]));
@@ -1126,8 +1198,8 @@ ip_set_udel(struct sk_buff *skb, struct genl_info *info)
                int nla_rem;
 
                nla_for_each_nested(nla, attr[IPSET_ATTR_ADT], nla_rem) {
-                       if (nla_type(nla) != IPSET_ATTR_DATA
-                           || !flag_nested(nla))
+                       if (nla_type(nla) != IPSET_ATTR_DATA ||
+                           !flag_nested(nla))
                                return -IPSET_ERR_PROTOCOL;
                        ret = call_ad(skb, attr,
                                       set, nla, IPSET_DEL, flags);
@@ -1146,10 +1218,10 @@ ip_set_utest(struct sk_buff *skb, struct genl_info *info)
        struct ip_set *set;
        int ret = 0;
 
-       if (unlikely(protocol_failed(attr)
-                    || attr[IPSET_ATTR_SETNAME] == NULL
-                    || attr[IPSET_ATTR_DATA] == NULL
-                    || !flag_nested(attr[IPSET_ATTR_DATA])))
+       if (unlikely(protocol_failed(attr) ||
+                    attr[IPSET_ATTR_SETNAME] == NULL ||
+                    attr[IPSET_ATTR_DATA] == NULL ||
+                    !flag_nested(attr[IPSET_ATTR_DATA])))
                return -IPSET_ERR_PROTOCOL;
 
        set = find_set(nla_data(attr[IPSET_ATTR_SETNAME]));
@@ -1182,8 +1254,8 @@ ip_set_header(struct sk_buff *skb, struct genl_info *info)
        ip_set_id_t index;
        int ret = 0;
 
-       if (unlikely(protocol_failed(attr)
-                    || attr[IPSET_ATTR_SETNAME] == NULL))
+       if (unlikely(protocol_failed(attr) ||
+                    attr[IPSET_ATTR_SETNAME] == NULL))
                return -IPSET_ERR_PROTOCOL;
 
        index = find_set_id(nla_data(attr[IPSET_ATTR_SETNAME]));
@@ -1240,22 +1312,16 @@ ip_set_type(struct sk_buff *skb, struct genl_info *info)
        const char *typename;
        int ret = 0;
 
-       if (unlikely(protocol_failed(attr)
-                    || attr[IPSET_ATTR_TYPENAME] == NULL
-                    || attr[IPSET_ATTR_FAMILY] == NULL))
+       if (unlikely(protocol_failed(attr) ||
+                    attr[IPSET_ATTR_TYPENAME] == NULL ||
+                    attr[IPSET_ATTR_FAMILY] == NULL))
                return -IPSET_ERR_PROTOCOL;
 
        family = nla_get_u8(attr[IPSET_ATTR_FAMILY]);
        typename = nla_data(attr[IPSET_ATTR_TYPENAME]);
-       if (!find_set_type_minmax(typename, family, &min, &max)) {
-               /* Try to load in the type module */
-               load_type_module(typename);
-               if (!find_set_type_minmax(typename, family, &min, &max)) {
-                       pr_debug("can't find: %s, family: %u",
-                                typename, family);
-                       return -EEXIST;
-               }
-       }
+       ret = find_set_type_minmax(typename, family, &min, &max);
+       if (ret)
+               return ret;
 
        skb2 = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (skb2 == NULL)
@@ -1272,6 +1338,7 @@ ip_set_type(struct sk_buff *skb, struct genl_info *info)
        NLA_PUT_U8(skb2, IPSET_ATTR_REVISION_MIN, min);
        genlmsg_end(skb2, nlh2);
 
+       pr_debug("Send TYPE, nlmsg_len: %u\n", skb2->len);
        ret = genlmsg_unicast(genl_info_net(info), skb2, NETLINK_CB(skb).pid);
        if (ret < 0)
                return -EFAULT;
@@ -1421,7 +1488,7 @@ static struct genl_family ip_set_netlink_subsys __read_mostly = {
 /* Interface to iptables/ip6tables */
 
 static int
-ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
+ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len)
 {
        unsigned *op;
        void *data;
@@ -1482,8 +1549,8 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
        case IP_SET_OP_GET_BYINDEX: {
                struct ip_set_req_get_set *req_get = data;
 
-               if (*len != sizeof(struct ip_set_req_get_set)
-                   || req_get->set.index >= ip_set_max) {
+               if (*len != sizeof(struct ip_set_req_get_set) ||
+                   req_get->set.index >= ip_set_max) {
                        ret = -EINVAL;
                        goto done;
                }
@@ -1531,12 +1598,10 @@ ip_set_init(void)
        ip_set_list = kzalloc(sizeof(struct ip_set *) * ip_set_max,
                              GFP_KERNEL);
        if (!ip_set_list) {
-               pr_err("ip_set: Unable to create ip_set_list");
+               pr_err("ip_set: Unable to create ip_set_list\n");
                return -ENOMEM;
        }
 
-       INIT_LIST_HEAD(&ip_set_type_list);
-
        ret = genl_register_family_with_ops(&ip_set_netlink_subsys,
              ip_set_netlink_subsys_cb, ARRAY_SIZE(ip_set_netlink_subsys_cb));
        if (ret != 0) {
@@ -1546,13 +1611,13 @@ ip_set_init(void)
        }
        ret = nf_register_sockopt(&so_set);
        if (ret != 0) {
-               pr_err("SO_SET registry failed: %d", ret);
+               pr_err("SO_SET registry failed: %d\n", ret);
                genl_unregister_family(&ip_set_netlink_subsys);
                kfree(ip_set_list);
                return ret;
        }
 
-       pr_notice("ip_set: protocol %u", IPSET_PROTOCOL);
+       pr_notice("ip_set: protocol %u\n", IPSET_PROTOCOL);
        return 0;
 }
 
@@ -1563,7 +1628,7 @@ ip_set_fini(void)
        nf_unregister_sockopt(&so_set);
        genl_unregister_family(&ip_set_netlink_subsys);
        kfree(ip_set_list);
-       pr_debug("these are the famous last words");
+       pr_debug("these are the famous last words\n");
 }
 
 module_init(ip_set_init);
diff --git a/extensions/ipset-5/ip_set_getport.c b/extensions/ipset-5/ip_set_getport.c
new file mode 100644 (file)
index 0000000..d6cf5d2
--- /dev/null
@@ -0,0 +1,136 @@
+/* Copyright (C) 2003-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.
+ */
+
+/* Get Layer-4 data from the packets */
+
+#include <linux/ip.h>
+#include <linux/skbuff.h>
+#include <linux/icmp.h>
+#include <linux/icmpv6.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <net/ip.h>
+
+#include "ip_set_getport.h"
+
+/* We must handle non-linear skbs */
+static bool
+get_port(const struct sk_buff *skb, int protocol, unsigned int protooff,
+        bool src, __be16 *port, u8 *proto)
+{
+       switch (protocol) {
+       case IPPROTO_TCP: {
+               struct tcphdr _tcph;
+               const struct tcphdr *th;
+
+               th = skb_header_pointer(skb, protooff, sizeof(_tcph), &_tcph);
+               if (th == NULL)
+                       /* No choice either */
+                       return false;
+
+               *port = src ? th->source : th->dest;
+               break;
+       }
+       case IPPROTO_UDP: {
+               struct udphdr _udph;
+               const struct udphdr *uh;
+
+               uh = skb_header_pointer(skb, protooff, sizeof(_udph), &_udph);
+               if (uh == NULL)
+                       /* No choice either */
+                       return false;
+
+               *port = src ? uh->source : uh->dest;
+               break;
+       }
+       case IPPROTO_ICMP: {
+               struct icmphdr _ich;
+               const struct icmphdr *ic;
+
+               ic = skb_header_pointer(skb, protooff, sizeof(_ich), &_ich);
+               if (ic == NULL)
+                       return false;
+
+               *port = (__force __be16)htons((ic->type << 8) | ic->code);
+               break;
+       }
+       case IPPROTO_ICMPV6: {
+               struct icmp6hdr _ich;
+               const struct icmp6hdr *ic;
+
+               ic = skb_header_pointer(skb, protooff, sizeof(_ich), &_ich);
+               if (ic == NULL)
+                       return false;
+
+               *port = (__force __be16)
+                       htons((ic->icmp6_type << 8) | ic->icmp6_code);
+               break;
+       }
+       default:
+               break;
+       }
+       *proto = protocol;
+
+       return true;
+}
+
+bool
+ip_set_get_ip4_port(const struct sk_buff *skb, bool src,
+                   __be16 *port, u8 *proto)
+{
+       const struct iphdr *iph = ip_hdr(skb);
+       unsigned int protooff = ip_hdrlen(skb);
+       int protocol = iph->protocol;
+
+       /* See comments at tcp_match in ip_tables.c */
+       if (protocol <= 0 || (ntohs(iph->frag_off) & IP_OFFSET))
+               return false;
+
+       return get_port(skb, protocol, protooff, src, port, proto);
+}
+EXPORT_SYMBOL_GPL(ip_set_get_ip4_port);
+
+bool
+ip_set_get_ip6_port(const struct sk_buff *skb, bool src,
+                   __be16 *port, u8 *proto)
+{
+       unsigned int protooff = 0;
+       int protocol;
+       unsigned short fragoff;
+
+       protocol = ipv6_find_hdr(skb, &protooff, -1, &fragoff);
+       if (protocol <= 0 || fragoff)
+               return false;
+
+       return get_port(skb, protocol, protooff, src, port, proto);
+}
+EXPORT_SYMBOL_GPL(ip_set_get_ip6_port);
+
+bool
+ip_set_get_ip_port(const struct sk_buff *skb, u8 pf, bool src, __be16 *port)
+{
+       bool ret;
+       u8 proto;
+
+       switch (pf) {
+       case AF_INET:
+               ret = ip_set_get_ip4_port(skb, src, port, &proto);
+       case AF_INET6:
+               ret = ip_set_get_ip6_port(skb, src, port, &proto);
+       default:
+               return false;
+       }
+       if (!ret)
+               return ret;
+       switch (proto) {
+       case IPPROTO_TCP:
+       case IPPROTO_UDP:
+               return true;
+       default:
+               return false;
+       }
+}
+EXPORT_SYMBOL_GPL(ip_set_get_ip_port);
index 8be8ecfdebe4a3cb147bfa28139511ef7a016fd6..694c433298b8b261585912b7551fa2a74df7aea5 100644 (file)
 #ifndef _IP_SET_GETPORT_H
 #define _IP_SET_GETPORT_H
 
-#ifdef __KERNEL__
-#include <linux/icmp.h>
-#include <linux/icmpv6.h>
-#include <linux/netfilter_ipv6/ip6_tables.h>
-#include <net/ip.h>
-
-#define IPSET_INVALID_PORT     65536
-
-/* We must handle non-linear skbs */
-static inline bool
-get_port(const struct sk_buff *skb, int protocol, unsigned int protooff,
-        bool src, u16 *port, u8 *proto)
-{
-       switch (protocol) {
-       case IPPROTO_TCP: {
-               struct tcphdr _tcph;
-               const struct tcphdr *th;
-
-               th = skb_header_pointer(skb, protooff, sizeof(_tcph), &_tcph);
-               if (th == NULL)
-                       /* No choice either */
-                       return false;
-
-               *port = src ? th->source : th->dest;
-               break;
-       }
-       case IPPROTO_UDP: {
-               struct udphdr _udph;
-               const struct udphdr *uh;
-
-               uh = skb_header_pointer(skb, protooff, sizeof(_udph), &_udph);
-               if (uh == NULL)
-                       /* No choice either */
-                       return false;
-
-               *port = src ? uh->source : uh->dest;
-               break;
-       }
-       case IPPROTO_ICMP: {
-               struct icmphdr _icmph;
-               const struct icmphdr *ic;
-
-               ic = skb_header_pointer(skb, protooff, sizeof(_icmph), &_icmph);
-               if (ic == NULL)
-                       return false;
-
-               *port = (ic->type << 8) & ic->code;
-               break;
-       }
-       case IPPROTO_ICMPV6: {
-               struct icmp6hdr _icmph;
-               const struct icmp6hdr *ic;
-
-               ic = skb_header_pointer(skb, protooff, sizeof(_icmph), &_icmph);
-               if (ic == NULL)
-                       return false;
-
-               *port = (ic->icmp6_type << 8) & ic->icmp6_code;
-               break;
-       }
-       default:
-               break;
-       }
-       *proto = protocol;
-
-       return true;
-}
-
-static inline bool
-get_ip4_port(const struct sk_buff *skb, bool src, u16 *port, u8 *proto)
-{
-       const struct iphdr *iph = ip_hdr(skb);
-       unsigned int protooff = ip_hdrlen(skb);
-       int protocol = iph->protocol;
-
-       /* See comments at tcp_match in ip_tables.c */
-       if (protocol <= 0 || (ntohs(iph->frag_off) & IP_OFFSET))
-               return false;
-
-       return get_port(skb, protocol, protooff, src, port, proto);
-}
-
-static inline bool
-get_ip6_port(const struct sk_buff *skb, bool src, u16 *port, u8 *proto)
-{
-       unsigned int protooff = 0;
-       int protocol;
-       unsigned short fragoff;
-
-       protocol = ipv6_find_hdr(skb, &protooff, -1, &fragoff);
-       if (protocol <= 0 || fragoff)
-               return false;
-
-       return get_port(skb, protocol, protooff, src, port, proto);
-}
-
-static inline bool
-get_ip_port(const struct sk_buff *skb, u8 pf, bool src, u16 *port)
-{
-       bool ret;
-       u8 proto;
-
-       switch (pf) {
-       case AF_INET:
-               ret = get_ip4_port(skb, src, port, &proto);
-       case AF_INET6:
-               ret = get_ip6_port(skb, src, port, &proto);
-       default:
-               return false;
-       }
-       if (!ret)
-               return ret;
-       switch (proto) {
-       case IPPROTO_TCP:
-       case IPPROTO_UDP:
-               return true;
-       default:
-               return false;
-       }
-}
-#endif /* __KERNEL__ */
+extern bool ip_set_get_ip4_port(const struct sk_buff *skb, bool src,
+                               __be16 *port, u8 *proto);
+extern bool ip_set_get_ip6_port(const struct sk_buff *skb, bool src,
+                               __be16 *port, u8 *proto);
+extern bool ip_set_get_ip_port(const struct sk_buff *skb, u8 pf, bool src,
+                               __be16 *port);
 
 #endif /*_IP_SET_GETPORT_H*/
index 5e12105c99bfacfd854dfb636ccc9744fc24bb59..3eaa9109e12c41127fce52064aabb9b0a8b4dd49 100644 (file)
@@ -7,7 +7,6 @@
 
 /* Kernel module implementing an IP set type: the hash:ip type */
 
-#include "ip_set_kernel.h"
 #include "jhash.h"
 #include <linux/module.h>
 #include <linux/ip.h>
@@ -46,12 +45,12 @@ hash_ip_same_set(const struct ip_set *a, const struct ip_set *b);
 
 /* Member elements without timeout */
 struct hash_ip4_elem {
-       u32 ip;
+       __be32 ip;
 };
 
 /* Member elements with timeout support */
 struct hash_ip4_telem {
-       u32 ip;
+       __be32 ip;
        unsigned long timeout;
 };
 
@@ -74,12 +73,6 @@ hash_ip4_data_copy(struct hash_ip4_elem *dst, const struct hash_ip4_elem *src)
        dst->ip = src->ip;
 }
 
-static inline void
-hash_ip4_data_swap(struct hash_ip4_elem *dst, struct hash_ip4_elem *src)
-{
-       swap(dst->ip, src->ip);
-}
-
 /* Zero valued IP addresses cannot be stored */
 static inline void
 hash_ip4_data_zero_out(struct hash_ip4_elem *elem)
@@ -97,7 +90,7 @@ nla_put_failure:
        return 1;
 }
 
-static inline bool
+static bool
 hash_ip4_data_tlist(struct sk_buff *skb, const struct hash_ip4_elem *data)
 {
        const struct hash_ip4_telem *tdata =
@@ -124,10 +117,10 @@ hash_ip4_kadt(struct ip_set *set, const struct sk_buff *skb,
 {
        const struct ip_set_hash *h = set->data;
        ipset_adtfn adtfn = set->variant->adt[adt];
-       u32 ip;
+       __be32 ip;
 
        ip4addrptr(skb, flags & IPSET_DIM_ONE_SRC, &ip);
-       ip &= NETMASK(h->netmask);
+       ip &= ip_set_netmask(h->netmask);
        if (ip == 0)
                return -EINVAL;
 
@@ -149,23 +142,26 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *head, int len,
        const struct ip_set_hash *h = set->data;
        struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
        ipset_adtfn adtfn = set->variant->adt[adt];
-       u32 ip, nip, ip_to, hosts, timeout = h->timeout;
+       u32 ip, ip_to, hosts, timeout = h->timeout;
+       __be32 nip;
        int ret = 0;
 
        if (nla_parse(tb, IPSET_ATTR_ADT_MAX, head, len,
                      hash_ip4_adt_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!tb[IPSET_ATTR_IP] ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               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, &ip);
+       ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip);
        if (ret)
                return ret;
 
-       ip &= NETMASK(h->netmask);
-       if (ip == 0)
-               return -IPSET_ERR_HASH_ELEM;
+       ip &= ip_set_hostmask(h->netmask);
 
        if (tb[IPSET_ATTR_TIMEOUT]) {
                if (!with_timeout(h->timeout))
@@ -173,15 +169,17 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *head, int len,
                timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
        }
 
-       if (adt == IPSET_TEST)
-               return adtfn(set, &ip, timeout);
+       if (adt == IPSET_TEST) {
+               nip = htonl(ip);
+               if (nip == 0)
+                       return -IPSET_ERR_HASH_ELEM;
+               return adtfn(set, &nip, timeout);
+       }
 
-       ip = ntohl(ip);
        if (tb[IPSET_ATTR_IP_TO]) {
-               ret = ip_set_get_ipaddr4(tb, IPSET_ATTR_IP_TO, &ip_to);
+               ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
                if (ret)
                        return ret;
-               ip_to = ntohl(ip_to);
                if (ip > ip_to)
                        swap(ip, ip_to);
        } else if (tb[IPSET_ATTR_CIDR]) {
@@ -189,8 +187,8 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *head, int len,
 
                if (cidr > 32)
                        return -IPSET_ERR_INVALID_CIDR;
-               ip &= HOSTMASK(cidr);
-               ip_to = ip | ~HOSTMASK(cidr);
+               ip &= ip_set_hostmask(cidr);
+               ip_to = ip | ~ip_set_hostmask(cidr);
        } else
                ip_to = ip;
 
@@ -198,6 +196,8 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *head, int len,
 
        for (; !before(ip_to, ip); ip += hosts) {
                nip = htonl(ip);
+               if (nip == 0)
+                       return -IPSET_ERR_HASH_ELEM;
                ret = adtfn(set, &nip, timeout);
 
                if (ret && !ip_set_eexist(ret, flags))
@@ -215,9 +215,9 @@ hash_ip_same_set(const struct ip_set *a, const struct ip_set *b)
        const struct ip_set_hash *y = b->data;
 
        /* Resizing changes htable_bits, so we ignore it */
-       return x->maxelem == y->maxelem
-              && x->timeout == y->timeout
-              && x->netmask == y->netmask;
+       return x->maxelem == y->maxelem &&
+              x->timeout == y->timeout &&
+              x->netmask == y->netmask;
 }
 
 /* The type variant functions: IPv6 */
@@ -250,16 +250,6 @@ hash_ip6_data_copy(struct hash_ip6_elem *dst, const struct hash_ip6_elem *src)
        ipv6_addr_copy(&dst->ip.in6, &src->ip.in6);
 }
 
-static inline void
-hash_ip6_data_swap(struct hash_ip6_elem *dst, struct hash_ip6_elem *src)
-{
-       struct in6_addr tmp;
-
-       ipv6_addr_copy(&tmp, &dst->ip.in6);
-       ipv6_addr_copy(&dst->ip.in6, &src->ip.in6);
-       ipv6_addr_copy(&src->ip.in6, &tmp);
-}
-
 static inline void
 hash_ip6_data_zero_out(struct hash_ip6_elem *elem)
 {
@@ -269,13 +259,13 @@ hash_ip6_data_zero_out(struct hash_ip6_elem *elem)
 static inline void
 ip6_netmask(union nf_inet_addr *ip, u8 prefix)
 {
-       ip->ip6[0] &= NETMASK6(prefix)[0];
-       ip->ip6[1] &= NETMASK6(prefix)[1];
-       ip->ip6[2] &= NETMASK6(prefix)[2];
-       ip->ip6[3] &= NETMASK6(prefix)[3];
+       ip->ip6[0] &= ip_set_netmask6(prefix)[0];
+       ip->ip6[1] &= ip_set_netmask6(prefix)[1];
+       ip->ip6[2] &= ip_set_netmask6(prefix)[2];
+       ip->ip6[3] &= ip_set_netmask6(prefix)[3];
 }
 
-static inline bool
+static bool
 hash_ip6_data_list(struct sk_buff *skb, const struct hash_ip6_elem *data)
 {
        NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &data->ip);
@@ -285,7 +275,7 @@ nla_put_failure:
        return 1;
 }
 
-static inline bool
+static bool
 hash_ip6_data_tlist(struct sk_buff *skb, const struct hash_ip6_elem *data)
 {
        const struct hash_ip6_telem *e =
@@ -344,10 +334,14 @@ hash_ip6_uadt(struct ip_set *set, struct nlattr *head, int len,
                      hash_ip6_adt_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!tb[IPSET_ATTR_IP] ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               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, &ip);
+       ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &ip);
        if (ret)
                return ret;
 
@@ -389,13 +383,18 @@ hash_ip_create(struct ip_set *set, struct nlattr *head, int len, u32 flags)
        if (!(set->family == AF_INET || set->family == AF_INET6))
                return -IPSET_ERR_INVALID_FAMILY;
        netmask = set->family == AF_INET ? 32 : 128;
-       pr_debug("Create set %s with family %s",
+       pr_debug("Create set %s with family %s\n",
                 set->name, set->family == AF_INET ? "inet" : "inet6");
 
        if (nla_parse(tb, IPSET_ATTR_CREATE_MAX, head, len,
                      hash_ip_create_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               return -IPSET_ERR_PROTOCOL;
+
        if (tb[IPSET_ATTR_HASHSIZE]) {
                hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
                if (hashsize < IPSET_MIMINAL_HASHSIZE)
@@ -408,9 +407,9 @@ hash_ip_create(struct ip_set *set, struct nlattr *head, int len, u32 flags)
        if (tb[IPSET_ATTR_NETMASK]) {
                netmask = nla_get_u8(tb[IPSET_ATTR_NETMASK]);
 
-               if ((set->family == AF_INET && netmask > 32)
-                   || (set->family == AF_INET6 && netmask > 128)
-                   || netmask == 0)
+               if ((set->family == AF_INET && netmask > 32) ||
+                   (set->family == AF_INET6 && netmask > 128) ||
+                   netmask == 0)
                        return -IPSET_ERR_INVALID_NETMASK;
        }
 
@@ -451,7 +450,7 @@ hash_ip_create(struct ip_set *set, struct nlattr *head, int len, u32 flags)
                        ? &hash_ip4_variant : &hash_ip6_variant;
        }
 
-       pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)",
+       pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
                 set->name, jhash_size(h->table->htable_bits),
                 h->table->htable_bits, h->maxelem, set->data, h->table);
 
index e92f6c5eb719bd82f4cf4b8e9bd726c9a9623e0f..0ffc9fb0251e507b3e4f1cfdd1b9ec06353a3651 100644 (file)
@@ -7,7 +7,6 @@
 
 /* Kernel module implementing an IP set type: the hash:ip,port type */
 
-#include "ip_set_kernel.h"
 #include "jhash.h"
 #include <linux/module.h>
 #include <linux/ip.h>
@@ -47,16 +46,16 @@ hash_ipport_same_set(const struct ip_set *a, const struct ip_set *b);
 
 /* Member elements without timeout */
 struct hash_ipport4_elem {
-       u32 ip;
-       u16 port;
+       __be32 ip;
+       __be16 port;
        u8 proto;
        u8 padding;
 };
 
 /* Member elements with timeout support */
 struct hash_ipport4_telem {
-       u32 ip;
-       u16 port;
+       __be32 ip;
+       __be16 port;
        u8 proto;
        u8 padding;
        unsigned long timeout;
@@ -66,9 +65,9 @@ static inline bool
 hash_ipport4_data_equal(const struct hash_ipport4_elem *ip1,
                        const struct hash_ipport4_elem *ip2)
 {
-       return ip1->ip == ip2->ip
-              && ip1->port == ip2->port
-              && ip1->proto == ip2->proto;
+       return ip1->ip == ip2->ip &&
+              ip1->port == ip2->port &&
+              ip1->proto == ip2->proto;
 }
 
 static inline bool
@@ -86,22 +85,13 @@ hash_ipport4_data_copy(struct hash_ipport4_elem *dst,
        dst->proto = src->proto;
 }
 
-static inline void
-hash_ipport4_data_swap(struct hash_ipport4_elem *dst,
-                      struct hash_ipport4_elem *src)
-{
-       swap(dst->ip, src->ip);
-       swap(dst->port, src->port);
-       swap(dst->proto, src->proto);
-}
-
 static inline void
 hash_ipport4_data_zero_out(struct hash_ipport4_elem *elem)
 {
        elem->proto = 0;
 }
 
-static inline bool
+static bool
 hash_ipport4_data_list(struct sk_buff *skb,
                       const struct hash_ipport4_elem *data)
 {
@@ -114,7 +104,7 @@ nla_put_failure:
        return 1;
 }
 
-static inline bool
+static bool
 hash_ipport4_data_tlist(struct sk_buff *skb,
                        const struct hash_ipport4_elem *data)
 {
@@ -145,8 +135,8 @@ hash_ipport4_kadt(struct ip_set *set, const struct sk_buff *skb,
        ipset_adtfn adtfn = set->variant->adt[adt];
        struct hash_ipport4_elem data = { };
 
-       if (!get_ip4_port(skb, flags & IPSET_DIM_TWO_SRC,
-                         &data.port, &data.proto))
+       if (!ip_set_get_ip4_port(skb, flags & IPSET_DIM_TWO_SRC,
+                                &data.port, &data.proto))
                return -EINVAL;
 
        ip4addrptr(skb, flags & IPSET_DIM_ONE_SRC, &data.ip);
@@ -182,15 +172,21 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *head, int len,
                      hash_ipport_adt_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!tb[IPSET_ATTR_IP] ||
+                    !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               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, &data.ip);
+       ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP], &data.ip);
        if (ret)
                return ret;
 
        if (tb[IPSET_ATTR_PORT])
-               data.port = ip_set_get_n16(tb[IPSET_ATTR_PORT]);
+               data.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
        else
                return -IPSET_ERR_PROTOCOL;
 
@@ -218,20 +214,19 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *head, int len,
                timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
        }
 
-       if (adt == IPSET_TEST
-           || !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP)
-           || !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR]
-                || tb[IPSET_ATTR_PORT_TO])) {
+       if (adt == IPSET_TEST ||
+           !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) ||
+           !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] ||
+             tb[IPSET_ATTR_PORT_TO])) {
                ret = adtfn(set, &data, timeout);
                return ip_set_eexist(ret, flags) ? 0 : ret;
        }
 
        ip = ntohl(data.ip);
        if (tb[IPSET_ATTR_IP_TO]) {
-               ret = ip_set_get_ipaddr4(tb, IPSET_ATTR_IP_TO, &ip_to);
+               ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
                if (ret)
                        return ret;
-               ip_to = ntohl(ip_to);
                if (ip > ip_to)
                        swap(ip, ip_to);
        } else if (tb[IPSET_ATTR_CIDR]) {
@@ -239,8 +234,8 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *head, int len,
 
                if (cidr > 32)
                        return -IPSET_ERR_INVALID_CIDR;
-               ip &= HOSTMASK(cidr);
-               ip_to = ip | ~HOSTMASK(cidr);
+               ip &= ip_set_hostmask(cidr);
+               ip_to = ip | ~ip_set_hostmask(cidr);
        } else
                ip_to = ip;
 
@@ -273,22 +268,22 @@ hash_ipport_same_set(const struct ip_set *a, const struct ip_set *b)
        const struct ip_set_hash *y = b->data;
 
        /* Resizing changes htable_bits, so we ignore it */
-       return x->maxelem == y->maxelem
-              && x->timeout == y->timeout;
+       return x->maxelem == y->maxelem &&
+              x->timeout == y->timeout;
 }
 
 /* The type variant functions: IPv6 */
 
 struct hash_ipport6_elem {
        union nf_inet_addr ip;
-       u16 port;
+       __be16 port;
        u8 proto;
        u8 padding;
 };
 
 struct hash_ipport6_telem {
        union nf_inet_addr ip;
-       u16 port;
+       __be16 port;
        u8 proto;
        u8 padding;
        unsigned long timeout;
@@ -298,9 +293,9 @@ static inline bool
 hash_ipport6_data_equal(const struct hash_ipport6_elem *ip1,
                        const struct hash_ipport6_elem *ip2)
 {
-       return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0
-              && ip1->port == ip2->port
-              && ip1->proto == ip2->proto;
+       return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 &&
+              ip1->port == ip2->port &&
+              ip1->proto == ip2->proto;
 }
 
 static inline bool
@@ -316,24 +311,13 @@ hash_ipport6_data_copy(struct hash_ipport6_elem *dst,
        memcpy(dst, src, sizeof(*dst));
 }
 
-static inline void
-hash_ipport6_data_swap(struct hash_ipport6_elem *dst,
-                      struct hash_ipport6_elem *src)
-{
-       struct hash_ipport6_elem tmp;
-
-       memcpy(&tmp, dst, sizeof(tmp));
-       memcpy(dst, src, sizeof(tmp));
-       memcpy(src, &tmp, sizeof(tmp));
-}
-
 static inline void
 hash_ipport6_data_zero_out(struct hash_ipport6_elem *elem)
 {
        elem->proto = 0;
 }
 
-static inline bool
+static bool
 hash_ipport6_data_list(struct sk_buff *skb,
                       const struct hash_ipport6_elem *data)
 {
@@ -346,7 +330,7 @@ nla_put_failure:
        return 1;
 }
 
-static inline bool
+static bool
 hash_ipport6_data_tlist(struct sk_buff *skb,
                        const struct hash_ipport6_elem *data)
 {
@@ -379,8 +363,8 @@ hash_ipport6_kadt(struct ip_set *set, const struct sk_buff *skb,
        ipset_adtfn adtfn = set->variant->adt[adt];
        struct hash_ipport6_elem data = { };
 
-       if (!get_ip6_port(skb, flags & IPSET_DIM_TWO_SRC,
-                         &data.port, &data.proto))
+       if (!ip_set_get_ip6_port(skb, flags & IPSET_DIM_TWO_SRC,
+                                &data.port, &data.proto))
                return -EINVAL;
 
        ip6addrptr(skb, flags & IPSET_DIM_ONE_SRC, &data.ip.in6);
@@ -404,15 +388,21 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *head, int len,
                      hash_ipport_adt_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!tb[IPSET_ATTR_IP] ||
+                    !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               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, &data.ip);
+       ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip);
        if (ret)
                return ret;
 
        if (tb[IPSET_ATTR_PORT])
-               data.port = ip_set_get_n16(tb[IPSET_ATTR_PORT]);
+               data.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
        else
                return -IPSET_ERR_PROTOCOL;
 
@@ -440,9 +430,9 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *head, int len,
                timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
        }
 
-       if (adt == IPSET_TEST
-           || !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP)
-           || !tb[IPSET_ATTR_PORT_TO]) {
+       if (adt == IPSET_TEST ||
+           !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) ||
+           !tb[IPSET_ATTR_PORT_TO]) {
                ret = adtfn(set, &data, timeout);
                return ip_set_eexist(ret, flags) ? 0 : ret;
        }
@@ -491,6 +481,11 @@ hash_ipport_create(struct ip_set *set, struct nlattr *head, int len, u32 flags)
                      hash_ipport_create_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               return -IPSET_ERR_PROTOCOL;
+
        if (tb[IPSET_ATTR_HASHSIZE]) {
                hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
                if (hashsize < IPSET_MIMINAL_HASHSIZE)
@@ -536,7 +531,7 @@ hash_ipport_create(struct ip_set *set, struct nlattr *head, int len, u32 flags)
                        ? &hash_ipport4_variant : &hash_ipport6_variant;
        }
 
-       pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)",
+       pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
                 set->name, jhash_size(h->table->htable_bits),
                 h->table->htable_bits, h->maxelem, set->data, h->table);
 
index e074f3b0763d1476ace9f387e9c350f0dd37bc18..506377577a9d4f337e656645e04edd392fac217e 100644 (file)
@@ -7,7 +7,6 @@
 
 /* Kernel module implementing an IP set type: the hash:ip,port,ip type */
 
-#include "ip_set_kernel.h"
 #include "jhash.h"
 #include <linux/module.h>
 #include <linux/ip.h>
@@ -47,18 +46,18 @@ hash_ipportip_same_set(const struct ip_set *a, const struct ip_set *b);
 
 /* Member elements without timeout */
 struct hash_ipportip4_elem {
-       u32 ip;
-       u32 ip2;
-       u16 port;
+       __be32 ip;
+       __be32 ip2;
+       __be16 port;
        u8 proto;
        u8 padding;
 };
 
 /* Member elements with timeout support */
 struct hash_ipportip4_telem {
-       u32 ip;
-       u32 ip2;
-       u16 port;
+       __be32 ip;
+       __be32 ip2;
+       __be16 port;
        u8 proto;
        u8 padding;
        unsigned long timeout;
@@ -68,10 +67,10 @@ static inline bool
 hash_ipportip4_data_equal(const struct hash_ipportip4_elem *ip1,
                          const struct hash_ipportip4_elem *ip2)
 {
-       return ip1->ip == ip2->ip
-              && ip1->ip2 == ip2->ip2
-              && ip1->port == ip2->port
-              && ip1->proto == ip2->proto;
+       return ip1->ip == ip2->ip &&
+              ip1->ip2 == ip2->ip2 &&
+              ip1->port == ip2->port &&
+              ip1->proto == ip2->proto;
 }
 
 static inline bool
@@ -87,24 +86,13 @@ hash_ipportip4_data_copy(struct hash_ipportip4_elem *dst,
        memcpy(dst, src, sizeof(*dst));
 }
 
-static inline void
-hash_ipportip4_data_swap(struct hash_ipportip4_elem *dst,
-                        struct hash_ipportip4_elem *src)
-{
-       struct hash_ipportip4_elem tmp;
-
-       memcpy(&tmp, dst, sizeof(tmp));
-       memcpy(dst, src, sizeof(tmp));
-       memcpy(src, &tmp, sizeof(tmp));
-}
-
 static inline void
 hash_ipportip4_data_zero_out(struct hash_ipportip4_elem *elem)
 {
        elem->proto = 0;
 }
 
-static inline bool
+static bool
 hash_ipportip4_data_list(struct sk_buff *skb,
                       const struct hash_ipportip4_elem *data)
 {
@@ -118,7 +106,7 @@ nla_put_failure:
        return 1;
 }
 
-static inline bool
+static bool
 hash_ipportip4_data_tlist(struct sk_buff *skb,
                        const struct hash_ipportip4_elem *data)
 {
@@ -150,8 +138,8 @@ hash_ipportip4_kadt(struct ip_set *set, const struct sk_buff *skb,
        ipset_adtfn adtfn = set->variant->adt[adt];
        struct hash_ipportip4_elem data = { };
 
-       if (!get_ip4_port(skb, flags & IPSET_DIM_TWO_SRC,
-                         &data.port, &data.proto))
+       if (!ip_set_get_ip4_port(skb, flags & IPSET_DIM_TWO_SRC,
+                                &data.port, &data.proto))
                return -EINVAL;
 
        ip4addrptr(skb, flags & IPSET_DIM_ONE_SRC, &data.ip);
@@ -189,19 +177,25 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *head, int len,
                      hash_ipportip_adt_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
+                    !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               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, &data.ip);
+       ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP], &data.ip);
        if (ret)
                return ret;
 
-       ret = ip_set_get_ipaddr4(tb, IPSET_ATTR_IP2, &data.ip2);
+       ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP2], &data.ip2);
        if (ret)
                return ret;
 
        if (tb[IPSET_ATTR_PORT])
-               data.port = ip_set_get_n16(tb[IPSET_ATTR_PORT]);
+               data.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
        else
                return -IPSET_ERR_PROTOCOL;
 
@@ -229,20 +223,19 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *head, int len,
                timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
        }
 
-       if (adt == IPSET_TEST
-           || !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP)
-           || !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR]
-                || tb[IPSET_ATTR_PORT_TO])) {
+       if (adt == IPSET_TEST ||
+           !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) ||
+           !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] ||
+             tb[IPSET_ATTR_PORT_TO])) {
                ret = adtfn(set, &data, timeout);
                return ip_set_eexist(ret, flags) ? 0 : ret;
        }
 
        ip = ntohl(data.ip);
        if (tb[IPSET_ATTR_IP_TO]) {
-               ret = ip_set_get_ipaddr4(tb, IPSET_ATTR_IP_TO, &ip_to);
+               ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
                if (ret)
                        return ret;
-               ip_to = ntohl(ip_to);
                if (ip > ip_to)
                        swap(ip, ip_to);
        } else if (tb[IPSET_ATTR_CIDR]) {
@@ -250,8 +243,8 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *head, int len,
 
                if (cidr > 32)
                        return -IPSET_ERR_INVALID_CIDR;
-               ip &= HOSTMASK(cidr);
-               ip_to = ip | ~HOSTMASK(cidr);
+               ip &= ip_set_hostmask(cidr);
+               ip_to = ip | ~ip_set_hostmask(cidr);
        } else
                ip_to = ip;
 
@@ -284,8 +277,8 @@ hash_ipportip_same_set(const struct ip_set *a, const struct ip_set *b)
        const struct ip_set_hash *y = b->data;
 
        /* Resizing changes htable_bits, so we ignore it */
-       return x->maxelem == y->maxelem
-              && x->timeout == y->timeout;
+       return x->maxelem == y->maxelem &&
+              x->timeout == y->timeout;
 }
 
 /* The type variant functions: IPv6 */
@@ -293,7 +286,7 @@ hash_ipportip_same_set(const struct ip_set *a, const struct ip_set *b)
 struct hash_ipportip6_elem {
        union nf_inet_addr ip;
        union nf_inet_addr ip2;
-       u16 port;
+       __be16 port;
        u8 proto;
        u8 padding;
 };
@@ -301,7 +294,7 @@ struct hash_ipportip6_elem {
 struct hash_ipportip6_telem {
        union nf_inet_addr ip;
        union nf_inet_addr ip2;
-       u16 port;
+       __be16 port;
        u8 proto;
        u8 padding;
        unsigned long timeout;
@@ -311,10 +304,10 @@ static inline bool
 hash_ipportip6_data_equal(const struct hash_ipportip6_elem *ip1,
                          const struct hash_ipportip6_elem *ip2)
 {
-       return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0
-              && ipv6_addr_cmp(&ip1->ip2.in6, &ip2->ip2.in6) == 0
-              && ip1->port == ip2->port
-              && ip1->proto == ip2->proto;
+       return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 &&
+              ipv6_addr_cmp(&ip1->ip2.in6, &ip2->ip2.in6) == 0 &&
+              ip1->port == ip2->port &&
+              ip1->proto == ip2->proto;
 }
 
 static inline bool
@@ -330,24 +323,13 @@ hash_ipportip6_data_copy(struct hash_ipportip6_elem *dst,
        memcpy(dst, src, sizeof(*dst));
 }
 
-static inline void
-hash_ipportip6_data_swap(struct hash_ipportip6_elem *dst,
-                        struct hash_ipportip6_elem *src)
-{
-       struct hash_ipportip6_elem tmp;
-
-       memcpy(&tmp, dst, sizeof(tmp));
-       memcpy(dst, src, sizeof(tmp));
-       memcpy(src, &tmp, sizeof(tmp));
-}
-
 static inline void
 hash_ipportip6_data_zero_out(struct hash_ipportip6_elem *elem)
 {
        elem->proto = 0;
 }
 
-static inline bool
+static bool
 hash_ipportip6_data_list(struct sk_buff *skb,
                         const struct hash_ipportip6_elem *data)
 {
@@ -361,7 +343,7 @@ nla_put_failure:
        return 1;
 }
 
-static inline bool
+static bool
 hash_ipportip6_data_tlist(struct sk_buff *skb,
                          const struct hash_ipportip6_elem *data)
 {
@@ -395,8 +377,8 @@ hash_ipportip6_kadt(struct ip_set *set, const struct sk_buff *skb,
        ipset_adtfn adtfn = set->variant->adt[adt];
        struct hash_ipportip6_elem data = { };
 
-       if (!get_ip6_port(skb, flags & IPSET_DIM_TWO_SRC,
-                         &data.port, &data.proto))
+       if (!ip_set_get_ip6_port(skb, flags & IPSET_DIM_TWO_SRC,
+                                &data.port, &data.proto))
                return -EINVAL;
 
        ip6addrptr(skb, flags & IPSET_DIM_ONE_SRC, &data.ip.in6);
@@ -421,19 +403,25 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *head, int len,
                      hash_ipportip_adt_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
+                    !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               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, &data.ip);
+       ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip);
        if (ret)
                return ret;
 
-       ret = ip_set_get_ipaddr6(tb, IPSET_ATTR_IP2, &data.ip2);
+       ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP2], &data.ip2);
        if (ret)
                return ret;
 
        if (tb[IPSET_ATTR_PORT])
-               data.port = ip_set_get_n16(tb[IPSET_ATTR_PORT]);
+               data.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
        else
                return -IPSET_ERR_PROTOCOL;
 
@@ -461,9 +449,9 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *head, int len,
                timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
        }
 
-       if (adt == IPSET_TEST
-           || !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP)
-           || !tb[IPSET_ATTR_PORT_TO]) {
+       if (adt == IPSET_TEST ||
+           !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) ||
+           !tb[IPSET_ATTR_PORT_TO]) {
                ret = adtfn(set, &data, timeout);
                return ip_set_eexist(ret, flags) ? 0 : ret;
        }
@@ -512,6 +500,11 @@ hash_ipportip_create(struct ip_set *set, struct nlattr *head,
                      hash_ipportip_create_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               return -IPSET_ERR_PROTOCOL;
+
        if (tb[IPSET_ATTR_HASHSIZE]) {
                hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
                if (hashsize < IPSET_MIMINAL_HASHSIZE)
@@ -557,7 +550,7 @@ hash_ipportip_create(struct ip_set *set, struct nlattr *head,
                        ? &hash_ipportip4_variant : &hash_ipportip6_variant;
        }
 
-       pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)",
+       pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
                 set->name, jhash_size(h->table->htable_bits),
                 h->table->htable_bits, h->maxelem, set->data, h->table);
 
index 1a257b94153f9d03dd2bc42724b5062266b217fc..85fa6c744911062b3dde26e3bbc5039f3e5a4ccc 100644 (file)
@@ -7,7 +7,6 @@
 
 /* Kernel module implementing an IP set type: the hash:ip,port,net type */
 
-#include "ip_set_kernel.h"
 #include "jhash.h"
 #include <linux/module.h>
 #include <linux/ip.h>
@@ -47,18 +46,18 @@ hash_ipportnet_same_set(const struct ip_set *a, const struct ip_set *b);
 
 /* Member elements without timeout */
 struct hash_ipportnet4_elem {
-       u32 ip;
-       u32 ip2;
-       u16 port;
+       __be32 ip;
+       __be32 ip2;
+       __be16 port;
        u8 cidr;
        u8 proto;
 };
 
 /* Member elements with timeout support */
 struct hash_ipportnet4_telem {
-       u32 ip;
-       u32 ip2;
-       u16 port;
+       __be32 ip;
+       __be32 ip2;
+       __be16 port;
        u8 cidr;
        u8 proto;
        unsigned long timeout;
@@ -68,11 +67,11 @@ static inline bool
 hash_ipportnet4_data_equal(const struct hash_ipportnet4_elem *ip1,
                           const struct hash_ipportnet4_elem *ip2)
 {
-       return ip1->ip == ip2->ip
-              && ip1->ip2 == ip2->ip2
-              && ip1->cidr == ip2->cidr
-              && ip1->port == ip2->port
-              && ip1->proto == ip2->proto;
+       return ip1->ip == ip2->ip &&
+              ip1->ip2 == ip2->ip2 &&
+              ip1->cidr == ip2->cidr &&
+              ip1->port == ip2->port &&
+              ip1->proto == ip2->proto;
 }
 
 static inline bool
@@ -88,21 +87,10 @@ hash_ipportnet4_data_copy(struct hash_ipportnet4_elem *dst,
        memcpy(dst, src, sizeof(*dst));
 }
 
-static inline void
-hash_ipportnet4_data_swap(struct hash_ipportnet4_elem *dst,
-                         struct hash_ipportnet4_elem *src)
-{
-       struct hash_ipportnet4_elem tmp;
-
-       memcpy(&tmp, dst, sizeof(tmp));
-       memcpy(dst, src, sizeof(tmp));
-       memcpy(src, &tmp, sizeof(tmp));
-}
-
 static inline void
 hash_ipportnet4_data_netmask(struct hash_ipportnet4_elem *elem, u8 cidr)
 {
-       elem->ip2 &= NETMASK(cidr);
+       elem->ip2 &= ip_set_netmask(cidr);
        elem->cidr = cidr;
 }
 
@@ -112,7 +100,7 @@ hash_ipportnet4_data_zero_out(struct hash_ipportnet4_elem *elem)
        elem->proto = 0;
 }
 
-static inline bool
+static bool
 hash_ipportnet4_data_list(struct sk_buff *skb,
                          const struct hash_ipportnet4_elem *data)
 {
@@ -127,7 +115,7 @@ nla_put_failure:
        return 1;
 }
 
-static inline bool
+static bool
 hash_ipportnet4_data_tlist(struct sk_buff *skb,
                           const struct hash_ipportnet4_elem *data)
 {
@@ -169,13 +157,13 @@ hash_ipportnet4_kadt(struct ip_set *set, const struct sk_buff *skb,
        if (adt == IPSET_TEST)
                data.cidr = HOST_MASK;
 
-       if (!get_ip4_port(skb, flags & IPSET_DIM_TWO_SRC,
-                         &data.port, &data.proto))
+       if (!ip_set_get_ip4_port(skb, flags & IPSET_DIM_TWO_SRC,
+                                &data.port, &data.proto))
                return -EINVAL;
 
        ip4addrptr(skb, flags & IPSET_DIM_ONE_SRC, &data.ip);
        ip4addrptr(skb, flags & IPSET_DIM_THREE_SRC, &data.ip2);
-       data.ip2 &= NETMASK(data.cidr);
+       data.ip2 &= ip_set_netmask(data.cidr);
 
        return adtfn(set, &data, h->timeout);
 }
@@ -210,14 +198,20 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *head, int len,
                      hash_ipportnet_adt_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
+                    !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               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, &data.ip);
+       ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP], &data.ip);
        if (ret)
                return ret;
 
-       ret = ip_set_get_ipaddr4(tb, IPSET_ATTR_IP2, &data.ip2);
+       ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP2], &data.ip2);
        if (ret)
                return ret;
 
@@ -227,16 +221,16 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *head, int len,
        if (!data.cidr)
                return -IPSET_ERR_INVALID_CIDR;
 
-       data.ip2 &= NETMASK(data.cidr);
+       data.ip2 &= ip_set_netmask(data.cidr);
 
        if (tb[IPSET_ATTR_PORT])
-               data.port = ip_set_get_n16(tb[IPSET_ATTR_PORT]);
+               data.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
        else
                return -IPSET_ERR_PROTOCOL;
 
        if (tb[IPSET_ATTR_PROTO]) {
                data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
-               
+
                if (data.proto == 0)
                        return -IPSET_ERR_INVALID_PROTO;
        } else
@@ -258,20 +252,19 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *head, int len,
                timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
        }
 
-       if (adt == IPSET_TEST
-           || !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP)
-           || !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR]
-                || tb[IPSET_ATTR_PORT_TO])) {
+       if (adt == IPSET_TEST ||
+           !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) ||
+           !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] ||
+             tb[IPSET_ATTR_PORT_TO])) {
                ret = adtfn(set, &data, timeout);
                return ip_set_eexist(ret, flags) ? 0 : ret;
        }
 
        ip = ntohl(data.ip);
        if (tb[IPSET_ATTR_IP_TO]) {
-               ret = ip_set_get_ipaddr4(tb, IPSET_ATTR_IP_TO, &ip_to);
+               ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
                if (ret)
                        return ret;
-               ip_to = ntohl(ip_to);
                if (ip > ip_to)
                        swap(ip, ip_to);
        } else if (tb[IPSET_ATTR_CIDR]) {
@@ -279,8 +272,8 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *head, int len,
 
                if (cidr > 32)
                        return -IPSET_ERR_INVALID_CIDR;
-               ip &= HOSTMASK(cidr);
-               ip_to = ip | ~HOSTMASK(cidr);
+               ip &= ip_set_hostmask(cidr);
+               ip_to = ip | ~ip_set_hostmask(cidr);
        } else
                ip_to = ip;
 
@@ -311,10 +304,10 @@ hash_ipportnet_same_set(const struct ip_set *a, const struct ip_set *b)
 {
        const struct ip_set_hash *x = a->data;
        const struct ip_set_hash *y = b->data;
-       
+
        /* Resizing changes htable_bits, so we ignore it */
-       return x->maxelem == y->maxelem
-              && x->timeout == y->timeout;
+       return x->maxelem == y->maxelem &&
+              x->timeout == y->timeout;
 }
 
 /* The type variant functions: IPv6 */
@@ -322,7 +315,7 @@ hash_ipportnet_same_set(const struct ip_set *a, const struct ip_set *b)
 struct hash_ipportnet6_elem {
        union nf_inet_addr ip;
        union nf_inet_addr ip2;
-       u16 port;
+       __be16 port;
        u8 cidr;
        u8 proto;
 };
@@ -330,7 +323,7 @@ struct hash_ipportnet6_elem {
 struct hash_ipportnet6_telem {
        union nf_inet_addr ip;
        union nf_inet_addr ip2;
-       u16 port;
+       __be16 port;
        u8 cidr;
        u8 proto;
        unsigned long timeout;
@@ -340,11 +333,11 @@ static inline bool
 hash_ipportnet6_data_equal(const struct hash_ipportnet6_elem *ip1,
                           const struct hash_ipportnet6_elem *ip2)
 {
-       return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0
-              && ipv6_addr_cmp(&ip1->ip2.in6, &ip2->ip2.in6) == 0
-              && ip1->cidr == ip2->cidr
-              && ip1->port == ip2->port
-              && ip1->proto == ip2->proto;
+       return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 &&
+              ipv6_addr_cmp(&ip1->ip2.in6, &ip2->ip2.in6) == 0 &&
+              ip1->cidr == ip2->cidr &&
+              ip1->port == ip2->port &&
+              ip1->proto == ip2->proto;
 }
 
 static inline bool
@@ -360,17 +353,6 @@ hash_ipportnet6_data_copy(struct hash_ipportnet6_elem *dst,
        memcpy(dst, src, sizeof(*dst));
 }
 
-static inline void
-hash_ipportnet6_data_swap(struct hash_ipportnet6_elem *dst,
-                        struct hash_ipportnet6_elem *src)
-{
-       struct hash_ipportnet6_elem tmp;
-       
-       memcpy(&tmp, dst, sizeof(tmp));
-       memcpy(dst, src, sizeof(tmp));
-       memcpy(src, &tmp, sizeof(tmp));
-}
-
 static inline void
 hash_ipportnet6_data_zero_out(struct hash_ipportnet6_elem *elem)
 {
@@ -380,10 +362,10 @@ hash_ipportnet6_data_zero_out(struct hash_ipportnet6_elem *elem)
 static inline void
 ip6_netmask(union nf_inet_addr *ip, u8 prefix)
 {
-       ip->ip6[0] &= NETMASK6(prefix)[0];
-       ip->ip6[1] &= NETMASK6(prefix)[1];
-       ip->ip6[2] &= NETMASK6(prefix)[2];
-       ip->ip6[3] &= NETMASK6(prefix)[3];
+       ip->ip6[0] &= ip_set_netmask6(prefix)[0];
+       ip->ip6[1] &= ip_set_netmask6(prefix)[1];
+       ip->ip6[2] &= ip_set_netmask6(prefix)[2];
+       ip->ip6[3] &= ip_set_netmask6(prefix)[3];
 }
 
 static inline void
@@ -393,7 +375,7 @@ hash_ipportnet6_data_netmask(struct hash_ipportnet6_elem *elem, u8 cidr)
        elem->cidr = cidr;
 }
 
-static inline bool
+static bool
 hash_ipportnet6_data_list(struct sk_buff *skb,
                          const struct hash_ipportnet6_elem *data)
 {
@@ -408,13 +390,13 @@ nla_put_failure:
        return 1;
 }
 
-static inline bool
+static bool
 hash_ipportnet6_data_tlist(struct sk_buff *skb,
                           const struct hash_ipportnet6_elem *data)
 {
-       const struct hash_ipportnet6_telem *e = 
+       const struct hash_ipportnet6_telem *e =
                (const struct hash_ipportnet6_telem *)data;
-       
+
        NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &e->ip);
        NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP2, &data->ip2);
        NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port);
@@ -449,8 +431,8 @@ hash_ipportnet6_kadt(struct ip_set *set, const struct sk_buff *skb,
        if (adt == IPSET_TEST)
                data.cidr = HOST_MASK;
 
-       if (!get_ip6_port(skb, flags & IPSET_DIM_TWO_SRC,
-                         &data.port, &data.proto))
+       if (!ip_set_get_ip6_port(skb, flags & IPSET_DIM_TWO_SRC,
+                                &data.port, &data.proto))
                return -EINVAL;
 
        ip6addrptr(skb, flags & IPSET_DIM_ONE_SRC, &data.ip.in6);
@@ -476,14 +458,20 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *head, int len,
                      hash_ipportnet_adt_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
+                    !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               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, &data.ip);
+       ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip);
        if (ret)
                return ret;
 
-       ret = ip_set_get_ipaddr6(tb, IPSET_ATTR_IP2, &data.ip2);
+       ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP2], &data.ip2);
        if (ret)
                return ret;
 
@@ -496,7 +484,7 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *head, int len,
        ip6_netmask(&data.ip2, data.cidr);
 
        if (tb[IPSET_ATTR_PORT])
-               data.port = ip_set_get_n16(tb[IPSET_ATTR_PORT]);
+               data.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
        else
                return -IPSET_ERR_PROTOCOL;
 
@@ -524,9 +512,9 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *head, int len,
                timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
        }
 
-       if (adt == IPSET_TEST
-           || !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP)
-           || !tb[IPSET_ATTR_PORT_TO]) {
+       if (adt == IPSET_TEST ||
+           !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) ||
+           !tb[IPSET_ATTR_PORT_TO]) {
                ret = adtfn(set, &data, timeout);
                return ip_set_eexist(ret, flags) ? 0 : ret;
        }
@@ -575,6 +563,11 @@ hash_ipportnet_create(struct ip_set *set, struct nlattr *head,
                      hash_ipportnet_create_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               return -IPSET_ERR_PROTOCOL;
+
        if (tb[IPSET_ATTR_HASHSIZE]) {
                hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
                if (hashsize < IPSET_MIMINAL_HASHSIZE)
@@ -609,7 +602,7 @@ hash_ipportnet_create(struct ip_set *set, struct nlattr *head,
 
        if (tb[IPSET_ATTR_TIMEOUT]) {
                h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
-               
+
                set->variant = set->family == AF_INET
                        ? &hash_ipportnet4_tvariant
                        : &hash_ipportnet6_tvariant;
@@ -622,11 +615,11 @@ hash_ipportnet_create(struct ip_set *set, struct nlattr *head,
                set->variant = set->family == AF_INET
                        ? &hash_ipportnet4_variant : &hash_ipportnet6_variant;
        }
-       
-       pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)",
+
+       pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
                 set->name, jhash_size(h->table->htable_bits),
                 h->table->htable_bits, h->maxelem, set->data, h->table);
-          
+
        return 0;
 }
 
index bc8a8db2034666f25bb1148260abefeda474ee75..7f01112490b50a03f5d7a2eff47580e108accc14 100644 (file)
@@ -7,7 +7,6 @@
 
 /* Kernel module implementing an IP set type: the hash:net type */
 
-#include "ip_set_kernel.h"
 #include "jhash.h"
 #include <linux/module.h>
 #include <linux/ip.h>
@@ -45,7 +44,7 @@ hash_net_same_set(const struct ip_set *a, const struct ip_set *b);
 
 /* Member elements without timeout */
 struct hash_net4_elem {
-       u32 ip;
+       __be32 ip;
        u16 padding0;
        u8 padding1;
        u8 cidr;
@@ -53,7 +52,7 @@ struct hash_net4_elem {
 
 /* Member elements with timeout support */
 struct hash_net4_telem {
-       u32 ip;
+       __be32 ip;
        u16 padding0;
        u8 padding1;
        u8 cidr;
@@ -81,18 +80,10 @@ hash_net4_data_copy(struct hash_net4_elem *dst,
        dst->cidr = src->cidr;
 }
 
-static inline void
-hash_net4_data_swap(struct hash_net4_elem *dst,
-                   struct hash_net4_elem *src)
-{
-       swap(dst->ip, src->ip);
-       swap(dst->cidr, src->cidr);
-}
-
 static inline void
 hash_net4_data_netmask(struct hash_net4_elem *elem, u8 cidr)
 {
-       elem->ip &= NETMASK(cidr);
+       elem->ip &= ip_set_netmask(cidr);
        elem->cidr = cidr;
 }
 
@@ -103,7 +94,7 @@ hash_net4_data_zero_out(struct hash_net4_elem *elem)
        elem->cidr = 0;
 }
 
-static inline bool
+static bool
 hash_net4_data_list(struct sk_buff *skb, const struct hash_net4_elem *data)
 {
        NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, data->ip);
@@ -114,7 +105,7 @@ nla_put_failure:
        return 1;
 }
 
-static inline bool
+static bool
 hash_net4_data_tlist(struct sk_buff *skb, const struct hash_net4_elem *data)
 {
        const struct hash_net4_telem *tdata =
@@ -151,7 +142,7 @@ hash_net4_kadt(struct ip_set *set, const struct sk_buff *skb,
                data.cidr = HOST_MASK;
 
        ip4addrptr(skb, flags & IPSET_DIM_ONE_SRC, &data.ip);
-       data.ip &= NETMASK(data.cidr);
+       data.ip &= ip_set_netmask(data.cidr);
 
        return adtfn(set, &data, h->timeout);
 }
@@ -177,10 +168,14 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *head, int len,
                      hash_net_adt_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!tb[IPSET_ATTR_IP] ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               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, &data.ip);
+       ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP], &data.ip);
        if (ret)
                return ret;
 
@@ -190,7 +185,7 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *head, int len,
        if (!data.cidr)
                return -IPSET_ERR_INVALID_CIDR;
 
-       data.ip &= NETMASK(data.cidr);
+       data.ip &= ip_set_netmask(data.cidr);
 
        if (tb[IPSET_ATTR_TIMEOUT]) {
                if (!with_timeout(h->timeout))
@@ -210,8 +205,8 @@ hash_net_same_set(const struct ip_set *a, const struct ip_set *b)
        const struct ip_set_hash *y = b->data;
 
        /* Resizing changes htable_bits, so we ignore it */
-       return x->maxelem == y->maxelem
-              && x->timeout == y->timeout;
+       return x->maxelem == y->maxelem &&
+              x->timeout == y->timeout;
 }
 
 /* The type variant functions: IPv6 */
@@ -235,8 +230,8 @@ static inline bool
 hash_net6_data_equal(const struct hash_net6_elem *ip1,
                     const struct hash_net6_elem *ip2)
 {
-       return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0
-              && ip1->cidr == ip2->cidr;
+       return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 &&
+              ip1->cidr == ip2->cidr;
 }
 
 static inline bool
@@ -253,16 +248,6 @@ hash_net6_data_copy(struct hash_net6_elem *dst,
        dst->cidr = src->cidr;
 }
 
-static inline void
-hash_net6_data_swap(struct hash_net6_elem *dst, struct hash_net6_elem *src)
-{
-       struct hash_net6_elem tmp;
-
-       memcpy(&tmp, dst, sizeof(tmp));
-       memcpy(dst, src, sizeof(tmp));
-       memcpy(src, &tmp, sizeof(tmp));
-}
-
 static inline void
 hash_net6_data_zero_out(struct hash_net6_elem *elem)
 {
@@ -272,10 +257,10 @@ hash_net6_data_zero_out(struct hash_net6_elem *elem)
 static inline void
 ip6_netmask(union nf_inet_addr *ip, u8 prefix)
 {
-       ip->ip6[0] &= NETMASK6(prefix)[0];
-       ip->ip6[1] &= NETMASK6(prefix)[1];
-       ip->ip6[2] &= NETMASK6(prefix)[2];
-       ip->ip6[3] &= NETMASK6(prefix)[3];
+       ip->ip6[0] &= ip_set_netmask6(prefix)[0];
+       ip->ip6[1] &= ip_set_netmask6(prefix)[1];
+       ip->ip6[2] &= ip_set_netmask6(prefix)[2];
+       ip->ip6[3] &= ip_set_netmask6(prefix)[3];
 }
 
 static inline void
@@ -285,7 +270,7 @@ hash_net6_data_netmask(struct hash_net6_elem *elem, u8 cidr)
        elem->cidr = cidr;
 }
 
-static inline bool
+static bool
 hash_net6_data_list(struct sk_buff *skb, const struct hash_net6_elem *data)
 {
        NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &data->ip);
@@ -296,7 +281,7 @@ nla_put_failure:
        return 1;
 }
 
-static inline bool
+static bool
 hash_net6_data_tlist(struct sk_buff *skb, const struct hash_net6_elem *data)
 {
        const struct hash_net6_telem *e =
@@ -353,10 +338,14 @@ hash_net6_uadt(struct ip_set *set, struct nlattr *head, int len,
                      hash_net_adt_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!tb[IPSET_ATTR_IP] ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               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, &data.ip);
+       ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip);
        if (ret)
                return ret;
 
@@ -405,6 +394,11 @@ hash_net_create(struct ip_set *set, struct nlattr *head, int len, u32 flags)
                      hash_net_create_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               return -IPSET_ERR_PROTOCOL;
+
        if (tb[IPSET_ATTR_HASHSIZE]) {
                hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
                if (hashsize < IPSET_MIMINAL_HASHSIZE)
@@ -452,7 +446,7 @@ hash_net_create(struct ip_set *set, struct nlattr *head, int len, u32 flags)
                        ? &hash_net4_variant : &hash_net6_variant;
        }
 
-       pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)",
+       pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
                 set->name, jhash_size(h->table->htable_bits),
                 h->table->htable_bits, h->maxelem, set->data, h->table);
 
index 168cdc3e89ca3778479b8981d40cc276ff357253..6e86b620b0fc4be3d63fab16f71a5d98d48adf57 100644 (file)
@@ -7,7 +7,6 @@
 
 /* Kernel module implementing an IP set type: the hash:net,port type */
 
-#include "ip_set_kernel.h"
 #include "jhash.h"
 #include <linux/module.h>
 #include <linux/ip.h>
@@ -46,16 +45,16 @@ hash_netport_same_set(const struct ip_set *a, const struct ip_set *b);
 
 /* Member elements without timeout */
 struct hash_netport4_elem {
-       u32 ip;
-       u16 port;
+       __be32 ip;
+       __be16 port;
        u8 proto;
        u8 cidr;
 };
 
 /* Member elements with timeout support */
 struct hash_netport4_telem {
-       u32 ip;
-       u16 port;
+       __be32 ip;
+       __be16 port;
        u8 proto;
        u8 cidr;
        unsigned long timeout;
@@ -65,10 +64,10 @@ static inline bool
 hash_netport4_data_equal(const struct hash_netport4_elem *ip1,
                         const struct hash_netport4_elem *ip2)
 {
-       return ip1->ip == ip2->ip
-              && ip1->port == ip2->port
-              && ip1->proto == ip2->proto
-              && ip1->cidr == ip2->cidr;
+       return ip1->ip == ip2->ip &&
+              ip1->port == ip2->port &&
+              ip1->proto == ip2->proto &&
+              ip1->cidr == ip2->cidr;
 }
 
 static inline bool
@@ -87,20 +86,10 @@ hash_netport4_data_copy(struct hash_netport4_elem *dst,
        dst->cidr = src->cidr;
 }
 
-static inline void
-hash_netport4_data_swap(struct hash_netport4_elem *dst,
-                       struct hash_netport4_elem *src)
-{
-       swap(dst->ip, src->ip);
-       swap(dst->port, src->port);
-       swap(dst->proto, src->proto);
-       swap(dst->cidr, src->cidr);
-}
-
 static inline void
 hash_netport4_data_netmask(struct hash_netport4_elem *elem, u8 cidr)
 {
-       elem->ip &= NETMASK(cidr);
+       elem->ip &= ip_set_netmask(cidr);
        elem->cidr = cidr;
 }
 
@@ -110,7 +99,7 @@ hash_netport4_data_zero_out(struct hash_netport4_elem *elem)
        elem->proto = 0;
 }
 
-static inline bool
+static bool
 hash_netport4_data_list(struct sk_buff *skb,
                        const struct hash_netport4_elem *data)
 {
@@ -124,7 +113,7 @@ nla_put_failure:
        return 1;
 }
 
-static inline bool
+static bool
 hash_netport4_data_tlist(struct sk_buff *skb,
                         const struct hash_netport4_elem *data)
 {
@@ -165,12 +154,12 @@ hash_netport4_kadt(struct ip_set *set, const struct sk_buff *skb,
        if (adt == IPSET_TEST)
                data.cidr = HOST_MASK;
 
-       if (!get_ip4_port(skb, flags & IPSET_DIM_TWO_SRC,
-                         &data.port, &data.proto))
+       if (!ip_set_get_ip4_port(skb, flags & IPSET_DIM_TWO_SRC,
+                                &data.port, &data.proto))
                return -EINVAL;
 
        ip4addrptr(skb, flags & IPSET_DIM_ONE_SRC, &data.ip);
-       data.ip &= NETMASK(data.cidr);
+       data.ip &= ip_set_netmask(data.cidr);
 
        return adtfn(set, &data, h->timeout);
 }
@@ -202,10 +191,16 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *head, int len,
                      hash_netport_adt_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!tb[IPSET_ATTR_IP] ||
+                    !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               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, &data.ip);
+       ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP], &data.ip);
        if (ret)
                return ret;
 
@@ -213,10 +208,10 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *head, int len,
                data.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
        if (!data.cidr)
                return -IPSET_ERR_INVALID_CIDR;
-       data.ip &= NETMASK(data.cidr);
+       data.ip &= ip_set_netmask(data.cidr);
 
        if (tb[IPSET_ATTR_PORT])
-               data.port = ip_set_get_n16(tb[IPSET_ATTR_PORT]);
+               data.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
        else
                return -IPSET_ERR_PROTOCOL;
 
@@ -244,9 +239,9 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *head, int len,
                timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
        }
 
-       if (adt == IPSET_TEST
-           || !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP)
-           || !tb[IPSET_ATTR_PORT_TO]) {
+       if (adt == IPSET_TEST ||
+           !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) ||
+           !tb[IPSET_ATTR_PORT_TO]) {
                ret = adtfn(set, &data, timeout);
                return ip_set_eexist(ret, flags) ? 0 : ret;
        }
@@ -275,22 +270,22 @@ hash_netport_same_set(const struct ip_set *a, const struct ip_set *b)
        const struct ip_set_hash *y = b->data;
 
        /* Resizing changes htable_bits, so we ignore it */
-       return x->maxelem == y->maxelem
-              && x->timeout == y->timeout;
+       return x->maxelem == y->maxelem &&
+              x->timeout == y->timeout;
 }
 
 /* The type variant functions: IPv6 */
 
 struct hash_netport6_elem {
        union nf_inet_addr ip;
-       u16 port;
+       __be16 port;
        u8 proto;
        u8 cidr;
 };
 
 struct hash_netport6_telem {
        union nf_inet_addr ip;
-       u16 port;
+       __be16 port;
        u8 proto;
        u8 cidr;
        unsigned long timeout;
@@ -300,10 +295,10 @@ static inline bool
 hash_netport6_data_equal(const struct hash_netport6_elem *ip1,
                         const struct hash_netport6_elem *ip2)
 {
-       return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0
-              && ip1->port == ip2->port
-              && ip1->proto == ip2->proto
-              && ip1->cidr == ip2->cidr;
+       return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 &&
+              ip1->port == ip2->port &&
+              ip1->proto == ip2->proto &&
+              ip1->cidr == ip2->cidr;
 }
 
 static inline bool
@@ -319,17 +314,6 @@ hash_netport6_data_copy(struct hash_netport6_elem *dst,
        memcpy(dst, src, sizeof(*dst));
 }
 
-static inline void
-hash_netport6_data_swap(struct hash_netport6_elem *dst,
-                       struct hash_netport6_elem *src)
-{
-       struct hash_netport6_elem tmp;
-
-       memcpy(&tmp, dst, sizeof(tmp));
-       memcpy(dst, src, sizeof(tmp));
-       memcpy(src, &tmp, sizeof(tmp));
-}
-
 static inline void
 hash_netport6_data_zero_out(struct hash_netport6_elem *elem)
 {
@@ -339,10 +323,10 @@ hash_netport6_data_zero_out(struct hash_netport6_elem *elem)
 static inline void
 ip6_netmask(union nf_inet_addr *ip, u8 prefix)
 {
-       ip->ip6[0] &= NETMASK6(prefix)[0];
-       ip->ip6[1] &= NETMASK6(prefix)[1];
-       ip->ip6[2] &= NETMASK6(prefix)[2];
-       ip->ip6[3] &= NETMASK6(prefix)[3];
+       ip->ip6[0] &= ip_set_netmask6(prefix)[0];
+       ip->ip6[1] &= ip_set_netmask6(prefix)[1];
+       ip->ip6[2] &= ip_set_netmask6(prefix)[2];
+       ip->ip6[3] &= ip_set_netmask6(prefix)[3];
 }
 
 static inline void
@@ -352,7 +336,7 @@ hash_netport6_data_netmask(struct hash_netport6_elem *elem, u8 cidr)
        elem->cidr = cidr;
 }
 
-static inline bool
+static bool
 hash_netport6_data_list(struct sk_buff *skb,
                        const struct hash_netport6_elem *data)
 {
@@ -366,7 +350,7 @@ nla_put_failure:
        return 1;
 }
 
-static inline bool
+static bool
 hash_netport6_data_tlist(struct sk_buff *skb,
                         const struct hash_netport6_elem *data)
 {
@@ -406,8 +390,8 @@ hash_netport6_kadt(struct ip_set *set, const struct sk_buff *skb,
        if (adt == IPSET_TEST)
                data.cidr = HOST_MASK;
 
-       if (!get_ip6_port(skb, flags & IPSET_DIM_TWO_SRC,
-                         &data.port, &data.proto))
+       if (!ip_set_get_ip6_port(skb, flags & IPSET_DIM_TWO_SRC,
+                                &data.port, &data.proto))
                return -EINVAL;
 
        ip6addrptr(skb, flags & IPSET_DIM_ONE_SRC, &data.ip.in6);
@@ -432,10 +416,16 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *head, int len,
                      hash_netport_adt_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!tb[IPSET_ATTR_IP] ||
+                    !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               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, &data.ip);
+       ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip);
        if (ret)
                return ret;
 
@@ -446,7 +436,7 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *head, int len,
        ip6_netmask(&data.ip, data.cidr);
 
        if (tb[IPSET_ATTR_PORT])
-               data.port = ip_set_get_n16(tb[IPSET_ATTR_PORT]);
+               data.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
        else
                return -IPSET_ERR_PROTOCOL;
 
@@ -474,9 +464,9 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *head, int len,
                timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
        }
 
-       if (adt == IPSET_TEST
-           || !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP)
-           || !tb[IPSET_ATTR_PORT_TO]) {
+       if (adt == IPSET_TEST ||
+           !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) ||
+           !tb[IPSET_ATTR_PORT_TO]) {
                ret = adtfn(set, &data, timeout);
                return ip_set_eexist(ret, flags) ? 0 : ret;
        }
@@ -525,6 +515,11 @@ hash_netport_create(struct ip_set *set, struct nlattr *head, int len, u32 flags)
                      hash_netport_create_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               return -IPSET_ERR_PROTOCOL;
+
        if (tb[IPSET_ATTR_HASHSIZE]) {
                hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
                if (hashsize < IPSET_MIMINAL_HASHSIZE)
@@ -572,7 +567,7 @@ hash_netport_create(struct ip_set *set, struct nlattr *head, int len, u32 flags)
                        ? &hash_netport4_variant : &hash_netport6_variant;
        }
 
-       pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)",
+       pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
                 set->name, jhash_size(h->table->htable_bits),
                 h->table->htable_bits, h->maxelem, set->data, h->table);
 
diff --git a/extensions/ipset-5/ip_set_kernel.h b/extensions/ipset-5/ip_set_kernel.h
deleted file mode 100644 (file)
index d770589..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef _IP_SET_KERNEL_H
-#define _IP_SET_KERNEL_H
-
-#ifdef __KERNEL__
-
-#ifdef CONFIG_DEBUG_KERNEL
-/* Complete debug messages */
-#define pr_fmt(fmt) "%s %s[%i]: " fmt "\n", __FILE__, __func__, __LINE__
-#endif
-
-#include <linux/kernel.h>
-
-#endif /* __KERNEL__ */
-
-#endif /*_IP_SET_H */
index c1434a135c0bca4069e67725d186fd85a33f7b5d..398adc4fccf14cd117dbcb5169689dd092c20373 100644 (file)
@@ -7,7 +7,6 @@
 
 /* Kernel module implementing an IP set type: the list:set type */
 
-#include "ip_set_kernel.h"
 #include <linux/module.h>
 #include <linux/ip.h>
 #include <linux/skbuff.h>
@@ -68,8 +67,8 @@ list_set_expired(const struct list_set *map, u32 id)
 static inline int
 list_set_exist(const struct set_telem *elem)
 {
-       return elem->id != IPSET_INVALID_ID
-              && !ip_set_timeout_expired(elem->timeout);
+       return elem->id != IPSET_INVALID_ID &&
+              !ip_set_timeout_expired(elem->timeout);
 }
 
 /* Set list without and with timeout */
@@ -122,22 +121,22 @@ static const struct nla_policy list_set_adt_policy[IPSET_ATTR_ADT_MAX+1] = {
        [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
 };
 
-static inline bool
+static bool
 next_id_eq(const struct list_set *map, u32 i, ip_set_id_t id)
 {
        const struct set_elem *elem;
 
        if (i + 1 < map->size) {
                elem = list_set_elem(map, i + 1);
-               return !!(elem->id == id
-                         && !(with_timeout(map->timeout)
-                              && list_set_expired(map, i + 1)));
+               return !!(elem->id == id &&
+                         !(with_timeout(map->timeout) &&
+                           list_set_expired(map, i + 1)));
        }
 
        return 0;
 }
 
-static inline void
+static void
 list_elem_add(struct list_set *map, u32 i, ip_set_id_t id)
 {
        struct set_elem *e;
@@ -150,7 +149,7 @@ list_elem_add(struct list_set *map, u32 i, ip_set_id_t id)
        }
 }
 
-static inline void
+static void
 list_elem_tadd(struct list_set *map, u32 i, ip_set_id_t id,
               unsigned long timeout)
 {
@@ -223,20 +222,22 @@ list_set_uadt(struct ip_set *set, struct nlattr *head, int len,
                      list_set_adt_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!tb[IPSET_ATTR_NAME] ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
+               return -IPSET_ERR_PROTOCOL;
+
        if (tb[IPSET_ATTR_LINENO])
                *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 
-       if (tb[IPSET_ATTR_NAME]) {
-               id = ip_set_get_byname(nla_data(tb[IPSET_ATTR_NAME]), &s);
-               if (id == IPSET_INVALID_ID)
-                       return -IPSET_ERR_NAME;
-               /* "Loop detection" */
-               if (s->type->features & IPSET_TYPE_NAME) {
-                       ret = -IPSET_ERR_LOOP;
-                       goto finish;
-               }
-       } else
-               return -IPSET_ERR_PROTOCOL;
+       id = ip_set_get_byname(nla_data(tb[IPSET_ATTR_NAME]), &s);
+       if (id == IPSET_INVALID_ID)
+               return -IPSET_ERR_NAME;
+       /* "Loop detection" */
+       if (s->type->features & IPSET_TYPE_NAME) {
+               ret = -IPSET_ERR_LOOP;
+               goto finish;
+       }
 
        if (tb[IPSET_ATTR_CADT_FLAGS]) {
                u32 f = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
@@ -270,8 +271,8 @@ list_set_uadt(struct ip_set *set, struct nlattr *head, int len,
        case IPSET_TEST:
                for (i = 0; i < map->size && !ret; i++) {
                        elem = list_set_elem(map, i);
-                       if (elem->id == IPSET_INVALID_ID
-                           || (before != 0 && i + 1 >= map->size))
+                       if (elem->id == IPSET_INVALID_ID ||
+                           (before != 0 && i + 1 >= map->size))
                                break;
                        else if (with_timeout && list_set_expired(map, i))
                                continue;
@@ -286,8 +287,8 @@ list_set_uadt(struct ip_set *set, struct nlattr *head, int len,
        case IPSET_ADD:
                for (i = 0; i < map->size && !ret; i++) {
                        elem = list_set_elem(map, i);
-                       if (elem->id == id
-                           && !(with_timeout && list_set_expired(map, i)))
+                       if (elem->id == id &&
+                           !(with_timeout && list_set_expired(map, i)))
                                ret = -IPSET_ERR_EXIST;
                }
                if (ret == -IPSET_ERR_EXIST)
@@ -318,14 +319,14 @@ list_set_uadt(struct ip_set *set, struct nlattr *head, int len,
                                break;
                        } else if (with_timeout && list_set_expired(map, i))
                                continue;
-                       else if (elem->id == id
-                                && (before == 0
-                                    || (before > 0
-                                        && next_id_eq(map, i, refid))))
+                       else if (elem->id == id &&
+                                (before == 0 ||
+                                 (before > 0 &&
+                                  next_id_eq(map, i, refid))))
                                ret = list_set_del(map, id, i);
-                       else if (before < 0
-                                && elem->id == refid
-                                && next_id_eq(map, i, id))
+                       else if (before < 0 &&
+                                elem->id == refid &&
+                                next_id_eq(map, i, id))
                                ret = list_set_del(map, id, i + 1);
                }
                break;
@@ -449,8 +450,8 @@ list_set_same_set(const struct ip_set *a, const struct ip_set *b)
        const struct list_set *x = a->data;
        const struct list_set *y = b->data;
 
-       return x->size == y->size
-              && x->timeout == y->timeout;
+       return x->size == y->size &&
+              x->timeout == y->timeout;
 }
 
 static const struct ip_set_type_variant list_set = {
@@ -476,8 +477,8 @@ list_set_gc(unsigned long ul_set)
        read_lock_bh(&set->lock);
        for (i = map->size - 1; i >= 0; i--) {
                e = (struct set_telem *) list_set_elem(map, i);
-               if (e->id != IPSET_INVALID_ID
-                   && list_set_expired(map, i))
+               if (e->id != IPSET_INVALID_ID &&
+                   list_set_expired(map, i))
                        list_set_del(map, e->id, i);
        }
        read_unlock_bh(&set->lock);
@@ -486,7 +487,7 @@ list_set_gc(unsigned long ul_set)
        add_timer(&map->gc);
 }
 
-static inline void
+static void
 list_set_gc_init(struct ip_set *set)
 {
        struct list_set *map = set->data;
@@ -506,7 +507,7 @@ list_set_create_policy[IPSET_ATTR_CREATE_MAX+1] = {
        [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
 };
 
-static inline bool
+static bool
 init_list_set(struct ip_set *set, u32 size, size_t dsize,
              unsigned long timeout)
 {
@@ -542,6 +543,10 @@ list_set_create(struct ip_set *set, struct nlattr *head, int len,
                      list_set_create_policy))
                return -IPSET_ERR_PROTOCOL;
 
+       if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_SIZE) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+               return -IPSET_ERR_PROTOCOL;
+
        if (tb[IPSET_ATTR_SIZE])
                size = ip_set_get_h32(tb[IPSET_ATTR_SIZE]);
        if (size < IP_SET_LIST_MIN_SIZE)
index 738371604b26a568a819f189b0a85ee6d39575a2..9f30c5f2ec1cfcd6f02bb3d76413f4e223402827 100644 (file)
@@ -43,17 +43,17 @@ ip_set_timeout_uget(struct nlattr *tb)
 static inline bool
 ip_set_timeout_test(unsigned long timeout)
 {
-       return timeout != IPSET_ELEM_UNSET
-               && (timeout == IPSET_ELEM_PERMANENT
-                   || time_after(timeout, jiffies));
+       return timeout != IPSET_ELEM_UNSET &&
+              (timeout == IPSET_ELEM_PERMANENT ||
+               time_after(timeout, jiffies));
 }
 
 static inline bool
 ip_set_timeout_expired(unsigned long timeout)
 {
-       return timeout != IPSET_ELEM_UNSET
-              && timeout != IPSET_ELEM_PERMANENT
-              && time_before(timeout, jiffies);
+       return timeout != IPSET_ELEM_UNSET &&
+              timeout != IPSET_ELEM_PERMANENT &&
+              time_before(timeout, jiffies);
 }
 
 static inline unsigned long
@@ -88,15 +88,15 @@ ip_set_timeout_get(unsigned long timeout)
 static inline bool
 ip_set_timeout_test(unsigned long timeout)
 {
-       return timeout == IPSET_ELEM_PERMANENT
-              || time_after(timeout, jiffies);
+       return timeout == IPSET_ELEM_PERMANENT ||
+              time_after(timeout, jiffies);
 }
 
 static inline bool
 ip_set_timeout_expired(unsigned long timeout)
 {
-       return timeout != IPSET_ELEM_PERMANENT
-              && time_before(timeout, jiffies);
+       return timeout != IPSET_ELEM_PERMANENT &&
+              time_before(timeout, jiffies);
 }
 
 static inline unsigned long
index e3473ba560e3b9ec097845b72a322786d97018bd..e9c0764df9ee9d06dabe2e18017b43d06ef73e63 100644 (file)
@@ -14,7 +14,7 @@
  * This table works for both IPv4 and IPv6;
  * just use prefixlen_netmask_map[prefixlength].ip.
  */
-const union nf_inet_addr prefixlen_netmask_map[] = {
+const union nf_inet_addr ip_set_netmask_map[] = {
        E(0x00000000, 0x00000000, 0x00000000, 0x00000000),
        E(0x80000000, 0x00000000, 0x00000000, 0x00000000),
        E(0xC0000000, 0x00000000, 0x00000000, 0x00000000),
@@ -145,17 +145,19 @@ const union nf_inet_addr prefixlen_netmask_map[] = {
        E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE),
        E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF),
 };
-EXPORT_SYMBOL_GPL(prefixlen_netmask_map);
+EXPORT_SYMBOL_GPL(ip_set_netmask_map);
 
 #undef  E
-#define E(a, b, c, d) \
-       {.ip6 = { a, b, c, d } }
+#define E(a, b, c, d)                                          \
+       {.ip6 = { (__force __be32) a, (__force __be32) b,       \
+                 (__force __be32) c, (__force __be32) d,       \
+       } }
 
 /*
  * This table works for both IPv4 and IPv6;
  * just use prefixlen_hostmask_map[prefixlength].ip.
  */
-const union nf_inet_addr prefixlen_hostmask_map[] = {
+const union nf_inet_addr ip_set_hostmask_map[] = {
        E(0x00000000, 0x00000000, 0x00000000, 0x00000000),
        E(0x80000000, 0x00000000, 0x00000000, 0x00000000),
        E(0xC0000000, 0x00000000, 0x00000000, 0x00000000),
@@ -286,4 +288,4 @@ const union nf_inet_addr prefixlen_hostmask_map[] = {
        E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE),
        E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF),
 };
-EXPORT_SYMBOL_GPL(prefixlen_hostmask_map);
+EXPORT_SYMBOL_GPL(ip_set_hostmask_map);
index fe7153cc0851af775a3a1e77f0d8c087c782cbf6..0e1fb50da562914a794d4cb9f02f32132b4f0e41 100644 (file)
@@ -5,12 +5,31 @@
 #include <linux/netfilter.h> 
 
 /* Prefixlen maps, by Jan Engelhardt  */
-extern const union nf_inet_addr prefixlen_netmask_map[];
-extern const union nf_inet_addr prefixlen_hostmask_map[];
+extern const union nf_inet_addr ip_set_netmask_map[];
+extern const union nf_inet_addr ip_set_hostmask_map[];
 
-#define NETMASK(n)     prefixlen_netmask_map[n].ip
-#define NETMASK6(n)    prefixlen_netmask_map[n].ip6
-#define HOSTMASK(n)    prefixlen_hostmask_map[n].ip
-#define HOSTMASK6(n)   prefixlen_hostmask_map[n].ip6
+static inline __be32
+ip_set_netmask(u8 pfxlen)
+{
+       return ip_set_netmask_map[pfxlen].ip;
+}
+
+static inline const __be32 *
+ip_set_netmask6(u8 pfxlen)
+{
+       return &ip_set_netmask_map[pfxlen].ip6[0];
+}
+
+static inline u32
+ip_set_hostmask(u8 pfxlen)
+{
+       return (__force u32) ip_set_hostmask_map[pfxlen].ip;
+}
+
+static inline const __be32 *
+ip_set_hostmask6(u8 pfxlen)
+{
+       return &ip_set_hostmask_map[pfxlen].ip6[0];
+}
 
 #endif /*_PFXLEN_H */
index beb3dab7bf510e1a2e7a0c90c8d4728409aba44f..56e6937d932155ed90942ad8330f0fb912681486 100644 (file)
@@ -108,12 +108,12 @@ set_match_v0_checkentry(const struct xt_mtchk_param *par)
        index = ip_set_nfnl_get_byindex(info->match_set.index);
 
        if (index == IPSET_INVALID_ID) {
-               pr_warning("Cannot find set indentified by id %u to match",
+               pr_warning("Cannot find set indentified by id %u to match\n",
                           info->match_set.index);
                return CHECK_FAIL;      /* error */
        }
        if (info->match_set.u.flags[IPSET_DIM_MAX-1] != 0) {
-               pr_warning("That's nasty!");
+               pr_warning("That's nasty!\n");
                return CHECK_FAIL;      /* error */
        }
 
@@ -167,7 +167,7 @@ set_target_v0_checkentry(const struct xt_tgchk_param *par)
        if (info->add_set.index != IPSET_INVALID_ID) {
                index = ip_set_nfnl_get_byindex(info->add_set.index);
                if (index == IPSET_INVALID_ID) {
-                       pr_warning("cannot find add_set index %u as target",
+                       pr_warning("cannot find add_set index %u as target\n",
                                   info->add_set.index);
                        return CHECK_FAIL;      /* error */
                }
@@ -176,14 +176,14 @@ set_target_v0_checkentry(const struct xt_tgchk_param *par)
        if (info->del_set.index != IPSET_INVALID_ID) {
                index = ip_set_nfnl_get_byindex(info->del_set.index);
                if (index == IPSET_INVALID_ID) {
-                       pr_warning("cannot find del_set index %u as target",
+                       pr_warning("cannot find del_set index %u as target\n",
                                   info->del_set.index);
                        return CHECK_FAIL;      /* error */
                }
        }
-       if (info->add_set.u.flags[IPSET_DIM_MAX-1] != 0
-           || info->del_set.u.flags[IPSET_DIM_MAX-1] != 0) {
-               pr_warning("That's nasty!");
+       if (info->add_set.u.flags[IPSET_DIM_MAX-1] != 0 ||
+           info->del_set.u.flags[IPSET_DIM_MAX-1] != 0) {
+               pr_warning("That's nasty!\n");
                return CHECK_FAIL;      /* error */
        }
 
@@ -237,12 +237,12 @@ set_match_checkentry(const struct xt_mtchk_param *par)
        index = ip_set_nfnl_get_byindex(info->match_set.index);
 
        if (index == IPSET_INVALID_ID) {
-               pr_warning("Cannot find set indentified by id %u to match",
+               pr_warning("Cannot find set indentified by id %u to match\n",
                           info->match_set.index);
                return CHECK_FAIL;      /* error */
        }
        if (info->match_set.dim > IPSET_DIM_MAX) {
-               pr_warning("That's nasty!");
+               pr_warning("That's nasty!\n");
                return CHECK_FAIL;      /* error */
        }
 
@@ -295,7 +295,7 @@ set_target_checkentry(const struct xt_tgchk_param *par)
        if (info->add_set.index != IPSET_INVALID_ID) {
                index = ip_set_nfnl_get_byindex(info->add_set.index);
                if (index == IPSET_INVALID_ID) {
-                       pr_warning("cannot find add_set index %u as target",
+                       pr_warning("cannot find add_set index %u as target\n",
                                   info->add_set.index);
                        return CHECK_FAIL;      /* error */
                }
@@ -304,14 +304,14 @@ set_target_checkentry(const struct xt_tgchk_param *par)
        if (info->del_set.index != IPSET_INVALID_ID) {
                index = ip_set_nfnl_get_byindex(info->del_set.index);
                if (index == IPSET_INVALID_ID) {
-                       pr_warning("cannot find del_set index %u as target",
+                       pr_warning("cannot find del_set index %u as target\n",
                                   info->del_set.index);
                        return CHECK_FAIL;      /* error */
                }
        }
-       if (info->add_set.dim > IPSET_DIM_MAX
-           || info->del_set.flags > IPSET_DIM_MAX) {
-               pr_warning("That's nasty!");
+       if (info->add_set.dim > IPSET_DIM_MAX ||
+           info->del_set.flags > IPSET_DIM_MAX) {
+               pr_warning("That's nasty!\n");
                return CHECK_FAIL;      /* error */
        }