]> granicus.if.org Git - ipset/commitdiff
Move the type specifici attribute validation to the core
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Thu, 27 Jan 2011 11:44:17 +0000 (12:44 +0100)
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Thu, 27 Jan 2011 11:44:17 +0000 (12:44 +0100)
The type specific attribute validation can be moved to the ipset core.
That way it's done centrally and thus can be eliminated from the individual
set types (suggested by Patrick McHardy).

13 files changed:
kernel/include/linux/netfilter/ipset/ip_set.h
kernel/include/linux/netfilter/ipset/ip_set_ahash.h
kernel/ip_set_bitmap_ip.c
kernel/ip_set_bitmap_ipmac.c
kernel/ip_set_bitmap_port.c
kernel/ip_set_core.c
kernel/ip_set_hash_ip.c
kernel/ip_set_hash_ipport.c
kernel/ip_set_hash_ipportip.c
kernel/ip_set_hash_ipportnet.c
kernel/ip_set_hash_net.c
kernel/ip_set_hash_netport.c
kernel/ip_set_list_set.c

index 5fbb1b538903cb82ed6c2f79b1e12c4b89f6f940..88e561cf5b28fb1a5773a259ee2f515b631d6426 100644 (file)
@@ -229,7 +229,7 @@ struct ip_set_type_variant {
         *              returns negative error code,
         *                      zero for no match/success to add/delete
         *                      positive for matching element */
-       int (*uadt)(struct ip_set *set, struct nlattr *head, int len,
+       int (*uadt)(struct ip_set *set, struct nlattr *tb[],
                    enum ipset_adt adt, u32 *lineno, u32 flags);
 
        /* Low level add/del/test functions */
@@ -272,8 +272,11 @@ struct ip_set_type {
        u8 revision;
 
        /* Create set */
-       int (*create)(struct ip_set *set,
-                     struct nlattr *head, int len, u32 flags);
+       int (*create)(struct ip_set *set, struct nlattr *tb[], u32 flags);
+
+       /* Attribute policies */
+       const struct nla_policy create_policy[IPSET_ATTR_CREATE_MAX + 1];
+       const struct nla_policy adt_policy[IPSET_ATTR_ADT_MAX + 1];
 
        /* Set this to THIS_MODULE if you are a module, otherwise NULL */
        struct module *me;
index 983eaf0518e50f1e3fada70a0ccaf7cbcadedb8f..ec9d9bea1e370e937aaf3006c70c157bc45eb7b4 100644 (file)
@@ -589,7 +589,7 @@ static int
 type_pf_kadt(struct ip_set *set, const struct sk_buff * skb,
             enum ipset_adt adt, u8 pf, u8 dim, u8 flags);
 static int
-type_pf_uadt(struct ip_set *set, struct nlattr *head, int len,
+type_pf_uadt(struct ip_set *set, struct nlattr *tb[],
             enum ipset_adt adt, u32 *lineno, u32 flags);
 
 static const struct ip_set_type_variant type_pf_variant = {
index 19251d6959d1af97e11a128efd58f8dd89ed2354..804dcc2f3e6092e888e3b4c97f7fad9a4f5918f8 100644 (file)
@@ -100,27 +100,14 @@ bitmap_ip_kadt(struct ip_set *set, const struct sk_buff *skb,
        }
 }
 
-static const struct nla_policy bitmap_ip_adt_policy[IPSET_ATTR_ADT_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 },
-       [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
-};
-
 static int
-bitmap_ip_uadt(struct ip_set *set, struct nlattr *head, int len,
+bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[],
               enum ipset_adt adt, u32 *lineno, u32 flags)
 {
        struct bitmap_ip *map = set->data;
-       struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
        u32 ip, ip_to, id;
        int ret = 0;
 
-       if (nla_parse(tb, IPSET_ATTR_ADT_MAX, head, len,
-                     bitmap_ip_adt_policy))
-               return -IPSET_ERR_PROTOCOL;
-
        if (unlikely(!tb[IPSET_ATTR_IP]))
                return -IPSET_ERR_PROTOCOL;
 
@@ -354,18 +341,13 @@ bitmap_ip_timeout_kadt(struct ip_set *set, const struct sk_buff *skb,
 }
 
 static int
-bitmap_ip_timeout_uadt(struct ip_set *set, struct nlattr *head, int len,
+bitmap_ip_timeout_uadt(struct ip_set *set, struct nlattr *tb[],
                       enum ipset_adt adt, u32 *lineno, u32 flags)
 {
        struct bitmap_ip_timeout *map = set->data;
-       struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
        u32 ip, ip_to, id, timeout = map->timeout;
        int ret = 0;
 
-       if (nla_parse(tb, IPSET_ATTR_ADT_MAX, head, 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;
@@ -571,15 +553,6 @@ bitmap_ip_gc_init(struct ip_set *set)
 
 /* Create bitmap:ip type of sets */
 
-static const struct nla_policy
-bitmap_ip_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_NETMASK]    = { .type = NLA_U8  },
-       [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
-};
-
 static bool
 init_map_ip(struct ip_set *set, struct bitmap_ip *map,
            u32 first_ip, u32 last_ip,
@@ -601,18 +574,12 @@ init_map_ip(struct ip_set *set, struct bitmap_ip *map,
 }
 
 static int
-bitmap_ip_create(struct ip_set *set, struct nlattr *head, int len,
-                u32 flags)
+bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
 {
-       struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1];
        u32 first_ip, last_ip, hosts, elements;
        u8 netmask = 32;
        int ret;
 
-       if (nla_parse(tb, IPSET_ATTR_CREATE_MAX, head, len,
-                     bitmap_ip_create_policy))
-               return -IPSET_ERR_PROTOCOL;
-
        if (unlikely(!tb[IPSET_ATTR_IP] ||
                     !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
                return -IPSET_ERR_PROTOCOL;
@@ -721,6 +688,20 @@ static struct ip_set_type bitmap_ip_type __read_mostly = {
        .family         = AF_INET,
        .revision       = 0,
        .create         = bitmap_ip_create,
+       .create_policy  = {
+               [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
+               [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
+               [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
+               [IPSET_ATTR_NETMASK]    = { .type = NLA_U8  },
+               [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
+       },
+       .adt_policy     = {
+               [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 },
+               [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
+       },
        .me             = THIS_MODULE,
 };
 
index 3fa392151c498be404e00e10f18dd129781f9cba..d826332d293708de9f8b225dffac7e1b68dbb003 100644 (file)
@@ -361,29 +361,16 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
        return adtfn(set, &data, map->timeout);
 }
 
-static const struct nla_policy
-bitmap_ipmac_adt_policy[IPSET_ATTR_ADT_MAX + 1] = {
-       [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
-       [IPSET_ATTR_ETHER]      = { .type = NLA_BINARY, .len  = ETH_ALEN },
-       [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
-       [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
-};
-
 static int
-bitmap_ipmac_uadt(struct ip_set *set, struct nlattr *head, int len,
+bitmap_ipmac_uadt(struct ip_set *set, struct nlattr *tb[],
                  enum ipset_adt adt, u32 *lineno, u32 flags)
 {
        const struct bitmap_ipmac *map = set->data;
-       struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
        ipset_adtfn adtfn = set->variant->adt[adt];
        struct ipmac data;
        u32 timeout = map->timeout;
        int ret = 0;
 
-       if (nla_parse(tb, IPSET_ATTR_ADT_MAX, head, 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;
@@ -542,14 +529,6 @@ bitmap_ipmac_gc_init(struct ip_set *set)
 
 /* Create bitmap:ip,mac type of sets */
 
-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 },
-};
-
 static bool
 init_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map,
               u32 first_ip, u32 last_ip)
@@ -568,18 +547,13 @@ init_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map,
 }
 
 static int
-bitmap_ipmac_create(struct ip_set *set, struct nlattr *head, int len,
+bitmap_ipmac_create(struct ip_set *set, struct nlattr *tb[],
                    u32 flags)
 {
-       struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1];
        u32 first_ip, last_ip, elements;
        struct bitmap_ipmac *map;
        int ret;
 
-       if (nla_parse(tb, IPSET_ATTR_CREATE_MAX, head, len,
-                     bitmap_ipmac_create_policy))
-               return -IPSET_ERR_PROTOCOL;
-
        if (unlikely(!tb[IPSET_ATTR_IP] ||
                     !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
                return -IPSET_ERR_PROTOCOL;
@@ -650,6 +624,18 @@ static struct ip_set_type bitmap_ipmac_type = {
        .family         = AF_INET,
        .revision       = 0,
        .create         = bitmap_ipmac_create,
+       .create_policy  = {
+               [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 },
+       },
+       .adt_policy     = {
+               [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
+               [IPSET_ATTR_ETHER]      = { .type = NLA_BINARY, .len  = ETH_ALEN },
+               [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
+               [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
+       },
        .me             = THIS_MODULE,
 };
 
index 862b74120d8adf6926b98fff5f70542cb66c7ed7..c5c4f279f3708657e602673ef40c30a25dc5b694 100644 (file)
@@ -95,27 +95,15 @@ bitmap_port_kadt(struct ip_set *set, const struct sk_buff *skb,
        }
 }
 
-static const struct nla_policy bitmap_port_adt_policy[IPSET_ATTR_ADT_MAX+1] = {
-       [IPSET_ATTR_PORT]       = { .type = NLA_U16 },
-       [IPSET_ATTR_PORT_TO]    = { .type = NLA_U16 },
-       [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
-       [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
-};
-
 static int
-bitmap_port_uadt(struct ip_set *set, struct nlattr *head, int len,
+bitmap_port_uadt(struct ip_set *set, struct nlattr *tb[],
                 enum ipset_adt adt, u32 *lineno, u32 flags)
 {
        struct bitmap_port *map = set->data;
-       struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
        u32 port;       /* wraparound */
        u16 id, port_to;
        int ret = 0;
 
-       if (nla_parse(tb, IPSET_ATTR_ADT_MAX, head, 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;
@@ -338,19 +326,14 @@ bitmap_port_timeout_kadt(struct ip_set *set, const struct sk_buff *skb,
 }
 
 static int
-bitmap_port_timeout_uadt(struct ip_set *set, struct nlattr *head, int len,
+bitmap_port_timeout_uadt(struct ip_set *set, struct nlattr *tb[],
                         enum ipset_adt adt, u32 *lineno, u32 flags)
 {
        const struct bitmap_port_timeout *map = set->data;
-       struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
        u16 id, port_to;
        u32 port, timeout = map->timeout;       /* wraparound */
        int ret = 0;
 
-       if (nla_parse(tb, IPSET_ATTR_ADT_MAX, head, 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)))
@@ -543,13 +526,6 @@ bitmap_port_gc_init(struct ip_set *set)
 
 /* Create bitmap:ip type of sets */
 
-static const struct nla_policy
-bitmap_port_create_policy[IPSET_ATTR_CREATE_MAX+1] = {
-       [IPSET_ATTR_PORT]       = { .type = NLA_U16 },
-       [IPSET_ATTR_PORT_TO]    = { .type = NLA_U16 },
-       [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
-};
-
 static bool
 init_map_port(struct ip_set *set, struct bitmap_port *map,
              u16 first_port, u16 last_port)
@@ -567,16 +543,11 @@ init_map_port(struct ip_set *set, struct bitmap_port *map,
 }
 
 static int
-bitmap_port_create(struct ip_set *set, struct nlattr *head, int len,
+bitmap_port_create(struct ip_set *set, struct nlattr *tb[],
                 u32 flags)
 {
-       struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1];
        u16 first_port, last_port;
 
-       if (nla_parse(tb, IPSET_ATTR_CREATE_MAX, head, len,
-                     bitmap_port_create_policy))
-               return -IPSET_ERR_PROTOCOL;
-
        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)))
@@ -638,6 +609,17 @@ static struct ip_set_type bitmap_port_type = {
        .family         = AF_UNSPEC,
        .revision       = 0,
        .create         = bitmap_port_create,
+       .create_policy  = {
+               [IPSET_ATTR_PORT]       = { .type = NLA_U16 },
+               [IPSET_ATTR_PORT_TO]    = { .type = NLA_U16 },
+               [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
+       },
+       .adt_policy     = {
+               [IPSET_ATTR_PORT]       = { .type = NLA_U16 },
+               [IPSET_ATTR_PORT_TO]    = { .type = NLA_U16 },
+               [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
+               [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
+       },
        .me             = THIS_MODULE,
 };
 
index 439268034669465a9747532aec1f2da052e3976c..bef659ab3d5f4842bc7d9d09e2f344f488d5c0eb 100644 (file)
@@ -621,10 +621,11 @@ ip_set_create(struct sock *ctnl, struct sk_buff *skb,
 {
        struct ip_set *set, *clash;
        ip_set_id_t index = IPSET_INVALID_ID;
+       struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1] = {};
        const char *name, *typename;
        u8 family, revision;
        u32 flags = flag_exist(nlh);
-       int ret = 0, len;
+       int ret = 0;
 
        if (unlikely(protocol_failed(attr) ||
                     attr[IPSET_ATTR_SETNAME] == NULL ||
@@ -669,11 +670,16 @@ ip_set_create(struct sock *ctnl, struct sk_buff *skb,
        /*
         * Without holding any locks, create private part.
         */
-       len = attr[IPSET_ATTR_DATA] ? nla_len(attr[IPSET_ATTR_DATA]) : 0;
-       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);
+       if (attr[IPSET_ATTR_DATA] &&
+           nla_parse(tb, IPSET_ATTR_CREATE_MAX,
+                     nla_data(attr[IPSET_ATTR_DATA]),
+                     nla_len(attr[IPSET_ATTR_DATA]),
+                     set->type->create_policy)) {
+               ret = -IPSET_ERR_PROTOCOL;
+               goto put_out;
+       }
+
+       ret = set->type->create(set, tb, flags);
        if (ret != 0)
                goto put_out;
 
@@ -1101,19 +1107,17 @@ static const struct nla_policy ip_set_adt_policy[IPSET_ATTR_CMD_MAX + 1] = {
 };
 
 static int
-call_ad(struct sk_buff *skb, const struct nlattr *const attr[],
-       struct ip_set *set, const struct nlattr *nla,
-       enum ipset_adt adt, u32 flags)
+call_ad(struct sk_buff *skb, struct ip_set *set,
+       struct nlattr *tb[], enum ipset_adt adt,
+       u32 flags, bool use_lineno)
 {
-       struct nlattr *head = nla_data(nla);
-       int ret, len = nla_len(nla), retried = 0;
+       int ret, retried = 0;
        u32 lineno = 0;
        bool eexist = flags & IPSET_FLAG_EXIST;
 
        do {
                write_lock_bh(&set->lock);
-               ret = set->variant->uadt(set, head, len, adt,
-                                        &lineno, flags);
+               ret = set->variant->uadt(set, tb, adt, &lineno, flags);
                write_unlock_bh(&set->lock);
        } while (ret == -EAGAIN &&
                 set->variant->resize &&
@@ -1121,7 +1125,7 @@ call_ad(struct sk_buff *skb, const struct nlattr *const attr[],
 
        if (!ret || (ret == -IPSET_ERR_EXIST && eexist))
                return 0;
-       if (lineno && attr[IPSET_ATTR_LINENO]) {
+       if (lineno && use_lineno) {
                /* Error in restore/batch mode: send back lineno */
                struct nlmsghdr *nlh = nlmsg_hdr(skb);
                int min_len = NLMSG_SPACE(sizeof(struct nfgenmsg));
@@ -1147,8 +1151,10 @@ ip_set_uadd(struct sock *ctnl, struct sk_buff *skb,
            const struct nlattr * const attr[])
 {
        struct ip_set *set;
+       struct nlattr *tb[IPSET_ATTR_ADT_MAX+1] = {};
        const struct nlattr *nla;
        u32 flags = flag_exist(nlh);
+       bool use_lineno;
        int ret = 0;
 
        if (unlikely(protocol_failed(attr) ||
@@ -1166,18 +1172,27 @@ ip_set_uadd(struct sock *ctnl, struct sk_buff *skb,
        if (set == NULL)
                return -ENOENT;
 
+       use_lineno = !!attr[IPSET_ATTR_LINENO];
        if (attr[IPSET_ATTR_DATA]) {
-               ret = call_ad(skb, attr,
-                             set, attr[IPSET_ATTR_DATA], IPSET_ADD, flags);
+               if (nla_parse(tb, IPSET_ATTR_ADT_MAX,
+                             nla_data(attr[IPSET_ATTR_DATA]),
+                             nla_len(attr[IPSET_ATTR_DATA]),
+                             set->type->adt_policy))
+                       return -IPSET_ERR_PROTOCOL;
+               ret = call_ad(skb, set, tb, IPSET_ADD, flags, use_lineno);
        } else {
                int nla_rem;
 
                nla_for_each_nested(nla, attr[IPSET_ATTR_ADT], nla_rem) {
+                       memset(tb, 0, sizeof(tb));
                        if (nla_type(nla) != IPSET_ATTR_DATA ||
-                           !flag_nested(nla))
+                           !flag_nested(nla) ||
+                           nla_parse(tb, IPSET_ATTR_ADT_MAX,
+                                     nla_data(nla), nla_len(nla),
+                                     set->type->adt_policy))
                                return -IPSET_ERR_PROTOCOL;
-                       ret = call_ad(skb, attr,
-                                      set, nla, IPSET_ADD, flags);
+                       ret = call_ad(skb, set, tb, IPSET_ADD,
+                                     flags, use_lineno);
                        if (ret < 0)
                                return ret;
                }
@@ -1191,8 +1206,10 @@ ip_set_udel(struct sock *ctnl, struct sk_buff *skb,
            const struct nlattr * const attr[])
 {
        struct ip_set *set;
+       struct nlattr *tb[IPSET_ATTR_ADT_MAX+1] = {};
        const struct nlattr *nla;
        u32 flags = flag_exist(nlh);
+       bool use_lineno;
        int ret = 0;
 
        if (unlikely(protocol_failed(attr) ||
@@ -1210,18 +1227,27 @@ ip_set_udel(struct sock *ctnl, struct sk_buff *skb,
        if (set == NULL)
                return -ENOENT;
 
+       use_lineno = !!attr[IPSET_ATTR_LINENO];
        if (attr[IPSET_ATTR_DATA]) {
-               ret = call_ad(skb, attr,
-                             set, attr[IPSET_ATTR_DATA], IPSET_DEL, flags);
+               if (nla_parse(tb, IPSET_ATTR_ADT_MAX,
+                             nla_data(attr[IPSET_ATTR_DATA]),
+                             nla_len(attr[IPSET_ATTR_DATA]),
+                             set->type->adt_policy))
+                       return -IPSET_ERR_PROTOCOL;
+               ret = call_ad(skb, set, tb, IPSET_DEL, flags, use_lineno);
        } else {
                int nla_rem;
 
                nla_for_each_nested(nla, attr[IPSET_ATTR_ADT], nla_rem) {
+                       memset(tb, 0, sizeof(*tb));
                        if (nla_type(nla) != IPSET_ATTR_DATA ||
-                           !flag_nested(nla))
+                           !flag_nested(nla) ||
+                           nla_parse(tb, IPSET_ATTR_ADT_MAX,
+                                     nla_data(nla), nla_len(nla),
+                                     set->type->adt_policy))
                                return -IPSET_ERR_PROTOCOL;
-                       ret = call_ad(skb, attr,
-                                      set, nla, IPSET_DEL, flags);
+                       ret = call_ad(skb, set, tb, IPSET_DEL,
+                                     flags, use_lineno);
                        if (ret < 0)
                                return ret;
                }
@@ -1235,6 +1261,7 @@ ip_set_utest(struct sock *ctnl, struct sk_buff *skb,
             const struct nlattr * const attr[])
 {
        struct ip_set *set;
+       struct nlattr *tb[IPSET_ATTR_ADT_MAX+1] = {};
        int ret = 0;
 
        if (unlikely(protocol_failed(attr) ||
@@ -1247,11 +1274,14 @@ ip_set_utest(struct sock *ctnl, struct sk_buff *skb,
        if (set == NULL)
                return -ENOENT;
 
+       if (nla_parse(tb, IPSET_ATTR_ADT_MAX,
+                     nla_data(attr[IPSET_ATTR_DATA]),
+                     nla_len(attr[IPSET_ATTR_DATA]),
+                     set->type->adt_policy))
+               return -IPSET_ERR_PROTOCOL;
+
        read_lock_bh(&set->lock);
-       ret = set->variant->uadt(set,
-                                nla_data(attr[IPSET_ATTR_DATA]),
-                                nla_len(attr[IPSET_ATTR_DATA]),
-                                IPSET_TEST, NULL, 0);
+       ret = set->variant->uadt(set, tb, IPSET_TEST, NULL, 0);
        read_unlock_bh(&set->lock);
        /* Userspace can't trigger element to be re-added */
        if (ret == -EAGAIN)
index 84caab6b0616f69fc693c936caf4f155f313f7af..53964bc831aac0ac6c691b6bdfc3f7740b7d2125 100644 (file)
@@ -127,29 +127,16 @@ hash_ip4_kadt(struct ip_set *set, const struct sk_buff *skb,
        return adtfn(set, &ip, h->timeout);
 }
 
-static const struct nla_policy hash_ip4_adt_policy[IPSET_ATTR_ADT_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 },
-       [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
-};
-
 static int
-hash_ip4_uadt(struct ip_set *set, struct nlattr *head, int len,
+hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
              enum ipset_adt adt, u32 *lineno, u32 flags)
 {
        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, 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;
@@ -320,22 +307,19 @@ static const struct nla_policy hash_ip6_adt_policy[IPSET_ATTR_ADT_MAX + 1] = {
 };
 
 static int
-hash_ip6_uadt(struct ip_set *set, struct nlattr *head, int len,
+hash_ip6_uadt(struct ip_set *set, struct nlattr *tb[],
              enum ipset_adt adt, u32 *lineno, u32 flags)
 {
        const struct ip_set_hash *h = set->data;
-       struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
        ipset_adtfn adtfn = set->variant->adt[adt];
        union nf_inet_addr ip;
        u32 timeout = h->timeout;
        int ret;
 
-       if (nla_parse(tb, IPSET_ATTR_ADT_MAX, head, len,
-                     hash_ip6_adt_policy))
-               return -IPSET_ERR_PROTOCOL;
-
        if (unlikely(!tb[IPSET_ATTR_IP] ||
-                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
+                    tb[IPSET_ATTR_IP_TO] ||
+                    tb[IPSET_ATTR_CIDR]))
                return -IPSET_ERR_PROTOCOL;
 
        if (tb[IPSET_ATTR_LINENO])
@@ -362,20 +346,9 @@ hash_ip6_uadt(struct ip_set *set, struct nlattr *head, int len,
 
 /* Create hash:ip type of sets */
 
-static const struct nla_policy
-hash_ip_create_policy[IPSET_ATTR_CREATE_MAX+1] = {
-       [IPSET_ATTR_HASHSIZE]   = { .type = NLA_U32 },
-       [IPSET_ATTR_MAXELEM]    = { .type = NLA_U32 },
-       [IPSET_ATTR_PROBES]     = { .type = NLA_U8 },
-       [IPSET_ATTR_RESIZE]     = { .type = NLA_U8  },
-       [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
-       [IPSET_ATTR_NETMASK]    = { .type = NLA_U8  },
-};
-
 static int
-hash_ip_create(struct ip_set *set, struct nlattr *head, int len, u32 flags)
+hash_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
 {
-       struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1];
        u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
        u8 netmask, hbits;
        struct ip_set_hash *h;
@@ -386,10 +359,6 @@ hash_ip_create(struct ip_set *set, struct nlattr *head, int len, u32 flags)
        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)))
@@ -464,6 +433,21 @@ static struct ip_set_type hash_ip_type __read_mostly = {
        .family         = AF_UNSPEC,
        .revision       = 0,
        .create         = hash_ip_create,
+       .create_policy  = {
+               [IPSET_ATTR_HASHSIZE]   = { .type = NLA_U32 },
+               [IPSET_ATTR_MAXELEM]    = { .type = NLA_U32 },
+               [IPSET_ATTR_PROBES]     = { .type = NLA_U8 },
+               [IPSET_ATTR_RESIZE]     = { .type = NLA_U8  },
+               [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
+               [IPSET_ATTR_NETMASK]    = { .type = NLA_U8  },
+       },
+       .adt_policy     = {
+               [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 },
+               [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
+       },
        .me             = THIS_MODULE,
 };
 
index c8bb7549d05732583d27638378547f0624246e5f..d9b192818e58ce8f28048e22e770539f89a4a4cd 100644 (file)
@@ -144,34 +144,17 @@ hash_ipport4_kadt(struct ip_set *set, const struct sk_buff *skb,
        return adtfn(set, &data, h->timeout);
 }
 
-static const struct nla_policy
-hash_ipport_adt_policy[IPSET_ATTR_ADT_MAX + 1] = {
-       [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
-       [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
-       [IPSET_ATTR_PORT]       = { .type = NLA_U16 },
-       [IPSET_ATTR_PORT_TO]    = { .type = NLA_U16 },
-       [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
-       [IPSET_ATTR_PROTO]      = { .type = NLA_U8 },
-       [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
-       [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
-};
-
 static int
-hash_ipport4_uadt(struct ip_set *set, struct nlattr *head, int len,
+hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
                  enum ipset_adt adt, u32 *lineno, u32 flags)
 {
        const struct ip_set_hash *h = set->data;
-       struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
        ipset_adtfn adtfn = set->variant->adt[adt];
        struct hash_ipport4_elem data = { };
        u32 ip, ip_to, p, port, port_to;
        u32 timeout = h->timeout;
        int ret;
 
-       if (nla_parse(tb, IPSET_ATTR_ADT_MAX, head, 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) ||
@@ -373,25 +356,22 @@ hash_ipport6_kadt(struct ip_set *set, const struct sk_buff *skb,
 }
 
 static int
-hash_ipport6_uadt(struct ip_set *set, struct nlattr *head, int len,
+hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[],
                  enum ipset_adt adt, u32 *lineno, u32 flags)
 {
        const struct ip_set_hash *h = set->data;
-       struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
        ipset_adtfn adtfn = set->variant->adt[adt];
        struct hash_ipport6_elem data = { };
        u32 port, port_to;
        u32 timeout = h->timeout;
        int ret;
 
-       if (nla_parse(tb, IPSET_ATTR_ADT_MAX, head, 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)))
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
+                    tb[IPSET_ATTR_IP_TO] ||
+                    tb[IPSET_ATTR_CIDR]))
                return -IPSET_ERR_PROTOCOL;
 
        if (tb[IPSET_ATTR_LINENO])
@@ -456,20 +436,9 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *head, int len,
 
 /* Create hash:ip type of sets */
 
-static const struct nla_policy
-hash_ipport_create_policy[IPSET_ATTR_CREATE_MAX+1] = {
-       [IPSET_ATTR_HASHSIZE]   = { .type = NLA_U32 },
-       [IPSET_ATTR_MAXELEM]    = { .type = NLA_U32 },
-       [IPSET_ATTR_PROBES]     = { .type = NLA_U8 },
-       [IPSET_ATTR_RESIZE]     = { .type = NLA_U8  },
-       [IPSET_ATTR_PROTO]      = { .type = NLA_U8 },
-       [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
-};
-
 static int
-hash_ipport_create(struct ip_set *set, struct nlattr *head, int len, u32 flags)
+hash_ipport_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
 {
-       struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1];
        struct ip_set_hash *h;
        u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
        u8 hbits;
@@ -477,10 +446,6 @@ hash_ipport_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;
 
-       if (nla_parse(tb, IPSET_ATTR_CREATE_MAX, head, len,
-                     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)))
@@ -545,6 +510,24 @@ static struct ip_set_type hash_ipport_type __read_mostly = {
        .family         = AF_UNSPEC,
        .revision       = 0,
        .create         = hash_ipport_create,
+       .create_policy  = {
+               [IPSET_ATTR_HASHSIZE]   = { .type = NLA_U32 },
+               [IPSET_ATTR_MAXELEM]    = { .type = NLA_U32 },
+               [IPSET_ATTR_PROBES]     = { .type = NLA_U8 },
+               [IPSET_ATTR_RESIZE]     = { .type = NLA_U8  },
+               [IPSET_ATTR_PROTO]      = { .type = NLA_U8 },
+               [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
+       },
+       .adt_policy     = {
+               [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
+               [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
+               [IPSET_ATTR_PORT]       = { .type = NLA_U16 },
+               [IPSET_ATTR_PORT_TO]    = { .type = NLA_U16 },
+               [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
+               [IPSET_ATTR_PROTO]      = { .type = NLA_U8 },
+               [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
+               [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
+       },
        .me             = THIS_MODULE,
 };
 
index 423bf4ea230b2b2d8bdaa150facbad7b39b33106..80dae9de5d18f1fadf4d0ac3efd7f341dd3c58d6 100644 (file)
@@ -148,35 +148,17 @@ hash_ipportip4_kadt(struct ip_set *set, const struct sk_buff *skb,
        return adtfn(set, &data, h->timeout);
 }
 
-static const struct nla_policy
-hash_ipportip_adt_policy[IPSET_ATTR_ADT_MAX + 1] = {
-       [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
-       [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
-       [IPSET_ATTR_IP2]        = { .type = NLA_NESTED },
-       [IPSET_ATTR_PORT]       = { .type = NLA_U16 },
-       [IPSET_ATTR_PORT_TO]    = { .type = NLA_U16 },
-       [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
-       [IPSET_ATTR_PROTO]      = { .type = NLA_U8 },
-       [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
-       [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
-};
-
 static int
-hash_ipportip4_uadt(struct ip_set *set, struct nlattr *head, int len,
+hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
                    enum ipset_adt adt, u32 *lineno, u32 flags)
 {
        const struct ip_set_hash *h = set->data;
-       struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
        ipset_adtfn adtfn = set->variant->adt[adt];
        struct hash_ipportip4_elem data = { };
        u32 ip, ip_to, p, port, port_to;
        u32 timeout = h->timeout;
        int ret;
 
-       if (nla_parse(tb, IPSET_ATTR_ADT_MAX, head, 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) ||
@@ -388,25 +370,22 @@ hash_ipportip6_kadt(struct ip_set *set, const struct sk_buff *skb,
 }
 
 static int
-hash_ipportip6_uadt(struct ip_set *set, struct nlattr *head, int len,
+hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[],
                    enum ipset_adt adt, u32 *lineno, u32 flags)
 {
        const struct ip_set_hash *h = set->data;
-       struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
        ipset_adtfn adtfn = set->variant->adt[adt];
        struct hash_ipportip6_elem data = { };
        u32 port, port_to;
        u32 timeout = h->timeout;
        int ret;
 
-       if (nla_parse(tb, IPSET_ATTR_ADT_MAX, head, 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)))
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
+                    tb[IPSET_ATTR_IP_TO] ||
+                    tb[IPSET_ATTR_CIDR]))
                return -IPSET_ERR_PROTOCOL;
 
        if (tb[IPSET_ATTR_LINENO])
@@ -475,20 +454,9 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *head, int len,
 
 /* Create hash:ip type of sets */
 
-static const struct nla_policy
-hash_ipportip_create_policy[IPSET_ATTR_CREATE_MAX+1] = {
-       [IPSET_ATTR_HASHSIZE]   = { .type = NLA_U32 },
-       [IPSET_ATTR_MAXELEM]    = { .type = NLA_U32 },
-       [IPSET_ATTR_PROBES]     = { .type = NLA_U8 },
-       [IPSET_ATTR_RESIZE]     = { .type = NLA_U8  },
-       [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
-};
-
 static int
-hash_ipportip_create(struct ip_set *set, struct nlattr *head,
-                    int len, u32 flags)
+hash_ipportip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
 {
-       struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1];
        struct ip_set_hash *h;
        u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
        u8 hbits;
@@ -496,10 +464,6 @@ hash_ipportip_create(struct ip_set *set, struct nlattr *head,
        if (!(set->family == AF_INET || set->family == AF_INET6))
                return -IPSET_ERR_INVALID_FAMILY;
 
-       if (nla_parse(tb, IPSET_ATTR_CREATE_MAX, head, len,
-                     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)))
@@ -564,6 +528,24 @@ static struct ip_set_type hash_ipportip_type __read_mostly = {
        .family         = AF_UNSPEC,
        .revision       = 0,
        .create         = hash_ipportip_create,
+       .create_policy  = {
+               [IPSET_ATTR_HASHSIZE]   = { .type = NLA_U32 },
+               [IPSET_ATTR_MAXELEM]    = { .type = NLA_U32 },
+               [IPSET_ATTR_PROBES]     = { .type = NLA_U8 },
+               [IPSET_ATTR_RESIZE]     = { .type = NLA_U8  },
+               [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
+       },
+       .adt_policy     = {
+               [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
+               [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
+               [IPSET_ATTR_IP2]        = { .type = NLA_NESTED },
+               [IPSET_ATTR_PORT]       = { .type = NLA_U16 },
+               [IPSET_ATTR_PORT_TO]    = { .type = NLA_U16 },
+               [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
+               [IPSET_ATTR_PROTO]      = { .type = NLA_U8 },
+               [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
+               [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
+       },
        .me             = THIS_MODULE,
 };
 
index 740ed5c1f635a5ea316167eaa047c83058d39e99..8eacd8a46c1c540d342129c95e7aa141cb99e15b 100644 (file)
@@ -168,36 +168,17 @@ hash_ipportnet4_kadt(struct ip_set *set, const struct sk_buff *skb,
        return adtfn(set, &data, h->timeout);
 }
 
-static const struct nla_policy
-hash_ipportnet_adt_policy[IPSET_ATTR_ADT_MAX + 1] = {
-       [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
-       [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
-       [IPSET_ATTR_IP2]        = { .type = NLA_NESTED },
-       [IPSET_ATTR_PORT]       = { .type = NLA_U16 },
-       [IPSET_ATTR_PORT_TO]    = { .type = NLA_U16 },
-       [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
-       [IPSET_ATTR_CIDR2]      = { .type = NLA_U8 },
-       [IPSET_ATTR_PROTO]      = { .type = NLA_U8 },
-       [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
-       [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
-};
-
 static int
-hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *head, int len,
+hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
                     enum ipset_adt adt, u32 *lineno, u32 flags)
 {
        const struct ip_set_hash *h = set->data;
-       struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
        ipset_adtfn adtfn = set->variant->adt[adt];
        struct hash_ipportnet4_elem data = { .cidr = HOST_MASK };
        u32 ip, ip_to, p, port, port_to;
        u32 timeout = h->timeout;
        int ret;
 
-       if (nla_parse(tb, IPSET_ATTR_ADT_MAX, head, 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) ||
@@ -443,25 +424,22 @@ hash_ipportnet6_kadt(struct ip_set *set, const struct sk_buff *skb,
 }
 
 static int
-hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *head, int len,
+hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
                     enum ipset_adt adt, u32 *lineno, u32 flags)
 {
        const struct ip_set_hash *h = set->data;
-       struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
        ipset_adtfn adtfn = set->variant->adt[adt];
        struct hash_ipportnet6_elem data = { .cidr = HOST_MASK };
        u32 port, port_to;
        u32 timeout = h->timeout;
        int ret;
 
-       if (nla_parse(tb, IPSET_ATTR_ADT_MAX, head, 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)))
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
+                    tb[IPSET_ATTR_IP_TO] ||
+                    tb[IPSET_ATTR_CIDR]))
                return -IPSET_ERR_PROTOCOL;
 
        if (tb[IPSET_ATTR_LINENO])
@@ -538,20 +516,9 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *head, int len,
 
 /* Create hash:ip type of sets */
 
-static const struct nla_policy
-hash_ipportnet_create_policy[IPSET_ATTR_CREATE_MAX+1] = {
-       [IPSET_ATTR_HASHSIZE]   = { .type = NLA_U32 },
-       [IPSET_ATTR_MAXELEM]    = { .type = NLA_U32 },
-       [IPSET_ATTR_PROBES]     = { .type = NLA_U8 },
-       [IPSET_ATTR_RESIZE]     = { .type = NLA_U8  },
-       [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
-};
-
 static int
-hash_ipportnet_create(struct ip_set *set, struct nlattr *head,
-                    int len, u32 flags)
+hash_ipportnet_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
 {
-       struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1];
        struct ip_set_hash *h;
        u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
        u8 hbits;
@@ -559,10 +526,6 @@ hash_ipportnet_create(struct ip_set *set, struct nlattr *head,
        if (!(set->family == AF_INET || set->family == AF_INET6))
                return -IPSET_ERR_INVALID_FAMILY;
 
-       if (nla_parse(tb, IPSET_ATTR_CREATE_MAX, head, len,
-                     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)))
@@ -630,6 +593,25 @@ static struct ip_set_type hash_ipportnet_type __read_mostly = {
        .family         = AF_UNSPEC,
        .revision       = 0,
        .create         = hash_ipportnet_create,
+       .create_policy  = {
+               [IPSET_ATTR_HASHSIZE]   = { .type = NLA_U32 },
+               [IPSET_ATTR_MAXELEM]    = { .type = NLA_U32 },
+               [IPSET_ATTR_PROBES]     = { .type = NLA_U8 },
+               [IPSET_ATTR_RESIZE]     = { .type = NLA_U8  },
+               [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
+       },
+       .adt_policy     = {
+               [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
+               [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
+               [IPSET_ATTR_IP2]        = { .type = NLA_NESTED },
+               [IPSET_ATTR_PORT]       = { .type = NLA_U16 },
+               [IPSET_ATTR_PORT_TO]    = { .type = NLA_U16 },
+               [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
+               [IPSET_ATTR_CIDR2]      = { .type = NLA_U8 },
+               [IPSET_ATTR_PROTO]      = { .type = NLA_U8 },
+               [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
+               [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
+       },
        .me             = THIS_MODULE,
 };
 
index 2330b4c39ecbafaba867a0d6ca037dce95b330b9..fb0e6a68d13e84148153d17e2544f4ee2c9b6df9 100644 (file)
@@ -147,27 +147,16 @@ hash_net4_kadt(struct ip_set *set, const struct sk_buff *skb,
        return adtfn(set, &data, h->timeout);
 }
 
-static const struct nla_policy hash_net_adt_policy[IPSET_ATTR_ADT_MAX + 1] = {
-       [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
-       [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
-       [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
-};
-
 static int
-hash_net4_uadt(struct ip_set *set, struct nlattr *head, int len,
+hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
               enum ipset_adt adt, u32 *lineno, u32 flags)
 {
        const struct ip_set_hash *h = set->data;
-       struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
        ipset_adtfn adtfn = set->variant->adt[adt];
        struct hash_net4_elem data = { .cidr = HOST_MASK };
        u32 timeout = h->timeout;
        int ret;
 
-       if (nla_parse(tb, IPSET_ATTR_ADT_MAX, head, 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;
@@ -324,20 +313,15 @@ hash_net6_kadt(struct ip_set *set, const struct sk_buff *skb,
 }
 
 static int
-hash_net6_uadt(struct ip_set *set, struct nlattr *head, int len,
+hash_net6_uadt(struct ip_set *set, struct nlattr *tb[],
               enum ipset_adt adt, u32 *lineno, u32 flags)
 {
        const struct ip_set_hash *h = set->data;
-       struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
        ipset_adtfn adtfn = set->variant->adt[adt];
        struct hash_net6_elem data = { .cidr = HOST_MASK };
        u32 timeout = h->timeout;
        int ret;
 
-       if (nla_parse(tb, IPSET_ATTR_ADT_MAX, head, 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;
@@ -370,19 +354,9 @@ hash_net6_uadt(struct ip_set *set, struct nlattr *head, int len,
 
 /* Create hash:ip type of sets */
 
-static const struct nla_policy
-hash_net_create_policy[IPSET_ATTR_CREATE_MAX+1] = {
-       [IPSET_ATTR_HASHSIZE]   = { .type = NLA_U32 },
-       [IPSET_ATTR_MAXELEM]    = { .type = NLA_U32 },
-       [IPSET_ATTR_PROBES]     = { .type = NLA_U8 },
-       [IPSET_ATTR_RESIZE]     = { .type = NLA_U8  },
-       [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
-};
-
 static int
-hash_net_create(struct ip_set *set, struct nlattr *head, int len, u32 flags)
+hash_net_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
 {
-       struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1];
        u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
        struct ip_set_hash *h;
        u8 hbits;
@@ -390,10 +364,6 @@ hash_net_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;
 
-       if (nla_parse(tb, IPSET_ATTR_CREATE_MAX, head, len,
-                     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)))
@@ -460,6 +430,18 @@ static struct ip_set_type hash_net_type __read_mostly = {
        .family         = AF_UNSPEC,
        .revision       = 0,
        .create         = hash_net_create,
+       .create_policy  = {
+               [IPSET_ATTR_HASHSIZE]   = { .type = NLA_U32 },
+               [IPSET_ATTR_MAXELEM]    = { .type = NLA_U32 },
+               [IPSET_ATTR_PROBES]     = { .type = NLA_U8 },
+               [IPSET_ATTR_RESIZE]     = { .type = NLA_U8  },
+               [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
+       },
+       .adt_policy     = {
+               [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
+               [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
+               [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
+       },
        .me             = THIS_MODULE,
 };
 
index f79077a63795af3d6ddc2344e03e7f352c4bbace..342250f9b114612948249aae59e2812d1c8131a9 100644 (file)
@@ -164,33 +164,17 @@ hash_netport4_kadt(struct ip_set *set, const struct sk_buff *skb,
        return adtfn(set, &data, h->timeout);
 }
 
-static const struct nla_policy
-hash_netport_adt_policy[IPSET_ATTR_ADT_MAX + 1] = {
-       [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
-       [IPSET_ATTR_PORT]       = { .type = NLA_U16 },
-       [IPSET_ATTR_PORT_TO]    = { .type = NLA_U16 },
-       [IPSET_ATTR_PROTO]      = { .type = NLA_U8 },
-       [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
-       [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
-       [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
-};
-
 static int
-hash_netport4_uadt(struct ip_set *set, struct nlattr *head, int len,
+hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
                   enum ipset_adt adt, u32 *lineno, u32 flags)
 {
        const struct ip_set_hash *h = set->data;
-       struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
        ipset_adtfn adtfn = set->variant->adt[adt];
        struct hash_netport4_elem data = { .cidr = HOST_MASK };
        u32 port, port_to;
        u32 timeout = h->timeout;
        int ret;
 
-       if (nla_parse(tb, IPSET_ATTR_ADT_MAX, head, 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) ||
@@ -401,21 +385,16 @@ hash_netport6_kadt(struct ip_set *set, const struct sk_buff *skb,
 }
 
 static int
-hash_netport6_uadt(struct ip_set *set, struct nlattr *head, int len,
+hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[],
                   enum ipset_adt adt, u32 *lineno, u32 flags)
 {
        const struct ip_set_hash *h = set->data;
-       struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
        ipset_adtfn adtfn = set->variant->adt[adt];
        struct hash_netport6_elem data = { .cidr = HOST_MASK };
        u32 port, port_to;
        u32 timeout = h->timeout;
        int ret;
 
-       if (nla_parse(tb, IPSET_ATTR_ADT_MAX, head, 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) ||
@@ -490,20 +469,9 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *head, int len,
 
 /* Create hash:ip type of sets */
 
-static const struct nla_policy
-hash_netport_create_policy[IPSET_ATTR_CREATE_MAX+1] = {
-       [IPSET_ATTR_HASHSIZE]   = { .type = NLA_U32 },
-       [IPSET_ATTR_MAXELEM]    = { .type = NLA_U32 },
-       [IPSET_ATTR_PROBES]     = { .type = NLA_U8 },
-       [IPSET_ATTR_RESIZE]     = { .type = NLA_U8  },
-       [IPSET_ATTR_PROTO]      = { .type = NLA_U8 },
-       [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
-};
-
 static int
-hash_netport_create(struct ip_set *set, struct nlattr *head, int len, u32 flags)
+hash_netport_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
 {
-       struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1];
        struct ip_set_hash *h;
        u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
        u8 hbits;
@@ -511,10 +479,6 @@ hash_netport_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;
 
-       if (nla_parse(tb, IPSET_ATTR_CREATE_MAX, head, len,
-                     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)))
@@ -581,6 +545,23 @@ static struct ip_set_type hash_netport_type __read_mostly = {
        .family         = AF_UNSPEC,
        .revision       = 0,
        .create         = hash_netport_create,
+       .create_policy  = {
+               [IPSET_ATTR_HASHSIZE]   = { .type = NLA_U32 },
+               [IPSET_ATTR_MAXELEM]    = { .type = NLA_U32 },
+               [IPSET_ATTR_PROBES]     = { .type = NLA_U8 },
+               [IPSET_ATTR_RESIZE]     = { .type = NLA_U8  },
+               [IPSET_ATTR_PROTO]      = { .type = NLA_U8 },
+               [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
+       },
+       .adt_policy     = {
+               [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
+               [IPSET_ATTR_PORT]       = { .type = NLA_U16 },
+               [IPSET_ATTR_PORT_TO]    = { .type = NLA_U16 },
+               [IPSET_ATTR_PROTO]      = { .type = NLA_U8 },
+               [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
+               [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
+               [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
+       },
        .me             = THIS_MODULE,
 };
 
index 933d9ef54664912507da039529d6eab461a2b82a..a47c32982f06233b48b37c386b32842cdf122614 100644 (file)
@@ -111,16 +111,6 @@ list_set_kadt(struct ip_set *set, const struct sk_buff *skb,
        return -EINVAL;
 }
 
-static const struct nla_policy list_set_adt_policy[IPSET_ATTR_ADT_MAX+1] = {
-       [IPSET_ATTR_NAME]       = { .type = NLA_STRING,
-                                   .len = IPSET_MAXNAMELEN },
-       [IPSET_ATTR_NAMEREF]    = { .type = NLA_STRING,
-                                   .len = IPSET_MAXNAMELEN },
-       [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
-       [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
-       [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
-};
-
 static bool
 next_id_eq(const struct list_set *map, u32 i, ip_set_id_t id)
 {
@@ -204,11 +194,10 @@ list_set_del(struct list_set *map, ip_set_id_t id, u32 i)
 }
 
 static int
-list_set_uadt(struct ip_set *set, struct nlattr *head, int len,
+list_set_uadt(struct ip_set *set, struct nlattr *tb[],
              enum ipset_adt adt, u32 *lineno, u32 flags)
 {
        struct list_set *map = set->data;
-       struct nlattr *tb[IPSET_ATTR_ADT_MAX+1];
        bool with_timeout = with_timeout(map->timeout);
        int before = 0;
        u32 timeout = map->timeout;
@@ -218,10 +207,6 @@ list_set_uadt(struct ip_set *set, struct nlattr *head, int len,
        u32 i;
        int ret = 0;
 
-       if (nla_parse(tb, IPSET_ATTR_ADT_MAX, head, 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)))
@@ -505,12 +490,6 @@ list_set_gc_init(struct ip_set *set)
 
 /* Create list:set type of sets */
 
-static const struct nla_policy
-list_set_create_policy[IPSET_ATTR_CREATE_MAX+1] = {
-       [IPSET_ATTR_SIZE]       = { .type = NLA_U32 },
-       [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
-};
-
 static bool
 init_list_set(struct ip_set *set, u32 size, size_t dsize,
              unsigned long timeout)
@@ -537,16 +516,10 @@ init_list_set(struct ip_set *set, u32 size, size_t dsize,
 }
 
 static int
-list_set_create(struct ip_set *set, struct nlattr *head, int len,
-               u32 flags)
+list_set_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
 {
-       struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1];
        u32 size = IP_SET_LIST_DEFAULT_SIZE;
 
-       if (nla_parse(tb, IPSET_ATTR_CREATE_MAX, head, 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;
@@ -579,6 +552,19 @@ static struct ip_set_type list_set_type __read_mostly = {
        .family         = AF_UNSPEC,
        .revision       = 0,
        .create         = list_set_create,
+       .create_policy  = {
+               [IPSET_ATTR_SIZE]       = { .type = NLA_U32 },
+               [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
+       },
+       .adt_policy     = {
+               [IPSET_ATTR_NAME]       = { .type = NLA_STRING,
+                                           .len = IPSET_MAXNAMELEN },
+               [IPSET_ATTR_NAMEREF]    = { .type = NLA_STRING,
+                                           .len = IPSET_MAXNAMELEN },
+               [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
+               [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
+               [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
+       },
        .me             = THIS_MODULE,
 };