Commit 023223df authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso

netfilter: nf_tables: make counter support built-in

Make counter support built-in to allow for direct call in case of
CONFIG_RETPOLINE.
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 690d5417
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
extern struct nft_expr_type nft_imm_type; extern struct nft_expr_type nft_imm_type;
extern struct nft_expr_type nft_cmp_type; extern struct nft_expr_type nft_cmp_type;
extern struct nft_expr_type nft_counter_type;
extern struct nft_expr_type nft_lookup_type; extern struct nft_expr_type nft_lookup_type;
extern struct nft_expr_type nft_bitwise_type; extern struct nft_expr_type nft_bitwise_type;
extern struct nft_expr_type nft_byteorder_type; extern struct nft_expr_type nft_byteorder_type;
...@@ -21,6 +22,7 @@ extern struct nft_expr_type nft_last_type; ...@@ -21,6 +22,7 @@ extern struct nft_expr_type nft_last_type;
#ifdef CONFIG_NETWORK_SECMARK #ifdef CONFIG_NETWORK_SECMARK
extern struct nft_object_type nft_secmark_obj_type; extern struct nft_object_type nft_secmark_obj_type;
#endif #endif
extern struct nft_object_type nft_counter_obj_type;
int nf_tables_core_module_init(void); int nf_tables_core_module_init(void);
void nf_tables_core_module_exit(void); void nf_tables_core_module_exit(void);
...@@ -120,6 +122,8 @@ bool nft_pipapo_lookup(const struct net *net, const struct nft_set *set, ...@@ -120,6 +122,8 @@ bool nft_pipapo_lookup(const struct net *net, const struct nft_set *set,
bool nft_pipapo_avx2_lookup(const struct net *net, const struct nft_set *set, bool nft_pipapo_avx2_lookup(const struct net *net, const struct nft_set *set,
const u32 *key, const struct nft_set_ext **ext); const u32 *key, const struct nft_set_ext **ext);
void nft_counter_init_seqcount(void);
struct nft_expr; struct nft_expr;
struct nft_regs; struct nft_regs;
struct nft_pktinfo; struct nft_pktinfo;
...@@ -143,4 +147,6 @@ void nft_dynset_eval(const struct nft_expr *expr, ...@@ -143,4 +147,6 @@ void nft_dynset_eval(const struct nft_expr *expr,
struct nft_regs *regs, const struct nft_pktinfo *pkt); struct nft_regs *regs, const struct nft_pktinfo *pkt);
void nft_rt_get_eval(const struct nft_expr *expr, void nft_rt_get_eval(const struct nft_expr *expr,
struct nft_regs *regs, const struct nft_pktinfo *pkt); struct nft_regs *regs, const struct nft_pktinfo *pkt);
void nft_counter_eval(const struct nft_expr *expr, struct nft_regs *regs,
const struct nft_pktinfo *pkt);
#endif /* _NET_NF_TABLES_CORE_H */ #endif /* _NET_NF_TABLES_CORE_H */
...@@ -515,12 +515,6 @@ config NFT_FLOW_OFFLOAD ...@@ -515,12 +515,6 @@ config NFT_FLOW_OFFLOAD
This option adds the "flow_offload" expression that you can use to This option adds the "flow_offload" expression that you can use to
choose what flows are placed into the hardware. choose what flows are placed into the hardware.
config NFT_COUNTER
tristate "Netfilter nf_tables counter module"
help
This option adds the "counter" expression that you can use to
include packet and byte counters in a rule.
config NFT_CONNLIMIT config NFT_CONNLIMIT
tristate "Netfilter nf_tables connlimit module" tristate "Netfilter nf_tables connlimit module"
depends on NF_CONNTRACK depends on NF_CONNTRACK
......
...@@ -75,7 +75,7 @@ nf_tables-objs := nf_tables_core.o nf_tables_api.o nft_chain_filter.o \ ...@@ -75,7 +75,7 @@ nf_tables-objs := nf_tables_core.o nf_tables_api.o nft_chain_filter.o \
nf_tables_trace.o nft_immediate.o nft_cmp.o nft_range.o \ nf_tables_trace.o nft_immediate.o nft_cmp.o nft_range.o \
nft_bitwise.o nft_byteorder.o nft_payload.o nft_lookup.o \ nft_bitwise.o nft_byteorder.o nft_payload.o nft_lookup.o \
nft_dynset.o nft_meta.o nft_rt.o nft_exthdr.o nft_last.o \ nft_dynset.o nft_meta.o nft_rt.o nft_exthdr.o nft_last.o \
nft_chain_route.o nf_tables_offload.o \ nft_counter.o nft_chain_route.o nf_tables_offload.o \
nft_set_hash.o nft_set_bitmap.o nft_set_rbtree.o \ nft_set_hash.o nft_set_bitmap.o nft_set_rbtree.o \
nft_set_pipapo.o nft_set_pipapo.o
...@@ -100,7 +100,6 @@ obj-$(CONFIG_NFT_REJECT) += nft_reject.o ...@@ -100,7 +100,6 @@ obj-$(CONFIG_NFT_REJECT) += nft_reject.o
obj-$(CONFIG_NFT_REJECT_INET) += nft_reject_inet.o obj-$(CONFIG_NFT_REJECT_INET) += nft_reject_inet.o
obj-$(CONFIG_NFT_REJECT_NETDEV) += nft_reject_netdev.o obj-$(CONFIG_NFT_REJECT_NETDEV) += nft_reject_netdev.o
obj-$(CONFIG_NFT_TUNNEL) += nft_tunnel.o obj-$(CONFIG_NFT_TUNNEL) += nft_tunnel.o
obj-$(CONFIG_NFT_COUNTER) += nft_counter.o
obj-$(CONFIG_NFT_LOG) += nft_log.o obj-$(CONFIG_NFT_LOG) += nft_log.o
obj-$(CONFIG_NFT_MASQ) += nft_masq.o obj-$(CONFIG_NFT_MASQ) += nft_masq.o
obj-$(CONFIG_NFT_REDIR) += nft_redir.o obj-$(CONFIG_NFT_REDIR) += nft_redir.o
......
...@@ -169,6 +169,7 @@ static void expr_call_ops_eval(const struct nft_expr *expr, ...@@ -169,6 +169,7 @@ static void expr_call_ops_eval(const struct nft_expr *expr,
X(e, nft_payload_eval); X(e, nft_payload_eval);
X(e, nft_cmp_eval); X(e, nft_cmp_eval);
X(e, nft_counter_eval);
X(e, nft_meta_get_eval); X(e, nft_meta_get_eval);
X(e, nft_lookup_eval); X(e, nft_lookup_eval);
X(e, nft_range_eval); X(e, nft_range_eval);
...@@ -292,18 +293,22 @@ static struct nft_expr_type *nft_basic_types[] = { ...@@ -292,18 +293,22 @@ static struct nft_expr_type *nft_basic_types[] = {
&nft_rt_type, &nft_rt_type,
&nft_exthdr_type, &nft_exthdr_type,
&nft_last_type, &nft_last_type,
&nft_counter_type,
}; };
static struct nft_object_type *nft_basic_objects[] = { static struct nft_object_type *nft_basic_objects[] = {
#ifdef CONFIG_NETWORK_SECMARK #ifdef CONFIG_NETWORK_SECMARK
&nft_secmark_obj_type, &nft_secmark_obj_type,
#endif #endif
&nft_counter_obj_type,
}; };
int __init nf_tables_core_module_init(void) int __init nf_tables_core_module_init(void)
{ {
int err, i, j = 0; int err, i, j = 0;
nft_counter_init_seqcount();
for (i = 0; i < ARRAY_SIZE(nft_basic_objects); i++) { for (i = 0; i < ARRAY_SIZE(nft_basic_objects); i++) {
err = nft_register_obj(nft_basic_objects[i]); err = nft_register_obj(nft_basic_objects[i]);
if (err) if (err)
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/netfilter.h> #include <linux/netfilter.h>
#include <linux/netfilter/nf_tables.h> #include <linux/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables.h> #include <net/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables_core.h>
#include <net/netfilter/nf_tables_offload.h> #include <net/netfilter/nf_tables_offload.h>
struct nft_counter { struct nft_counter {
...@@ -174,7 +175,7 @@ static const struct nla_policy nft_counter_policy[NFTA_COUNTER_MAX + 1] = { ...@@ -174,7 +175,7 @@ static const struct nla_policy nft_counter_policy[NFTA_COUNTER_MAX + 1] = {
[NFTA_COUNTER_BYTES] = { .type = NLA_U64 }, [NFTA_COUNTER_BYTES] = { .type = NLA_U64 },
}; };
static struct nft_object_type nft_counter_obj_type; struct nft_object_type nft_counter_obj_type;
static const struct nft_object_ops nft_counter_obj_ops = { static const struct nft_object_ops nft_counter_obj_ops = {
.type = &nft_counter_obj_type, .type = &nft_counter_obj_type,
.size = sizeof(struct nft_counter_percpu_priv), .size = sizeof(struct nft_counter_percpu_priv),
...@@ -184,7 +185,7 @@ static const struct nft_object_ops nft_counter_obj_ops = { ...@@ -184,7 +185,7 @@ static const struct nft_object_ops nft_counter_obj_ops = {
.dump = nft_counter_obj_dump, .dump = nft_counter_obj_dump,
}; };
static struct nft_object_type nft_counter_obj_type __read_mostly = { struct nft_object_type nft_counter_obj_type __read_mostly = {
.type = NFT_OBJECT_COUNTER, .type = NFT_OBJECT_COUNTER,
.ops = &nft_counter_obj_ops, .ops = &nft_counter_obj_ops,
.maxattr = NFTA_COUNTER_MAX, .maxattr = NFTA_COUNTER_MAX,
...@@ -192,9 +193,8 @@ static struct nft_object_type nft_counter_obj_type __read_mostly = { ...@@ -192,9 +193,8 @@ static struct nft_object_type nft_counter_obj_type __read_mostly = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
static void nft_counter_eval(const struct nft_expr *expr, void nft_counter_eval(const struct nft_expr *expr, struct nft_regs *regs,
struct nft_regs *regs, const struct nft_pktinfo *pkt)
const struct nft_pktinfo *pkt)
{ {
struct nft_counter_percpu_priv *priv = nft_expr_priv(expr); struct nft_counter_percpu_priv *priv = nft_expr_priv(expr);
...@@ -275,7 +275,15 @@ static void nft_counter_offload_stats(struct nft_expr *expr, ...@@ -275,7 +275,15 @@ static void nft_counter_offload_stats(struct nft_expr *expr,
preempt_enable(); preempt_enable();
} }
static struct nft_expr_type nft_counter_type; void nft_counter_init_seqcount(void)
{
int cpu;
for_each_possible_cpu(cpu)
seqcount_init(per_cpu_ptr(&nft_counter_seq, cpu));
}
struct nft_expr_type nft_counter_type;
static const struct nft_expr_ops nft_counter_ops = { static const struct nft_expr_ops nft_counter_ops = {
.type = &nft_counter_type, .type = &nft_counter_type,
.size = NFT_EXPR_SIZE(sizeof(struct nft_counter_percpu_priv)), .size = NFT_EXPR_SIZE(sizeof(struct nft_counter_percpu_priv)),
...@@ -289,7 +297,7 @@ static const struct nft_expr_ops nft_counter_ops = { ...@@ -289,7 +297,7 @@ static const struct nft_expr_ops nft_counter_ops = {
.offload_stats = nft_counter_offload_stats, .offload_stats = nft_counter_offload_stats,
}; };
static struct nft_expr_type nft_counter_type __read_mostly = { struct nft_expr_type nft_counter_type __read_mostly = {
.name = "counter", .name = "counter",
.ops = &nft_counter_ops, .ops = &nft_counter_ops,
.policy = nft_counter_policy, .policy = nft_counter_policy,
...@@ -297,39 +305,3 @@ static struct nft_expr_type nft_counter_type __read_mostly = { ...@@ -297,39 +305,3 @@ static struct nft_expr_type nft_counter_type __read_mostly = {
.flags = NFT_EXPR_STATEFUL, .flags = NFT_EXPR_STATEFUL,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
static int __init nft_counter_module_init(void)
{
int cpu, err;
for_each_possible_cpu(cpu)
seqcount_init(per_cpu_ptr(&nft_counter_seq, cpu));
err = nft_register_obj(&nft_counter_obj_type);
if (err < 0)
return err;
err = nft_register_expr(&nft_counter_type);
if (err < 0)
goto err1;
return 0;
err1:
nft_unregister_obj(&nft_counter_obj_type);
return err;
}
static void __exit nft_counter_module_exit(void)
{
nft_unregister_expr(&nft_counter_type);
nft_unregister_obj(&nft_counter_obj_type);
}
module_init(nft_counter_module_init);
module_exit(nft_counter_module_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
MODULE_ALIAS_NFT_EXPR("counter");
MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_COUNTER);
MODULE_DESCRIPTION("nftables counter rule support");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment