From: Jozsef Kadlecsik Date: Thu, 27 Jan 2011 11:44:17 +0000 (+0100) Subject: Move the type specifici attribute validation to the core X-Git-Tag: v6.0~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b84145e442d1b8adec11648d09b2b45ccbe31c4e;p=thirdparty%2Fipset.git Move the type specifici attribute validation to the core 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). --- diff --git a/kernel/include/linux/netfilter/ipset/ip_set.h b/kernel/include/linux/netfilter/ipset/ip_set.h index 5fbb1b53..88e561cf 100644 --- a/kernel/include/linux/netfilter/ipset/ip_set.h +++ b/kernel/include/linux/netfilter/ipset/ip_set.h @@ -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; diff --git a/kernel/include/linux/netfilter/ipset/ip_set_ahash.h b/kernel/include/linux/netfilter/ipset/ip_set_ahash.h index 983eaf05..ec9d9bea 100644 --- a/kernel/include/linux/netfilter/ipset/ip_set_ahash.h +++ b/kernel/include/linux/netfilter/ipset/ip_set_ahash.h @@ -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 = { diff --git a/kernel/ip_set_bitmap_ip.c b/kernel/ip_set_bitmap_ip.c index 19251d69..804dcc2f 100644 --- a/kernel/ip_set_bitmap_ip.c +++ b/kernel/ip_set_bitmap_ip.c @@ -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, }; diff --git a/kernel/ip_set_bitmap_ipmac.c b/kernel/ip_set_bitmap_ipmac.c index 3fa39215..d826332d 100644 --- a/kernel/ip_set_bitmap_ipmac.c +++ b/kernel/ip_set_bitmap_ipmac.c @@ -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, }; diff --git a/kernel/ip_set_bitmap_port.c b/kernel/ip_set_bitmap_port.c index 862b7412..c5c4f279 100644 --- a/kernel/ip_set_bitmap_port.c +++ b/kernel/ip_set_bitmap_port.c @@ -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, }; diff --git a/kernel/ip_set_core.c b/kernel/ip_set_core.c index 43926803..bef659ab 100644 --- a/kernel/ip_set_core.c +++ b/kernel/ip_set_core.c @@ -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) diff --git a/kernel/ip_set_hash_ip.c b/kernel/ip_set_hash_ip.c index 84caab6b..53964bc8 100644 --- a/kernel/ip_set_hash_ip.c +++ b/kernel/ip_set_hash_ip.c @@ -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, }; diff --git a/kernel/ip_set_hash_ipport.c b/kernel/ip_set_hash_ipport.c index c8bb7549..d9b19281 100644 --- a/kernel/ip_set_hash_ipport.c +++ b/kernel/ip_set_hash_ipport.c @@ -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, }; diff --git a/kernel/ip_set_hash_ipportip.c b/kernel/ip_set_hash_ipportip.c index 423bf4ea..80dae9de 100644 --- a/kernel/ip_set_hash_ipportip.c +++ b/kernel/ip_set_hash_ipportip.c @@ -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, }; diff --git a/kernel/ip_set_hash_ipportnet.c b/kernel/ip_set_hash_ipportnet.c index 740ed5c1..8eacd8a4 100644 --- a/kernel/ip_set_hash_ipportnet.c +++ b/kernel/ip_set_hash_ipportnet.c @@ -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, }; diff --git a/kernel/ip_set_hash_net.c b/kernel/ip_set_hash_net.c index 2330b4c3..fb0e6a68 100644 --- a/kernel/ip_set_hash_net.c +++ b/kernel/ip_set_hash_net.c @@ -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, }; diff --git a/kernel/ip_set_hash_netport.c b/kernel/ip_set_hash_netport.c index f79077a6..342250f9 100644 --- a/kernel/ip_set_hash_netport.c +++ b/kernel/ip_set_hash_netport.c @@ -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, }; diff --git a/kernel/ip_set_list_set.c b/kernel/ip_set_list_set.c index 933d9ef5..a47c3298 100644 --- a/kernel/ip_set_list_set.c +++ b/kernel/ip_set_list_set.c @@ -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, };