* [PATCH nf-next 0/3] netfilter: flowtable: update upper device stats in the fast path
@ 2026-10-04 17:16 Julius Bairaktaris
2026-10-04 17:16 ` [PATCH nf-next 1/3] 8021q: add vlan_dev_sw_netstats_rx_add() and vlan_dev_sw_netstats_tx_add() Julius Bairaktaris
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Julius Bairaktaris @ 2026-10-04 17:16 UTC (permalink / raw)
To: netfilter-devel
Cc: pablo, fw, phil, coreteam, netdev, davem, edumazet, kuba, pabeni,
horms, andrew+netdev, shuah, linux-kselftest, linux-kernel, nbd
With the software flowtable, packets bypass the bridge, VLAN, PPPoE and
tunnel devices above the flowtable device, so their counters only see
the first packets of each connection. The classic forwarding path
always counts them, so this series does too, without a flag.
Patch 1 adds VLAN stats helpers; it touches include/linux/if_vlan.h, so
a netdev ack would let it go through nf-next. Patch 2 updates the
counters from the fast path with the lengths the classic path counts.
Patch 3 adds bridge, VLAN and tunnel counter checks to nft_flowtable.sh,
which fail without patches 1 and 2.
Hardware offloaded flows are not counted. A GSO packet sent through a
PPPoE device counts once, not once per segment.
Cost: struct flow_offload grows from 296 to 328 bytes (slab object 320
to 384). Forwarding from a bridge with a VLAN port to a veth in an x86
guest, mean of three interleaved runs without/with the series: TCP
55.7/55.0 Gbit/s, 64 byte UDP 177/173 kpps.
This series was written with the help of an AI coding assistant. I have
reviewed and tested it.
Julius Bairaktaris (3):
8021q: add vlan_dev_sw_netstats_rx_add() and
vlan_dev_sw_netstats_tx_add()
netfilter: flowtable: update upper device stats in the fast path
selftests: netfilter: nft_flowtable.sh: check upper device counters
include/linux/if_vlan.h | 36 ++++++++++
include/net/netfilter/nf_flow_table.h | 8 ++-
net/netfilter/nf_flow_table_core.c | 3 +
net/netfilter/nf_flow_table_ip.c | 53 +++++++++++++++
net/netfilter/nf_flow_table_path.c | 9 +++
.../selftests/net/netfilter/nft_flowtable.sh | 67 +++++++++++++++++++
6 files changed, 175 insertions(+), 1 deletion(-)
base-commit: 87b80c2f6b05cad9f0ff9136709c62a0f59923e3
--
2.53.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH nf-next 1/3] 8021q: add vlan_dev_sw_netstats_rx_add() and vlan_dev_sw_netstats_tx_add()
2026-10-04 17:16 [PATCH nf-next 0/3] netfilter: flowtable: update upper device stats in the fast path Julius Bairaktaris
@ 2026-10-04 17:16 ` Julius Bairaktaris
2026-10-04 17:16 ` [PATCH nf-next 2/3] netfilter: flowtable: update upper device stats in the fast path Julius Bairaktaris
2026-10-04 17:16 ` [PATCH nf-next 3/3] selftests: netfilter: nft_flowtable.sh: check upper device counters Julius Bairaktaris
2 siblings, 0 replies; 4+ messages in thread
From: Julius Bairaktaris @ 2026-10-04 17:16 UTC (permalink / raw)
To: netfilter-devel
Cc: pablo, fw, phil, coreteam, netdev, davem, edumazet, kuba, pabeni,
horms, andrew+netdev, shuah, linux-kselftest, linux-kernel, nbd
Let code that forwards packets on behalf of a VLAN device update its
per-cpu counters, like dev_sw_netstats_rx_add() and
dev_sw_netstats_tx_add() do for devices with tstats. The netfilter
flowtable fast path uses them in the next patch.
Assisted-by: Claude:claude-fable-5-1
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
---
include/linux/if_vlan.h | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 20cc16ea4e5a..4873a12958da 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -231,6 +231,31 @@ vlan_dev_get_egress_qos_mask(struct net_device *dev, u32 skprio)
return vlan_qos;
}
+static inline void vlan_dev_sw_netstats_rx_add(struct net_device *dev,
+ unsigned int len)
+{
+ struct vlan_pcpu_stats *stats;
+
+ stats = this_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats);
+ u64_stats_update_begin(&stats->syncp);
+ u64_stats_inc(&stats->rx_packets);
+ u64_stats_add(&stats->rx_bytes, len);
+ u64_stats_update_end(&stats->syncp);
+}
+
+static inline void vlan_dev_sw_netstats_tx_add(struct net_device *dev,
+ unsigned int packets,
+ unsigned int len)
+{
+ struct vlan_pcpu_stats *stats;
+
+ stats = this_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats);
+ u64_stats_update_begin(&stats->syncp);
+ u64_stats_add(&stats->tx_packets, packets);
+ u64_stats_add(&stats->tx_bytes, len);
+ u64_stats_update_end(&stats->syncp);
+}
+
extern bool vlan_do_receive(struct sk_buff **skb);
extern int vlan_vid_add(struct net_device *dev, __be16 proto, u16 vid);
@@ -249,6 +274,17 @@ static inline bool is_vlan_dev(const struct net_device *dev)
return false;
}
+static inline void vlan_dev_sw_netstats_rx_add(struct net_device *dev,
+ unsigned int len)
+{
+}
+
+static inline void vlan_dev_sw_netstats_tx_add(struct net_device *dev,
+ unsigned int packets,
+ unsigned int len)
+{
+}
+
static inline struct net_device *
__vlan_find_dev_deep_rcu(struct net_device *real_dev,
__be16 vlan_proto, u16 vlan_id)
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH nf-next 2/3] netfilter: flowtable: update upper device stats in the fast path
2026-10-04 17:16 [PATCH nf-next 0/3] netfilter: flowtable: update upper device stats in the fast path Julius Bairaktaris
2026-10-04 17:16 ` [PATCH nf-next 1/3] 8021q: add vlan_dev_sw_netstats_rx_add() and vlan_dev_sw_netstats_tx_add() Julius Bairaktaris
@ 2026-10-04 17:16 ` Julius Bairaktaris
2026-10-04 17:16 ` [PATCH nf-next 3/3] selftests: netfilter: nft_flowtable.sh: check upper device counters Julius Bairaktaris
2 siblings, 0 replies; 4+ messages in thread
From: Julius Bairaktaris @ 2026-10-04 17:16 UTC (permalink / raw)
To: netfilter-devel
Cc: pablo, fw, phil, coreteam, netdev, davem, edumazet, kuba, pabeni,
horms, andrew+netdev, shuah, linux-kselftest, linux-kernel, nbd
The software fast path receives and transmits on the lowest devices of
the input and output stacks, so the bridge, VLAN, PPPoE and tunnel
devices above them stop counting after the first packets of a
connection.
Store the ifindexes of these devices from the forward path and update
their counters from the fast path. Each device counts what it counts in
the classic path: the IP packet plus the headers of the devices above it
(PPPoE, outer IP, inner VLAN tag), plus the Ethernet header on transmit
for Ethernet devices.
A GSO packet sent through a PPPoE device is counted once. The classic
path segments it in front of the ppp device and counts every segment.
struct flow_offload grows from 296 to 328 bytes.
Assisted-by: Claude:claude-fable-5-1
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
---
include/net/netfilter/nf_flow_table.h | 8 +++-
net/netfilter/nf_flow_table_core.c | 3 ++
net/netfilter/nf_flow_table_ip.c | 53 +++++++++++++++++++++++++++
net/netfilter/nf_flow_table_path.c | 9 +++++
4 files changed, 72 insertions(+), 1 deletion(-)
diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h
index f2e2771f188f..1f451fcf05d0 100644
--- a/include/net/netfilter/nf_flow_table.h
+++ b/include/net/netfilter/nf_flow_table.h
@@ -106,6 +106,8 @@ enum flow_offload_xmit_type {
};
#define NF_FLOW_TABLE_ENCAP_MAX 2
+/* Devices above the flowtable device in a forward path. */
+#define NF_FLOW_TABLE_UPPER_MAX (NET_DEVICE_PATH_STACK_MAX - 1)
struct flow_offload_tunnel {
union {
@@ -153,7 +155,8 @@ struct flow_offload_tuple {
encap_num:2,
needs_gso_segment:1,
tun_num:2,
- in_vlan_ingress:2;
+ in_vlan_ingress:2,
+ num_uppers:3;
u16 mtu;
u32 dst_cookie;
struct dst_entry *dst_cache;
@@ -171,6 +174,7 @@ struct flow_offload_tuple {
u32 iifidx;
} tc;
};
+ u32 upper_ifidx[NF_FLOW_TABLE_UPPER_MAX];
};
struct flow_offload_tuple_rhash {
@@ -228,6 +232,8 @@ struct nf_flow_route {
u8 num_encaps:2,
num_tuns:2,
ingress_vlans:2;
+ u32 upper_ifidx[NF_FLOW_TABLE_UPPER_MAX];
+ u8 num_uppers;
} in;
struct {
u32 ifindex;
diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c
index 03241d4bfd5e..2c9a0d97c9fb 100644
--- a/net/netfilter/nf_flow_table_core.c
+++ b/net/netfilter/nf_flow_table_core.c
@@ -122,6 +122,9 @@ static int flow_offload_fill_route(struct flow_offload *flow,
flow_tuple->tun = route->tuple[dir].in.tun;
flow_tuple->encap_num = route->tuple[dir].in.num_encaps;
+ memcpy(flow_tuple->upper_ifidx, route->tuple[dir].in.upper_ifidx,
+ sizeof(flow_tuple->upper_ifidx));
+ flow_tuple->num_uppers = route->tuple[dir].in.num_uppers;
flow_tuple->needs_gso_segment = route->tuple[dir].out.needs_gso_segment;
flow_tuple->tun_num = route->tuple[dir].in.num_tuns;
diff --git a/net/netfilter/nf_flow_table_ip.c b/net/netfilter/nf_flow_table_ip.c
index c8c29a9a1684..e1a3511d5f1f 100644
--- a/net/netfilter/nf_flow_table_ip.c
+++ b/net/netfilter/nf_flow_table_ip.c
@@ -453,6 +453,49 @@ static void nf_flow_encap_pop(struct nf_flowtable_ctx *ctx,
nf_flow_ip_tunnel_pop(ctx, skb);
}
+/* The fast path bypasses the devices above the flowtable device. */
+static void nf_flow_upper_stats_add(struct net *net,
+ const struct flow_offload_tuple *tuple,
+ bool rx, unsigned int len)
+{
+ unsigned int n, vlan_hlen = 0;
+ struct net_device *dev;
+ int i;
+
+ for (i = 0; i < tuple->num_uppers; i++) {
+ dev = dev_get_by_index_rcu(net, tuple->upper_ifidx[i]);
+ if (!dev)
+ continue;
+
+ n = len;
+ if (!rx && dev->type == ARPHRD_ETHER)
+ n += ETH_HLEN;
+
+ if (is_vlan_dev(dev)) {
+ /* Q-in-Q: the outer VLAN device counts the inner tag. */
+ n += vlan_hlen;
+ if (rx)
+ vlan_dev_sw_netstats_rx_add(dev, n);
+ else
+ vlan_dev_sw_netstats_tx_add(dev, 1, n);
+ vlan_hlen += VLAN_HLEN;
+ } else if (dev->pcpu_stat_type == NETDEV_PCPU_STAT_TSTATS) {
+ if (rx)
+ dev_sw_netstats_rx_add(dev, n);
+ else
+ dev_sw_netstats_tx_add(dev, 1, n);
+ }
+
+ /* The devices below also count this device's header. */
+ if (dev->type == ARPHRD_PPP)
+ len += PPPOE_SES_HLEN;
+ else if (dev->type == ARPHRD_TUNNEL)
+ len += sizeof(struct iphdr);
+ else if (dev->type == ARPHRD_TUNNEL6)
+ len += sizeof(struct ipv6hdr);
+ }
+}
+
static struct flow_offload_tuple_rhash *
nf_flow_offload_lookup(struct nf_flowtable_ctx *ctx,
struct nf_flowtable *flow_table, struct sk_buff *skb)
@@ -512,6 +555,11 @@ static int nf_flow_offload_forward(struct nf_flowtable_ctx *ctx,
if (flow_table->flags & NF_FLOWTABLE_COUNTER)
nf_ct_acct_update(flow->ct, tuplehash->tuple.dir, skb->len);
+ nf_flow_upper_stats_add(dev_net(ctx->in), &tuplehash->tuple, true,
+ skb->len);
+ nf_flow_upper_stats_add(dev_net(ctx->in), &flow->tuplehash[!dir].tuple,
+ false, skb->len);
+
return 1;
}
@@ -1107,6 +1155,11 @@ static int nf_flow_offload_ipv6_forward(struct nf_flowtable_ctx *ctx,
if (flow_table->flags & NF_FLOWTABLE_COUNTER)
nf_ct_acct_update(flow->ct, tuplehash->tuple.dir, skb->len);
+ nf_flow_upper_stats_add(dev_net(ctx->in), &tuplehash->tuple, true,
+ skb->len);
+ nf_flow_upper_stats_add(dev_net(ctx->in), &flow->tuplehash[!dir].tuple,
+ false, skb->len);
+
return 1;
}
diff --git a/net/netfilter/nf_flow_table_path.c b/net/netfilter/nf_flow_table_path.c
index 1e55644f2edb..ba5ac3ebe614 100644
--- a/net/netfilter/nf_flow_table_path.c
+++ b/net/netfilter/nf_flow_table_path.c
@@ -83,6 +83,8 @@ static int nft_dev_fill_forward_path(const struct dst_entry *dst_cache,
struct nft_forward_info {
const struct net_device *dev;
+ u32 upper_ifidx[NF_FLOW_TABLE_UPPER_MAX];
+ u8 num_uppers;
struct id {
__u16 id;
__be16 proto;
@@ -187,6 +189,10 @@ static int nft_dev_path_info(struct net_device_path_stack *stack,
}
}
+ for (i = 0; info->dev && stack->path[i].dev != info->dev; i++)
+ info->upper_ifidx[i] = stack->path[i].dev->ifindex;
+ info->num_uppers = i;
+
if (nf_flowtable_hw_offload(&ft->data) &&
nft_is_valid_ether_device(info->dev))
info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
@@ -253,6 +259,9 @@ static int nft_dev_forward_path(const struct nft_pktinfo *pkt,
route->tuple[!dir].in.num_encaps = info.num_encaps;
route->tuple[!dir].in.ingress_vlans = info.ingress_vlans;
+ memcpy(route->tuple[!dir].in.upper_ifidx, info.upper_ifidx,
+ sizeof(info.upper_ifidx));
+ route->tuple[!dir].in.num_uppers = info.num_uppers;
if (info.xmit_type == FLOW_OFFLOAD_XMIT_DIRECT) {
memcpy(route->tuple[dir].out.h_source, info.h_source, ETH_ALEN);
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH nf-next 3/3] selftests: netfilter: nft_flowtable.sh: check upper device counters
2026-10-04 17:16 [PATCH nf-next 0/3] netfilter: flowtable: update upper device stats in the fast path Julius Bairaktaris
2026-10-04 17:16 ` [PATCH nf-next 1/3] 8021q: add vlan_dev_sw_netstats_rx_add() and vlan_dev_sw_netstats_tx_add() Julius Bairaktaris
2026-10-04 17:16 ` [PATCH nf-next 2/3] netfilter: flowtable: update upper device stats in the fast path Julius Bairaktaris
@ 2026-10-04 17:16 ` Julius Bairaktaris
2 siblings, 0 replies; 4+ messages in thread
From: Julius Bairaktaris @ 2026-10-04 17:16 UTC (permalink / raw)
To: netfilter-devel
Cc: pablo, fw, phil, coreteam, netdev, davem, edumazet, kuba, pabeni,
horms, andrew+netdev, shuah, linux-kselftest, linux-kernel, nbd
The bridge and tunnel tests forward through devices above the flowtable
device: br0, the tunnels, and the VLAN devices under them. Each test
sends the file in both directions, twice for IPv4 (masquerade and dnat)
and once for IPv6, so check that these devices count between n and n + 1
times the file size on rx and on tx.
Assisted-by: Claude:claude-fable-5-1
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
---
.../selftests/net/netfilter/nft_flowtable.sh | 67 +++++++++++++++++++
1 file changed, 67 insertions(+)
diff --git a/tools/testing/selftests/net/netfilter/nft_flowtable.sh b/tools/testing/selftests/net/netfilter/nft_flowtable.sh
index 449c518bd947..e89f86916f4e 100755
--- a/tools/testing/selftests/net/netfilter/nft_flowtable.sh
+++ b/tools/testing/selftests/net/netfilter/nft_flowtable.sh
@@ -272,6 +272,43 @@ check_counters()
fi
}
+dev_bytes()
+{
+ local ns=$1
+ local dev=$2
+
+ ip -net "$ns" -s link show dev "$dev" | \
+ awk '/RX:/ { getline; rx = $1 } /TX:/ { getline; tx = $1 } END { print rx, tx }'
+}
+
+# Fails if the fast path does not update the device counters.
+check_dev_bytes()
+{
+ local what=$1
+ local ns=$2
+ local dev=$3
+ local rx0=$4
+ local tx0=$5
+ local n=${6:-2}
+ local min=$((filesize * n))
+ local max=$((filesize * (n + 1)))
+ local rx tx
+
+ read -r rx tx < <(dev_bytes "$ns" "$dev")
+ rx=$((rx - rx0))
+ tx=$((tx - tx0))
+
+ if [ "$rx" -lt "$min" ] || [ "$tx" -lt "$min" ] ||
+ [ "$rx" -gt "$max" ] || [ "$tx" -gt "$max" ]; then
+ echo "FAIL: $what: $dev counted rx $rx tx $tx bytes," \
+ "expected $min to $max" 1>&2
+ ret=1
+ return
+ fi
+
+ echo "PASS: $what"
+}
+
check_dscp()
{
local what=$1
@@ -626,12 +663,18 @@ ip netns exec "$nsr1" nft -a insert rule inet filter forward 'meta oif tun6 acce
ip netns exec "$nsr1" nft -a insert rule inet filter forward \
'meta oif "veth0" tcp sport 12345 ct mark set 1 flow add @f1 counter name routed_repl accept'
+read -r tun_rx tun_tx < <(dev_bytes "$nsr1" tun0)
+
if ! test_tcp_forwarding_nat "$ns1" "$ns2" 1 "IPIP tunnel"; then
echo "FAIL: flow offload for ns1/ns2 with IPIP tunnel" 1>&2
ip netns exec "$nsr1" nft list ruleset
ret=1
fi
+check_dev_bytes "IPIP tunnel counters" "$nsr1" tun0 "$tun_rx" "$tun_tx"
+
+read -r tun_rx tun_tx < <(dev_bytes "$nsr1" tun6)
+
if test_tcp_forwarding "$ns1" "$ns2" 1 6 "[dead:2::99]" 12345; then
check_counters "flow offload for ns1/ns2 IP6IP6 tunnel"
else
@@ -640,6 +683,8 @@ else
ret=1
fi
+check_dev_bytes "IP6IP6 tunnel counters" "$nsr1" tun6 "$tun_rx" "$tun_tx" 1
+
# Create vlan tagged devices for IPIP traffic.
ip -net "$nsr1" link add link veth1 name veth1.10 type vlan id 10
ip -net "$nsr1" link set veth1.10 up
@@ -686,12 +731,21 @@ ip -net "$nsr2" addr add fee1:5::2/64 dev tun6.10 nodad
ip -6 -net "$nsr2" route delete default
ip -6 -net "$nsr2" route add default via fee1:5::1
+read -r tun_rx tun_tx < <(dev_bytes "$nsr1" tun0.10)
+read -r vlan_rx vlan_tx < <(dev_bytes "$nsr1" veth1.10)
+
if ! test_tcp_forwarding_nat "$ns1" "$ns2" 1 "IPIP tunnel over vlan"; then
echo "FAIL: flow offload for ns1/ns2 with IPIP tunnel over vlan" 1>&2
ip netns exec "$nsr1" nft list ruleset
ret=1
fi
+check_dev_bytes "IPIP tunnel counters over VLAN" "$nsr1" tun0.10 "$tun_rx" "$tun_tx"
+check_dev_bytes "VLAN counters under IPIP tunnel" "$nsr1" veth1.10 "$vlan_rx" "$vlan_tx"
+
+read -r tun_rx tun_tx < <(dev_bytes "$nsr1" tun6.10)
+read -r vlan_rx vlan_tx < <(dev_bytes "$nsr1" veth1.10)
+
if test_tcp_forwarding "$ns1" "$ns2" 1 6 "[dead:2::99]" 12345; then
check_counters "flow offload for ns1/ns2 IP6IP6 tunnel over vlan"
else
@@ -700,6 +754,9 @@ else
ret=1
fi
+check_dev_bytes "IP6IP6 tunnel counters over VLAN" "$nsr1" tun6.10 "$tun_rx" "$tun_tx" 1
+check_dev_bytes "VLAN counters under IP6IP6 tunnel" "$nsr1" veth1.10 "$vlan_rx" "$vlan_tx" 1
+
# Restore the previous configuration
ip -net "$nsr1" route change default via 192.168.10.2
ip -net "$nsr2" route change default via 192.168.10.1
@@ -740,12 +797,16 @@ table ip nat {
}
EOF
+read -r br_rx br_tx < <(dev_bytes "$nsr1" br0)
+
if ! test_tcp_forwarding_nat "$ns1" "$ns2" 1 "on bridge"; then
echo "FAIL: flow offload for ns1/ns2 with bridge NAT" 1>&2
ip netns exec "$nsr1" nft list ruleset
ret=1
fi
+check_dev_bytes "bridge counters" "$nsr1" br0 "$br_rx" "$br_tx"
+
if ip -net "$nsr1" link show tun0 > /dev/null 2>&1 &&
ip -net "$nsr2" link show tun0 > /dev/null 2>&1; then
ip -net "$nsr1" route change default via 192.168.100.2
@@ -819,12 +880,18 @@ ip -net "$ns1" addr add 10.0.1.99/24 dev eth0.10
ip -net "$ns1" route add default via 10.0.1.1
ip -net "$ns1" addr add dead:1::99/64 dev eth0.10 nodad
+read -r br_rx br_tx < <(dev_bytes "$nsr1" br0)
+read -r vlan_rx vlan_tx < <(dev_bytes "$nsr1" veth0.10)
+
if ! test_tcp_forwarding_nat "$ns1" "$ns2" 1 "bridge and VLAN"; then
echo "FAIL: flow offload for ns1/ns2 with bridge NAT and VLAN" 1>&2
ip netns exec "$nsr1" nft list ruleset
ret=1
fi
+check_dev_bytes "bridge counters with VLAN" "$nsr1" br0 "$br_rx" "$br_tx"
+check_dev_bytes "VLAN counters under bridge" "$nsr1" veth0.10 "$vlan_rx" "$vlan_tx"
+
# restore test topology (remove bridge and VLAN)
ip -net "$nsr1" link set veth0 nomaster
ip -net "$nsr1" link set veth0 down
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-10-04 17:16 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-04 17:16 [PATCH nf-next 0/3] netfilter: flowtable: update upper device stats in the fast path Julius Bairaktaris
2026-10-04 17:16 ` [PATCH nf-next 1/3] 8021q: add vlan_dev_sw_netstats_rx_add() and vlan_dev_sw_netstats_tx_add() Julius Bairaktaris
2026-10-04 17:16 ` [PATCH nf-next 2/3] netfilter: flowtable: update upper device stats in the fast path Julius Bairaktaris
2026-10-04 17:16 ` [PATCH nf-next 3/3] selftests: netfilter: nft_flowtable.sh: check upper device counters Julius Bairaktaris
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox