Merge tag 'io_uring-5.14-2021-08-07' of git://git.kernel.dk/linux-block
[linux-2.6-microblaze.git] / net / netfilter / nft_counter.c
index 85ed461..8edd3b3 100644 (file)
@@ -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 = {