summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2011-01-27 12:44:17 +0100
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2011-01-27 12:44:17 +0100
commitb84145e442d1b8adec11648d09b2b45ccbe31c4e (patch)
tree59c3b8e8fdc76f06c398e7488fd2bbd2c859de2a
parent9113631680f783fc1a920c3320ba1ed3ca527562 (diff)
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).
-rw-r--r--kernel/include/linux/netfilter/ipset/ip_set.h9
-rw-r--r--kernel/include/linux/netfilter/ipset/ip_set_ahash.h2
-rw-r--r--kernel/ip_set_bitmap_ip.c53
-rw-r--r--kernel/ip_set_bitmap_ipmac.c42
-rw-r--r--kernel/ip_set_bitmap_port.c46
-rw-r--r--kernel/ip_set_core.c86
-rw-r--r--kernel/ip_set_hash_ip.c58
-rw-r--r--kernel/ip_set_hash_ipport.c65
-rw-r--r--kernel/ip_set_hash_ipportip.c66
-rw-r--r--kernel/ip_set_hash_ipportnet.c68
-rw-r--r--kernel/ip_set_hash_net.c48
-rw-r--r--kernel/ip_set_hash_netport.c59
-rw-r--r--kernel/ip_set_list_set.c44
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,
};