netfilter: ipset: Fix "don't update counters" mode when counters used at the matching
The matching of the counters was not taken into account, fixed. Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
Родитель
c045337751
Коммит
4750005a85
|
@ -122,6 +122,8 @@ struct ip_set_ext {
|
||||||
u64 bytes;
|
u64 bytes;
|
||||||
char *comment;
|
char *comment;
|
||||||
u32 timeout;
|
u32 timeout;
|
||||||
|
u8 packets_op;
|
||||||
|
u8 bytes_op;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ip_set;
|
struct ip_set;
|
||||||
|
@ -339,6 +341,10 @@ extern int ip_set_get_extensions(struct ip_set *set, struct nlattr *tb[],
|
||||||
struct ip_set_ext *ext);
|
struct ip_set_ext *ext);
|
||||||
extern int ip_set_put_extensions(struct sk_buff *skb, const struct ip_set *set,
|
extern int ip_set_put_extensions(struct sk_buff *skb, const struct ip_set *set,
|
||||||
const void *e, bool active);
|
const void *e, bool active);
|
||||||
|
extern bool ip_set_match_extensions(struct ip_set *set,
|
||||||
|
const struct ip_set_ext *ext,
|
||||||
|
struct ip_set_ext *mext,
|
||||||
|
u32 flags, void *data);
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
ip_set_get_hostipaddr4(struct nlattr *nla, u32 *ipaddr)
|
ip_set_get_hostipaddr4(struct nlattr *nla, u32 *ipaddr)
|
||||||
|
|
|
@ -34,20 +34,33 @@ ip_set_get_packets(const struct ip_set_counter *counter)
|
||||||
return (u64)atomic64_read(&(counter)->packets);
|
return (u64)atomic64_read(&(counter)->packets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
ip_set_match_counter(u64 counter, u64 match, u8 op)
|
||||||
|
{
|
||||||
|
switch (op) {
|
||||||
|
case IPSET_COUNTER_NONE:
|
||||||
|
return true;
|
||||||
|
case IPSET_COUNTER_EQ:
|
||||||
|
return counter == match;
|
||||||
|
case IPSET_COUNTER_NE:
|
||||||
|
return counter != match;
|
||||||
|
case IPSET_COUNTER_LT:
|
||||||
|
return counter < match;
|
||||||
|
case IPSET_COUNTER_GT:
|
||||||
|
return counter > match;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
ip_set_update_counter(struct ip_set_counter *counter,
|
ip_set_update_counter(struct ip_set_counter *counter,
|
||||||
const struct ip_set_ext *ext,
|
const struct ip_set_ext *ext, u32 flags)
|
||||||
struct ip_set_ext *mext, u32 flags)
|
|
||||||
{
|
{
|
||||||
if (ext->packets != ULLONG_MAX &&
|
if (ext->packets != ULLONG_MAX &&
|
||||||
!(flags & IPSET_FLAG_SKIP_COUNTER_UPDATE)) {
|
!(flags & IPSET_FLAG_SKIP_COUNTER_UPDATE)) {
|
||||||
ip_set_add_bytes(ext->bytes, counter);
|
ip_set_add_bytes(ext->bytes, counter);
|
||||||
ip_set_add_packets(ext->packets, counter);
|
ip_set_add_packets(ext->packets, counter);
|
||||||
}
|
}
|
||||||
if (flags & IPSET_FLAG_MATCH_COUNTERS) {
|
|
||||||
mext->packets = ip_set_get_packets(counter);
|
|
||||||
mext->bytes = ip_set_get_bytes(counter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
|
|
|
@ -127,14 +127,7 @@ mtype_test(struct ip_set *set, void *value, const struct ip_set_ext *ext,
|
||||||
|
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
return ret;
|
return ret;
|
||||||
if (SET_WITH_TIMEOUT(set) &&
|
return ip_set_match_extensions(set, ext, mext, flags, x);
|
||||||
ip_set_timeout_expired(ext_timeout(x, set)))
|
|
||||||
return 0;
|
|
||||||
if (SET_WITH_COUNTER(set))
|
|
||||||
ip_set_update_counter(ext_counter(x, set), ext, mext, flags);
|
|
||||||
if (SET_WITH_SKBINFO(set))
|
|
||||||
ip_set_get_skbinfo(ext_skbinfo(x, set), ext, mext, flags);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
|
@ -472,6 +472,31 @@ ip_set_put_extensions(struct sk_buff *skb, const struct ip_set *set,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(ip_set_put_extensions);
|
EXPORT_SYMBOL_GPL(ip_set_put_extensions);
|
||||||
|
|
||||||
|
bool
|
||||||
|
ip_set_match_extensions(struct ip_set *set, const struct ip_set_ext *ext,
|
||||||
|
struct ip_set_ext *mext, u32 flags, void *data)
|
||||||
|
{
|
||||||
|
if (SET_WITH_TIMEOUT(set) &&
|
||||||
|
ip_set_timeout_expired(ext_timeout(data, set)))
|
||||||
|
return false;
|
||||||
|
if (SET_WITH_COUNTER(set)) {
|
||||||
|
struct ip_set_counter *counter = ext_counter(data, set);
|
||||||
|
|
||||||
|
if (flags & IPSET_FLAG_MATCH_COUNTERS &&
|
||||||
|
!(ip_set_match_counter(ip_set_get_packets(counter),
|
||||||
|
mext->packets, mext->packets_op) &&
|
||||||
|
ip_set_match_counter(ip_set_get_bytes(counter),
|
||||||
|
mext->bytes, mext->bytes_op)))
|
||||||
|
return false;
|
||||||
|
ip_set_update_counter(counter, ext, flags);
|
||||||
|
}
|
||||||
|
if (SET_WITH_SKBINFO(set))
|
||||||
|
ip_set_get_skbinfo(ext_skbinfo(data, set),
|
||||||
|
ext, mext, flags);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(ip_set_match_extensions);
|
||||||
|
|
||||||
/* Creating/destroying/renaming/swapping affect the existence and
|
/* Creating/destroying/renaming/swapping affect the existence and
|
||||||
* the properties of a set. All of these can be executed from userspace
|
* the properties of a set. All of these can be executed from userspace
|
||||||
* only and serialized by the nfnl mutex indirectly from nfnetlink.
|
* only and serialized by the nfnl mutex indirectly from nfnetlink.
|
||||||
|
|
|
@ -917,12 +917,9 @@ static inline int
|
||||||
mtype_data_match(struct mtype_elem *data, const struct ip_set_ext *ext,
|
mtype_data_match(struct mtype_elem *data, const struct ip_set_ext *ext,
|
||||||
struct ip_set_ext *mext, struct ip_set *set, u32 flags)
|
struct ip_set_ext *mext, struct ip_set *set, u32 flags)
|
||||||
{
|
{
|
||||||
if (SET_WITH_COUNTER(set))
|
if (!ip_set_match_extensions(set, ext, mext, flags, data))
|
||||||
ip_set_update_counter(ext_counter(data, set),
|
return 0;
|
||||||
ext, mext, flags);
|
/* nomatch entries return -ENOTEMPTY */
|
||||||
if (SET_WITH_SKBINFO(set))
|
|
||||||
ip_set_get_skbinfo(ext_skbinfo(data, set),
|
|
||||||
ext, mext, flags);
|
|
||||||
return mtype_do_data_match(data);
|
return mtype_do_data_match(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -941,9 +938,9 @@ mtype_test_cidrs(struct ip_set *set, struct mtype_elem *d,
|
||||||
struct mtype_elem *data;
|
struct mtype_elem *data;
|
||||||
#if IPSET_NET_COUNT == 2
|
#if IPSET_NET_COUNT == 2
|
||||||
struct mtype_elem orig = *d;
|
struct mtype_elem orig = *d;
|
||||||
int i, j = 0, k;
|
int ret, i, j = 0, k;
|
||||||
#else
|
#else
|
||||||
int i, j = 0;
|
int ret, i, j = 0;
|
||||||
#endif
|
#endif
|
||||||
u32 key, multi = 0;
|
u32 key, multi = 0;
|
||||||
|
|
||||||
|
@ -969,18 +966,13 @@ mtype_test_cidrs(struct ip_set *set, struct mtype_elem *d,
|
||||||
data = ahash_data(n, i, set->dsize);
|
data = ahash_data(n, i, set->dsize);
|
||||||
if (!mtype_data_equal(data, d, &multi))
|
if (!mtype_data_equal(data, d, &multi))
|
||||||
continue;
|
continue;
|
||||||
if (SET_WITH_TIMEOUT(set)) {
|
ret = mtype_data_match(data, ext, mext, set, flags);
|
||||||
if (!ip_set_timeout_expired(
|
if (ret != 0)
|
||||||
ext_timeout(data, set)))
|
return ret;
|
||||||
return mtype_data_match(data, ext,
|
|
||||||
mext, set,
|
|
||||||
flags);
|
|
||||||
#ifdef IP_SET_HASH_WITH_MULTI
|
#ifdef IP_SET_HASH_WITH_MULTI
|
||||||
multi = 0;
|
/* No match, reset multiple match flag */
|
||||||
|
multi = 0;
|
||||||
#endif
|
#endif
|
||||||
} else
|
|
||||||
return mtype_data_match(data, ext,
|
|
||||||
mext, set, flags);
|
|
||||||
}
|
}
|
||||||
#if IPSET_NET_COUNT == 2
|
#if IPSET_NET_COUNT == 2
|
||||||
}
|
}
|
||||||
|
@ -1027,12 +1019,11 @@ mtype_test(struct ip_set *set, void *value, const struct ip_set_ext *ext,
|
||||||
if (!test_bit(i, n->used))
|
if (!test_bit(i, n->used))
|
||||||
continue;
|
continue;
|
||||||
data = ahash_data(n, i, set->dsize);
|
data = ahash_data(n, i, set->dsize);
|
||||||
if (mtype_data_equal(data, d, &multi) &&
|
if (!mtype_data_equal(data, d, &multi))
|
||||||
!(SET_WITH_TIMEOUT(set) &&
|
continue;
|
||||||
ip_set_timeout_expired(ext_timeout(data, set)))) {
|
ret = mtype_data_match(data, ext, mext, set, flags);
|
||||||
ret = mtype_data_match(data, ext, mext, set, flags);
|
if (ret != 0)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -55,8 +55,9 @@ list_set_ktest(struct ip_set *set, const struct sk_buff *skb,
|
||||||
struct ip_set_adt_opt *opt, const struct ip_set_ext *ext)
|
struct ip_set_adt_opt *opt, const struct ip_set_ext *ext)
|
||||||
{
|
{
|
||||||
struct list_set *map = set->data;
|
struct list_set *map = set->data;
|
||||||
|
struct ip_set_ext *mext = &opt->ext;
|
||||||
struct set_elem *e;
|
struct set_elem *e;
|
||||||
u32 cmdflags = opt->cmdflags;
|
u32 flags = opt->cmdflags;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Don't lookup sub-counters at all */
|
/* Don't lookup sub-counters at all */
|
||||||
|
@ -64,21 +65,11 @@ list_set_ktest(struct ip_set *set, const struct sk_buff *skb,
|
||||||
if (opt->cmdflags & IPSET_FLAG_SKIP_SUBCOUNTER_UPDATE)
|
if (opt->cmdflags & IPSET_FLAG_SKIP_SUBCOUNTER_UPDATE)
|
||||||
opt->cmdflags &= ~IPSET_FLAG_SKIP_COUNTER_UPDATE;
|
opt->cmdflags &= ~IPSET_FLAG_SKIP_COUNTER_UPDATE;
|
||||||
list_for_each_entry_rcu(e, &map->members, list) {
|
list_for_each_entry_rcu(e, &map->members, list) {
|
||||||
if (SET_WITH_TIMEOUT(set) &&
|
|
||||||
ip_set_timeout_expired(ext_timeout(e, set)))
|
|
||||||
continue;
|
|
||||||
ret = ip_set_test(e->id, skb, par, opt);
|
ret = ip_set_test(e->id, skb, par, opt);
|
||||||
if (ret > 0) {
|
if (ret <= 0)
|
||||||
if (SET_WITH_COUNTER(set))
|
continue;
|
||||||
ip_set_update_counter(ext_counter(e, set),
|
if (ip_set_match_extensions(set, ext, mext, flags, e))
|
||||||
ext, &opt->ext,
|
return 1;
|
||||||
cmdflags);
|
|
||||||
if (SET_WITH_SKBINFO(set))
|
|
||||||
ip_set_get_skbinfo(ext_skbinfo(e, set),
|
|
||||||
ext, &opt->ext,
|
|
||||||
cmdflags);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,13 +39,17 @@ match_set(ip_set_id_t index, const struct sk_buff *skb,
|
||||||
return inv;
|
return inv;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ADT_OPT(n, f, d, fs, cfs, t) \
|
#define ADT_OPT(n, f, d, fs, cfs, t, p, b, po, bo) \
|
||||||
struct ip_set_adt_opt n = { \
|
struct ip_set_adt_opt n = { \
|
||||||
.family = f, \
|
.family = f, \
|
||||||
.dim = d, \
|
.dim = d, \
|
||||||
.flags = fs, \
|
.flags = fs, \
|
||||||
.cmdflags = cfs, \
|
.cmdflags = cfs, \
|
||||||
.ext.timeout = t, \
|
.ext.timeout = t, \
|
||||||
|
.ext.packets = p, \
|
||||||
|
.ext.bytes = b, \
|
||||||
|
.ext.packets_op = po, \
|
||||||
|
.ext.bytes_op = bo, \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Revision 0 interface: backward compatible with netfilter/iptables */
|
/* Revision 0 interface: backward compatible with netfilter/iptables */
|
||||||
|
@ -56,7 +60,8 @@ set_match_v0(const struct sk_buff *skb, struct xt_action_param *par)
|
||||||
const struct xt_set_info_match_v0 *info = par->matchinfo;
|
const struct xt_set_info_match_v0 *info = par->matchinfo;
|
||||||
|
|
||||||
ADT_OPT(opt, xt_family(par), info->match_set.u.compat.dim,
|
ADT_OPT(opt, xt_family(par), info->match_set.u.compat.dim,
|
||||||
info->match_set.u.compat.flags, 0, UINT_MAX);
|
info->match_set.u.compat.flags, 0, UINT_MAX,
|
||||||
|
0, 0, 0, 0);
|
||||||
|
|
||||||
return match_set(info->match_set.index, skb, par, &opt,
|
return match_set(info->match_set.index, skb, par, &opt,
|
||||||
info->match_set.u.compat.flags & IPSET_INV_MATCH);
|
info->match_set.u.compat.flags & IPSET_INV_MATCH);
|
||||||
|
@ -119,7 +124,8 @@ set_match_v1(const struct sk_buff *skb, struct xt_action_param *par)
|
||||||
const struct xt_set_info_match_v1 *info = par->matchinfo;
|
const struct xt_set_info_match_v1 *info = par->matchinfo;
|
||||||
|
|
||||||
ADT_OPT(opt, xt_family(par), info->match_set.dim,
|
ADT_OPT(opt, xt_family(par), info->match_set.dim,
|
||||||
info->match_set.flags, 0, UINT_MAX);
|
info->match_set.flags, 0, UINT_MAX,
|
||||||
|
0, 0, 0, 0);
|
||||||
|
|
||||||
if (opt.flags & IPSET_RETURN_NOMATCH)
|
if (opt.flags & IPSET_RETURN_NOMATCH)
|
||||||
opt.cmdflags |= IPSET_FLAG_RETURN_NOMATCH;
|
opt.cmdflags |= IPSET_FLAG_RETURN_NOMATCH;
|
||||||
|
@ -160,46 +166,22 @@ set_match_v1_destroy(const struct xt_mtdtor_param *par)
|
||||||
|
|
||||||
/* Revision 3 match */
|
/* Revision 3 match */
|
||||||
|
|
||||||
static bool
|
|
||||||
match_counter0(u64 counter, const struct ip_set_counter_match0 *info)
|
|
||||||
{
|
|
||||||
switch (info->op) {
|
|
||||||
case IPSET_COUNTER_NONE:
|
|
||||||
return true;
|
|
||||||
case IPSET_COUNTER_EQ:
|
|
||||||
return counter == info->value;
|
|
||||||
case IPSET_COUNTER_NE:
|
|
||||||
return counter != info->value;
|
|
||||||
case IPSET_COUNTER_LT:
|
|
||||||
return counter < info->value;
|
|
||||||
case IPSET_COUNTER_GT:
|
|
||||||
return counter > info->value;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
set_match_v3(const struct sk_buff *skb, struct xt_action_param *par)
|
set_match_v3(const struct sk_buff *skb, struct xt_action_param *par)
|
||||||
{
|
{
|
||||||
const struct xt_set_info_match_v3 *info = par->matchinfo;
|
const struct xt_set_info_match_v3 *info = par->matchinfo;
|
||||||
int ret;
|
|
||||||
|
|
||||||
ADT_OPT(opt, xt_family(par), info->match_set.dim,
|
ADT_OPT(opt, xt_family(par), info->match_set.dim,
|
||||||
info->match_set.flags, info->flags, UINT_MAX);
|
info->match_set.flags, info->flags, UINT_MAX,
|
||||||
|
info->packets.value, info->bytes.value,
|
||||||
|
info->packets.op, info->bytes.op);
|
||||||
|
|
||||||
if (info->packets.op != IPSET_COUNTER_NONE ||
|
if (info->packets.op != IPSET_COUNTER_NONE ||
|
||||||
info->bytes.op != IPSET_COUNTER_NONE)
|
info->bytes.op != IPSET_COUNTER_NONE)
|
||||||
opt.cmdflags |= IPSET_FLAG_MATCH_COUNTERS;
|
opt.cmdflags |= IPSET_FLAG_MATCH_COUNTERS;
|
||||||
|
|
||||||
ret = match_set(info->match_set.index, skb, par, &opt,
|
return match_set(info->match_set.index, skb, par, &opt,
|
||||||
info->match_set.flags & IPSET_INV_MATCH);
|
info->match_set.flags & IPSET_INV_MATCH);
|
||||||
|
|
||||||
if (!(ret && opt.cmdflags & IPSET_FLAG_MATCH_COUNTERS))
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (!match_counter0(opt.ext.packets, &info->packets))
|
|
||||||
return false;
|
|
||||||
return match_counter0(opt.ext.bytes, &info->bytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define set_match_v3_checkentry set_match_v1_checkentry
|
#define set_match_v3_checkentry set_match_v1_checkentry
|
||||||
|
@ -207,46 +189,22 @@ set_match_v3(const struct sk_buff *skb, struct xt_action_param *par)
|
||||||
|
|
||||||
/* Revision 4 match */
|
/* Revision 4 match */
|
||||||
|
|
||||||
static bool
|
|
||||||
match_counter(u64 counter, const struct ip_set_counter_match *info)
|
|
||||||
{
|
|
||||||
switch (info->op) {
|
|
||||||
case IPSET_COUNTER_NONE:
|
|
||||||
return true;
|
|
||||||
case IPSET_COUNTER_EQ:
|
|
||||||
return counter == info->value;
|
|
||||||
case IPSET_COUNTER_NE:
|
|
||||||
return counter != info->value;
|
|
||||||
case IPSET_COUNTER_LT:
|
|
||||||
return counter < info->value;
|
|
||||||
case IPSET_COUNTER_GT:
|
|
||||||
return counter > info->value;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
set_match_v4(const struct sk_buff *skb, struct xt_action_param *par)
|
set_match_v4(const struct sk_buff *skb, struct xt_action_param *par)
|
||||||
{
|
{
|
||||||
const struct xt_set_info_match_v4 *info = par->matchinfo;
|
const struct xt_set_info_match_v4 *info = par->matchinfo;
|
||||||
int ret;
|
|
||||||
|
|
||||||
ADT_OPT(opt, xt_family(par), info->match_set.dim,
|
ADT_OPT(opt, xt_family(par), info->match_set.dim,
|
||||||
info->match_set.flags, info->flags, UINT_MAX);
|
info->match_set.flags, info->flags, UINT_MAX,
|
||||||
|
info->packets.value, info->bytes.value,
|
||||||
|
info->packets.op, info->bytes.op);
|
||||||
|
|
||||||
if (info->packets.op != IPSET_COUNTER_NONE ||
|
if (info->packets.op != IPSET_COUNTER_NONE ||
|
||||||
info->bytes.op != IPSET_COUNTER_NONE)
|
info->bytes.op != IPSET_COUNTER_NONE)
|
||||||
opt.cmdflags |= IPSET_FLAG_MATCH_COUNTERS;
|
opt.cmdflags |= IPSET_FLAG_MATCH_COUNTERS;
|
||||||
|
|
||||||
ret = match_set(info->match_set.index, skb, par, &opt,
|
return match_set(info->match_set.index, skb, par, &opt,
|
||||||
info->match_set.flags & IPSET_INV_MATCH);
|
info->match_set.flags & IPSET_INV_MATCH);
|
||||||
|
|
||||||
if (!(ret && opt.cmdflags & IPSET_FLAG_MATCH_COUNTERS))
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (!match_counter(opt.ext.packets, &info->packets))
|
|
||||||
return false;
|
|
||||||
return match_counter(opt.ext.bytes, &info->bytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define set_match_v4_checkentry set_match_v1_checkentry
|
#define set_match_v4_checkentry set_match_v1_checkentry
|
||||||
|
@ -260,9 +218,11 @@ set_target_v0(struct sk_buff *skb, const struct xt_action_param *par)
|
||||||
const struct xt_set_info_target_v0 *info = par->targinfo;
|
const struct xt_set_info_target_v0 *info = par->targinfo;
|
||||||
|
|
||||||
ADT_OPT(add_opt, xt_family(par), info->add_set.u.compat.dim,
|
ADT_OPT(add_opt, xt_family(par), info->add_set.u.compat.dim,
|
||||||
info->add_set.u.compat.flags, 0, UINT_MAX);
|
info->add_set.u.compat.flags, 0, UINT_MAX,
|
||||||
|
0, 0, 0, 0);
|
||||||
ADT_OPT(del_opt, xt_family(par), info->del_set.u.compat.dim,
|
ADT_OPT(del_opt, xt_family(par), info->del_set.u.compat.dim,
|
||||||
info->del_set.u.compat.flags, 0, UINT_MAX);
|
info->del_set.u.compat.flags, 0, UINT_MAX,
|
||||||
|
0, 0, 0, 0);
|
||||||
|
|
||||||
if (info->add_set.index != IPSET_INVALID_ID)
|
if (info->add_set.index != IPSET_INVALID_ID)
|
||||||
ip_set_add(info->add_set.index, skb, par, &add_opt);
|
ip_set_add(info->add_set.index, skb, par, &add_opt);
|
||||||
|
@ -333,9 +293,11 @@ set_target_v1(struct sk_buff *skb, const struct xt_action_param *par)
|
||||||
const struct xt_set_info_target_v1 *info = par->targinfo;
|
const struct xt_set_info_target_v1 *info = par->targinfo;
|
||||||
|
|
||||||
ADT_OPT(add_opt, xt_family(par), info->add_set.dim,
|
ADT_OPT(add_opt, xt_family(par), info->add_set.dim,
|
||||||
info->add_set.flags, 0, UINT_MAX);
|
info->add_set.flags, 0, UINT_MAX,
|
||||||
|
0, 0, 0, 0);
|
||||||
ADT_OPT(del_opt, xt_family(par), info->del_set.dim,
|
ADT_OPT(del_opt, xt_family(par), info->del_set.dim,
|
||||||
info->del_set.flags, 0, UINT_MAX);
|
info->del_set.flags, 0, UINT_MAX,
|
||||||
|
0, 0, 0, 0);
|
||||||
|
|
||||||
if (info->add_set.index != IPSET_INVALID_ID)
|
if (info->add_set.index != IPSET_INVALID_ID)
|
||||||
ip_set_add(info->add_set.index, skb, par, &add_opt);
|
ip_set_add(info->add_set.index, skb, par, &add_opt);
|
||||||
|
@ -402,9 +364,11 @@ set_target_v2(struct sk_buff *skb, const struct xt_action_param *par)
|
||||||
const struct xt_set_info_target_v2 *info = par->targinfo;
|
const struct xt_set_info_target_v2 *info = par->targinfo;
|
||||||
|
|
||||||
ADT_OPT(add_opt, xt_family(par), info->add_set.dim,
|
ADT_OPT(add_opt, xt_family(par), info->add_set.dim,
|
||||||
info->add_set.flags, info->flags, info->timeout);
|
info->add_set.flags, info->flags, info->timeout,
|
||||||
|
0, 0, 0, 0);
|
||||||
ADT_OPT(del_opt, xt_family(par), info->del_set.dim,
|
ADT_OPT(del_opt, xt_family(par), info->del_set.dim,
|
||||||
info->del_set.flags, 0, UINT_MAX);
|
info->del_set.flags, 0, UINT_MAX,
|
||||||
|
0, 0, 0, 0);
|
||||||
|
|
||||||
/* Normalize to fit into jiffies */
|
/* Normalize to fit into jiffies */
|
||||||
if (add_opt.ext.timeout != IPSET_NO_TIMEOUT &&
|
if (add_opt.ext.timeout != IPSET_NO_TIMEOUT &&
|
||||||
|
@ -432,11 +396,14 @@ set_target_v3(struct sk_buff *skb, const struct xt_action_param *par)
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ADT_OPT(add_opt, xt_family(par), info->add_set.dim,
|
ADT_OPT(add_opt, xt_family(par), info->add_set.dim,
|
||||||
info->add_set.flags, info->flags, info->timeout);
|
info->add_set.flags, info->flags, info->timeout,
|
||||||
|
0, 0, 0, 0);
|
||||||
ADT_OPT(del_opt, xt_family(par), info->del_set.dim,
|
ADT_OPT(del_opt, xt_family(par), info->del_set.dim,
|
||||||
info->del_set.flags, 0, UINT_MAX);
|
info->del_set.flags, 0, UINT_MAX,
|
||||||
|
0, 0, 0, 0);
|
||||||
ADT_OPT(map_opt, xt_family(par), info->map_set.dim,
|
ADT_OPT(map_opt, xt_family(par), info->map_set.dim,
|
||||||
info->map_set.flags, 0, UINT_MAX);
|
info->map_set.flags, 0, UINT_MAX,
|
||||||
|
0, 0, 0, 0);
|
||||||
|
|
||||||
/* Normalize to fit into jiffies */
|
/* Normalize to fit into jiffies */
|
||||||
if (add_opt.ext.timeout != IPSET_NO_TIMEOUT &&
|
if (add_opt.ext.timeout != IPSET_NO_TIMEOUT &&
|
||||||
|
|
Загрузка…
Ссылка в новой задаче