diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/include/linux/netfilter/ipset/ip_set.h | 9 | ||||
-rw-r--r-- | kernel/include/linux/netfilter/ipset/ip_set_ahash.h | 2 | ||||
-rw-r--r-- | kernel/ip_set_bitmap_ip.c | 53 | ||||
-rw-r--r-- | kernel/ip_set_bitmap_ipmac.c | 42 | ||||
-rw-r--r-- | kernel/ip_set_bitmap_port.c | 46 | ||||
-rw-r--r-- | kernel/ip_set_core.c | 86 | ||||
-rw-r--r-- | kernel/ip_set_hash_ip.c | 58 | ||||
-rw-r--r-- | kernel/ip_set_hash_ipport.c | 65 | ||||
-rw-r--r-- | kernel/ip_set_hash_ipportip.c | 66 | ||||
-rw-r--r-- | kernel/ip_set_hash_ipportnet.c | 68 | ||||
-rw-r--r-- | kernel/ip_set_hash_net.c | 48 | ||||
-rw-r--r-- | kernel/ip_set_hash_netport.c | 59 | ||||
-rw-r--r-- | kernel/ip_set_list_set.c | 44 |
13 files changed, 254 insertions, 392 deletions
diff --git a/kernel/include/linux/netfilter/ipset/ip_set.h b/kernel/include/linux/netfilter/ipset/ip_set.h index 5fbb1b5..88e561c 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 983eaf0..ec9d9be 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 19251d6..804dcc2 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 3fa3921..d826332 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 862b741..c5c4f27 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 4392680..bef659a 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 84caab6..53964bc 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 c8bb754..d9b1928 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 423bf4e..80dae9d 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 740ed5c..8eacd8a 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 2330b4c..fb0e6a6 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 f79077a..342250f 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 933d9ef..a47c329 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, }; |