get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2215612/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2215612,
    "url": "http://patchwork.ozlabs.org/api/patches/2215612/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/netfilter-devel/patch/20260324204016.2089193-2-anzaki@gmail.com/",
    "project": {
        "id": 26,
        "url": "http://patchwork.ozlabs.org/api/projects/26/?format=api",
        "name": "Netfilter Development",
        "link_name": "netfilter-devel",
        "list_id": "netfilter-devel.vger.kernel.org",
        "list_email": "netfilter-devel@vger.kernel.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20260324204016.2089193-2-anzaki@gmail.com>",
    "list_archive_url": null,
    "date": "2026-03-24T20:40:15",
    "name": "[nf-next,v2,1/2] netfilter: flowtable: update netdev stats with HW_OFFLOAD flows",
    "commit_ref": null,
    "pull_url": null,
    "state": "needs-review-ack",
    "archived": false,
    "hash": "17705f54f9f4096f92b120ca6c66febdb47a0146",
    "submitter": {
        "id": 77450,
        "url": "http://patchwork.ozlabs.org/api/people/77450/?format=api",
        "name": "Ahmed Zaki",
        "email": "anzaki@gmail.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/netfilter-devel/patch/20260324204016.2089193-2-anzaki@gmail.com/mbox/",
    "series": [
        {
            "id": 497346,
            "url": "http://patchwork.ozlabs.org/api/series/497346/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/netfilter-devel/list/?series=497346",
            "date": "2026-03-24T20:40:16",
            "name": "Update (DSA) netdev stats with offloaded flows",
            "version": 2,
            "mbox": "http://patchwork.ozlabs.org/series/497346/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2215612/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2215612/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "\n <netfilter-devel+bounces-11387-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=iAKtSEfZ;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c04:e001:36c::12fc:5321; helo=tor.lore.kernel.org;\n envelope-from=netfilter-devel+bounces-11387-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=\"iAKtSEfZ\"",
            "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=209.85.128.48",
            "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 tor.lore.kernel.org (tor.lore.kernel.org\n [IPv6:2600:3c04:e001:36c::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 4fgMSn3gWPz1xy1\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 25 Mar 2026 07:43:37 +1100 (AEDT)",
            "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby tor.lore.kernel.org (Postfix) with ESMTP id EEEBC308C836\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 24 Mar 2026 20:41:36 +0000 (UTC)",
            "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id AB08D35836A;\n\tTue, 24 Mar 2026 20:41:33 +0000 (UTC)",
            "from mail-wm1-f48.google.com (mail-wm1-f48.google.com\n [209.85.128.48])\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 A063F33B6DB\n\tfor <netfilter-devel@vger.kernel.org>; Tue, 24 Mar 2026 20:41:31 +0000 (UTC)",
            "by mail-wm1-f48.google.com with SMTP id\n 5b1f17b1804b1-486507134e4so21093265e9.0\n        for <netfilter-devel@vger.kernel.org>;\n Tue, 24 Mar 2026 13:41:31 -0700 (PDT)",
            "from azaki-desk1.. ([41.234.201.118])\n        by smtp.gmail.com with ESMTPSA id\n 5b1f17b1804b1-48716658352sm3686825e9.13.2026.03.24.13.41.24\n        (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n        Tue, 24 Mar 2026 13:41:25 -0700 (PDT)"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1774384893; cv=none;\n b=l6DbsuLMS6agxZrQs5+IEoSAvwTacMTRFBc5ogtWFeI0niuQmJxvIkzCki7PKalUeyvg/ekNWBhdqqhrAs1BZ7Vwnc6CdgblX0celQN3WbNxmui6PZOdIAM9xbjpUdInNxaOmRflNLhjzi2JGoObWBa+ViJbf/lk3byhVp3drXs=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1774384893; c=relaxed/simple;\n\tbh=OMzMv0TSgnhZtLvwhP+BHffFyvt+TSPyAeE/6RqIn8A=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=MYia12zNEIAJ5uLmFcXYORNrB3km/9W2kp6DEqEqAbBiFf87emwxcYoGDfNXtmltxaKvv91d/D5AOxvM65Hn0mR9ZE7ueHOvsUFINdGetF8d71y6A1kfpTvGG6MoLG7D3okc5WnVcuJ78V9VuQHewxoxFa7+3Vta2MrFg1vrdFA=",
        "ARC-Authentication-Results": "i=1; 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=iAKtSEfZ; arc=none smtp.client-ip=209.85.128.48",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n        d=gmail.com; s=20251104; t=1774384887; x=1774989687;\n darn=vger.kernel.org;\n        h=content-transfer-encoding:mime-version:references:in-reply-to\n         :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n         :message-id:reply-to;\n        bh=D0C5qZvIKcbCB9gIop4y1SIVtOCb4Lm6XlWELeubUrQ=;\n        b=iAKtSEfZS2/Or6UT5n+zWYVaGk0wFOcjtJF3ZUI3b0H13o8I5B9nQsADOUJ2dxc30U\n         mUeRNaV4Acp0+Ng/8Q6vjIiBk81zBdsg3ag9LhtHsK/mQzYrxEO+C2lKTgzVcSf0Vsos\n         s9lSr+qtoKWRT/M2yzQQ0Ra4eVSoz2MpfLGatyDKotQ06ZSRAimZrDk0xQK2Z2jWVWZv\n         RQKQE5L+LVJNpTT9dqY5FgQ1HRrtb+6LgN5PmdERvArgYlJhNvxswkDYB0iADDq4pssf\n         csStCGtImcViBTAauFGJKYR+By+VWli50k2+/J1T2FJGtcIgu9VDAuAxNYJsGR08KAbP\n         f2fA==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n        d=1e100.net; s=20251104; t=1774384887; x=1774989687;\n        h=content-transfer-encoding:mime-version:references:in-reply-to\n         :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n         :to:cc:subject:date:message-id:reply-to;\n        bh=D0C5qZvIKcbCB9gIop4y1SIVtOCb4Lm6XlWELeubUrQ=;\n        b=su+53+IhZLH+2OBtzAftElv7ggxSRTsL0VUoemAiuS+vXQfudfPApaOOv6YDNDxTkA\n         NTZRliv9eUHWhVFBIarOsvAXNFyFzGmLnM/up1CPw/iTAKnbfMx5QsFzFoGV7q8gT/ui\n         rkfNbdm0cR02Iq1lErJdAdyidU1Win3APTQihV7N6+2jkhKw8igWP7Z48DfJWONwKhjr\n         0YjYJ9DQE7NiTjP5QpaqFpx1QihfWewn+J0CuXGI5tE3BCu8QRu7PpV+RhuTCc/HM+LK\n         qTOPVGthY9cUyPQSUrqpGqxeZrYj3hv4ibm52uYTv8PtUGHfm086d1Y+FYcG4LkyJAv1\n         wSlA==",
        "X-Gm-Message-State": "AOJu0Yz4Q3K6vwmFfjdU6p8OHaddZhrCmznJKMS9hEsdHUZ9YEjGjZnt\n\tO9GjB4JuVL6NYDUv/Zngsw+aMq08/+ci1vnw5spHoQ4DPwHFo/LAfqKgojb9b0vRPwxoCw==",
        "X-Gm-Gg": "ATEYQzzzwSmx0cVGKR77yxFu0TMAyK+bptpZo+1LFHDF8+hFx2+IqvQ246MvTtnxwyA\n\t9U4fKr8R5c6o5mf8jTE5EgWNcgJgVCgKUD+rwx+ayfPqYjPOcvZNvw1HCWRx9ESMRTa4EyNr6nt\n\tR1PfBVkP3HUnqG5gxA2UApQ/2AXYHdAi6jB6PUL8OmZQ0ucChNHu/qVqa6h9iyT9tDzifep+NrN\n\tlDaIZIJ/OdoJLJb0ZTRvPe2Ic5yCmSCJMo11V5thiOz1VWa+Vn/IVXa9BmkHn5uEYaZztq6qWL8\n\tqD68CSAhrM2urnEGgz8/RD+2msF1XxmQrSjhhIDgr3Tk4jtKqa1+WOTc7f7G0v/PjzwO60YVts4\n\tjcSevzIB1LObvBjWr5gFCAJd7XhSr5f2eAbxFfBsKNajMu53yepLkdIkebQYear02fOrdZ5eq/g\n\tCOXIcYH8smFM7bvbHiTwH6",
        "X-Received": "by 2002:a05:600c:4685:b0:486:5f71:5829 with SMTP id\n 5b1f17b1804b1-48715fc3870mr17265075e9.5.1774384886440;\n        Tue, 24 Mar 2026 13:41:26 -0700 (PDT)",
        "From": "Ahmed Zaki <anzaki@gmail.com>",
        "To": "netfilter-devel@vger.kernel.org,\n\tandrew@lunn.ch,\n\tolteanv@gmail.com,\n\tpablo@netfilter.org,\n\tfw@strlen.de,\n\tkuba@kernel.org,\n\tpabeni@redhat.com,\n\tedumazet@google.com",
        "Cc": "coreteam@netfilter.org,\n\tnetdev@vger.kernel.org",
        "Subject": "[PATCH nf-next v2 1/2] netfilter: flowtable: update netdev stats with\n HW_OFFLOAD flows",
        "Date": "Tue, 24 Mar 2026 14:40:15 -0600",
        "Message-ID": "<20260324204016.2089193-2-anzaki@gmail.com>",
        "X-Mailer": "git-send-email 2.43.0",
        "In-Reply-To": "<20260324204016.2089193-1-anzaki@gmail.com>",
        "References": "<20260324204016.2089193-1-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-Transfer-Encoding": "8bit"
    },
    "content": "Some drivers (notably DSA) delegate the nft flowtable HW_OFFLOAD flows\nto a parent driver. While the parent driver is able to report the\noffloaded traffic stats directly from the HW, the delegating driver\ndoes not report the stats. This fails SNMP-based monitoring tools that\nrely on netdev stats to report the network traffic.\n\nAdd a new struct pcpu_sw_netstats \"fstats\" to net_device that gets\nallocated only if the new flag \"flow_offload_via_parent\" is set by the\ndriver. The new stats are lazily allocated by the nft flow offloading\ncode when the first flow is offloaded. The stats are updated periodically\nin flow_offload_work_stats() and also once in flow_offload_work_del()\nbefore the flow is deleted. For this, flow_offload_work_del() had to\nbe moved below flow_offload_tuple_stats().\n\nSigned-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(-)",
    "diff": "diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h\nindex 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);\ndiff --git a/net/core/dev.c b/net/core/dev.c\nindex 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);\ndiff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c\nindex 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",
    "prefixes": [
        "nf-next",
        "v2",
        "1/2"
    ]
}