Skip to content

Commit

Permalink
netfilter: ipset: The hash types with counter support
Browse files Browse the repository at this point in the history
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  • Loading branch information
Jozsef Kadlecsik authored and Pablo Neira Ayuso committed Apr 29, 2013
1 parent f48d19d commit 00d71b2
Show file tree
Hide file tree
Showing 8 changed files with 381 additions and 19 deletions.
65 changes: 63 additions & 2 deletions net/netfilter/ipset/ip_set_hash_gen.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ hbucket_elem_add(struct hbucket *n, u8 ahash_max, size_t dsize)

#define ext_timeout(e, h) \
(unsigned long *)(((void *)(e)) + (h)->offset[IPSET_OFFSET_TIMEOUT])
#define ext_counter(e, h) \
(struct ip_set_counter *)(((void *)(e)) + (h)->offset[IPSET_OFFSET_COUNTER])

#endif /* _IP_SET_HASH_GEN_H */

Expand Down Expand Up @@ -660,6 +662,8 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
#endif
if (SET_WITH_TIMEOUT(set))
ip_set_timeout_set(ext_timeout(data, h), ext->timeout);
if (SET_WITH_COUNTER(set))
ip_set_init_counter(ext_counter(data, h), ext);

out:
rcu_read_unlock_bh();
Expand Down Expand Up @@ -721,6 +725,10 @@ static inline int
mtype_data_match(struct mtype_elem *data, const struct ip_set_ext *ext,
struct ip_set_ext *mext, struct ip_set *set, u32 flags)
{
if (SET_WITH_COUNTER(set))
ip_set_update_counter(ext_counter(data,
(struct htype *)(set->data)),
ext, mext, flags);
return mtype_do_data_match(data);
}

Expand Down Expand Up @@ -826,7 +834,10 @@ mtype_head(struct ip_set *set, struct sk_buff *skb)
if (nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)) ||
((set->extensions & IPSET_EXT_TIMEOUT) &&
nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(h->timeout))))
nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(h->timeout))) ||
((set->extensions & IPSET_EXT_COUNTER) &&
nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS,
htonl(IPSET_FLAG_WITH_COUNTERS))))
goto nla_put_failure;
ipset_nest_end(skb, nested);

