summaryrefslogtreecommitdiff
path: root/net
AgeCommit message (Collapse)Author
3 daysMerge tag 'net-next-7.4' of ↵stableLinus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next Pull networking updates from Paolo Abeni: "This includes a significant number of low-priority fixes - especially in the NIC drivers area - that we deferred from the last few RCs in the previous cycle, which can't be easily outlined in the synopsis below. Core & protocols: - Continue the work on removing rtnl_lock dependencies: - per-netns ARP and ND neighbour tables, with the default settings now configurable per netns (inheritance from init_net is controlled by the new net.core.neigh_inherit_init_net sysctl) - RCU-protected configuration and rtnl_lock-less fill_info() for hsr, netkit, sit, vlan and vxlan devices - per-netns device unregistration for ip tunnel and gre devices - use the netdev instance lock instead of rtnl_lock when reading speed and duplex via sysfs - batch the flushing of uncached routes at device unregistration time, relieving rtnl_lock contention on netns dismantle. - Add hardware pacing offload support, admin-controlled via a new rtnetlink attribute, with sch_fq integration (implemented in idpf). - Re-segment BIG TCP GSO packets into GSO packets fitting the egress device limits instead of plain MSS-sized segments, improving throughput for mixed BIG TCP / non-BIG TCP paths by up to 70%. - Generate RSS keys that spread flows over all the RX queues; the previous random keys could leave some queues unused. - Optimize the bridge VLAN forwarding paths: cache the port-VLAN in fdb entries and consider only VLAN members when flooding, for ~10% more Mpps in the fdb forwarding path. - A few TCP/IP performance improvements aimed at efficient cache usage and reducing contention. - Add the TCP ROCCET congestion control, a CUBIC variant aimed at avoiding bufferbloat in cellular networks. - Continue the conversion of getsockopt callbacks to sockopt_t. - Add an ethtool command to list the front-facing ports of an interface, including SFP cages and modules, using the phy_port representation. - Enable BIG TCP support for bareudp tunnels. - Remove the IPV6_ADDRFORM socket option and disallow buggy TCP state transitions (listen() + shutdown() + connect() and connect() + connect(AF_UNSPEC) + listen()). - Remove most BUG_ON()s from core packet processing, replacing them with error paths. Wireless: - Latency improvements, including lockless station get/dump and beacon updates, plus RTNL reduction and locking cleanups. - Infrastructure for non-station TX/RX with MLO. - NAN (Wi-Fi Aware) Instant Communication support and other NAN improvements. - Control frame Integrity Protocol (CIP) and protected TWT support. - Improvements for AP regulatory checks. Netfilter: - Disable br_netfilter in user namespaces and schedule it for removal in 2027. - Restrict the raw table in nft_compat to the specific family, hook and priority. - Prepare the flowtable for mixed IPv4-over-IPv6 tunneling (and vice versa). - Use GFP_KERNEL_ACCOUNT for most netfilter allocations, for better integration with memcg. - Allow discovering conntrack zone filtering support in ctnetlink dumps, and fix nfnetlink_hook handling of large dumps. Deletions: - Move the LLC type 2 sockets out of tree. There are no known users and the code attracts a never-ending stream of LLM-driven fixes. Device drivers: - New drivers: - Meta Platforms NIC (mpnic), the second-generation NIC from Meta - initial skeleton of the Nebula-matrix NICs driver (nbl) - X-Powers AC200/AC300 Fast Ethernet PHYs - Ethernet high-speed NICs: - Intel: - i40e: XDP metadata support for RX hash and VLAN tag - ice: expose the E825 TSPLL state via the DPLL subsystem - nVidia/Mellanox: - move the data direct infrastructure from IB to core, in preparation for netdev support. - reduce the memory used per offloaded TC rule - Meta (fbnic): - support large io_uring zero-copy RX buffers - Microsoft vNIC (mana): - add BQL support - Ethernet NICs consumer, and embedded: - Airoha: - LRO offload support - Cadence (macb): - context swapping for ringparam and MTU changes, avoiding buffer loss under memory pressure - Mucse (rnpgbe): - TX/RX and link status support - NXP (enetc): - SR-IOV improvements and VF support for ENETC v4 - Qualcomm (ppe): - IPQ5424 support - Realtek PCI (r8169): - phylink support - RSS support for RTL8127 - Renesas (ravb): - gPTP support for R-Car Gen4 - Synopsys (stmmac): - XDP multi-buffer support on the TX side - tc mqprio hw queue priority offload - support for RK3568 SGMII, Allwinner H616 EMAC1, UltraRISC DP1000 and Qualcomm sa8255p - Ethernet switches: - Mediatek (mt7530): - fast age and change conduit support - Microchip (ksz): - support for KSZ8995XA/KS8995XA - Microchip (lan966x): - PCIe FDMA support, ~20x throughput increase in PCIe endpoint - Microchip (sparx5): - Time Aware Shaper (taprio) offload - Motorcomm (yt921x): - LED and SerDes PCS support - Realtek (rtl8365mb): - EEE support - Ethernet PHYs: - Broadcom: - enable jumbo frames on BCM54xx - Realtek: - support for RTL8261CE_CG and RTL8261D_VM - MDIO support for RTL838x and RTL839x - WiFi drivers: - Broadcom (brcmfmac): - FT/OKC roaming offload - Intel (iwlwifi): - UHR sniffer support - support for newer UEFI/BIOS tables - MediaTek (mt76): - mt7925 NAN improvements - offchannel/scan improvements and MLO fixes - Morse Micro (mm81x): - monitor mode support - Qualcomm (ath12k): - IPQ5332 platform infrastructure - Realtek (rtw88): - RTL8723BS support - SDIO TX performance improvements - Realtek (rtw89): - P2P_DEVICE support - BT-coex updates for RTL8922D - Bluetooth: - move H:4 reassembly into the Bluetooth core - add generic support for vendor packets - MGMT: add security level changed event - Bluetooth drivers: - btusb: support Bulk Serialization Mode - Intel: support Draco and Titan Lake, allow unsigned firmware - Mediatek: MT7928 support - Qualcomm: QCC2072 support - Broadcom: Synaptics 4384 support" * tag 'net-next-7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (2126 commits) Bluetooth: btusb: disable by default Qualcomm multi-subsystem tipc: fix broadcast sender hang on last acker departure tipc: fix use-after-free of broadcast reception link at node release r8169: clear TX LPI on RTL8168h at link up after phylink conversion tun: Require CAP_NET_ADMIN to attach to an ownerless device net/sched/sch_cake: drop dead nla_nest_end() error check net/sched/sch_cake: widen buffer_used to u64 net/sched/sch_cake: reduce parent backlog when clearing a tin net/sched/sch_cake: serialize reconfiguration with the datapath tg3: Add Datto SIRIS 5 1U Server to restart AER quirk table net/mlx5e: Stop asserting for RTNL when closing channels net: shrink the payload-only part of skb dataref to one bit net: wwan: iosm: validate msg_head before indexing msg_ring net: bgmac: rate limit RX error messages selftests: net: veth: test XDP_TX to a peer with GRO enabled veth: schedule the peer's NAPI after XDP_TX when only GRO is enabled pppoe: delete session hash entries by pointer match net: lan969x: don't disable hardirqs in fdma tx clear net: sparx5/lan969x: do not clobber the PSFP cycle timer update period net: lan969x: fix DSM calendar for empty taxis ...
4 daysMerge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netPaolo Abeni
Merge in late fixes in preparation for the net-next PR. Conflicts: net/netfilter/nf_conntrack_netlink.c cd37ab22a74e0 ("netfilter: nf_conntrack_netlink: fix inverted IPv6 tuple filter") 1ae2d094b0200 ("netfilter: ctnetlink: fix inverted IPv6 address match in dump filter") Adjacent changes: drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c 8830e65ed46de ("net: use assign_bit() where applicable") 07bd391eb957 ("octeontx2-af: Fix CQ enable state tracking after AQ writes") net/core/sock.c 31c5ea8a3296 ("ipv6: Remove IPV6_ADDRFORM.") 31b564f70d88 ("net: use the full socket in sk_mc_loop()") net/mptcp/protocol.h 0cb6910130a3 ("mptcp: remove thmac from subflow ctx") 7538fa33bb2f ("mptcp: fix subflow bitfield misuse") Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 daystipc: fix broadcast sender hang on last acker departureHenry Martin
TIPC group broadcast senders are blocked while a replicast still has outstanding member acks: tipc_group_bc_cong() returns true as long as grp->bc_ackers is non-zero, and clears *grp->open, which is what tipc_poll() uses to report EPOLLOUT (via tsk->group_is_open). When the last outstanding acker departs before acking, tipc_group_delete_member() decrements grp->bc_ackers to zero but never restores *grp->open. As a result poll(EPOLLOUT) never fires again. A writer blocked in sendmsg() is only released if some other wakeup happens after the deletion: with TIPC_GROUP_MEMBER_EVTS the leave event delivery calls sk_data_ready() and wakes it, but without member events nothing does and it sleeps indefinitely, since the default send timeout is MAX_SCHEDULE_TIMEOUT. Commit 99cc2a62e07a ("tipc: reject invalid and unexpected GRP_ACK_MSG to prevent bc_ackers underflow") already calls this out in its changelog as a pre-existing issue. Restore the open state exactly on the 1->0 transition in the delete path, mirroring the GRP_ACK_MSG completion path, and invoke sk->sk_write_space() from tipc_sk_filter_rcv() when the group just became writable again. Also make the ack accounting precise. The delete path used to test less(m->bc_acked, grp->bc_snd_nxt - 1), which also matches members that were never counted for the current replicast (JOINING/LEAVING members keep a stale bc_acked), and the GRP_ACK_MSG handler accepted an ack from any member whose bc_acked differed from the expected value. Either could zero bc_ackers on behalf of a member that owes nothing and silently void an ack still owed by a real acker. Track whether a member owes an ack for the current replicast in a new per-member bc_pending flag, set when the member is counted and cleared when its ack arrives, and use it both to accept an ack and to decide on deletion. bc_acked has no remaining user and is removed. Suggested by Tung Quang Nguyen. This issue was discovered by Tencent CodeBuddy Security. Cc: stable@vger.kernel.org Fixes: 2f487712b893 ("tipc: guarantee that group broadcast doesn't bypass group unicast") Signed-off-by: Henry Martin <bsdhenrymartin@gmail.com> Reviewed-by: Tung Nguyen <tung.quang.nguyen@est.tech> Link: https://patch.msgid.link/20261019115859.3471295-1-bsdhenrymartin@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 daystipc: fix use-after-free of broadcast reception link at node releaseBinbin Deng
When the last reference to a tipc_node is dropped, the node itself is deferred to the RCU callback tipc_node_free(), but the nested broadcast reception link, n->bc_entry.link, is kfree()d synchronously in tipc_node_kref_release(), before call_rcu(), and the pointer is never cleared. Readers that obtained the node from node_list and then dereference bc_entry.link deep into the link (tipc_link_name() in tipc_nl_node_reset_link_stats(), bcl->name/stats in tipc_nl_add_bc_link() on the link dump path) therefore touch freed memory although the enclosing node stays alive for a full grace period. The sibling per-bearer links get "kfree + NULL" under the node write lock in tipc_node_clear_links(); the broadcast entry was missed. The race is reachable through the node cleanup timer: once a peer has been unreachable for NODE_CLEANUP_AFTER (300 s), tipc_node_timeout() -> tipc_node_cleanup() unlinks the node under the write lock, and the final tipc_node_put() at the caller runs outside node_list_lock, so the kfree executes in timer softirq context, concurrently with genl dump/ reset walkers that hold only rcu_read_lock(). (A netlink "peer remove" cannot race those walkers itself: tipc_genl_family has no parallel_ops, so all doit/dumpit calls serialize on the global genl lock.) Reproduced in a QEMU/KVM guest running v7.3.0 with KASAN and PREEMPT(full): 10 TIPC peer namespaces on veth bearers, bearer removal staggered so the 300 s node cleanup timers expire while other tasks loop link dumps with the broadcast filter and reset-link-stats lookups. KASAN hit within two cleanup cycles: BUG: KASAN: slab-use-after-free in strlen+0x85/0xa0 Read of size 1 at addr ffff88800b54a004 by task poc_eth/371 strlen+0x85/0xa0 tipc_nl_add_bc_link+0x2f9/0xd40 __tipc_nl_add_node_links+0x10c/0x140 tipc_nl_node_dump_link+0x8d5/0xd50 Freed by task 0: kfree+0x121/0x380 tipc_node_timeout+0xa33/0xcf0 run_timer_softirq+0x144/0x250 sysvec_apic_timer_interrupt with the freed object being the kmalloc-1k tipc_link allocated by tipc_link_bc_create() during peer discovery. The same defect fires in strcmp() called from tipc_nl_node_reset_link_stats(). Move the kfree of n->bc_entry.link into the tipc_node_free() RCU callback so the broadcast link lives exactly as long as the enclosing node. All readers are covered: the netlink walkers are inside rcu_read_lock(), and the packet reception path reaches the node via tipc_node_find(), whose kref defers kref_release itself. Found during a static-analysis-assisted audit: candidate sites were surfaced by a Coccinelle rule, and the reader/writer paths were confirmed by LLM-assisted (GLM-5.3) code inspection. Fixes: d25a01257e42 ("tipc: fix crash during node removal") Assisted-by: GLM-5.3 coccinelle Signed-off-by: Binbin Deng <18983559317@163.com> Reviewed-by: Simon Horman <horms@kernel.org> Reviewed-by: Tung Nguyen <tung.quang.nguyen@est.tech> Link: https://patch.msgid.link/20261019104352.488347-1-18983559317@163.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 daysnet/sched/sch_cake: drop dead nla_nest_end() error checkJamal Hadi Salim
cake_dump_class_stats() closes the TCA_STATS_APP nest with if (nla_nest_end(d->skb, stats) < 0) return -1; nla_nest_end() never returns a negative value: it has a single `return skb->len;` and no error path (that is why the overflow-aware nla_nest_end_safe() helper was later added). The '< 0' test can never be true, so the 'return -1' is unreachable dead code. Drop the check and close the nest with the bare statement, matching the sibling cake nests in the same file. This issue was discovered while fixing a bug on the gate action, see: https://lore.kernel.org/netdev/QDISC-H19Z.v1.20261001053234@mojatatu.com/ Conditions to recreate the bug: - not runtime observable: the issue is found by inspection. Link: https://lore.kernel.org/netdev/87v77csd5q.fsf@toke.dk/ Reviewed-by: Victor Nogueira <victor@mojatatu.com> Acked-by: Toke Høiland-Jørgensen <toke@toke.dk> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Link: https://patch.msgid.link/QDISC-5RTM.v3.r0.20261020053711-4@mojatatu.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
4 daysnet/sched/sch_cake: widen buffer_used to u64Jamal Hadi Salim
This is a follow-up to commit 4c660ee8c809 ("net: sched: fix 32-bit backlog wrap in gred, bfifo and plug enqueue"), which promoted the backlog + length admission sums in gred, bfifo and plug to u64. CAKE's own memory accounting has the same 32-bit wrap. The issue: cake_sched_data.buffer_used accumulates skb->truesize and is compared against memory_limit: q->buffer_used += skb->truesize; if (q->buffer_used <= q->buffer_limit) return NET_XMIT_SUCCESS; while (q->buffer_used > q->buffer_limit) drop... buffer_used is u32, so once the resident truesize passes 2^32 it wraps to a small value, the <= test passes and the drop loop is skipped even though far more than the configured limit is queued. memory_limit is a u32 attribute (TCA_CAKE_MEMORY), so buffer_limit can be as large as U32_MAX and never caps buffer_used below the wrap point; with a large memory_limit the queue then grows until the machine is out of memory. The fix: Widen buffer_used and buffer_max_used to u64, the same shape as the gred/bfifo/plug fix. buffer_limit stays u32; the comparison promotes it to u64, so the bounded queue stops at the configured limit below 2^32 and the counter can no longer wrap. buffer_used is subtracted on dequeue and drop, so the widened type flows through unchanged. The ACK-filter replacement applied the net delta as one expression, q->buffer_used += skb->truesize - ack->truesize. Both operands are unsigned int, so the subtraction is evaluated at u32 and a larger removed ACK wraps the delta; the old u32 accumulator folded that back to the correct net value, but the widened u64 accumulator would persist it as a roughly 4 GiB over-count. Apply the replacement as two exact operations on the widened counter instead; the queue already accounts ack->truesize, so the subtraction cannot underflow. Widening the counters alone is incomplete because cake_dump_stats() still exports buffer_max_used through PUT_STAT_U32(MEMORY_USED, ...), and tc.yaml declares memory-used as u32. buffer_max_used only ever rises, so once the widened counter passes 2^32 the export reports peak - 2^32 for the rest of the qdisc's life. Clamp the exported value to U32_MAX; the counter itself is unaffected. The dump path runs without the qdisc lock: tc_fill_qdisc() passes NULL to gnet_stats_start_copy_compat(), so the reader races with the enqueue-side update. READ_ONCE() is not an atomic 64-bit load on 32-bit CPUs, so a reader can observe a torn high-water mark and report a bogus MEMORY_USED. Publish the counter as u64_stats_t under the qdisc lock, which the enqueue path already holds, and take a seqcount-protected snapshot in the dump. The counter stays u64; only the exported value is bounded. Conditions to recreate the bug: CAP_NET_ADMIN (root or a user namespace, the qdisc attach is gated by netlink_net_capable(CAP_NET_ADMIN)). A TUN device is needed so the root qdisc can park packets instead of dropping them. Open /dev/net/tun, request TUNSETIFF with IFF_TUN | IFF_NO_PI | IFF_BACKPRESSURE and keep the fd open without reading it (run it in the background and stop it at teardown): with IFF_BACKPRESSURE the full tx ring calls netif_tx_stop_queue() rather than dropping, so the queue behind the qdisc can grow past 4 GiB of resident truesize. A plain 'ip tuntap add' attaches no fd and does not request IFF_BACKPRESSURE, so it cannot park the queue this way. ip link set tun0 txqueuelen 32 up ip addr add 10.99.0.1/24 dev tun0 tc qdisc add dev tun0 root handle 1: cake memlimit 4294967295 # Then push more than 4 GiB of resident truesize through the qdisc: six # UDP senders using large SO_SNDBUFFORCE buffers send 1400-byte # datagrams (the reported OOM witness used 6 workers for 100 s on a # 12 GiB guest). On the unfixed kernel buffer_used wraps, the admission # test passes, the drop loop is bypassed and the guest runs out of # memory; with the fix the counter passes the limit without wrapping and # the excess is dropped. # The ACK-filter over-count is a separate corner: it needs ack-filter # enabled and a queued pure ACK whose truesize is larger than the # replacement ACK. Use a fresh interface (or 'tc qdisc change') rather # than a second root 'tc qdisc add' on an interface that already has a # qdisc: tc qdisc change dev tun0 root cake ack-filter CONFIG_NET_SCH_CAKE=y and CONFIG_TUN=y are required, and the memory-residency recipe needs a root-run sender envelope with enough guest RAM to hold the queued data. Reported-by: Sashiko (gemini) <sashiko-bot@kernel.org> Closes: https://sashiko.dev/#/patchset/20260818095927.15901-1-jhs@mojatatu.com Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260818095927.15901-1-jhs@mojatatu.com Link: https://lore.kernel.org/netdev/20260818095927.15901-1-jhs@mojatatu.com/ Reviewed-by: Victor Nogueira <victor@mojatatu.com> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Acked-by: Toke Høiland-Jørgensen <toke@toke.dk> Link: https://patch.msgid.link/QDISC-5RTM.v3.r0.20261020053711-3@mojatatu.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
4 daysnet/sched/sch_cake: reduce parent backlog when clearing a tinJamal Hadi Salim
The issue: CAKE has purged unused tins on DiffServ reconfiguration since commit 83f8fd69af4f ("sch_cake: Add DiffServ handling") without propagating the resulting backlog reduction to classful parents. The issue was noticed while reviewing 7cbfb180945c, but predates that change. cake_clear_tin() drops every packet from a tin with kfree_skb_reason() but never calls qdisc_tree_reduce_backlog(), so a CAKE qdisc under a classful parent (e.g. HTB) leaves the dropped packets in the parent qdisc's and class's qlen/backlog accounting forever. The normal dequeue path does reduce the parent; only the live reconfigure purge misses it. The fix: Tins are cleared from cake_reset() and, on reconfigure, from cake_configure_rates(). The qdisc core already owns the parent delta for the reset path: qdisc_purge_queue() snapshots qlen/backlog, runs qdisc_reset(), then reduces the tree, so propagating the reduction from cake_clear_tin() itself would subtract the same backlog twice. Snapshot CAKE's qlen/backlog around only the reconfiguration purge in cake_configure_rates() and reduce the parent once afterwards, matching the delta pattern already used by cake_enqueue(). Conditions to recreate the bug: put CAKE (diffserv8) under an HTB class, flood DSCP-classified traffic into a high tin so it backlogs, then change CAKE to diffserv3. The HTB parent keeps the purged packets in its qlen and backlog; a kernel with the fix shows the parent at the leaf's backlog (426b/5p) instead of retaining the purged packets. Reported-by: Sashiko (gemini) <sashiko-bot@kernel.org> Link: https://sashiko.dev/#/patchset/20260816012109.2865223-1-ooonea@gmail.com Link: https://lore.kernel.org/netdev/20260816012109.2865223-1-ooonea@gmail.com/ Link: https://lore.kernel.org/netdev/8733ugtry8.fsf@toke.dk/ Reviewed-by: Victor Nogueira <victor@mojatatu.com> Acked-by: Toke Høiland-Jørgensen <toke@toke.dk> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Link: https://patch.msgid.link/QDISC-5RTM.v3.r0.20261020053711-2@mojatatu.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
4 daysnet/sched/sch_cake: serialize reconfiguration with the datapathJamal Hadi Salim
This is a follow-up to commit 7cbfb180945c ("net/sched: sch_cake: fix autorate reconfiguration throttling"). That change only stored last_reconfig_time; it did not address the concurrency between the autorate rate update in cake_enqueue() and the netlink reconfiguration path, which the original review flagged. The issue: cake_change() -> cake_config_change() updates the fields of the shared struct cake_sched_config under RTNL but not under the qdisc lock: it only took sch_tree_lock() later, around cake_reconfigure(). The datapath in turn serializes cake_enqueue() with itself under the qdisc lock, and its autorate-ingress path stores the estimated rate into q->config->rate_bps. Two writers therefore update the same rate with no common lock: CPU0: cake_enqueue() sees CAKE_FLAG_AUTORATE_INGRESS, computes an estimate, and is about to store it. CPU1: 'tc qdisc change ... bandwidth X' clears autorate in its local rate_flags, writes rate_bps = X, publishes the cleared flag, and waits in sch_tree_lock(). CPU0: stores the estimate, calls cake_reconfigure(), and unlocks. CPU1: reconfigures from the estimate and returns. The qdisc is left with autorate disabled but with the estimate installed instead of X. The fix: Commit the parsed configuration and reconfigure while holding the same qdisc lock that serializes the datapath, so the netlink writer and the autorate writer can no longer interleave. rate_bps needs no atomic: it is only ever loaded and stored, so plain READ_ONCE()/WRITE_ONCE() annotations are enough for the accesses that run outside the lock. The lockless paths read the rate once into a local and reuse that value, so a single coherent snapshot is used per operation. The annotations do not make a 64-bit access single-copy atomic on 32-bit: READ_ONCE()/WRITE_ONCE() are still two 32-bit accesses there. The lockless readers -- cake_config_dump() and the cake_mq children, which observe the shared config under a different child's lock -- can therefore still see a torn rate on 32-bit. That rate is an advisory shaper value and is accepted as best-effort; the state that must be consistent (the configured rate and the autorate flag) is written under the qdisc lock. Conditions to recreate the bug: The lost update (a) needs no sanitizer. Put cake in autorate-ingress on a device, drive bursty traffic with gaps so the 250 ms autorate reconfiguration fires, and concurrently loop 'tc qdisc change ... cake bandwidth <N>kbit' without autorate-ingress (specifying a bandwidth clears the flag). If the autorate store lands after the change wrote its rate but before the change reconfigures, the qdisc ends up with autorate disabled and the estimate installed instead of <N>; reading the rate back then shows the estimate, which an unfixed kernel can do and a fixed one cannot. (b) The unsynchronized access is reported by KCSAN: build with CONFIG_KCSAN=y and run the same trigger with the change loop keeping autorate-ingress set; KCSAN reports a data race in cake_config_change / cake_enqueue. The non-atomic 64-bit store only shows up as tearing on a 32-bit machine; on 64-bit the store is atomic and KCSAN flags the access discipline instead. Reported-by: Sashiko (gemini) <sashiko-bot@kernel.org> Link: https://sashiko.dev/#/patchset/20260816012109.2865223-1-ooonea@gmail.com Link: https://lore.kernel.org/netdev/20260816012109.2865223-1-ooonea@gmail.com/ Link: https://lore.kernel.org/netdev/875wzctsky.fsf@toke.dk/ Link: https://lore.kernel.org/netdev/87ld7t3kl3.fsf@all.your.base.are.belong.to.us/ Reviewed-by: Victor Nogueira <victor@mojatatu.com> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Acked-by: Toke Høiland-Jørgensen <toke@toke.dk> Link: https://patch.msgid.link/QDISC-5RTM.v3.r0.20261020053711-1@mojatatu.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
4 daysnetmem: rename get/put_netmem() to netmem_inc/dec_ref()Mina Almasry
Follow the object_action() naming convention for netmem non-page_pool reference helpers by renaming get_netmem() and put_netmem() to netmem_inc_ref() and netmem_dec_ref(). Use netmem_inc_ref() and netmem_dec_ref() rather than netmem_ref() and netmem_unref() because netmem_ref is already a typedef (typedef unsigned long __bitwise netmem_ref). Suggested-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Mina Almasry <almasrymina@google.com> Link: https://patch.msgid.link/20261021015558.4124825-3-almasrymina@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
4 daysnetmem: rename get/put_net_iov() to net_iov_inc/dec_ref()Mina Almasry
Follow the object_action() naming convention for net_iov non-page_pool reference helpers by renaming get_net_iov() and put_net_iov() to net_iov_inc_ref() and net_iov_dec_ref(), and renaming net_devmem_get_net_iov() and net_devmem_put_net_iov() to net_devmem_net_iov_inc_ref() and net_devmem_net_iov_dec_ref(). Use *_inc_ref() and *_dec_ref() rather than *_ref() and *_unref() to pair symmetrically with netmem_inc_ref() and netmem_dec_ref() (since netmem_ref is already the typedef for the generic network memory handle). Suggested-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Mina Almasry <almasrymina@google.com> Link: https://patch.msgid.link/20261021015558.4124825-2-almasrymina@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
4 daysnet: ethtool: Introduce ethtool command to list portsMaxime Chevallier
Expose the phy_port information to userspace, so that we can know how many ports are available on a given interface, as well as their capabilities. For MDI ports, we report the list of supported linkmodes based on what the PHY that drives this port says. For MII ports, i.e. empty SFP cages, we report the MII linkmodes that we can output on this port. Tested-by: Aleksei Sviridkin <f@lex.la> Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org> Tested-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org> Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com> Link: https://patch.msgid.link/20261016133107.54054-10-maxime.chevallier@bootlin.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
4 daysnet: phy: phy_link_topology: Track ports in phy_link_topologyMaxime Chevallier
phy_port is aimed at representing the various physical interfaces of a net_device. They can be controlled by various components in the link, such as the Ethernet PHY, the Ethernet MAC, and SFP module, etc. Let's therefore make so we keep track of all the ports connected to a netdev in phy_link_topology. The only ports added for now are phy-driven ports. Reviewed-by: Andrew Lunn <andrew@lunn.ch> Tested-by: Aleksei Sviridkin <f@lex.la> Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org> Tested-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org> Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com> Link: https://patch.msgid.link/20261016133107.54054-3-maxime.chevallier@bootlin.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
4 daysMerge tag 'timers-core-2026-10-20' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull timer core updates from Thomas Gleixner: "Updates for the core timekeeping and timers subsystem: - Futher cleanups for the POSIX timer exit/exec related code to simplify the code flow and to make it more robust against future changes. - Prevent tearing of timekeeper::ktime_sec which can be accessed without the sequence count protection. The timekeeper is updated by memcpy() with an uneven sequence count to force readers into the retry path. On 64-bit machine the ktime_sec member can be accessed atomically without the sequence count protection. That is only correct when the update side memcpy() guarantees atomicity at the 64-bit granularity. That's not guaranteed due to debug options, compilers and instruction availability. If the memcpy() does not provide the atomicity then the unprotected readers can observe store tearing. To prevent this write the ktime_sec member before the memcpy() so that a non-atomic memcpy() will write the same data. A similar fix has been done for the xtime_sec member, but the ktime_sec equivalent was missed. - Prevent time64_to_tm() day truncation on 32-bit kernels The function receives a 64-bit seconds value but stores the quotient of the computation in a long, which truncates the result for large input values. Cure this by using div_s64_rem() which stores the quotient in s64 and only leaves the seconds-within-day reminder in a long, which is guaranteed to fit. This fix comes with a corresponding kunit test to prevent further mishaps. - Mark data-racy accesses to the hrtimer_sleeper::task member. The recent updates to KCSAN flagged these benign races. Annotate them with new helper functions, convert all existing usage sites and mark the task member private after that so that future users which fail to use the helpers can be detected automatically. - Address similar benign KCSAN flagged issues in the hrtimer, timer and timer migration code. - Fixes for a few selftest issues" * tag 'timers-core-2026-10-20' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (26 commits) selftests/timers: clocksource-switch: Fix unchecked open()/read() selftests: timers: Measure the CPU timers on the clock they count selftests: timers: Count what tick is worth in the drift estimate time/kunit: Add time64_to_tm() case beyond 32-bit day count time: Prevent time64_to_tm() day truncation on 32-bit timekeeping: Use READ_ONCE/WRITE_ONCE() for ktime_sec to prevent tearing timers/migration: Mark racy updates to tmigr_event::ignore field timers: Mark racy updates to hlist_node::pprev field hrtimer: Apply READ_ONCE() to lockless base->running loads hrtimer: Mark the hrtimer_sleeper structure's ->task field __private hrtimer: Update hrtimer_resolution only if value changes futex: Use accessor for hrtimer_sleeper ->task field in requeue rtmutex: Use accessor for hrtimer_sleeper ->task field net: pktgen: Use accessor for hrtimer_sleeper ->task field timers: Use accessor for hrtimer_sleeper ->task field in sleep_timeout.c futex: Use accessor for hrtimer_sleeper ->task field in waitwake.c io-uring/rw: Use accessor for hrtimer_sleeper ->task field wait: Use accessor for hrtimer_sleeper ->task field aio: Use accessor for hrtimer_sleeper ->task field hrtimer: Mark data-racy accesses to hrtimer_sleeper ->task field ...
5 daysMerge __{get,put}_user() removal branchLinus Torvalds
This is long over-due: the __get_user() and __put_user() functions are entirely historical, and are never the rigth thing to use any more. And when mis-used (read: every case) they are not only slower than the right thing, but also insecure because they don't check the user address range. Most of the usage sites have been converted long ago, but various left-overs remained. So this started out as a single patch that I wrote as a "show people how to convert __{get,put}_user() to modern code". In particular, Thomas last year implemented the very nice new scoped user access region helpers (see commit e497310b4ffb: "uaccess: Provide scoped user access regions") that makes the modern interfaces particularly easy to use and really removes any excuse for the old horrors. That small example patch then grew to this, partly using Claude as a glorified coccinelle script to apply the pattern to other places. There were a few different reasons for using __put_user() and __get_user() rather than the alternatives, but the original historical one was performance: when doing multiple accesses off the same base pointer, doing a single range check followed by multiple non-checked accesses used to create smaller and faster code. The keyword here is "used to". It hasn't been true for years, because the range check isn't actually the real cost these days. The real cost of user accesses on modern hardware is turning the user accesses on and off in the first place (on x86, using the STAC/CLAC instructions). Those sequences get turned into 'scoped_user_read_access() { }' blocks, see for example that first patch in the series: "signal: use scoped user access for old-style sigaction". Another, historical reason for using __get_user() and friends is that you actually want to do a kernel pointer access, but the pointer might not be entirely reliable (typically during fault handling), so you want to have exception handling for the kernel access. The modern way to do that kind of non-faulting kernel access is using "get_kernel_nofault()", but some code predates that helper existing at all, and used __get_user() as a way to just get a memory access with exception handling. For that pattern, see for example "alpha: use get_kernel_nofault() in dik_show_code()" A third bad reason for using __get_user() and friends was that the proper get_user() had a "might_fault()" in it, and code that ran in atomic regions but hadn't disabled page faults would result in a warning. That kind of code needs to explicitly disable page faults, because "atomic region" is not well defined at run-time and can be invisible (eg a preempt-off region in a non-preemptible kernel). See "vdpa_sim: disable page faults around vringh_need_notify_iotlb()" for an example of that pattern, where the local_bh_disable() now also grows a pagefault_disable(), which makes the normal get_user() no longer warn about the user access in non-process context, because it can see that the potential page fault will not cause problems. And finally, the really nasty reason to use __get_user() and friends: pointers that can be either kernel pointers or user pointers. We've gotten rid of almost all such cases, but a couple remained. See for example "x86/sev: Use explicit user-or-kernel accessors for #VC memory operands". NOTE! This series removes all __get/put_user() calls from generic code but only does the final removal of the whole interface on x86. Other architectures have not been entirely converted, for a variety of reasons: - arm64 makes __{get,put}_user() be exactly the same as {get,put}_user() so it's harmless and didn't have the dangers of the legacy use cases. - any architecture that uses <asm-generic/uaccess.h> will still use __{get,put}_user as the underlying helper function name - several architectures had some legacy uses that weren't entirely trivial and I didn't want to extend this patch series to things that I don't know and that don't really matter. but I did do a couple of the obvious "follows the exact same pattern" just because it could be done mindlessly and automatically. Let's see if I broke anything, but we should have done this years ago. * uaccess-cleanups: (48 commits) drm/i915/gem: ignore errors on presumed_offset write-back powerpc/align: use get_user_instr() for a user-mode instruction powerpc/signal64: use scoped user access in setup_trampoline() powerpc/signal64: use get_user() for the single context reads powerpc/signal32: use get_user() for the single context reads KVM: PPC: Book3S HV: use get_user()/put_user() for the HPT fd powerpc/powernv: use get_user()/put_user() in the LPC debugfs files s390: use get_user()/put_user() instead of the unchecked variants ARM: OABI: use scoped user access in epoll_put_uevent() ARM: signal: stop using __put_user() for the signal frame ARM: signal: check the FDPIC function descriptor address alpha: split the prefetch check in do_page_fault() by mode openrisc: use get_kernel_nofault() in show_registers() alpha: use get_kernel_nofault() in dik_show_code() nios2: use scoped user access for the signal frame nios2: check the signal frame address before writing to it hexagon: use scoped user access for the signal frame alpha: use scoped user access when setting up signal frames alpha: use scoped user access in the sigreturn path alpha: use scoped user access in osf_sigaction() ...
5 daysvsock: support SO_INQ on stream socketsDavid Carlier
SO_INQ makes recvmsg() return the bytes left in the receive queue in an SCM_INQ cmsg, saving a SIOCINQ call per receive. AF_UNIX stream sockets support it, AF_VSOCK fails with ENOPROTOOPT. Add it for SOCK_STREAM, reusing the hint already computed for io_uring. As with TCP_INQ, 1 is reported once the stream is finished so the caller reads again and sees EOF, and accepted sockets inherit the setting from the listener. No cmsg is sent when the transport cannot report the queue length. SOCK_SEQPACKET is refused, as on AF_UNIX: its transport callback counts messages, not bytes. Signed-off-by: David Carlier <devnexen@gmail.com> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> Link: https://patch.msgid.link/20261016132716.272018-3-devnexen@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
5 daysvsock: move SOL_SOCKET options to vsock_sol_socket_setsockopt()David Carlier
SO_ZEROCOPY is handled inline in vsock_connectible_setsockopt(). Move it to a helper with a switch on optname, so other SOL_SOCKET options can be added as new cases. The value parsing goes to its own helper too, so each option can do its own checks before it. No functional change. Signed-off-by: David Carlier <devnexen@gmail.com> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> Link: https://patch.msgid.link/20261016132716.272018-2-devnexen@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
5 daysnet: add AF_PACKET multicast dumpsYuyang Huang
RTM_GETMULTICAST dumps IPv4 and IPv6 multicast group memberships, but the device multicast list (dev->mc) is only available through /proc/net/dev_mcast, so "ip maddr show" still has to parse procfs for its link-layer entries. Handle RTM_GETMULTICAST dumps with ifa_family set to AF_PACKET next to the dev->mc helpers in dev_addr_lists.c and report every entry of dev->mc in the existing ifaddrmsg format: - IFA_MULTICAST carries the raw link-layer address - IFA_MC_USERS carries the entry reference count - IFA_F_GLOBAL in IFA_FLAGS reports netdev_hw_addr::global_use, set by dev_mc_add_global() (SIOCADDMULTI) and dev_mc_add_excl() ("bridge fdb add ... self"), i.e. entries added explicitly rather than by a protocol join. This is the static column of /proc/net/dev_mcast - ifa_scope is RT_SCOPE_LINK This covers every column of /proc/net/dev_mcast. AF_PACKET is the family iproute2 already uses for link-layer addresses ("ip -0"). The default FDB dump also walks dev->mc, but only for Ethernet devices and only if the driver uses it, vxlan for example does not, and it has no users count or global_use bit. Extending it would change "bridge fdb show" output and add NDA_* attributes. Requests are always validated, there are no legacy users: prefixlen, flags and scope must be zero, ifa_index selects one device and IFA_TARGET_NETNSID is the only attribute accepted. The dump runs under RCU and netif_addr_lock_bh() without RTNL. cb->seq is set from the dev->mc generation counter and dev_base_seq before each round and checked after it, so an entry added or removed since the previous round sets NLM_F_DUMP_INTR. A round without a message skips the check and cb->seq is set once more after the round, so the NLMSG_DONE check reports a change made during the last round or before an empty one. Signed-off-by: Yuyang Huang <sigefriedhyy@gmail.com> Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Link: https://patch.msgid.link/20261012011707.3378-5-sigefriedhyy@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
5 daysnet: add a generation counter for dev->mc changesYuyang Huang
A multi-part RTM_GETMULTICAST dump of dev->mc resumes by position, so entries added or removed between two dump rounds can be skipped or repeated. The IPv4 and IPv6 dumps report that with NLM_F_DUMP_INTR by stamping cb->seq from a per netns generation counter combined with dev_base_seq, see inet_base_seq(). Add the equivalent for the device multicast lists: a per netns counter bumped whenever an entry is added to or removed from any dev->mc. The list helpers do not know which device a list belongs to, so give netdev_hw_addr_list an mc_dev pointer, set for dev->mc only, and bump the counter of dev_net(mc_dev) from the count helpers. That covers the dev_mc_* helpers, both lists of a sync, the hardware sync helpers drivers call from their rx mode callbacks or their own workers and the reconciliation after an asynchronous rx mode update. It is atomic since the writers only hold the address lock of their own device. Used by the following patch for the AF_PACKET multicast dump. Signed-off-by: Yuyang Huang <sigefriedhyy@gmail.com> Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Link: https://patch.msgid.link/20261012011707.3378-4-sigefriedhyy@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
5 daysnet: change netdev_hw_addr_list count through helpersYuyang Huang
The count of a netdev_hw_addr_list is changed in several places of dev_addr_lists.c and a few drivers read it directly. The next patch needs to account every change of the count of dev->mc. Add __hw_addr_count_add(), __hw_addr_count_inc(), __hw_addr_count_dec() and __hw_addr_count_reset(), use them for every change of the count and rename the field to _count so that a direct write stands out. Readers keep using netdev_hw_addr_list_count() and the netdev_uc_count() and netdev_mc_count() helpers, the few that read the field directly are converted. No functional change. Signed-off-by: Yuyang Huang <sigefriedhyy@gmail.com> Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Link: https://patch.msgid.link/20261012011707.3378-3-sigefriedhyy@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
5 daystcp_bpf: propagate error code in tcp_bpf_sendmsg()Dmitry Antipov
In tcp_bpf_sendmsg(), the value returned by sk_msg_memcopy_from_iter() is checked for error but not propagated to 'out_err' label, so error handling may not work as expected. Fix this by assigning error value to 'err', thus making sure that error won't be silently ignored. Reported-by: Sashiko <shodan.ai@mcst.ru> Fixes: 5153a75ef34b ("tcp_bpf: Fix copied value in tcp_bpf_sendmsg") Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Reviewed-by: Jason Xing <kerneljasonxing@gmail.com> Reviewed-by: Eric Dumazet <edumazet@kernel.org> Link: https://patch.msgid.link/20261019082214.102398-1-dmantipov@yandex.ru Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysMerge tag 'nf-26-10-19' of ↵Jakub Kicinski
git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf Pablo Neira Ayuso says: ==================== Netfilter/IPVS fixes for net The following patchset contains Netfilter/IPVS for net: 1) Fix IPv6 nexthdr offset truncation in fragment reassembly, this has been uncovered by LLM, from Jeremy Jean. 2) Restrict checksums in nfqueue to known protocols and offset, after this patch the plan is to re-enable nfqueue in userns, this came via LLM report. from Florian Westhphal. 3) Fix races when handling overload flag in IPVS, this patch is not perfect but Julian considers this improves the situation. This was uncovered by LLM. From Julian Anastasov. 4) Error handling for IPVS sync_threshold sysctl, from Joel Granados. 5) Use skb_vlan_tag_get_id() to retrieve the VLAN id, discard tci bits, when handling VLAN in the flowtable, from Shuangfeng He. 6) Initialize IPCB for inet/ingress reject, uncovered by LLM. 7) Restrict completion of binary search array to anonymous set. 8) Restrict DCCP option matching to avoid out-of-bound read, from Sung Byeongchan. 9) Reset transport header offset in flowtable after tunnel decapsulation to fix issue with qdisc xmit path, from Lorenzo Bianconi. 10) Fix inverted matching in ctnetlink dump filtering, from Liu Chao. * tag 'nf-26-10-19' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf: netfilter: nf_conntrack_netlink: fix inverted IPv6 tuple filter netfilter: flowtable: reset transport header after nf_flow_encap_pop() netfilter: xt_dccp: handle reserved options as single-byte netfilter: nft_set_rbtree: narrow down range completion to anonymous sets netfilter: nf_reject: initialize IPCB at inet ingress netfilter: flowtable: use the vlan id, not the full tci, in the tuple key ipvs: skip committing sync_threshold when proc_dointvec fails ipvs: fix more races around the overload flag netfilter: nft_payload: restrict checksum offsets to known values netfilter: nf_conntrack: avoid truncating IPv6 nexthdr offset ==================== Link: https://patch.msgid.link/20261019150249.1879516-1-pablo@netfilter.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysnet: skbuff: don't copy alloc_cpu in skb header copiesCarolina Jubran
Commit 68822bdf76f1 ("net: generalize skb freeing deferral to per-cpu lists") added alloc_cpu to struct sk_buff and placed it in the headers group copied by __copy_skb_header(). This is wrong for newly allocated skbs. For example, skb_segment() allocates a new skb and records the current CPU in alloc_cpu, but __copy_skb_header() overwrites it with the value from the original skb. If the original skb was allocated on another CPU, the segment may later be treated as remotely allocated and unnecessarily deferred there when it is freed. Move alloc_cpu out of the headers group so it is preserved across header copies. Copy it explicitly in skb_clone(), which allocates the skb object directly instead of going through __alloc_skb(). This was discovered while investigating a throughput regression with software IPsec. The load used 512 IPsec tunnels carrying traffic over VXLAN, with 512 parallel iperf3 flows and an MTU of 4500. Before the fix: 16.09% queued_spin_lock_slowpath | --15.90%--_raw_spin_lock_irqsave | --9.37%--__slab_free kfree skb_release_data napi_consume_skb mlx5e_poll_tx_cq After the fix: 6.84% queued_spin_lock_slowpath | --6.57%--_raw_spin_lock_irqsave | --5.00%--__slab_free kfree skb_release_data napi_consume_skb mlx5e_poll_tx_cq Fixes: 68822bdf76f1 ("net: generalize skb freeing deferral to per-cpu lists") Signed-off-by: Carolina Jubran <cjubran@nvidia.com> Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com> Reviewed-by: Björn Töpel <bjorn@kernel.org> Reviewed-by: Jason Xing <kerneljasonxing@gmail.com> Reviewed-by: Eric Dumazet <edumazet@kernel.org> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20261019174152.2932829-1-cjubran@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysnet/smc: queue the copied chunk when smc_tx_sendmsg() faultsBryam Vargas
When a send wraps the end of the send buffer, smc_tx_sendmsg() copies the data in two chunks. If memcpy_from_msg() faults on the second one, smc_tx_sendmsg() returns send_done, which already counts the first chunk, but leaves tx_curs_prep and sndbuf_space as they were. send() reports bytes the peer never receives, and the next send() overwrites them. Any caller can hit this on its own stream with a buffer whose tail is unreadable. On a fault in the second chunk, queue the first one. The next pass retries the rest and returns send_done if it faults again, so send() reports only what it queued, as TCP does. Fixes: e6727f39004b ("smc: send data (through RDMA)") Cc: stable@vger.kernel.org Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me> Link: https://patch.msgid.link/20261013-b4-disp-872a3689-v1-1-2a4c63b04761@proton.me Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysipv6: Hold RCU when emitting route hardware flags notificationIdo Schimmel
fib6_info_hw_flags_set() is called by drivers from process context without RTNL or RCU. When the route uses a nexthop object, rt6_nlmsg_size() and rt6_fill_node() access the nexthop's RCU protected nexthop info and group pointers via rcu_dereference_rtnl(), resulting in suspicious RCU usage splats [1]. Fix by holding RCU while sizing and filling the notification, like fib_alias_hw_flags_set() already does. Switch to GFP_ATOMIC for the skb allocation accordingly. Reproducer: # echo "10 0" > /sys/bus/netdevsim/new_device # sysctl -wq net.ipv6.fib_notify_on_flag_change=1 # sysctl -wq net.ipv4.nexthop_compat_mode=1 # ip -6 nexthop add id 1 blackhole # ip -6 route add 2001:db8:1::1/128 nhid 1 [1] WARNING: suspicious RCU usage 7.3.0-rc7-virtme-g191aa41548b2 #38 Not tainted net/ipv4/nexthop.c:1539 suspicious rcu_dereference_check() usage! [...] Workqueue: events nsim_fib_event_work Call Trace: <TASK> dump_stack_lvl (lib/dump_stack.c:94 lib/dump_stack.c:120) lockdep_rcu_suspicious.cold (kernel/locking/lockdep.c:6972) nexthop_for_each_fib6_nh (net/ipv4/nexthop.c:1539 (discriminator 16)) rt6_nlmsg_size (net/ipv6/route.c:5728) fib6_info_hw_flags_set (net/ipv6/route.c:6503) nsim_fib6_rt_add (drivers/net/netdevsim/fib.c:671 drivers/net/netdevsim/fib.c:694) nsim_fib6_rt_insert (drivers/net/netdevsim/fib.c:759) nsim_fib_event_work (drivers/net/netdevsim/fib.c:856 drivers/net/netdevsim/fib.c:889 drivers/net/netdevsim/fib.c:1493) process_one_work (kernel/workqueue.c:3396) worker_thread (kernel/workqueue.c:3479 kernel/workqueue.c:3560) kthread (kernel/kthread.c:436) ret_from_fork (arch/x86/kernel/process.c:158) ret_from_fork_asm (arch/x86/entry/entry_64.S:245) </TASK> Fixes: 907eea486888 ("net: ipv6: Emit notification when fib hardware flags are changed") Reported-by: Sashiko <netdev-bot+sashiko@kernel.org> Closes: https://lore.kernel.org/netdev/179152182668.434549.18232968419539498055@kernel.org/ Signed-off-by: Ido Schimmel <idosch@nvidia.com> Reviewed-by: Eric Dumazet <edumazet@kernel.org> Reviewed-by: David Ahern <dsahern@kernel.org> Link: https://patch.msgid.link/20261019140337.2886875-2-idosch@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysnet: unix: reject negative max_dgram_qlen valuesYingjie Wang
net.unix.max_dgram_qlen is parsed as a signed int and copied to the u32 sock::sk_max_ack_backlog when an AF_UNIX socket is created. Consequently, a negative value such as -1 is accepted and converted to UINT_MAX. Since the receive queue length is also u32, its fullness check cannot become true for that limit. max_dgram_qlen has no documented negative sentinel. Its existing signed interface represents nonnegative values only through INT_MAX; negative bit patterns are not a supported encoding for the upper half of the u32 consumer range. Switch to proc_dointvec_minmax and make the established 0..INT_MAX input range explicit. This rejects negative values without adding new accepted values or changing the default and zero-value behavior. Very large valid values can still make the queue limit impractical to reach; this change corrects the input domain rather than imposing a new resource ceiling. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Yingjie Wang <1075151112@qq.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/tencent_A643419B56079E9A448D97922763FF069F08@qq.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysip6mr: clear skb->cb[] in reg_vif_xmit()Eric Dumazet
reg_vif_xmit() hands the skb to ip6mr_cache_report() as an MRT6MSG_WHOLEPKT report. skb_realloc_headroom() copies skb->cb[] into the report, which is queued to the mroute socket, where rawv6_recvmsg() reads it as IP6CB. By the time the pim6reg device transmits the packet, skb->cb[] is not IP6CB anymore: qdisc_pkt_len_init() overwrites iif and ra, and any qdisc installed on the device (fq, fq_codel, pie, cake...) or a tc BPF program writing skb->cb[] fills the area holding dst0, srcrt, dst1, lastopt and flags. Since commit dd433671fef3 ("ipv6: validate extension header length before copying to cmsg") these stale offsets can no longer cause out-of-bounds reads, but the mroute socket can still receive bogus IPV6_PKTINFO ifindex and extension header ancillary data. Clear IP6CB before building the report. The skb is freed right after, so nothing else depends on its control block. Fixes: 14fb64e1f449 ("[IPV6] MROUTE: Support PIM-SM (SSM).") Signed-off-by: Eric Dumazet <edumazet@kernel.org> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysnet/rds: ib: don't enable IRQs in rds_ib_conn_free()Nguyen Ngoc Thang
__rds_conn_create() calls trans->conn_free() with rds_conn_lock held and IRQs disabled when it loses the race to insert a connection. rds_ib_conn_free() takes the device list lock with spin_lock_irq() and releases it with spin_unlock_irq(), so IRQs are turned on while rds_conn_lock is still held: raw_local_irq_restore() called with IRQs enabled WARNING: kernel/locking/irqflag-debug.c:10 at warn_bogus_irq_restore+0xc/0x20 _raw_spin_unlock_irqrestore+0x67/0x80 __rds_conn_create+0x1de5/0x2290 rds_conn_create_outgoing+0x43/0x60 rds_sendmsg+0xfca/0x20e0 __sys_sendto+0x408/0x5a0 It needs an RDS socket bound to an address on an RDMA device (e.g. rxe) and two concurrent sendto() calls to the same new destination. The TCP and loopback ->conn_free() callbacks already use irqsave, so do the same here. Fixes: 745cbccac3fe ("RDS: Rewrite connection cleanup, fixing oops on rmmod") Reported-by: syzbot+c3741bb338b5c6d6a4aa@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=c3741bb338b5c6d6a4aa Cc: stable@vger.kernel.org Signed-off-by: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysMerge tag 'nf-next-26-10-18' of ↵Jakub Kicinski
git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next Pablo Neira Ayuso says: ==================== Netfilter updates for net-next The following patchset contains Netfilter/IPVS updates for net-next: 1) Disable br_netfilter in userns and schedule it for removal in 2027, from Florian Westphal. 2) Update selftest nft_queue.sh to make it more stable on debug kernels, from Jakub Kicinski. 3) Fix a overflow in IPVS sync messages which can only happen in very old 2.6 kernels, from Julian Anastasov. 4) Finer grain packet drop in nfnetlink_queue when dependency objects are going away, from Antonio Ojea. 5) Add a selftest for the nfnetlink_queue packet drop case, also from Antonio Ojea. 6) Flush conntrack gc worker when existing netns to address a unlikely UaF, from Florian Westphal. 7) Switch nf_tables chain types to use rcu, otherwise module removal can trigger UaF, also from Florian. 8) Remove redundant parsing in nft_exthdr for the tcp options case, from Fernando F. Mancera. 9) Remove redundant skb_header_pointer() calls in nft_exthdr for tcp options, from Fernando F. Mancera. 10) Fix conntrack_vrf.sh selftest return value in zone subtest, from Florian Westphal. 11) Restrict raw table in nft_compat to specific family, hook and priority, from Florian Westphal. Prepare the flowtable to support for IPv4 over IPv6 tunneling and vice-versa, this includes 4 patches from Lorenzo Bianconi. 12) Explicitly set inner protocol when popping header, this is not needed for the existing IPIP and IP6IP6 case because skb->protocol remains the same. 13) Simplify tuple tunnel information fill up when parsing outer tunnel IP headers. 14) Add a new encap_proto which determines the outer tunnel protocol family. 15) Prepare flowtable forwarding path to deal with mixed IPv4-IPv6 tunnels. * tag 'nf-next-26-10-18' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next: netfilter: flowtable: unify tunnel push for IPv4 and IPv6 netfilter: flowtable: add encap_proto to flow_offload_tunnel netfilter: flowtable: populate tunnel tuple regardless of inner protocol netfilter: flowtable: set inner protocol when popping tunnel header netfilter: nft_compat: restrict raw table targets/matches selftests: netfilter: fix return value in zone subtest netfilter: nft_exthdr: avoid 60 bytes stack buffer in TCP option mangling netfilter: nft_exthdr: remove redundant op parsing in tcp_set_init netfilter: nf_tables: switch chain_types array to rcu netfilter: conntrack: fix unlikely UaF in gc worker selftests: netfilter: nft_queue: check the scope of the hook drop flush netfilter: nf_queue: limit the hook drop flush to the unregistered hook point ipvs: fix buffer overflow when sending sync messages selftests: netfilter: nft_queue.sh: only queue icmp echo request/reply netfilter: disable br_netfilter in user namespaces ==================== Link: https://patch.msgid.link/20261018005638.1776148-1-pablo@netfilter.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysnet: Port skb_segment tests of the test_bpf module to KUnitDaniel Borkmann
The old test_bpf module is going away, therefore port the two test cases which were added in 76db8087c4c9 ("net: bpf: add a test for skb_segment in test_bpf module") as well as cf204a718357 ("bpf, testing: Introduce 'gso_linear_no_head_frag' skb_segment test") into the net_test.c to retain coverage. With it in place: # Subtest: gso_test_func ok 1 no_gso ok 2 linear ok 3 frags ok 4 frags_pure ok 5 gso_partial ok 6 frag_list ok 7 frag_list_pure ok 8 frag_list_non_uniform ok 9 frag_list_head_frag ok 10 frag_list_no_head_frag ok 11 gso_by_frags ok 12 resegment ok 13 resegment_multi ok 14 resegment_tail ok 15 resegment_one_mss # gso_test_func: pass:15 fail:0 skip:0 total:15 Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Cc: Willem de Bruijn <willemb@google.com> Reviewed-by: Willem de Bruijn <willemb@google.com> Link: https://patch.msgid.link/20261015151033.591439-1-daniel@iogearbox.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysipv6: account route exceptions to the netns of their dstEric Dumazet
rt6_insert_exception() and rt6_remove_exception() update rt6_stats->fib_rt_cache of dev_net(rt6i->dst.dev), but the device of an exception dst can move to another netns while the exception is still in its bucket. This happens when the bucket is flushed from an RCU callback, for instance from nexthop_free_rcu() for the nh_info of a replaced nexthop, whose exceptions still point to live routes. If the device moves to another netns before that callback runs, the decrement hits the other netns, whose u32 counter underflows in /proc/net/rt6_stats, while the counter of the original netns never goes back down. Account exceptions to the netns their dst was allocated in, derived from dst->ops as ip6_dst_gc() already does, which does not depend on the device. The dst already relies on that netns' ip6_dst_ops being alive when it is destroyed, which happens after the exception is removed. Fixes: 81eb8447daae ("ipv6: take care of rt6_stats") Signed-off-by: Eric Dumazet <edumazet@kernel.org> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20261016091556.2750902-1-edumazet@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysnet: devmem: allow peer-to-peer dma-buf attach for bindingsErfan Sharafzadeh
net_devmem_bind_dmabuf() uses dma_buf_attach(), a static attachment with peer2peer false. Exporters must then keep the buffer reachable without P2P; amdgpu does so by placing it in GTT (system memory), so a device memory binding silently ends up in host memory. Use dma_buf_dynamic_attach() with allow_peer2peer set, so an exporter that can do P2P to the device keeps the buffer in device memory. Dynamic attachments are not pinned on map, and devmem cannot handle the buffer moving, so: - pin it with dma_buf_pin() before mapping, which keeps it in place for the lifetime of the binding, as before; - wait for the exporter's kernel fences after mapping, interruptibly, as the core does for static attachments. This follows the pinned RDMA umem path, including its limits: the binding cannot be revoked by the exporter, and once a P2P binding has pinned a buffer in device memory, a later attachment to the same buffer that cannot do P2P may fail to pin it. Exporters that cannot do P2P to the device place the buffer as before. RX and TX bindings both go through this function. Signed-off-by: Erfan Sharafzadeh <erfansh@meta.com> Acked-by: Stanislav Fomichev <sdf@fomichev.me> Link: https://patch.msgid.link/20261013210954.2170175-1-erfansh@meta.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysbridge: mcast: Delete empty MDB entry when port group creation failsIdo Schimmel
When a port group cannot be created for a new group, the MDB entry that was created for it is left with no ports and is not joined by the host. Its timer is never armed, so the entry is never deleted, but it is counted towards mcast_hash_max. When this maximum is reached, the bridge disables multicast snooping. Since commit b57e8d870d52 ("net: bridge: Maintain number of MDB entries in net_bridge_mcast_port"), port group creation also fails when the port reached its mcast_max_groups limit. A host behind such a port can therefore disable snooping by sending reports for new groups, which is what the limit is meant to prevent. The RTM_NEWMDB path has the same problem. Fix by deleting the entry after a failure if it is unused. Delete it immediately rather than arming its timer, so that it stops counting towards the maximum right away. Fixes: b57e8d870d52 ("net: bridge: Maintain number of MDB entries in net_bridge_mcast_port") Reported-by: Yunlong Ma <yunlong_ma@buaa.edu.cn> Closes: https://lore.kernel.org/netdev/2f5b61e2.1e71a.1a11fcb3809.Coremail.yunlong_ma@buaa.edu.cn/ Acked-by: Nikolay Aleksandrov <nikolay@nvidia.com> Signed-off-by: Ido Schimmel <idosch@nvidia.com> Tested-by: Gabriel Goller <g.goller@proxmox.com> Reviewed-by: Gabriel Goller <g.goller@proxmox.com> Link: https://patch.msgid.link/20261016101407.2030133-2-idosch@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysnet/sched: act_api: report an oversized action dump instead of silently ↵Jamal Hadi Salim
truncating it The issue: tcf_dump_walker() trims the half-built nest and returns the number of actions dumped so far as soon as one action does not fit. When the action at the current index cannot be serialized even into an *empty* dump skb, that count is zero, so tc_dump_action() returns skb->len (zero) and netlink sends NLMSG_DONE with no error: "tc actions ls" silently drops that action and every action after it. That case is reachable inside the gate entry cap this series adds: a gate entry serializes to 36 bytes (40 with the gate-open flag) while a dump skb is clamped to SKB_WITH_OVERHEAD(32768) by netlink_recvmsg()/netlink_dump(), so the top of the range the cap admits installs but cannot be dumped - and, before this change, fails silently. The Fix: tcf_dump_walker() already has to distinguish the two cases: a walk that filled the skb before completing the current action must keep returning a positive count so netlink retries that action in a fresh skb, while an action that cannot be serialized even into an empty skb must return -EMSGSIZE. So return n_i when anything was dumped and -EMSGSIZE (with an extack) when nothing was, and let tc_dump_action() propagate the walker's error code instead of overwriting it with skb->len. That mirrors tc_dump_tfilter(), which returns the walker error when a retry made no progress (if (skb->len == 0 && err) return err;), and tc_dump_chain() carries the same idiom. This is netlink's documented contract: -EMSGSIZE with data in the skb means "more to dump", -EMSGSIZE with an empty skb is delivered to user space. Context note: The shared nla_put_failure label stamps -EMSGSIZE for any inner tcf_action_dump_1()/terse failure, not only a size failure, consistent with how every other nla_put_failure label in the file reports; the -EMSGSIZE the action dump now returns is therefore not a strict size assertion. The cap stays a memory bound; this only makes an action the cap admits but the dump buffer cannot carry fail loudly instead of silently truncating the list. This is a long-standing silent failure, not a regression, so it is net-next hardening. Reported-by: Paul Moses <p@1g4.org> Closes: https://lore.kernel.org/netdev/vPFrhbkwAui8zFPcGQTUDazQfsFDlr5GYuaYQ5BxJcrDiT6x1EljEze4cYadHqbeUW2ivLdpa8eC_cXC6ceACswgb-lW47aSVkHvHjhn_X8=@1g4.org/ Suggested-by: Paul Moses <p@1g4.org> Reviewed-by: Victor Nogueira <victor@mojatatu.com> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Link: https://patch.msgid.link/QDISC-H19Z.v3.r0.20261012193813-5@mojatatu.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysnet/sched: sch_taprio: cap the number of schedule entriesJamal Hadi Salim
parse_sched_list() accepts _any number_ of TCA_TAPRIO_SCHED_ENTRY elements. The only bound is the enclosing nlattr u16 nla_len. A minimal accepted entry is 12 bytes (the entry nest plus TCA_TAPRIO_SCHED_ENTRY_INTERVAL), so that u16 admits roughly 5460 entries - protocol-bounded amplification, not truly unbounded, but far past any hardware schedule. The bug: Each entry is a separate sched_entry allocation (368 bytes, rounded up to the kmalloc-512 bucket) and, in full offload, is also composed into a per-entry offload array, so the largest representable minimal list pins roughly 2.7 MiB for the lifetime of the schedule. Some context: The schedule list is not dumped the way the gate action list is: a taprio dump is bounded by the carrying skb (the 32K dump skb, and NLMSG_GOODSIZE for notify and unicast get), which keeps the plain nla_nest_end() closes from ever seeing a wrapped length. But the input-side amplification is the same class as the act_gate entry list, and the offload interface composes every supplied entry into the hardware schedule table without a capacity check. The top of the accepted band cannot be read back: a schedule above roughly 900 entries does not fit the 32K dump skb, so "tc qdisc show" fails loudly with -EMSGSIZE for it (as the action-dump patch does). The pre-existing silent gaps - no change notification above about 100 entries, and no unicast get reply - are tracked separately. The Cap: Cap the list at 1024 entries. This matches the SJA1105 schedule-table capacity (SJA1110 provides 4096) and the act_gate entry cap, and keeps the list inside the current 16-bit TLV format. This is an operational cap on a configuration the uAPI accepted before, so it is net-next hardening; a stable backport would start rejecting taprio configurations that install today. Conditions to recreate the bug: CAP_NET_ADMIN with CONFIG_NET_SCH_TAPRIO=y. Install a taprio qdisc with more than 1024 minimal TCA_TAPRIO_SCHED_ENTRY elements over a raw netlink RTM_NEWQDISC request. The cap rejects the list with -E2BIG and an extack naming the limit; 1024 entries install. Reviewed-by: Victor Nogueira <victor@mojatatu.com> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Link: https://patch.msgid.link/QDISC-H19Z.v3.r0.20261012193813-4@mojatatu.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysnet/sched: act_gate: cap the number of scheduling entriesJamal Hadi Salim
parse_gate_list() accepts _any number_ of TCA_GATE_ONE_ENTRY elements. The only bound/cap is the enclosing nlattr u16 nla_len (~5460 minimal 12-byte entries). Each entry is a separate GFP_ATOMIC allocation, and the dump of a large list grows one action's reply well past NLMSG_GOODSIZE. The bugs: 1. A single gate can make tcf_dump_walker() silently truncate "tc actions ls" ("net/sched: act_api: report an oversized action dump instead of silently truncating it" makes such an action report -EMSGSIZE instead of dropping the rest of the list). 2. Lack of capping pins memory for as long as the action lives: the largest representable minimal list is roughly 5460 entries, each a separate GFP_ATOMIC allocation, with a per-entry offload array on top in full offload. The held-reply RTM_GETACTION amplification demonstrated in the original posting of this series (Link below) is a generic netlink property this cap does not remove; the bound added here is the install-side pin. So we need to provide an upper bound cap of TCA_GATE_ONE_ENTRY elements. Some context: The gate action offloads through FLOW_ACTION_GATE. The offload interface passes the priority, base time, cycle time, cycle-time extension, the complete entry count and an array holding each entry's gate state, interval, IPV and maximum-octet value. The in-tree SJA1105 DSA driver forwards that complete list to sja1105_vl_gate() without any entry cap check, and composes every supplied entry into the hardware schedule table. Act gate challenges: SJA1105 and SJA1110 are two device families in the one sja1105 driver. They expose different schedule-table capacities: SJA1105 provides up to 1024 schedule entries and SJA1110 up to 4096. These are total table capacities shared with other schedules, so they are upper bounds, not a guaranteed per-action budget. Software gate actions with _a lot more_ entries install and serialize today, so a low cap would reject working configurations and would look like a UAPI breakage; but an infinite size of entries is a bogus choice; a 65-entry configuration was verified during this work to install and dump well-formed. Netlink Challenges: Netlink attributes record their total size, including the four-byte header, in a 16-bit nla_len, so a nested attribute can describe at most 65532 bytes. A minimal accepted input entry is 12 bytes, which puts the max we can fit at roughly 5460 entries; a dumped entry occupies 36 bytes, or 40 bytes when it carries the gate-open flag. 1024 entries therefore serialize to 36868-40964 bytes, which fits inside one nested attribute, while a 4096-entry schedule would need roughly 144-160 KiB which _cannot fit_ at the moment due to the 16bit length. Note: This represents challenges primarily with netlink. The Cap: Cap the list at 1024 entries. This value is based on the existing SJA1105 schedule-table capacity and preserves the verified 65-entry configuration while providing a substantial headroom, and keeps the complete gate list inside the current 16-bit TLV format. It deliberately declines to expose SJA1110's 1025-4096 range through an interface that cannot serialize it, and deliberately rejects software-only schedules above 1024. Why 1024 despite the dump budget: 1024 is a SJA1105 schedule-table capacity, not a dump-budget value. The kernel clamps a dump skb to SKB_WITH_OVERHEAD(32768), so only ~800-890 entries of this list fit "tc actions ls"; the top of the admitted band therefore installs but is not listed. That is accepted deliberately: a unicast RTM_GETACTION reply is pre-sized from the action's advertised size (budgeted per entry since the parent fix), so "tc actions get" enumerates the whole band, and "net/sched: act_api: report an oversized action dump instead of silently truncating it" makes the list view fail loudly with -EMSGSIZE and an extack rather than silently truncating. A filter whose action list contains such a gate also stops "tc filter show" for that chain with -EMSGSIZE (loud), through tc_dump_tfilter()'s no-progress path. This is an operational cap on a configuration the uAPI accepted before, so it is net-next hardening; if we made this a stable backport then it would start rejecting gate configurations that install today (even though those settings would be totally bogus). Conditions to recreate the bug: CAP_NET_ADMIN with CONFIG_NET_ACT_GATE=y. Install a gate action with 1025 or more minimal TCA_GATE_ONE_ENTRY elements over a raw netlink RTM_NEWACTION request. The cap rejects the list with -E2BIG and an extack naming the limit; 1024 entries install and an indexed RTM_GETACTION returns a well-formed reply. Link: https://lore.kernel.org/netdev/QDISC-H19Z.v1.20261001053234@mojatatu.com/ Reviewed-by: Victor Nogueira <victor@mojatatu.com> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Link: https://patch.msgid.link/QDISC-H19Z.v3.r0.20261012193813-3@mojatatu.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysnet/sched: act_api: keep an add that created its actions from failingJamal Hadi Salim
Spotted while fixing the dump sizing reported by Sashiko. This references commit cfa165cbfbed ("net/sched: act_gate: budget the per-entry list in get_fill_size"), which is only one way to trigger the issue. The issue: tcf_action_add() returns the result of tcf_add_notify(), so an RTM_NEWACTION is reported back to user space as a failure when the event notification cannot be built, even though tcf_action_init() has already inserted the actions into the idr. The realistic trigger is an action list whose TCA_ACT_TAB exceeds a u16 nest (the notification can never be built), or a memory-pressure -ENOBUFS from the notification's alloc_skb(). The Fix: Drop the notification failure on the add path: the created actions stay installed and the add reports success, with an extack noting that the event notification could not be sent. The extack is set on a successful ack, so iproute2 reports it as a warning; it replaces any warning tcf_action_init() left there. This needs no idr/refcount audit - tca_put_bound_many() already runs unconditionally after the notification, so this path releases exactly what the success path does and only the returned result changes. A create that ignores a notification failure is already the filter-side norm: tc_new_tfilter() does not look at tfilter_notify()'s result. This is net-next hardening: it corrects the reported result of an add that already took effect, not a regression. Conditions to recreate the bug: CONFIG_NET_CLS_ACT=y; CONFIG_NET_ACT_GATE=y. Send an RTM_NEWACTION whose actions create an aggregate TCA_ACT_TAB larger than a u16 nest, so the notification cannot be built; before this change the add reports -EINVAL although the actions were installed, after it the add reports success and the actions are present. Reported-by: Sashiko (nipa) <sashiko-bot@kernel.org> Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260824153903.4143642-1-victor@mojatatu.com Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/QDISC-H19Z.v2.20261007062551%40mojatatu.com Reviewed-by: Victor Nogueira <victor@mojatatu.com> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Link: https://patch.msgid.link/QDISC-H19Z.v3.r0.20261012193813-2@mojatatu.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysnet/sched: act_gate: reject oversized dumps instead of wrapping themJamal Hadi Salim
This is a followup of commit cfa165cbfbed ("net/sched: act_gate: budget the per-entry list in get_fill_size") as reported by Sashiko. The issue: An action dump is carried inside nested netlink attributes whose lengths are u16. A gate action with enough schedule entries produces a dump larger than U16_MAX, and the plain nla_nest_end() closes by writing a wrapped length: the reply is structurally corrupt. On a CONFIG_DEBUG_NET kernel a plain nla_nest_end() also warns (DEBUG_NET_WARN_ON_ONCE warns once per call site), which an unprivileged RTM_GETACTION or RTM_GETTFILTER can reach once the action or filter exists. The oversized dump also reaches the filter notification path through tcf_fill_node(), which reports the failure as -EMSGSIZE. tfilter_notify_prep() treats that as socket-buffer exhaustion and retries with an ever larger alloc_skb(); a dump that does not fit a u16 nest cannot be built at any skb size, so the loop only spins until the allocation itself fails. The Fix: Close every wrap-capable nest an action dump travels in with nla_nest_end_safe(), which reports -EMSGSIZE before writing a wrapped length: TCA_GATE_ENTRY_LIST, TCA_ACT_OPTIONS, the per-action nest and TCA_ACT_TAB; the shared action and police containers in tcf_exts_dump()/tcf_exts_terse_dump(); and the caller-owned TCA_OPTIONS of every action-capable classifier (flower, matchall, basic, bpf, cgroup, flow, fw, route4, u32). The output is byte identical for every message that serializes. Bound the tfilter_notify_prep() retry once the skb is already larger than any valid message, while a regular dump that only needs a bigger skb still retries. The retry bound and the checked closes are one change: it is nla_nest_end_safe() that turns an unrepresentable dump into -EMSGSIZE, so a backport has to take both together if either is taken. Context note: A delete notification that cannot be built must not veto the state change the caller asked for. Two delete paths built the notification before the state change and propagated the build failure. tfilter_del_notify() builds the filter's delete notification before calling ->delete(), so a filter whose dump cannot be represented in a u16 nest could be created but never removed by "tc filter del ... handle H" - and only when a notification was actually needed (rtnl_notify_needed(): an RTNLGRP_TC listener or NLM_F_ECHO), which made it intermittent. tcf_del_notify() has the same shape for RTM_DELACTION: it builds the notification before tcf_action_delete(), so an action list whose TCA_ACT_TAB exceeds a u16 nest could not be deleted either. In both cases drop the unbuildable notification instead: on -EMSGSIZE the delete proceeds. This needs tca_get_fill() and tcf_del_notify_msg() to pass -EMSGSIZE up instead of collapsing it to -1/-EINVAL, and tca_get_fill() reports any inner tcf_action_dump() failure as -EMSGSIZE too (tcf_gate_dump() and tcf_action_dump_1() return plain -1 after one of their checked closes fails), so a single oversized action's delete is not vetoed either. On the delete paths the rule is scoped to notification BUILD failures: a delivery failure after the state change (rtnetlink_send() failing once ->delete() has already committed) still reports an error to the caller, as it did before this series. The extack that notes a dropped filter event is set only after ->delete() has returned 0. -EMSGSIZE here is the general tcf_fill_node() outcome for any ->dump() that does not fit, not only a u16 nest overflow; the effect of the new branch is limited to dropping a best-effort notification. why net-next? This is hardening rather than a regression fix: the enclosing action and filter-path nests have wrapped since the actions and classifiers allowed large entry lists - TCA_ACT_TAB is core act_api and the filter-side container predates the act_gate sizing change. A plain nla_nest_end() has always written the wrapped length at U16_MAX; this stops the corruption at the abstraction boundary instead of imposing a new policy limit on accepted gate schedules. A separate patch caps the entry list itself. Conditions to recreate the bug: CONFIG_NET_CLS_ACT=y; CONFIG_NET_ACT_GATE=y; CONFIG_NET_CLS_MATCHALL=y and/or CONFIG_NET_CLS_BASIC=y. Create a matchall or basic filter on an ingress/clsact qdisc whose action list holds two gate actions of 1024 minimal TCA_GATE_ONE_ENTRY elements each (TCA_ACT_MAX_PRIO admits up to 32 actions); the aggregate TCA_ACT_TAB nest is ~74.3 KiB > 65532 and wraps, then RTM_GETTFILTER it (or trigger the notify with NLM_F_ECHO). The same shape as two standalone gate actions is hit on the action path by RTM_DELACTION with NLM_F_ECHO; before this change the fill fails and the delete is refused, after it the actions are removed and only the notification is dropped. For a single action the outermost TCA_ACT_TAB wraps from 1815 entries (1821 for the innermost TCA_GATE_ENTRY_LIST); on the filter path the outermost wrap-capable nest is the classifier's TCA_OPTIONS. Installing needs CAP_NET_ADMIN in a user namespace; the RTM_GETTFILTER trigger needs no capability once it exists. The two-action shape survives the per-action cap added by "net/sched: act_gate: cap the number of scheduling entries": the enclosing nests overflow from aggregate action size, which no per-action cap can bound. Reported-by: Sashiko (nipa) <sashiko-bot@kernel.org> Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260824153903.4143642-1-victor@mojatatu.com Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/QDISC-H19Z.v2.20261007062551%40mojatatu.com Link: https://lore.kernel.org/netdev/QDISC-H19Z.v2.20261007062551@mojatatu.com/ Link: https://lore.kernel.org/netdev/QDISC-H19Z.v1.20261001053234@mojatatu.com/ Link: https://lore.kernel.org/netdev/179111893181.434549.13449660670267048994@kernel.org/ Reviewed-by: Victor Nogueira <victor@mojatatu.com> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Link: https://patch.msgid.link/QDISC-H19Z.v3.r0.20261012193813-1@mojatatu.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daystls: device: protect async RX resync state during device-downRishikesh Jethwani
tls_device_rx_resync_new_rec() can run in process context with the socket lock held, but without an RCU read lock: from the strparser work item (tls_strp_work()) and from the receive paths (tls_rx_rec_wait(), tls_rx_rec_done()). The resync_async pointer belongs to the driver RX context, which tls_device_down() tears down from the netdev notifier without taking the socket lock; only the softirq entry to the parser is implicitly inside an RCU section. If the parser passes the TLS_RX_DEV_DEGRADED check before device-down sets it, tls_device_down() can complete synchronize_net() and delete the driver context before the parser accesses resync_async->req or its record log. In the asynchronous stage the parser also writes the record log, so this is a write to freed memory, not only a stale read. The RCU section in tls_device_resync_rx() starts after those accesses and therefore does not prevent the use-after-free. Found by code inspection; not reproduced. Hitting the window requires the parser to be preempted between the DEGRADED check and the resync_async access across the device-down grace period and the driver's teardown. Fixes: ed9b7646b06a ("net/tls: Add asynchronous resync") Signed-off-by: Rishikesh Jethwani <rjethwani@purestorage.com> Link: https://patch.msgid.link/20261013213517.2219663-1-rjethwani@purestorage.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daystcp: tcp_metrics: use the socket netns, not the dst device netnsEric Dumazet
tcp_get_metrics(), __tcp_get_metrics_req() and tcpm_new() look up and create metrics entries in the netns of the cached dst device rather than in the netns of the socket. These usually match, but not after the device has been moved to another netns or unregistered: a socket can keep a stale dst in sk_dst_cache until it is checked again, and tcp_update_metrics() reads it with __sk_dst_get() without any dst_check(). Once dst_dev_put() has run, the dst device is blackhole_netdev and the entry is created in init_net. Before that, for instance for routes through nexthop objects whose cached dsts are released from a nested RCU callback, it is the netns the device has just been moved to. A TCP socket of netns A that enters TIME_WAIT in that window then creates or updates an entry carrying A's addresses and RTT in another netns, where TCP_METRICS_CMD_GET can dump it and where new connections to the same peer inherit those metrics. The metrics belong to the netns of the socket, so use sock_net() for full sockets and request sockets, and pass it to tcpm_new(). Kernel sockets that do not hold a netns reference can still reach tcp_time_wait() after tcp_net_metrics_exit_batch() has flushed the entries of their dismantling netns, and an entry created then would never be flushed and would keep a dangling tcpm_net. Make tcpm_new() refuse to create entries when check_net() fails. Its callers are in an RCU read-side section, and cleanup_net() waits for a grace period between the refcount reaching zero and the flush, so an entry added after a successful check is always seen by the flush. Fixes: 51c5d0c4b169 ("tcp: Maintain dynamic metrics in local cache.") Signed-off-by: Eric Dumazet <edumazet@kernel.org> Cc: Qiliang Yuan <odys.yuan@gmail.com> Reviewed-by: Neal Cardwell <ncardwell@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20261016084802.2725187-1-edumazet@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysipv6: do not restart DAD for a dead ifaddrDaehyeon Ko
addrconf_dad_failure() can create a stable-privacy replacement without RTNL. After ipv6_add_addr() publishes it, addrconf_ifdown() can mark the new ifaddr DEAD, clear its route, and unlink it before the recovery path takes ifp2->lock. The recovery path then unconditionally changes the state back to PREDAD and queues delayed DAD work. The MTU teardown path can leave IF_READY set. For an optimistic address, addrconf_dad_begin() can consequently pass the cleared NULL route to ip6_ins_rt(). This follow-on was found by source review and was not separately triggered at runtime. The new ifaddr is already initialized in PREDAD. Under ifp2->lock, record the retry and queue DAD only if teardown has not changed the state to DEAD. If teardown wins after this check, the work observes DEAD and exits without reviving the address. This complements the existing lock_errdad check that preserves the original ifaddr's DEAD state after the same function reacquires its lock. Fixes: 5f40ef77adb2 ("ipv6: do retries on stable privacy addresses") Cc: stable@vger.kernel.org Reported-by: Sashiko <netdev-bot+sashiko@kernel.org> Closes: https://lore.kernel.org/r/179161099408.434549.14449036924552933828@kernel.org Link: https://lore.kernel.org/r/20260513025509.3776405-1-lilinmao@kylinos.cn Signed-off-by: Daehyeon Ko <4ncienth@gmail.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20261015050651.1841557-5-4ncienth@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysipv6: initialize temporary ifaddr before publicationDaehyeon Ko
ipv6_create_tempaddr() holds a reference to the public ifaddr, publishes the new temporary address through ipv6_add_addr(), and only then stores the reference and final timestamps. addrconf_ifdown() can remove the temporary address before ifpub is stored, leaking the public ifaddr reference. Publishing ifpub alone is insufficient: manage_tempaddrs() can then find the object before cstamp and tstamp are final, update its lifetimes, and have the constructor overwrite its timestamp with an older value. This follow-on was found by source review and was not separately triggered at runtime. Pass the public ifaddr and both timestamps in ifa6_config. Initialize all three fields before adding the temporary address to either the hash or per-device lists. On success the existing public-ifaddr reference transfers to the temporary object. On error it remains owned and released by ipv6_create_tempaddr(). Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Reported-by: Sashiko <netdev-bot+sashiko@kernel.org> Closes: https://lore.kernel.org/r/179122559913.434549.12720841717630168470@kernel.org Link: https://lore.kernel.org/r/179161099665.434549.5858601179492551889@kernel.org Link: https://lore.kernel.org/r/20261007164548.GA1153540@shredder Link: https://lore.kernel.org/r/20261012145240.GA779501@shredder Suggested-by: Ido Schimmel <idosch@nvidia.com> Signed-off-by: Daehyeon Ko <4ncienth@gmail.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20261015050651.1841557-4-4ncienth@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysipv6: serialize address publication with device teardownDaehyeon Ko
ipv6_add_addr() checks idev state before allocating an ifaddr, but publishes the object later. addrconf_ifdown() can mark and detach the idev between the check and publication. This happens when a non-loopback device MTU falls below IPV6_MIN_MTU. A forced interleaving published an address on a dead idev, and ipv6_get_ifaddr() still returned it after teardown. Later device deletion remained blocked with: unregister_netdevice: waiting for ac0 to become free. Usage count = 3 Protect the dead indication with idev->lock and keep that lock across both hash and device-list publication. Recheck dead before publishing; if teardown wins the lock, reject the unpublished object. Non-unregister teardown does not set dead. The preceding change covers an add that misses the initial hash scan but reaches the per-device list snapshot. Both changes are required when backporting this fix. Fixes: 8814c4b53381 ("[IPV6] ADDRCONF: Convert addrconf_lock to RCU.") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/179161099408.434549.14449036924552933828@kernel.org Link: https://lore.kernel.org/r/20261012145306.GB779501@shredder Suggested-by: Ido Schimmel <idosch@nvidia.com> Signed-off-by: Daehyeon Ko <4ncienth@gmail.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20261015050651.1841557-3-4ncienth@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysipv6: remove ifaddr from hash during ifdown list cleanupDaehyeon Ko
addrconf_ifdown() clears the address hash before snapshotting the per-device address list. A concurrent ipv6_add_addr() can publish an address after the hash scan and before the list snapshot. The ifdown path then removes the address from the device list and drops the list-owned reference while it is still linked in the hash. Once the remaining references are released, inet6_ifa_finish_destroy() warns, but a DEAD address continues to kfree_rcu(). The hash therefore points to freed memory that later RCU walkers can dereference. This follow-on was found by source review and was not separately triggered at runtime. Remove each non-kept address from the hash immediately before removing it from the per-device list. Keeping it hashed through the delete notification blocks same-address publication until NETDEV_DOWN has been delivered. hlist_del_init_rcu() is safe when the earlier hash scan already removed the address. This handles a late publisher captured by the list snapshot. The next change serializes publication with teardown so an add cannot miss both observations. Both changes are required when backporting the complete fix. Fixes: 73a8bd74e261 ("ipv6: Revert 'administrative down' address handling changes.") Cc: stable@vger.kernel.org Reported-by: Ido Schimmel <idosch@nvidia.com> Link: https://lore.kernel.org/r/20261004135117.GA206930@shredder Link: https://lore.kernel.org/r/179161099539.434549.2238120015372268173@kernel.org Suggested-by: Ido Schimmel <idosch@nvidia.com> Signed-off-by: Daehyeon Ko <4ncienth@gmail.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20261015050651.1841557-2-4ncienth@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysneighbour: Floor neigh_periodic_work() interval at 1s.Kuniyuki Iwashima
neigh_periodic_work() reschedules tbl->gc_work with a delay of BASE_REACHABLE_TIME >> 1. neigh_table is now per-netns, and a user could hog CPU by setting BASE_REACHABLE_TIME to a small value. Unlike INTERVAL_PROBE_TIME_MS, BASE_REACHABLE_TIME is also used to compute reachable_time for NUD_REACHABLE entries. Let's floor only the GC interval at 1 second. Suggested-by: Ido Schimmel <idosch@nvidia.com> Link: https://lore.kernel.org/netdev/20260902143023.GA3966681@shredder/ Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20261013205816.1642597-6-kuniyu@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysneighbour: Floor INTERVAL_PROBE_TIME_MS at 1000.Kuniyuki Iwashima
Previously, neigh_managed_work() was not rescheduled within 1s since commit ed6cd6a17896 ("net, neigh: Set lower cap for neigh_managed_work rearming"). Later, commit 211da42eaa45 ("net, neigh: introduce interval_probe_time_ms for periodic probe") added INTERVAL_PROBE_TIME_MS and changed the limit to 1ms. The limit actually did not work but was fixed with netlink_range_validation by commit 6d79b223ec44 ("neighbour: Enforce min/max to NDTPA_INTERVAL_PROBE_TIME_MS."). neigh_table is now per-netns, and a user could hog CPU by setting INTERVAL_PROBE_TIME_MS to a small value. Let's floor the value at 1 second. This is a user-visible change, but given we had the 1s floor before and the default is 5s, it is unlikely that anyone but syzbot is setting it below 1s and affected by this change. Suggested-by: Ido Schimmel <idosch@nvidia.com> Link: https://lore.kernel.org/netdev/20260902143023.GA3966681@shredder/ Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20261013205816.1642597-5-kuniyu@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysneighbour: Schedule neigh_managed_work only when needed.Kuniyuki Iwashima
neigh_table is now per-netns. tbl->managed_work is scheduled when netns is created and runs periodically even though the netns does not have any NTF_MANAGED entries. Let's delay scheduling the work for the first NTF_MANAGED entry and stop rescheduling if tbl->managed_list is empty. Suggested-by: Ido Schimmel <idosch@nvidia.com> Link: https://lore.kernel.org/netdev/20260902143023.GA3966681@shredder/ Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20261013205816.1642597-4-kuniyu@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysnet: openvswitch: drop IP fragments on SCTP set actionFernando Fernandez Mancera
The SCTP checksum is a CRC32c over the whole SCTP packet. set_sctp() updates it as old_csum ^ old_correct_csum ^ new_csum, with the two CRCs computed over the bytes of the current skb only. That is correct only when the skb holds the whole SCTP packet. For a first fragment, and for a later fragment, it holds just a part of it, and the CRC delta of a change at the start of the packet depends on how many bytes follow, so the checksum written is wrong. The receiver drops the reassembled packet. validate_set() accepts SCTP set action for any flow with ip.proto set to SCTP, regardless of the fragmentation bits, as it only receives the masked key. As the checksum cannot be fixed up without the whole datagram, fail the action for packets that are IP fragments of either family, so the packet is dropped with OVS_DROP_ACTION_ERROR instead of being forwarded with modified ports and an invalid checksum. Link: https://lore.kernel.org/netdev/d4fc14f3-4308-4560-9012-43c09c1b3845@ovn.org/ Fixes: a175a723301a ("openvswitch: Add SCTP support") Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de> Reviewed-by: Ilya Maximets <i.maximets@ovn.org> Link: https://patch.msgid.link/20261015124749.4694-2-fmancera@suse.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysnet: openvswitch: skip IPv4 later fragments on TCP/UDP set actionsFernando Fernandez Mancera
An IPv4 later fragment carries no L4 header, but key extraction leaves ip.proto set to the real protocol and the flow may wildcard the frag field, so validate_set() accepts such packets. set_tcp() and set_udp() then treat the first bytes of the fragment payload as an L4 header, rewrite them as ports and patch the bytes at the checksum offset, corrupting the packet. Skip these actions for OVS_FRAG_TYPE_LATER. IPv6 later fragments are not affected, since their ip.proto is NEXTHDR_FRAGMENT and validate_set() rejects L4 set actions for them. Fixes: ccb1352e76cf ("net: Add Open vSwitch kernel components.") Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de> Reviewed-by: Ilya Maximets <i.maximets@ovn.org> Link: https://patch.msgid.link/20261015124749.4694-1-fmancera@suse.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysnet: rename skb_unshare() to skb_unclone_full()Nicolai Buchwitz
skb_unshare() only copies cloned skbs. A shared skb that is not a clone comes back unchanged, which the name doesn't suggest. The loopback selftest hooks got caught by this and hit BUG_ON(skb_shared()). Rename it to skb_unclone_full(). Like skb_unclone() it only acts on clones, but it copies the whole skb, not just the head. Suggested-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de> Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com> # dpaa2 Link: https://patch.msgid.link/20261015-nb-skb-unclone-full-v1-1-0dfbf01f60f2@tipi-net.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
6 daysrtnetlink: comment the RCU waits in unregister pathsAndrea Parri
rtnl_unregister_all() and rtnl_af_unregister() wait for RCU readers before tearing down what those readers use, but do not say which readers they are waiting for. A missing wait is then easy to overlook: rtnl_link_unregister() lacked its synchronize_rcu() until commit 3b70edea393d ("rtnetlink: wait for RCU readers in rtnl_link_unregister()"). Add a comment to both waits, naming the readers each one waits for. Suggested-by: Eric Dumazet <edumazet@kernel.org> Link: https://lore.kernel.org/CAL4WiioFMQN4troVjQjCmE6Z9kwwb95SnoEupjD=PPSK6Q5f6w@mail.gmail.com Assisted-by: LLM Signed-off-by: Andrea Parri <parri.andrea@gmail.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20261015081723.404990-1-parri.andrea@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>