aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter/nft_counter.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2021-04-15 20:10:18 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2021-04-18 22:04:49 +0200
commitb72920f6e4a9d6607b723d69b7f412c829769c75 (patch)
treeba27ac40ee59d6d83365ff1ce05f38933b7a5037 /net/netfilter/nft_counter.c
parent8826218215de1aae9d89a6ea8d3786f224711334 (diff)
downloadlinux-b72920f6e4a9d6607b723d69b7f412c829769c75.tar.gz
netfilter: nftables: counter hardware offload support
This patch adds the .offload_stats operation to synchronize hardware stats with the expression data. Update the counter expression to use this new interface. The hardware stats are retrieved from the netlink dump path via FLOW_CLS_STATS command to the driver. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter/nft_counter.c')
-rw-r--r--net/netfilter/nft_counter.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/net/netfilter/nft_counter.c b/net/netfilter/nft_counter.c
index 85ed461ec24e8..8edd3b3c173d7 100644
--- a/net/netfilter/nft_counter.c
+++ b/net/netfilter/nft_counter.c
@@ -13,6 +13,7 @@
#include <linux/netfilter.h>
#include <linux/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables.h>
+#include <net/netfilter/nf_tables_offload.h>
struct nft_counter {
s64 bytes;
@@ -248,6 +249,32 @@ static int nft_counter_clone(struct nft_expr *dst, const struct nft_expr *src)
return 0;
}
+static int nft_counter_offload(struct nft_offload_ctx *ctx,
+ struct nft_flow_rule *flow,
+ const struct nft_expr *expr)
+{
+ /* No specific offload action is needed, but report success. */
+ return 0;
+}
+
+static void nft_counter_offload_stats(struct nft_expr *expr,
+ const struct flow_stats *stats)
+{
+ struct nft_counter_percpu_priv *priv = nft_expr_priv(expr);
+ struct nft_counter *this_cpu;
+ seqcount_t *myseq;
+
+ preempt_disable();
+ this_cpu = this_cpu_ptr(priv->counter);
+ myseq = this_cpu_ptr(&nft_counter_seq);
+
+ write_seqcount_begin(myseq);
+ this_cpu->packets += stats->pkts;
+ this_cpu->bytes += stats->bytes;
+ write_seqcount_end(myseq);
+ preempt_enable();
+}
+
static struct nft_expr_type nft_counter_type;
static const struct nft_expr_ops nft_counter_ops = {
.type = &nft_counter_type,
@@ -258,6 +285,8 @@ static const struct nft_expr_ops nft_counter_ops = {
.destroy_clone = nft_counter_destroy,
.dump = nft_counter_dump,
.clone = nft_counter_clone,
+ .offload = nft_counter_offload,
+ .offload_stats = nft_counter_offload_stats,
};
static struct nft_expr_type nft_counter_type __read_mostly = {