Expand Down Expand Up @@ -880,6 +891,9 @@ mtype_list(const struct ip_set *set,
htonl(ip_set_timeout_get(
ext_timeout(e, h)))))
goto nla_put_failure;
if (SET_WITH_COUNTER(set) &&
ip_set_put_counter(skb, ext_counter(e, h)))
goto nla_put_failure;
ipset_nest_end(skb, nested);
}
}
Expand Down Expand Up @@ -931,6 +945,7 @@ static int
TOKEN(HTYPE, _create)(struct ip_set *set, struct nlattr *tb[], u32 flags)
{
u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
u32 cadt_flags = 0;
u8 hbits;
#ifdef IP_SET_HASH_WITH_NETMASK
u8 netmask;
Expand Down Expand Up @@ -1007,7 +1022,53 @@ TOKEN(HTYPE, _create)(struct ip_set *set, struct nlattr *tb[], u32 flags)
else
set->variant = &TOKEN(HTYPE, 6_variant);

if (tb[IPSET_ATTR_TIMEOUT]) {
if (tb[IPSET_ATTR_CADT_FLAGS])
cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
if (cadt_flags & IPSET_FLAG_WITH_COUNTERS) {
set->extensions |= IPSET_EXT_COUNTER;
if (tb[IPSET_ATTR_TIMEOUT]) {
h->timeout =
ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
set->extensions |= IPSET_EXT_TIMEOUT;
if (set->family == NFPROTO_IPV4) {
h->dsize =
sizeof(struct TOKEN(HTYPE, 4ct_elem));
h->offset[IPSET_OFFSET_TIMEOUT] =
offsetof(struct TOKEN(HTYPE, 4ct_elem),
timeout);
h->offset[IPSET_OFFSET_COUNTER] =
offsetof(struct TOKEN(HTYPE, 4ct_elem),
counter);
TOKEN(HTYPE, 4_gc_init)(set,
TOKEN(HTYPE, 4_gc));
} else {
h->dsize =
sizeof(struct TOKEN(HTYPE, 6ct_elem));
h->offset[IPSET_OFFSET_TIMEOUT] =
offsetof(struct TOKEN(HTYPE, 6ct_elem),
timeout);
h->offset[IPSET_OFFSET_COUNTER] =
offsetof(struct TOKEN(HTYPE, 6ct_elem),
counter);
TOKEN(HTYPE, 6_gc_init)(set,
TOKEN(HTYPE, 6_gc));
}
} else {
if (set->family == NFPROTO_IPV4) {
h->dsize =
sizeof(struct TOKEN(HTYPE, 4c_elem));
h->offset[IPSET_OFFSET_COUNTER] =
offsetof(struct TOKEN(HTYPE, 4c_elem),
counter);
} else {
h->dsize =
sizeof(struct TOKEN(HTYPE, 6c_elem));
h->offset[IPSET_OFFSET_COUNTER] =
offsetof(struct TOKEN(HTYPE, 6c_elem),
counter);
}
}
} else if (tb[IPSET_ATTR_TIMEOUT]) {
h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
set->extensions |= IPSET_EXT_TIMEOUT;
if (set->family == NFPROTO_IPV4) {
Expand Down
33 changes: 31 additions & 2 deletions net/netfilter/ipset/ip_set_hash_ip.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#include <linux/netfilter/ipset/ip_set_hash.h>

#define REVISION_MIN 0
#define REVISION_MAX 0
#define REVISION_MAX 1 /* Counters support */

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
Expand All @@ -48,6 +48,17 @@ struct hash_ip4t_elem {
unsigned long timeout;
};

struct hash_ip4c_elem {
__be32 ip;
struct ip_set_counter counter;
};

struct hash_ip4ct_elem {
__be32 ip;
struct ip_set_counter counter;
unsigned long timeout;
};

/* Common functions */

static inline bool
Expand Down Expand Up @@ -112,7 +123,9 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
int ret = 0;

if (unlikely(!tb[IPSET_ATTR_IP] ||
!ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
!ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
!ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
!ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
return -IPSET_ERR_PROTOCOL;

if (tb[IPSET_ATTR_LINENO])
Expand Down Expand Up @@ -177,6 +190,17 @@ struct hash_ip6t_elem {
unsigned long timeout;
};

struct hash_ip6c_elem {
union nf_inet_addr ip;
struct ip_set_counter counter;
};

struct hash_ip6ct_elem {
union nf_inet_addr ip;
struct ip_set_counter counter;
unsigned long timeout;
};

/* Common functions */

static inline bool
Expand Down Expand Up @@ -251,6 +275,8 @@ hash_ip6_uadt(struct ip_set *set, struct nlattr *tb[],

if (unlikely(!tb[IPSET_ATTR_IP] ||
!ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
!ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
!ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES) ||
tb[IPSET_ATTR_IP_TO] ||
tb[IPSET_ATTR_CIDR]))
return -IPSET_ERR_PROTOCOL;
Expand Down Expand Up @@ -288,13 +314,16 @@ static struct ip_set_type hash_ip_type __read_mostly = {
[IPSET_ATTR_RESIZE] = { .type = NLA_U8 },
[IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
[IPSET_ATTR_NETMASK] = { .type = NLA_U8 },
[IPSET_ATTR_CADT_FLAGS] = { .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 },
[IPSET_ATTR_BYTES] = { .type = NLA_U64 },
[IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
},
.me = THIS_MODULE,
};
Expand Down
46 changes: 44 additions & 2 deletions net/netfilter/ipset/ip_set_hash_ipport.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
#include <linux/netfilter/ipset/ip_set_hash.h>

#define REVISION_MIN 0
#define REVISION_MAX 1 /* SCTP and UDPLITE support added */
/* 1 SCTP and UDPLITE support added */
#define REVISION_MAX 2 /* Counters support added */

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
Expand Down Expand Up @@ -53,6 +54,23 @@ struct hash_ipport4t_elem {
unsigned long timeout;
};

struct hash_ipport4c_elem {
__be32 ip;
__be16 port;
u8 proto;
u8 padding;
struct ip_set_counter counter;
};

struct hash_ipport4ct_elem {
__be32 ip;
__be16 port;
u8 proto;
u8 padding;
struct ip_set_counter counter;
unsigned long timeout;
};

/* Common functions */

static inline bool
Expand Down Expand Up @@ -126,7 +144,9 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
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) ||
!ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
!ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
return -IPSET_ERR_PROTOCOL;

if (tb[IPSET_ATTR_LINENO])
Expand Down Expand Up @@ -219,6 +239,23 @@ struct hash_ipport6t_elem {
unsigned long timeout;
};

struct hash_ipport6c_elem {
union nf_inet_addr ip;
__be16 port;
u8 proto;
u8 padding;
struct ip_set_counter counter;
};

struct hash_ipport6ct_elem {
union nf_inet_addr ip;
__be16 port;
u8 proto;
u8 padding;
struct ip_set_counter counter;
unsigned long timeout;
};

/* Common functions */

static inline bool
Expand Down Expand Up @@ -298,6 +335,8 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[],
!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_PACKETS) ||
!ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES) ||
tb[IPSET_ATTR_IP_TO] ||
tb[IPSET_ATTR_CIDR]))
return -IPSET_ERR_PROTOCOL;
Expand Down Expand Up @@ -367,6 +406,7 @@ static struct ip_set_type hash_ipport_type __read_mostly = {
[IPSET_ATTR_RESIZE] = { .type = NLA_U8 },
[IPSET_ATTR_PROTO] = { .type = NLA_U8 },
[IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
[IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
},
.adt_policy = {
[IPSET_ATTR_IP] = { .type = NLA_NESTED },
Expand All @@ -377,6 +417,8 @@ static struct ip_set_type hash_ipport_type __read_mostly = {
[IPSET_ATTR_PROTO] = { .type = NLA_U8 },
[IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
[IPSET_ATTR_LINENO] = { .type = NLA_U32 },
[IPSET_ATTR_BYTES] = { .type = NLA_U64 },
[IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
},
.me = THIS_MODULE,
};
Expand Down
50 changes: 48 additions & 2 deletions net/netfilter/ipset/ip_set_hash_ipportip.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
#include <linux/netfilter/ipset/ip_set_hash.h>

#define REVISION_MIN 0
#define REVISION_MAX 1 /* SCTP and UDPLITE support added */
/* 1 SCTP and UDPLITE support added */
#define REVISION_MAX 2 /* Counters support added */

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
Expand Down Expand Up @@ -55,6 +56,25 @@ struct hash_ipportip4t_elem {
unsigned long timeout;
};

struct hash_ipportip4c_elem {
__be32 ip;
__be32 ip2;
__be16 port;
u8 proto;
u8 padding;
struct ip_set_counter counter;
};

struct hash_ipportip4ct_elem {
__be32 ip;
__be32 ip2;
__be16 port;
u8 proto;
u8 padding;
struct ip_set_counter counter;
unsigned long timeout;
};

static inline bool
hash_ipportip4_data_equal(const struct hash_ipportip4_elem *ip1,
const struct hash_ipportip4_elem *ip2,
Expand Down Expand Up @@ -129,7 +149,9 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
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) ||
!ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
!ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
return -IPSET_ERR_PROTOCOL;

if (tb[IPSET_ATTR_LINENO])
Expand Down Expand Up @@ -228,6 +250,25 @@ struct hash_ipportip6t_elem {
unsigned long timeout;
};

struct hash_ipportip6c_elem {
union nf_inet_addr ip;
union nf_inet_addr ip2;
__be16 port;
u8 proto;
u8 padding;
struct ip_set_counter counter;
};

struct hash_ipportip6ct_elem {
union nf_inet_addr ip;
union nf_inet_addr ip2;
__be16 port;
u8 proto;
u8 padding;
struct ip_set_counter counter;
unsigned long timeout;
};

/* Common functions */

static inline bool
Expand Down Expand Up @@ -308,6 +349,8 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[],
!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_PACKETS) ||
!ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES) ||
tb[IPSET_ATTR_IP_TO] ||
tb[IPSET_ATTR_CIDR]))
return -IPSET_ERR_PROTOCOL;
Expand Down Expand Up @@ -380,6 +423,7 @@ static struct ip_set_type hash_ipportip_type __read_mostly = {
[IPSET_ATTR_PROBES] = { .type = NLA_U8 },
[IPSET_ATTR_RESIZE] = { .type = NLA_U8 },
[IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
[IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
},
.adt_policy = {
[IPSET_ATTR_IP] = { .type = NLA_NESTED },
Expand All @@ -391,6 +435,8 @@ static struct ip_set_type hash_ipportip_type __read_mostly = {
[IPSET_ATTR_PROTO] = { .type = NLA_U8 },
[IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
[IPSET_ATTR_LINENO] = { .type = NLA_U32 },
[IPSET_ATTR_BYTES] = { .type = NLA_U64 },
[IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
},
.me = THIS_MODULE,
};
Expand Down
Loading

0 comments on commit 00d71b2

Please sign in to comment.