summaryrefslogtreecommitdiff
path: root/net/netfilter/nft_counter.c
diff options
context:
space:
mode:
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 85ed461ec24e..8edd3b3c173d 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 = {