[{"id":3668707,"web_url":"http://patchwork.ozlabs.org/comment/3668707/","msgid":"<acMB9xSTEmwly8QK@chamomile>","list_archive_url":null,"date":"2026-03-24T21:28:23","subject":"Re: [PATCH nf-next v2 1/2] netfilter: flowtable: update netdev stats\n with HW_OFFLOAD flows","submitter":{"id":1315,"url":"http://patchwork.ozlabs.org/api/people/1315/","name":"Pablo Neira Ayuso","email":"pablo@netfilter.org"},"content":"On Tue, Mar 24, 2026 at 02:40:15PM -0600, Ahmed Zaki wrote:\n> Some drivers (notably DSA) delegate the nft flowtable HW_OFFLOAD flows\n> to a parent driver. While the parent driver is able to report the\n> offloaded traffic stats directly from the HW, the delegating driver\n> does not report the stats. This fails SNMP-based monitoring tools that\n> rely on netdev stats to report the network traffic.\n> \n> Add a new struct pcpu_sw_netstats \"fstats\" to net_device that gets\n> allocated only if the new flag \"flow_offload_via_parent\" is set by the\n> driver. The new stats are lazily allocated by the nft flow offloading\n> code when the first flow is offloaded. The stats are updated periodically\n> in flow_offload_work_stats() and also once in flow_offload_work_del()\n> before the flow is deleted. For this, flow_offload_work_del() had to\n> be moved below flow_offload_tuple_stats().\n\nHm, I think v1 was a simpler approach... except that you innecesarily\nmodified a lot of callsites as Jakub pointed out. I don't see why you\nneed this new callback for netdev_ops.\n\n> Signed-off-by: Ahmed Zaki <anzaki@gmail.com>\n> ---\n>  include/linux/netdevice.h             | 45 ++++++++++++\n>  net/core/dev.c                        |  8 +++\n>  net/netfilter/nf_flow_table_offload.c | 98 +++++++++++++++++++++++++--\n>  3 files changed, 145 insertions(+), 6 deletions(-)\n> \n> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h\n> index 67e25f6d15a4..647758f78213 100644\n> --- a/include/linux/netdevice.h\n> +++ b/include/linux/netdevice.h\n> @@ -1840,6 +1840,11 @@ enum netdev_reg_state {\n>   *\t@stats:\t\tStatistics struct, which was left as a legacy, use\n>   *\t\t\trtnl_link_stats64 instead\n>   *\n> + *\t@fstats:\tHW offloaded flow statistics: RX/TX packets,\n> + *\t\t\tRX/TX bytes. Lazily allocated by the flow offload\n> + *\t\t\tpath on the first offloaded flow for devices that\n> + *\t\t\tset @flow_offload_via_parent. Freed by free_netdev().\n> + *\n>   *\t@core_stats:\tcore networking counters,\n>   *\t\t\tdo not use this in drivers\n>   *\t@carrier_up_count:\tNumber of times the carrier has been up\n> @@ -2048,6 +2053,12 @@ enum netdev_reg_state {\n>   *\t@change_proto_down: device supports setting carrier via IFLA_PROTO_DOWN\n>   *\t@netns_immutable: interface can't change network namespaces\n>   *\t@fcoe_mtu:\tdevice supports maximum FCoE MTU, 2158 bytes\n> + *\t@flow_offload_via_parent: device delegates nft flowtable hardware\n> + *\t\t\t\t  offload to a parent/conduit device (e.g. DSA\n> + *\t\t\t\t  user ports delegate to their conduit MAC).\n> + *\t\t\t\t  The parent's HW count the offloaded traffic\n> + *\t\t\t\t  but this device's sw netstats path does not.\n> + *\t\t\t\t  @fstats is allocated to fill that gap.\n>   *\n>   *\t@net_notifier_list:\tList of per-net netdev notifier block\n>   *\t\t\t\tthat follow this device when it is moved\n> @@ -2233,6 +2244,7 @@ struct net_device {\n>  \n>  \tstruct net_device_stats\tstats; /* not used by modern drivers */\n>  \n> +\tstruct pcpu_sw_netstats __percpu *fstats;\n>  \tstruct net_device_core_stats __percpu *core_stats;\n>  \n>  \t/* Stats to monitor link on/off, flapping */\n> @@ -2463,6 +2475,7 @@ struct net_device {\n>  \tunsigned long\t\tchange_proto_down:1;\n>  \tunsigned long\t\tnetns_immutable:1;\n>  \tunsigned long\t\tfcoe_mtu:1;\n> +\tunsigned long\t\tflow_offload_via_parent:1;\n>  \n>  \tstruct list_head\tnet_notifier_list;\n>  \n> @@ -2992,6 +3005,38 @@ struct pcpu_lstats {\n>  \n>  void dev_lstats_read(struct net_device *dev, u64 *packets, u64 *bytes);\n>  \n> +static inline void dev_fstats_rx_add(struct net_device *dev,\n> +\t\t\t\t     unsigned int packets,\n> +\t\t\t\t     unsigned int len)\n> +{\n> +\tstruct pcpu_sw_netstats *fstats;\n> +\n> +\tif (!dev->fstats)\n> +\t\treturn;\n> +\n> +\tfstats = this_cpu_ptr(dev->fstats);\n> +\tu64_stats_update_begin(&fstats->syncp);\n> +\tu64_stats_add(&fstats->rx_bytes, len);\n> +\tu64_stats_add(&fstats->rx_packets, packets);\n> +\tu64_stats_update_end(&fstats->syncp);\n> +}\n> +\n> +static inline void dev_fstats_tx_add(struct net_device *dev,\n> +\t\t\t\t     unsigned int packets,\n> +\t\t\t\t     unsigned int len)\n> +{\n> +\tstruct pcpu_sw_netstats *fstats;\n> +\n> +\tif (!dev->fstats)\n> +\t\treturn;\n> +\n> +\tfstats = this_cpu_ptr(dev->fstats);\n> +\tu64_stats_update_begin(&fstats->syncp);\n> +\tu64_stats_add(&fstats->tx_bytes, len);\n> +\tu64_stats_add(&fstats->tx_packets, packets);\n> +\tu64_stats_update_end(&fstats->syncp);\n> +}\n> +\n>  static inline void dev_sw_netstats_rx_add(struct net_device *dev, unsigned int len)\n>  {\n>  \tstruct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats);\n> diff --git a/net/core/dev.c b/net/core/dev.c\n> index f48dc299e4b2..07fb315ad42c 100644\n> --- a/net/core/dev.c\n> +++ b/net/core/dev.c\n> @@ -11865,6 +11865,7 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,\n>  {\n>  \tconst struct net_device_ops *ops = dev->netdev_ops;\n>  \tconst struct net_device_core_stats __percpu *p;\n> +\tconst struct pcpu_sw_netstats __percpu *fstats;\n>  \n>  \t/*\n>  \t * IPv{4,6} and udp tunnels share common stat helpers and use\n> @@ -11893,6 +11894,11 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,\n>  \t\tnetdev_stats_to_stats64(storage, &dev->stats);\n>  \t}\n>  \n> +\t/* This READ_ONCE() pairs with cmpxchg in flow_offload_fstats_ensure() */\n> +\tfstats = READ_ONCE(dev->fstats);\n> +\tif (fstats)\n> +\t\tdev_fetch_sw_netstats(storage, fstats);\n> +\n>  \t/* This READ_ONCE() pairs with the write in netdev_core_stats_alloc() */\n>  \tp = READ_ONCE(dev->core_stats);\n>  \tif (p) {\n> @@ -12212,6 +12218,8 @@ void free_netdev(struct net_device *dev)\n>  \tfree_percpu(dev->pcpu_refcnt);\n>  \tdev->pcpu_refcnt = NULL;\n>  #endif\n> +\tfree_percpu(dev->fstats);\n> +\tdev->fstats = NULL;\n>  \tfree_percpu(dev->core_stats);\n>  \tdev->core_stats = NULL;\n>  \tfree_percpu(dev->xdp_bulkq);\n> diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c\n> index b2e4fb6fa011..fc1e67a79904 100644\n> --- a/net/netfilter/nf_flow_table_offload.c\n> +++ b/net/netfilter/nf_flow_table_offload.c\n> @@ -925,13 +925,80 @@ static void flow_offload_work_add(struct flow_offload_work *offload)\n>  \tnf_flow_offload_destroy(flow_rule);\n>  }\n>  \n> -static void flow_offload_work_del(struct flow_offload_work *offload)\n> +static bool flow_offload_fstats_ensure(struct net_device *dev)\n>  {\n> -\tclear_bit(IPS_HW_OFFLOAD_BIT, &offload->flow->ct->status);\n> -\tflow_offload_tuple_del(offload, FLOW_OFFLOAD_DIR_ORIGINAL);\n> -\tif (test_bit(NF_FLOW_HW_BIDIRECTIONAL, &offload->flow->flags))\n> -\t\tflow_offload_tuple_del(offload, FLOW_OFFLOAD_DIR_REPLY);\n> -\tset_bit(NF_FLOW_HW_DEAD, &offload->flow->flags);\n> +\tstruct pcpu_sw_netstats __percpu *p;\n> +\n> +\tif (!dev->flow_offload_via_parent)\n> +\t\treturn false;\n> +\n> +\t/* Pairs with cmpxchg() below. */\n> +\tif (likely(READ_ONCE(dev->fstats)))\n> +\t\treturn true;\n> +\n> +\tp = __netdev_alloc_pcpu_stats(struct pcpu_sw_netstats, GFP_ATOMIC);\n> +\tif (!p)\n> +\t\treturn false;\n> +\n> +\tif (cmpxchg(&dev->fstats, NULL, p))\n> +\t\tfree_percpu(p);\t/* lost the race, discard and use winner's */\n> +\n> +\treturn true;\n> +}\n> +\n> +static u32 flow_offload_egress_ifidx(const struct flow_offload_tuple *tuple)\n> +{\n> +\tswitch (tuple->xmit_type) {\n> +\tcase FLOW_OFFLOAD_XMIT_NEIGH:\n> +\t\treturn tuple->ifidx;\n> +\tcase FLOW_OFFLOAD_XMIT_DIRECT:\n> +\t\treturn tuple->out.ifidx;\n> +\tdefault:\n> +\t\treturn 0;\n> +\t}\n> +}\n> +\n> +static void flow_offload_netdev_update(struct flow_offload_work *offload,\n> +\t\t\t\t       struct flow_stats *stats)\n> +{\n> +\tconst struct flow_offload_tuple *tuple;\n> +\tstruct net_device *indev, *outdev;\n> +\tstruct net *net;\n> +\n> +\trcu_read_lock();\n> +\tnet = read_pnet(&offload->flowtable->net);\n> +\tif (stats[FLOW_OFFLOAD_DIR_ORIGINAL].pkts) {\n> +\t\ttuple = &offload->flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple;\n> +\t\tindev = dev_get_by_index_rcu(net, tuple->iifidx);\n> +\t\tif (indev && flow_offload_fstats_ensure(indev))\n> +\t\t\tdev_fstats_rx_add(indev,\n> +\t\t\t\t\t  stats[FLOW_OFFLOAD_DIR_ORIGINAL].pkts,\n> +\t\t\t\t\t  stats[FLOW_OFFLOAD_DIR_ORIGINAL].bytes);\n> +\n> +\t\toutdev = dev_get_by_index_rcu(net,\n> +\t\t\t\t\t      flow_offload_egress_ifidx(tuple));\n> +\t\tif (outdev && flow_offload_fstats_ensure(outdev))\n> +\t\t\tdev_fstats_tx_add(outdev,\n> +\t\t\t\t\t  stats[FLOW_OFFLOAD_DIR_ORIGINAL].pkts,\n> +\t\t\t\t\t  stats[FLOW_OFFLOAD_DIR_ORIGINAL].bytes);\n> +\t}\n> +\n> +\tif (stats[FLOW_OFFLOAD_DIR_REPLY].pkts) {\n> +\t\ttuple = &offload->flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple;\n> +\t\tindev = dev_get_by_index_rcu(net, tuple->iifidx);\n> +\t\tif (indev && flow_offload_fstats_ensure(indev))\n> +\t\t\tdev_fstats_rx_add(indev,\n> +\t\t\t\t\t  stats[FLOW_OFFLOAD_DIR_REPLY].pkts,\n> +\t\t\t\t\t  stats[FLOW_OFFLOAD_DIR_REPLY].bytes);\n> +\n> +\t\toutdev = dev_get_by_index_rcu(net,\n> +\t\t\t\t\t      flow_offload_egress_ifidx(tuple));\n> +\t\tif (outdev && flow_offload_fstats_ensure(outdev))\n> +\t\t\tdev_fstats_tx_add(outdev,\n> +\t\t\t\t\t  stats[FLOW_OFFLOAD_DIR_REPLY].pkts,\n> +\t\t\t\t\t  stats[FLOW_OFFLOAD_DIR_REPLY].bytes);\n> +\t}\n> +\trcu_read_unlock();\n>  }\n>  \n>  static void flow_offload_tuple_stats(struct flow_offload_work *offload,\n> @@ -968,6 +1035,25 @@ static void flow_offload_work_stats(struct flow_offload_work *offload)\n>  \t\t\t\t       FLOW_OFFLOAD_DIR_REPLY,\n>  \t\t\t\t       stats[1].pkts, stats[1].bytes);\n>  \t}\n> +\n> +\tflow_offload_netdev_update(offload, stats);\n> +}\n> +\n> +static void flow_offload_work_del(struct flow_offload_work *offload)\n> +{\n> +\tstruct flow_stats stats[FLOW_OFFLOAD_DIR_MAX] = {};\n> +\n> +\tflow_offload_tuple_stats(offload, FLOW_OFFLOAD_DIR_ORIGINAL, &stats[0]);\n> +\tif (test_bit(NF_FLOW_HW_BIDIRECTIONAL, &offload->flow->flags))\n> +\t\tflow_offload_tuple_stats(offload, FLOW_OFFLOAD_DIR_REPLY,\n> +\t\t\t\t\t &stats[1]);\n> +\tflow_offload_netdev_update(offload, stats);\n> +\n> +\tclear_bit(IPS_HW_OFFLOAD_BIT, &offload->flow->ct->status);\n> +\tflow_offload_tuple_del(offload, FLOW_OFFLOAD_DIR_ORIGINAL);\n> +\tif (test_bit(NF_FLOW_HW_BIDIRECTIONAL, &offload->flow->flags))\n> +\t\tflow_offload_tuple_del(offload, FLOW_OFFLOAD_DIR_REPLY);\n> +\tset_bit(NF_FLOW_HW_DEAD, &offload->flow->flags);\n>  }\n>  \n>  static void flow_offload_work_handler(struct work_struct *work)\n> -- \n> 2.43.0\n>","headers":{"Return-Path":"\n <netfilter-devel+bounces-11388-incoming=patchwork.ozlabs.org@vger.kernel.org>","X-Original-To":["incoming@patchwork.ozlabs.org","netfilter-devel@vger.kernel.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=netfilter.org header.i=@netfilter.org\n header.a=rsa-sha256 header.s=2025 header.b=X82e3rBP;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=172.234.253.10; helo=sea.lore.kernel.org;\n envelope-from=netfilter-devel+bounces-11388-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org\n header.b=\"X82e3rBP\"","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=217.70.190.124","smtp.subspace.kernel.org;\n dmarc=none (p=none dis=none) header.from=netfilter.org","smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=netfilter.org"],"Received":["from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fgNVj6NSPz1y1G\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 25 Mar 2026 08:30:21 +1100 (AEDT)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id C16363021EB8\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 24 Mar 2026 21:28:39 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id D591E35F182;\n\tTue, 24 Mar 2026 21:28:38 +0000 (UTC)","from mail.netfilter.org (mail.netfilter.org [217.70.190.124])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 25378352921;\n\tTue, 24 Mar 2026 21:28:34 +0000 (UTC)","from netfilter.org (mail-agni [217.70.190.124])\n\tby mail.netfilter.org (Postfix) with UTF8SMTPSA id D79C5600B5;\n\tTue, 24 Mar 2026 22:28:25 +0100 (CET)"],"ARC-Seal":"i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1774387718; cv=none;\n b=Fw4j8N28o4sSDFni3A0ANKxPemuzItUQ2t9nY7QoeKPVPeFiAfJ4gz2Chyh08A4XJMXCkFnqMJxMlnc1umSU//T+QAWU/spQVBEfhnf0f/mc9cp0qzsT0RzIYce97kOZveUDv7urKR14VtT3QKB4q/FXOqhmcQWDWsY6y/KU2k8=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1774387718; c=relaxed/simple;\n\tbh=Pa8Giaac+RQBM5prQwB6l2LD3PHYdrPNru5oOwF2NrA=;\n\th=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version:\n\t Content-Type:Content-Disposition:In-Reply-To;\n b=dn3GagCHqNk+F5Jirg/UxR8HCdGpXxWgj//kiMbP5uBbF+R90gsDq5KfYynQIPquuhDcp+t+QDZ8HBUTrIjQRUcY3lKMq1ubQkPoS7TeXoHDBAiyIeH7SitrxPW1UVAelr956TFxmQW+GHYpmJfjXGwqIcX1TLeqW7qOqxvuHrQ=","ARC-Authentication-Results":"i=1; smtp.subspace.kernel.org;\n dmarc=none (p=none dis=none) header.from=netfilter.org;\n spf=pass smtp.mailfrom=netfilter.org;\n dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org\n header.b=X82e3rBP; arc=none smtp.client-ip=217.70.190.124","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=netfilter.org;\n\ts=2025; t=1774387706;\n\tbh=WSV63YLJEh/5Og9YjArs+nqErNOE9rA2hd+2DB8uIaA=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=X82e3rBP0FBVPefVhG7N9M30FVISRNddarhBBB4O/1HKKVYjVDpbVC+gdGiIccGQi\n\t hY2e8FsDEgW/aPXWZJhOY/WJCsukYLDqkfabn6yMBshRB9E1iJaRvXuJLWdNtu24FP\n\t ub/P/0mEeJyEmE9p3WpgsFmK3ZIeL9aeyXq4OdEwvPEppDIeAR/y66MsuHMwona5qD\n\t vchmdhqVGk07hIkHrxr9qsK1mGea5x5uJS/y8K3AWlKN2Z78vXIf4amLXOw2I07e7f\n\t ETtBtaXJWVr2UCwq7kyL8wDXyqBsJJ+lzgwZ236UnNiZ7ZFAEcrAbG3TKEHOkMADZT\n\t CJxfuZx+/t+OQ==","Date":"Tue, 24 Mar 2026 22:28:23 +0100","From":"Pablo Neira Ayuso <pablo@netfilter.org>","To":"Ahmed Zaki <anzaki@gmail.com>","Cc":"netfilter-devel@vger.kernel.org, andrew@lunn.ch, olteanv@gmail.com,\n\tfw@strlen.de, kuba@kernel.org, pabeni@redhat.com,\n\tedumazet@google.com, coreteam@netfilter.org, netdev@vger.kernel.org","Subject":"Re: [PATCH nf-next v2 1/2] netfilter: flowtable: update netdev stats\n with HW_OFFLOAD flows","Message-ID":"<acMB9xSTEmwly8QK@chamomile>","References":"<20260324204016.2089193-1-anzaki@gmail.com>\n <20260324204016.2089193-2-anzaki@gmail.com>","Precedence":"bulk","X-Mailing-List":"netfilter-devel@vger.kernel.org","List-Id":"<netfilter-devel.vger.kernel.org>","List-Subscribe":"<mailto:netfilter-devel+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:netfilter-devel+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20260324204016.2089193-2-anzaki@gmail.com>"}},{"id":3668741,"web_url":"http://patchwork.ozlabs.org/comment/3668741/","msgid":"<CANczwAHFy1fp4JU4ANJ2Uf-=B2uDP0GejrWUuELz9yf0wu9H2A@mail.gmail.com>","list_archive_url":null,"date":"2026-03-24T23:27:32","subject":"Re: [PATCH nf-next v2 1/2] netfilter: flowtable: update netdev stats\n with HW_OFFLOAD flows","submitter":{"id":77450,"url":"http://patchwork.ozlabs.org/api/people/77450/","name":"Ahmed Zaki","email":"anzaki@gmail.com"},"content":"On Tue, Mar 24, 2026 at 3:28 PM Pablo Neira Ayuso <pablo@netfilter.org> wrote:\n>\n> On Tue, Mar 24, 2026 at 02:40:15PM -0600, Ahmed Zaki wrote:\n> > Some drivers (notably DSA) delegate the nft flowtable HW_OFFLOAD flows\n> > to a parent driver. While the parent driver is able to report the\n> > offloaded traffic stats directly from the HW, the delegating driver\n> > does not report the stats. This fails SNMP-based monitoring tools that\n> > rely on netdev stats to report the network traffic.\n> >\n> > Add a new struct pcpu_sw_netstats \"fstats\" to net_device that gets\n> > allocated only if the new flag \"flow_offload_via_parent\" is set by the\n> > driver. The new stats are lazily allocated by the nft flow offloading\n> > code when the first flow is offloaded. The stats are updated periodically\n> > in flow_offload_work_stats() and also once in flow_offload_work_del()\n> > before the flow is deleted. For this, flow_offload_work_del() had to\n> > be moved below flow_offload_tuple_stats().\n>\n> Hm, I think v1 was a simpler approach... except that you innecesarily\n> modified a lot of callsites as Jakub pointed out. I don't see why you\n> need this new callback for netdev_ops.\n>\n\nNo new netdev_op, but I added the new stats field (fstats) since having a\nseparate field and flag guarantees that no other drivers gets broken and\nno other drivers (that already count offloaded stats) need to be touched.\n\nLooking at some drivers, tstats seems to be sometimes used by H/W drivers\nand sometimes not, which just complicates the code semantics if we also use it\nfor \"H/W flow offloaded\" stats. Some of these drivers already read H/W\nMIB registers.\nSo I think there is no way around adding a new flag to not break something.\n\nBut more importantly, I am not sure if there is no driver that sets\nNETDEV_PCPU_STAT_TSTATS\n**and** report its own offloaded flow stats. If we re-use tsats\nfor these, we will double count the offloaded traffic unless we set some\nflag so that nft does not double-count.\n\nAlso, any driver that already counts offloaded flow traffic and uses\nNETDEV_PCPU_STAT_DSTATS will break if we use tstas (union with dstats).","headers":{"Return-Path":"\n <netfilter-devel+bounces-11389-incoming=patchwork.ozlabs.org@vger.kernel.org>","X-Original-To":["incoming@patchwork.ozlabs.org","netfilter-devel@vger.kernel.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=WxPOYUy0;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c15:e001:75::12fc:5321; helo=sin.lore.kernel.org;\n envelope-from=netfilter-devel+bounces-11389-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com\n header.b=\"WxPOYUy0\"","smtp.subspace.kernel.org;\n arc=pass smtp.client-ip=209.85.128.180","smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=gmail.com","smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=gmail.com"],"Received":["from sin.lore.kernel.org (sin.lore.kernel.org\n [IPv6:2600:3c15:e001:75::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fgR6s0w2pz1y1G\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 25 Mar 2026 10:28:20 +1100 (AEDT)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sin.lore.kernel.org (Postfix) with ESMTP id 7B5C930274AF\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 24 Mar 2026 23:28:15 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 4B88C3CAE9D;\n\tTue, 24 Mar 2026 23:28:11 +0000 (UTC)","from mail-yw1-f180.google.com (mail-yw1-f180.google.com\n [209.85.128.180])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id A5160336884\n\tfor <netfilter-devel@vger.kernel.org>; Tue, 24 Mar 2026 23:28:09 +0000 (UTC)","by mail-yw1-f180.google.com with SMTP id\n 00721157ae682-79a40fb9890so45768307b3.1\n        for <netfilter-devel@vger.kernel.org>;\n Tue, 24 Mar 2026 16:28:09 -0700 (PDT)"],"ARC-Seal":["i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1774394890; cv=pass;\n b=I32AleOKPOobiUNc3PlJZE5g9zAdMOPKiT32Nk3ayuZW+e3sT/pjpLuxUZqiB/s7lPa+/GfjiemgGdP7NlNi5Wg304F2pCNUbe4V4NtC6cMOCPScCGwJQjBBUHTBbOBrcL+iiBY2wJZkjsfzRrR6t1amuxzXaSJSpMzVT/GTh6c=","i=1; a=rsa-sha256; t=1774394889; cv=none;\n        d=google.com; s=arc-20240605;\n        b=A4RMavfwf6+cmj32S0atS4Cd3tZ9mBdH8NlB6SXRSeCnqqY/kRHbX4Fa7otXE7d1vX\n         d8yJv72ZK4OcrgIDufElAdOZftefLjW8k+ZfGpEL41DMxe0J7F2f6w83/7rBN/HnjUFe\n         DianIaYu/AKMXuii1gq2z5xsad/tKQhF75fiTykvcFnzhhL+jsP4g1+9wvl3RywLQTxg\n         +P5G0zoW8Y07u3TLq1KSEmGCMlT0FT5FA3tU8qUJ2XolSHY15i3YnIa9cAUVbQkqDIP5\n         9UlEmPZAaD79ErUZViN7Yj4f68ll4fwq9rYm2wBK5UadhPSmrOPPRmV6KRNpIu3o/oqq\n         zvzg=="],"ARC-Message-Signature":["i=2; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1774394890; c=relaxed/simple;\n\tbh=LT2q8PEldt87z3mrWDdYA25Zu4LLlNbQMdEbJVa3TH4=;\n\th=MIME-Version:References:In-Reply-To:From:Date:Message-ID:Subject:\n\t To:Cc:Content-Type;\n b=DOgHW6bmgkvPtcNjrhCroRWatfCHkaKG4wP4lPSqeTCkFg3KEw91+PRMkjRmtMDrXFg/6Jd/IofFWlfONdl95cDm7dwyLV2VsLVmrHFbvZkT1wJtSjQxgcTyUDIiarelEsg2yl1d530mRnyXuiMs/j7Qfqzfpw8PTjQ6dviFxFA=","i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com;\n s=arc-20240605;\n        h=content-transfer-encoding:cc:to:subject:message-id:date:from\n         :in-reply-to:references:mime-version:dkim-signature;\n        bh=LT2q8PEldt87z3mrWDdYA25Zu4LLlNbQMdEbJVa3TH4=;\n        fh=RfTkRRQ9QGHC7Dv12BG7XbdNp64oE4mrTo9cmMiTN+o=;\n        b=aXk1DFYWuE4Zroz+C4FVdb7I6839z67P1ufD65CpW/6QTqIg1kwO9vzJ6/igr012qV\n         FjDPxbhkr99FGf4x6Eu2018brYpUd0sWFUlYmjBQjMtlQQ46et4o2teXFiXytWRs2sww\n         wpxruHNa2qR5BB3lhFdeICAHVh3c7lZoQX6idKKcwub5lng43WISaZuT0yOhZ3COfHKB\n         qkaDq6MKJiolL3pfxKxI/mpxo8QkUXWzWDLpOAhZUNpccRsSzoGQ6lZq7hXu/KR1QQ/4\n         zKtwa/dm4IUm+/rns1A833Hrk/4mRylL2GIKZq5vnEa2yaoRUk1fN9hKM6mfRN1mdDWU\n         fKYA==;\n        darn=vger.kernel.org"],"ARC-Authentication-Results":["i=2; smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=gmail.com;\n spf=pass smtp.mailfrom=gmail.com;\n dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com\n header.b=WxPOYUy0; arc=pass smtp.client-ip=209.85.128.180","i=1; mx.google.com; arc=none"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n        d=gmail.com; s=20251104; t=1774394889; x=1774999689;\n darn=vger.kernel.org;\n        h=content-transfer-encoding:cc:to:subject:message-id:date:from\n         :in-reply-to:references:mime-version:from:to:cc:subject:date\n         :message-id:reply-to;\n        bh=LT2q8PEldt87z3mrWDdYA25Zu4LLlNbQMdEbJVa3TH4=;\n        b=WxPOYUy082lc2OjwB4xhShORA4QxdFRtI+x6ZZ3ALQYlmgNlgflc0CvwJfY2ZiMWCA\n         Pda4hK8u24vnWwuYI/kSIA3qc2f3oDQRS22HgD3blGmLG0pIHFYoVfGESBjQPe3EviDJ\n         sPwfWbP4SiO2fsQ6U/Ogv3TFy00c0vMW13EhAc/wWXPXDJpIYtPqlb+HdbSx1f4bHUfl\n         h4br/PwT23zhZaBPgrgnGI3cgrCDG5jTxLvakOsPIP79Re619iJvl72QjTLXflRAL+vZ\n         2pmBRjiyA6K15DNVWIazxaAlOob38Qv+Heag7N6CQz3Ku7KIsUHwQXhuXn4ybMw9fs29\n         WwwQ==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n        d=1e100.net; s=20251104; t=1774394889; x=1774999689;\n        h=content-transfer-encoding:cc:to:subject:message-id:date:from\n         :in-reply-to:references:mime-version:x-gm-gg:x-gm-message-state:from\n         :to:cc:subject:date:message-id:reply-to;\n        bh=LT2q8PEldt87z3mrWDdYA25Zu4LLlNbQMdEbJVa3TH4=;\n        b=pVgCuBDaPaVyisKADShA2aD4tY/Pn4zsKqI5wLqBVbL2LpxPRBSdYqQAz87HfgwG1R\n         aRstQ57DcRkabEX42VgyjDqRjYj6x4+Bv4+kDTBuWB4skFHr29c6MHnzkfi0BM/KxvcD\n         A4BqCTDQMMyahh8ismsZGnAJdTD56l9y2P3ua0ALalMZCPJmKCPt5TixLfYE7Vt+5Q55\n         r+RK2+4DrimTI90IABMTqa4sdTcc5SjoWIec90y7u/++le4jCh3yflUowB/HinGZq7Rx\n         ZtT4Sn0/tnvfk/HAa6g07I76EmqXdGTU2++/FiWGtuUTMcXXwCz0AuXCUQ6h0X8ctp8V\n         qGSQ==","X-Gm-Message-State":"AOJu0YzIaicTI4xH0N6s80F6e100NZAVJwrTNhJir66XtgKzls1DUyNu\n\tEbSZf5A5vA6LED+vCY3EEiUIAO95tsmF04/9l7T7BJF+loulQYDsA6Sh+3L8bSclwHsY+/39nbN\n\tmTdZA+VSjhE+p9llucs2vXcQnR702hB8=","X-Gm-Gg":"ATEYQzyN6vnH58Ofl98+AWFROpqo6fkRvhSfZsHKgcM9OzRuKWqZSAz3vjN6G/ksJoz\n\t9z5xO7GEs+NGJ7tNLnS1z/y86ApTz8RscghNXGRUGwvS+90203KEHkBDD3cmHM6DktWDhBK1/52\n\tZpSTrp9Xnp0bM0hh8FrTrstjtzEubSDhuYBM15Pc0PVVfr2fngI4M7ZJ016XNOhKC4tyBMMpOYe\n\t8Co5rzlukLotGkkWUtHA/W6aQI4f6YdbVpteP2hYXBP1I2JEAE+wK7tmAJP2DLNkn11QLenY0iA\n\tSUPU4w5Q5DTUMkXEQWw=","X-Received":"by 2002:a05:690c:c0d3:b0:798:36:e110 with SMTP id\n 00721157ae682-79acf6f180fmr15427277b3.62.1774394888606; Tue, 24 Mar 2026\n 16:28:08 -0700 (PDT)","Precedence":"bulk","X-Mailing-List":"netfilter-devel@vger.kernel.org","List-Id":"<netfilter-devel.vger.kernel.org>","List-Subscribe":"<mailto:netfilter-devel+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:netfilter-devel+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","References":"<20260324204016.2089193-1-anzaki@gmail.com>\n <20260324204016.2089193-2-anzaki@gmail.com>\n <acMB9xSTEmwly8QK@chamomile>","In-Reply-To":"<acMB9xSTEmwly8QK@chamomile>","From":"Ahmed Zaki <anzaki@gmail.com>","Date":"Tue, 24 Mar 2026 17:27:32 -0600","X-Gm-Features":"AaiRm51IbJFq0DzIib_tS9CxsVxmnu9xjmu7KIN3YEOt6boriUdcPPCK74Wy5qM","Message-ID":"\n <CANczwAHFy1fp4JU4ANJ2Uf-=B2uDP0GejrWUuELz9yf0wu9H2A@mail.gmail.com>","Subject":"Re: [PATCH nf-next v2 1/2] netfilter: flowtable: update netdev stats\n with HW_OFFLOAD flows","To":"Pablo Neira Ayuso <pablo@netfilter.org>","Cc":"netfilter-devel@vger.kernel.org, andrew@lunn.ch, olteanv@gmail.com,\n\tfw@strlen.de, kuba@kernel.org, pabeni@redhat.com, edumazet@google.com,\n\tcoreteam@netfilter.org, netdev@vger.kernel.org","Content-Type":"text/plain; charset=\"UTF-8\"","Content-Transfer-Encoding":"quoted-printable"}}]