summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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,
};