Commit ac8cc925 authored by Jozsef Kadlecsik's avatar Jozsef Kadlecsik Committed by Patrick McHardy
Browse files

netfilter: ipset: options and flags support added to the kernel API



The support makes possible to specify the timeout value for
the SET target and a flag to reset the timeout for already existing
entries.
Signed-off-by: default avatarJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent 483e9ea3
......@@ -217,6 +217,15 @@ struct ip_set;
typedef int (*ipset_adtfn)(struct ip_set *set, void *value,
u32 timeout, u32 flags);
/* Kernel API function options */
struct ip_set_adt_opt {
u8 family; /* Actual protocol family */
u8 dim; /* Dimension of match/target */
u8 flags; /* Direction and negation flags */
u32 cmdflags; /* Command-like flags */
u32 timeout; /* Timeout value */
};
/* Set type, variant-specific part */
struct ip_set_type_variant {
/* Kernelspace: test/add/del entries
......@@ -224,7 +233,7 @@ struct ip_set_type_variant {
* zero for no match/success to add/delete
* positive for matching element */
int (*kadt)(struct ip_set *set, const struct sk_buff * skb,
enum ipset_adt adt, u8 pf, u8 dim, u8 flags);
enum ipset_adt adt, const struct ip_set_adt_opt *opt);
/* Userspace: test/add/del entries
* returns negative error code,
......@@ -314,12 +323,13 @@ extern ip_set_id_t ip_set_nfnl_get_byindex(ip_set_id_t index);
extern void ip_set_nfnl_put(ip_set_id_t index);
/* API for iptables set match, and SET target */
extern int ip_set_add(ip_set_id_t id, const struct sk_buff *skb,
u8 family, u8 dim, u8 flags);
const struct ip_set_adt_opt *opt);
extern int ip_set_del(ip_set_id_t id, const struct sk_buff *skb,
u8 family, u8 dim, u8 flags);
const struct ip_set_adt_opt *opt);
extern int ip_set_test(ip_set_id_t id, const struct sk_buff *skb,
u8 family, u8 dim, u8 flags);
const struct ip_set_adt_opt *opt);
/* Utility functions */
extern void * ip_set_alloc(size_t size);
......
......@@ -586,7 +586,7 @@ type_pf_list(const struct ip_set *set,
static int
type_pf_kadt(struct ip_set *set, const struct sk_buff * skb,
enum ipset_adt adt, u8 pf, u8 dim, u8 flags);
enum ipset_adt adt, const struct ip_set_adt_opt *opt);
static int
type_pf_uadt(struct ip_set *set, struct nlattr *tb[],
enum ipset_adt adt, u32 *lineno, u32 flags);
......
......@@ -22,6 +22,9 @@
#define with_timeout(timeout) ((timeout) != IPSET_NO_TIMEOUT)
#define opt_timeout(opt, map) \
(with_timeout((opt)->timeout) ? (opt)->timeout : (map)->timeout)
static inline unsigned int
ip_set_timeout_uget(struct nlattr *tb)
{
......
......@@ -35,7 +35,7 @@ struct xt_set_info_target_v0 {
struct xt_set_info_v0 del_set;
};
/* Revision 1: current interface to netfilter/iptables */
/* Revision 1 match and target */
struct xt_set_info {
ip_set_id_t index;
......@@ -44,13 +44,22 @@ struct xt_set_info {
};
/* match and target infos */
struct xt_set_info_match {
struct xt_set_info_match_v1 {
struct xt_set_info match_set;
};
struct xt_set_info_target {
struct xt_set_info_target_v1 {
struct xt_set_info add_set;
struct xt_set_info del_set;
};
/* Revision 2 target */
struct xt_set_info_target_v2 {
struct xt_set_info add_set;
struct xt_set_info del_set;
u32 flags;
u32 timeout;
};
#endif /*_XT_SET_H*/
......@@ -219,19 +219,19 @@ bitmap_ip_tlist(const struct ip_set *set,
static int
bitmap_ip_kadt(struct ip_set *set, const struct sk_buff *skb,
enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
enum ipset_adt adt, const struct ip_set_adt_opt *opt)
{
struct bitmap_ip *map = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
u32 ip;
ip = ntohl(ip4addr(skb, flags & IPSET_DIM_ONE_SRC));
ip = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC));
if (ip < map->first_ip || ip > map->last_ip)
return -IPSET_ERR_BITMAP_RANGE;
ip = ip_to_id(map, ip);
return adtfn(set, &ip, map->timeout, flags);
return adtfn(set, &ip, opt_timeout(opt, map), opt->cmdflags);
}
static int
......
......@@ -338,17 +338,17 @@ bitmap_ipmac_tlist(const struct ip_set *set,
static int
bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
enum ipset_adt adt, const struct ip_set_adt_opt *opt)
{
struct bitmap_ipmac *map = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
struct ipmac data;
/* MAC can be src only */
if (!(flags & IPSET_DIM_TWO_SRC))
if (!(opt->flags & IPSET_DIM_TWO_SRC))
return 0;
data.id = ntohl(ip4addr(skb, flags & IPSET_DIM_ONE_SRC));
data.id = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC));
if (data.id < map->first_ip || data.id > map->last_ip)
return -IPSET_ERR_BITMAP_RANGE;
......@@ -360,7 +360,7 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
data.id -= map->first_ip;
data.ether = eth_hdr(skb)->h_source;
return adtfn(set, &data, map->timeout, flags);
return adtfn(set, &data, opt_timeout(opt, map), opt->cmdflags);
}
static int
......
......@@ -208,14 +208,15 @@ bitmap_port_tlist(const struct ip_set *set,
static int
bitmap_port_kadt(struct ip_set *set, const struct sk_buff *skb,
enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
enum ipset_adt adt, const struct ip_set_adt_opt *opt)
{
struct bitmap_port *map = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
__be16 __port;
u16 port = 0;
if (!ip_set_get_ip_port(skb, pf, flags & IPSET_DIM_ONE_SRC, &__port))
if (!ip_set_get_ip_port(skb, opt->family,
opt->flags & IPSET_DIM_ONE_SRC, &__port))
return -EINVAL;
port = ntohs(__port);
......@@ -225,7 +226,7 @@ bitmap_port_kadt(struct ip_set *set, const struct sk_buff *skb,
port -= map->first_port;
return adtfn(set, &port, map->timeout, flags);
return adtfn(set, &port, opt_timeout(opt, map), opt->cmdflags);
}
static int
......
......@@ -325,7 +325,7 @@ __ip_set_put(ip_set_id_t index)
int
ip_set_test(ip_set_id_t index, const struct sk_buff *skb,
u8 family, u8 dim, u8 flags)
const struct ip_set_adt_opt *opt)
{
struct ip_set *set = ip_set_list[index];
int ret = 0;
......@@ -333,19 +333,19 @@ ip_set_test(ip_set_id_t index, const struct sk_buff *skb,
BUG_ON(set == NULL);
pr_debug("set %s, index %u\n", set->name, index);
if (dim < set->type->dimension ||
!(family == set->family || set->family == AF_UNSPEC))
if (opt->dim < set->type->dimension ||
!(opt->family == set->family || set->family == AF_UNSPEC))
return 0;
read_lock_bh(&set->lock);
ret = set->variant->kadt(set, skb, IPSET_TEST, family, dim, flags);
ret = set->variant->kadt(set, skb, IPSET_TEST, opt);
read_unlock_bh(&set->lock);
if (ret == -EAGAIN) {
/* Type requests element to be completed */
pr_debug("element must be competed, ADD is triggered\n");
write_lock_bh(&set->lock);
set->variant->kadt(set, skb, IPSET_ADD, family, dim, flags);
set->variant->kadt(set, skb, IPSET_ADD, opt);
write_unlock_bh(&set->lock);
ret = 1;
}
......@@ -357,7 +357,7 @@ EXPORT_SYMBOL_GPL(ip_set_test);
int
ip_set_add(ip_set_id_t index, const struct sk_buff *skb,
u8 family, u8 dim, u8 flags)
const struct ip_set_adt_opt *opt)
{
struct ip_set *set = ip_set_list[index];
int ret;
......@@ -365,12 +365,12 @@ ip_set_add(ip_set_id_t index, const struct sk_buff *skb,
BUG_ON(set == NULL);
pr_debug("set %s, index %u\n", set->name, index);
if (dim < set->type->dimension ||
!(family == set->family || set->family == AF_UNSPEC))
if (opt->dim < set->type->dimension ||
!(opt->family == set->family || set->family == AF_UNSPEC))
return 0;
write_lock_bh(&set->lock);
ret = set->variant->kadt(set, skb, IPSET_ADD, family, dim, flags);
ret = set->variant->kadt(set, skb, IPSET_ADD, opt);
write_unlock_bh(&set->lock);
return ret;
......@@ -379,7 +379,7 @@ EXPORT_SYMBOL_GPL(ip_set_add);
int
ip_set_del(ip_set_id_t index, const struct sk_buff *skb,
u8 family, u8 dim, u8 flags)
const struct ip_set_adt_opt *opt)
{
struct ip_set *set = ip_set_list[index];
int ret = 0;
......@@ -387,12 +387,12 @@ ip_set_del(ip_set_id_t index, const struct sk_buff *skb,
BUG_ON(set == NULL);
pr_debug("set %s, index %u\n", set->name, index);
if (dim < set->type->dimension ||
!(family == set->family || set->family == AF_UNSPEC))
if (opt->dim < set->type->dimension ||
!(opt->family == set->family || set->family == AF_UNSPEC))
return 0;
write_lock_bh(&set->lock);
ret = set->variant->kadt(set, skb, IPSET_DEL, family, dim, flags);
ret = set->variant->kadt(set, skb, IPSET_DEL, opt);
write_unlock_bh(&set->lock);
return ret;
......
......@@ -110,18 +110,18 @@ hash_ip4_data_tlist(struct sk_buff *skb, const struct hash_ip4_elem *data)
static int
hash_ip4_kadt(struct ip_set *set, const struct sk_buff *skb,
enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
enum ipset_adt adt, const struct ip_set_adt_opt *opt)
{
const struct ip_set_hash *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
__be32 ip;
ip4addrptr(skb, flags & IPSET_DIM_ONE_SRC, &ip);
ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &ip);
ip &= ip_set_netmask(h->netmask);
if (ip == 0)
return -EINVAL;
return adtfn(set, &ip, h->timeout, flags);
return adtfn(set, &ip, opt_timeout(opt, h), opt->cmdflags);
}
static int
......@@ -283,18 +283,18 @@ hash_ip6_data_tlist(struct sk_buff *skb, const struct hash_ip6_elem *data)
static int
hash_ip6_kadt(struct ip_set *set, const struct sk_buff *skb,
enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
enum ipset_adt adt, const struct ip_set_adt_opt *opt)
{
const struct ip_set_hash *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
union nf_inet_addr ip;
ip6addrptr(skb, flags & IPSET_DIM_ONE_SRC, &ip.in6);
ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &ip.in6);
ip6_netmask(&ip, h->netmask);
if (ipv6_addr_any(&ip.in6))
return -EINVAL;
return adtfn(set, &ip, h->timeout, flags);
return adtfn(set, &ip, opt_timeout(opt, h), opt->cmdflags);
}
static const struct nla_policy hash_ip6_adt_policy[IPSET_ATTR_ADT_MAX + 1] = {
......
......@@ -126,19 +126,19 @@ hash_ipport4_data_tlist(struct sk_buff *skb,
static int
hash_ipport4_kadt(struct ip_set *set, const struct sk_buff *skb,
enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
enum ipset_adt adt, const struct ip_set_adt_opt *opt)
{
const struct ip_set_hash *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipport4_elem data = { };
if (!ip_set_get_ip4_port(skb, flags & IPSET_DIM_TWO_SRC,
if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
&data.port, &data.proto))
return -EINVAL;
ip4addrptr(skb, flags & IPSET_DIM_ONE_SRC, &data.ip);
ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip);
return adtfn(set, &data, h->timeout, flags);
return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags);
}
static int
......@@ -330,19 +330,19 @@ hash_ipport6_data_tlist(struct sk_buff *skb,
static int
hash_ipport6_kadt(struct ip_set *set, const struct sk_buff *skb,
enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
enum ipset_adt adt, const struct ip_set_adt_opt *opt)
{
const struct ip_set_hash *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipport6_elem data = { };
if (!ip_set_get_ip6_port(skb, flags & IPSET_DIM_TWO_SRC,
if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
&data.port, &data.proto))
return -EINVAL;
ip6addrptr(skb, flags & IPSET_DIM_ONE_SRC, &data.ip.in6);
ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip.in6);
return adtfn(set, &data, h->timeout, flags);
return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags);
}
static int
......
......@@ -129,20 +129,20 @@ hash_ipportip4_data_tlist(struct sk_buff *skb,
static int
hash_ipportip4_kadt(struct ip_set *set, const struct sk_buff *skb,
enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
enum ipset_adt adt, const struct ip_set_adt_opt *opt)
{
const struct ip_set_hash *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipportip4_elem data = { };
if (!ip_set_get_ip4_port(skb, flags & IPSET_DIM_TWO_SRC,
if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
&data.port, &data.proto))
return -EINVAL;
ip4addrptr(skb, flags & IPSET_DIM_ONE_SRC, &data.ip);
ip4addrptr(skb, flags & IPSET_DIM_THREE_SRC, &data.ip2);
ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip);
ip4addrptr(skb, opt->flags & IPSET_DIM_THREE_SRC, &data.ip2);
return adtfn(set, &data, h->timeout, flags);
return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags);
}
static int
......@@ -343,20 +343,20 @@ hash_ipportip6_data_tlist(struct sk_buff *skb,
static int
hash_ipportip6_kadt(struct ip_set *set, const struct sk_buff *skb,
enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
enum ipset_adt adt, const struct ip_set_adt_opt *opt)
{
const struct ip_set_hash *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipportip6_elem data = { };
if (!ip_set_get_ip6_port(skb, flags & IPSET_DIM_TWO_SRC,
if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
&data.port, &data.proto))
return -EINVAL;
ip6addrptr(skb, flags & IPSET_DIM_ONE_SRC, &data.ip.in6);
ip6addrptr(skb, flags & IPSET_DIM_THREE_SRC, &data.ip2.in6);
ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip.in6);
ip6addrptr(skb, opt->flags & IPSET_DIM_THREE_SRC, &data.ip2.in6);
return adtfn(set, &data, h->timeout, flags);
return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags);
}
static int
......
......@@ -142,7 +142,7 @@ hash_ipportnet4_data_tlist(struct sk_buff *skb,
static int
hash_ipportnet4_kadt(struct ip_set *set, const struct sk_buff *skb,
enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
enum ipset_adt adt, const struct ip_set_adt_opt *opt)
{
const struct ip_set_hash *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
......@@ -154,15 +154,15 @@ hash_ipportnet4_kadt(struct ip_set *set, const struct sk_buff *skb,
if (adt == IPSET_TEST)
data.cidr = HOST_MASK;
if (!ip_set_get_ip4_port(skb, flags & IPSET_DIM_TWO_SRC,
if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
&data.port, &data.proto))
return -EINVAL;
ip4addrptr(skb, flags & IPSET_DIM_ONE_SRC, &data.ip);
ip4addrptr(skb, flags & IPSET_DIM_THREE_SRC, &data.ip2);
ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip);
ip4addrptr(skb, opt->flags & IPSET_DIM_THREE_SRC, &data.ip2);
data.ip2 &= ip_set_netmask(data.cidr);
return adtfn(set, &data, h->timeout, flags);
return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags);
}
static int
......@@ -390,7 +390,7 @@ hash_ipportnet6_data_tlist(struct sk_buff *skb,
static int
hash_ipportnet6_kadt(struct ip_set *set, const struct sk_buff *skb,
enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
enum ipset_adt adt, const struct ip_set_adt_opt *opt)
{
const struct ip_set_hash *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
......@@ -402,15 +402,15 @@ hash_ipportnet6_kadt(struct ip_set *set, const struct sk_buff *skb,
if (adt == IPSET_TEST)
data.cidr = HOST_MASK;
if (!ip_set_get_ip6_port(skb, flags & IPSET_DIM_TWO_SRC,
if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
&data.port, &data.proto))
return -EINVAL;
ip6addrptr(skb, flags & IPSET_DIM_ONE_SRC, &data.ip.in6);
ip6addrptr(skb, flags & IPSET_DIM_THREE_SRC, &data.ip2.in6);
ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip.in6);
ip6addrptr(skb, opt->flags & IPSET_DIM_THREE_SRC, &data.ip2.in6);
ip6_netmask(&data.ip2, data.cidr);
return adtfn(set, &data, h->timeout, flags);
return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags);
}
static int
......
......@@ -127,7 +127,7 @@ hash_net4_data_tlist(struct sk_buff *skb, const struct hash_net4_elem *data)
static int
hash_net4_kadt(struct ip_set *set, const struct sk_buff *skb,
enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
enum ipset_adt adt, const struct ip_set_adt_opt *opt)
{
const struct ip_set_hash *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
......@@ -138,10 +138,10 @@ hash_net4_kadt(struct ip_set *set, const struct sk_buff *skb,
if (adt == IPSET_TEST)
data.cidr = HOST_MASK;
ip4addrptr(skb, flags & IPSET_DIM_ONE_SRC, &data.ip);
ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip);
data.ip &= ip_set_netmask(data.cidr);
return adtfn(set, &data, h->timeout, flags);
return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags);
}
static int
......@@ -292,7 +292,7 @@ hash_net6_data_tlist(struct sk_buff *skb, const struct hash_net6_elem *data)
static int
hash_net6_kadt(struct ip_set *set, const struct sk_buff *skb,
enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
enum ipset_adt adt, const struct ip_set_adt_opt *opt)
{
const struct ip_set_hash *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
......@@ -303,10 +303,10 @@ hash_net6_kadt(struct ip_set *set, const struct sk_buff *skb,
if (adt == IPSET_TEST)
data.cidr = HOST_MASK;
ip6addrptr(skb, flags & IPSET_DIM_ONE_SRC, &data.ip.in6);
ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip.in6);
ip6_netmask(&data.ip, data.cidr);
return adtfn(set, &data, h->timeout, flags);
return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags);
}
static int
......
......@@ -139,7 +139,7 @@ hash_netport4_data_tlist(struct sk_buff *skb,
static int
hash_netport4_kadt(struct ip_set *set, const struct sk_buff *skb,
enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
enum ipset_adt adt, const struct ip_set_adt_opt *opt)
{
const struct ip_set_hash *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
......@@ -151,14 +151,14 @@ hash_netport4_kadt(struct ip_set *set, const struct sk_buff *skb,
if (adt == IPSET_TEST)
data.cidr = HOST_MASK;
if (!ip_set_get_ip4_port(skb, flags & IPSET_DIM_TWO_SRC,
if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
&data.port, &data.proto))
return -EINVAL;
ip4addrptr(skb, flags & IPSET_DIM_ONE_SRC, &data.ip);
ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip);
data.ip &= ip_set_netmask(data.cidr);
return adtfn(set, &data, h->timeout, flags);
return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags);
}
static int
......@@ -352,7 +352,7 @@ hash_netport6_data_tlist(struct sk_buff *skb,
static int
hash_netport6_kadt(struct ip_set *set, const struct sk_buff *skb,
enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
enum ipset_adt adt, const struct ip_set_adt_opt *opt)
{
const struct ip_set_hash *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
......@@ -364,14 +364,14 @@ hash_netport6_kadt(struct ip_set *set, const struct sk_buff *skb,
if (adt == IPSET_TEST)
data.cidr = HOST_MASK;
if (!ip_set_get_ip6_port(skb, flags & IPSET_DIM_TWO_SRC,
if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
&data.port, &data.proto))
return -EINVAL;
ip6addrptr(skb, flags & IPSET_DIM_ONE_SRC, &data.ip.in6);
ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip.in6);
ip6_netmask(&data.ip, data.cidr);
return adtfn(set, &data, h->timeout, flags);
return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags);
}
static int
......
......@@ -72,7 +72,7 @@ list_set_expired(const struct list_set *map, u32 id)
static int
list_set_kadt(struct ip_set *set, const struct sk_buff *skb,
enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
enum ipset_adt adt, const struct ip_set_adt_opt *opt)
{
struct list_set *map = set->data;
struct set_elem *elem;
......@@ -87,17 +87,17 @@ list_set_kadt(struct ip_set *set, const struct sk_buff *skb,
continue;
switch (adt) {
case IPSET_TEST:
ret = ip_set_test(elem->id, skb, pf, dim, flags);
ret = ip_set_test(elem->id, skb, opt);
if (ret > 0)
return ret;
break;