* Re: [RFC PATCH net-next v2 1/2] tcp: Add net.ipv4.tcp_purge_receive_queue sysctl
From: Leon Hwang @ 2026-07-16 4:47 UTC (permalink / raw)
To: Eric Dumazet
Cc: netdev, David S . Miller, Jakub Kicinski, Paolo Abeni,
Simon Horman, Jonathan Corbet, Shuah Khan, Neal Cardwell,
Kuniyuki Iwashima, Ido Schimmel, Ilpo Järvinen,
Chia-Yu Chang, Yung Chih Su, Wyatt Feng, Jason Xing, Lance Yang,
Jiayuan Chen, linux-doc, linux-kernel, linux-kselftest
In-Reply-To: <CANn89iLyeAPNV2VHTM3w0-zpzjZNFy3aJDsVUERYyniLN4ub7A@mail.gmail.com>
On 15/7/26 23:15, Eric Dumazet wrote:
> On Wed, Jul 15, 2026 at 4:54 PM Leon Hwang <leon.hwang@linux.dev> wrote:
[...]
>
> My thoughts are:
>
> out_of_order_queue has been forgotten. skbs could be there and still
> 'block devmem'
Yes. The tp->out_of_order_queue should also be purged here so that
out-of-order SKBs cannot continue holding devmem.
>
> WRITE_ONCE(tp->copied_seq, tp->rcv_nxt) is certainly wrong, because
> read() will return 0, instead of -1 (errno = EPIPE or ECONNRESET)
> So the application will not know a RST was received :/
Thanks for pointing this out. When sysctl_tcp_purge_receive_queue is
enabled, read() must report the reset error.
The reason read() returns 0 is that SOCK_DONE, which was set when the
FIN was processed, is checked before sk_err in tcp_recvmsg_locked(). I
think clearing SOCK_DONE after purging the queues could let read()
observes the error installed by tcp_done_with_error().
Will also update the packetdrill test to expect -1/EPIPE.
>
> I think that BSD and linux implementations have historically retained
> acknowledged,
> buffered receive data upon RST to allow applications to drain data
> already ACKed prior to the reset.
Agreed. The new sysctl is disabled by default specifically to preserve
this existing behavior.
Enabling it is an explicit opt-in to discard buffered receive data,
release the associated resources promptly, and report the reset error
immediately.
Will update the change in ip-sysctl.rst documentation with this
application-visible tradeoff.
>
> Adding a narrow sysctl specifically for CLOSE_WAIT creates
> inconsistent behavior across TCP states.
My bad. After reading the RFC 9293 section 3.10.7.4. [1] again, "All
segment queues should be flushed." should apply to these states:
- ESTABLISHED STATE
- FIN-WAIT-1 STATE
- FIN-WAIT-2 STATE
- CLOSE-WAIT STATE
So, the sysctl-controlled purge should be consistently applied to these
four states.
[1] https://www.rfc-editor.org/rfc/rfc9293.html#section-3.10.7.4
Thanks,
Leon
^ permalink raw reply
* Re: [PATCH iproute2-next] ipmaddr: use RTM_GETMULTICAST to list multicast addresses
From: Yuyang Huang @ 2026-07-16 4:16 UTC (permalink / raw)
To: David Ahern; +Cc: netdev
In-Reply-To: <01009484-2a68-4b44-b742-bee13bbb08b2@kernel.org>
On Thu, Jul 16, 2026 at 12:03 AM David Ahern <dsahern@kernel.org> wrote:
>
> On 7/10/26 9:07 PM, Yuyang Huang wrote:
> > +static int accept_maddr(struct nlmsghdr *n, void *arg)
> > +{
> > + struct maddr_dump_ctx *ctx = arg;
> > + struct ifaddrmsg *ifm = NLMSG_DATA(n);
> > + int len = n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifm));
> > + struct rtattr *tb[IFA_MAX + 1];
> > + struct ma_info *ma;
> > +
> > + if (n->nlmsg_type != RTM_GETMULTICAST &&
> > + n->nlmsg_type != RTM_NEWMULTICAST)
> > + return 0;
>
> From claude (and I agree with the finding)
>
> > +static int accept_maddr(struct nlmsghdr *n, void *arg)
> > +{
> > ...
> > + if (n->nlmsg_type != RTM_GETMULTICAST &&
> > + n->nlmsg_type != RTM_NEWMULTICAST)
> > + return 0;
>
> The kernel replies to a RTM_GETMULTICAST dump request with
> RTM_NEWMULTICAST messages — it never sends RTM_GETMULTICAST in a
> response. Including RTM_GETMULTICAST in the guard is dead code and is
> confusing; it inverts the usual convention used everywhere else in
> iproute2 (e.g. ipaddress.c always checks RTM_NEW* / RTM_DEL*, never
> RTM_GET*).
>
> Should be:
>
> if (n->nlmsg_type != RTM_NEWMULTICAST)
> return 0;
>
>
Thanks for the code review, I will fix this in patch v2.
Thanks,
Yuyang
^ permalink raw reply
* [PATCH v2] virtio_net: fix infinite loop in virtnet_poll_cleantx when device is broken
From: Jinqian Yang @ 2026-07-16 3:52 UTC (permalink / raw)
To: mst, jasowang, xuanzhuo, eperezma, andrew+netdev, davem, edumazet,
kuba, pabeni
Cc: netdev, virtualization, linux-kernel, liuyonglong, wangzhou1,
linuxarm, Jinqian Yang
virtnet_poll_cleantx() contains a do-while loop that cleans up
transmitted TX buffers and calls virtqueue_enable_cb_delayed() to check
whether more buffers need processing. When the virtio backend stops
responding during guest reboot, used->idx is never updated, so
virtqueue_enable_cb_delayed() always returns false and the loop never
terminates. Then it will block reboot process, and the guest will hang.
The problem occurs during guest reboot under network traffic:
1. kernel_restart() -> device_shutdown() traverses the device list
2. virtio_dev_shutdown() calls virtio_break_device() which sets
vq->broken = true
3. virtio_dev_shutdown() then calls virtio_synchronize_cbs() to wait
for in-flight callbacks to complete
4. A virtio interrupt fires, softirq is deferred to ksoftirqd which
calls net_rx_action() -> virtnet_poll() -> virtnet_poll_cleantx()
5. virtnet_poll_cleantx() enters the do-while loop and never exits
because the QEMU backend has stopped updating used->idx, despite
vq->broken having been set to true in step 2.
Since the loop runs inside ksoftirqd (a SCHED_OTHER kthread), it is
visible to the scheduler and does not trigger a hard lockup. However,
the kthread never leaves the loop, so RCU detects it as a CPU stall
and reports it periodically. Meanwhile, the reboot process remains
blocked in device_shutdown() because virtio_dev_shutdown() cannot
complete its synchronization step, and the guest hangs permanently.
This can be reproduced on a guest with a virtio-net device: run iperf3
traffic in the guest, then trigger reboot. The reboot occasionally hangs
permanently with RCU stall on ksoftirqd.
Observed on ARM64 KVM guest:
CPU#1 RCU stall (ksoftirqd/1), repeated periodically:
virtqueue_enable_cb_delayed_split <- virtnet_poll <- __napi_poll <-
net_rx_action <- handle_softirqs <- run_ksoftirqd <-
smpboot_thread_fn <- kthread
Fix by adding a virtqueue_is_broken() check to the loop condition, so
that the loop exits immediately when the device is broken, allowing
the device shutdown to proceed.
Signed-off-by: Jinqian Yang <yangjinqian1@huawei.com>
---
Changes in v2:
- Moved vq->broken check to virtqueue_enable_cb_delayed().
v1: https://lore.kernel.org/lkml/20260713132025.703147-1-yangjinqian1@huawei.com/
---
drivers/virtio/virtio_ring.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index b438dc2ce1b8..5c169fbb418a 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -3233,6 +3233,14 @@ bool virtqueue_enable_cb_delayed(struct virtqueue *_vq)
{
struct vring_virtqueue *vq = to_vvq(_vq);
+ /*
+ * When the device is broken there is no point in polling used->idx,
+ * the backend will never update it. Return true to let callers
+ * exit their cleanup loops instead of spinning forever.
+ */
+ if (unlikely(vq->broken))
+ return true;
+
if (vq->event_triggered)
data_race(vq->event_triggered = false);
--
2.33.0
^ permalink raw reply related
* [PATCH] vhost-vdpa: reject zero-size unmap
From: Weimin Xiong @ 2026-07-16 3:02 UTC (permalink / raw)
To: virtualization; +Cc: mst, jasowangio, eperezma, netdev, kvm, xiongweimin
From: xiongweimin <xiongweimin@kylinos.cn>
Reject unmap requests with size == 0 to prevent iova + size - 1
from underflowing to U64_MAX, which would incorrectly unmap the
entire IOTLB range.
This fix also covers the error rollback path in vhost_vdpa_va_map:
when the first VMA lookup fails, map_iova equals iova, resulting
in a zero-size unmap that would otherwise clear the whole IOTLB.
Signed-off-by: xiongweimin <xiongweimin@kylinos.cn>
---
drivers/vhost/vdpa.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index bb96b1aa5..f49bf1cfb 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -1035,6 +1035,9 @@ static void vhost_vdpa_unmap(struct vhost_vdpa *v,
const struct vdpa_config_ops *ops = vdpa->config;
u32 asid = iotlb_to_asid(iotlb);
+ if (!size)
+ return;
+
vhost_vdpa_iotlb_unmap(v, iotlb, iova, iova + size - 1, asid);
if (ops->set_map) {
--
2.39.3
^ permalink raw reply related
* [PATCH] vhost-vdpa: propagate set_map error to caller
From: Weimin Xiong @ 2026-07-16 3:02 UTC (permalink / raw)
To: virtualization; +Cc: mst, jasowangio, eperezma, netdev, kvm, xiongweimin
From: xiongweimin <xiongweimin@kylinos.cn>
The return value of ops->set_map() is currently ignored when handling
VHOST_IOTLB_BATCH_END. If the backend fails to program the IOTLB,
the VMM incorrectly believes the operation succeeded and may continue
with stale or incorrect mappings.
Save and propagate the error from ops->set_map() in BATCH_END.
Signed-off-by: xiongweimin <xiongweimin@kylinos.cn>
---
drivers/vhost/vdpa.c | 6 +++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index bb96b1aa5..ffbb10a92 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -1297,8 +1297,10 @@ static int vhost_vdpa_process_iotlb_msg(struct vhost_dev *dev, u32 asid,
v->in_batch = true;
break;
case VHOST_IOTLB_BATCH_END:
- if (v->in_batch && ops->set_map)
- ops->set_map(vdpa, asid, iotlb);
+ if (v->in_batch && ops->set_map) {
+ r = ops->set_map(vdpa, asid, iotlb);
+ break;
+ }
v->in_batch = false;
break;
default:
--
2.39.3
^ permalink raw reply related
* [PATCH] vhost: reject zero-size IOTLB INVALIDATE
From: Weimin Xiong @ 2026-07-16 3:02 UTC (permalink / raw)
To: virtualization; +Cc: mst, jasowangio, eperezma, netdev, kvm, xiongweimin
From: xiongweimin <xiongweimin@kylinos.cn>
Reject VHOST_IOTLB_INVALIDATE messages with size == 0 to prevent
iova + size - 1 from underflowing to U64_MAX, which would
incorrectly delete the entire IOTLB.
Signed-off-by: xiongweimin <xiongweimin@kylinos.cn>
---
drivers/vhost/vhost.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 3c080c454e374cabd7321416ed92c5f7d3135254..xxxxxxxxxx 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -1656,6 +1656,10 @@ static int vhost_process_iotlb_msg(struct vhost_dev *dev, u32 asid,
if (!dev->iotlb) {
ret = -EFAULT;
break;
+ }
+ if (!msg->size) {
+ ret = -EINVAL;
+ break;
}
vhost_vq_meta_reset(dev);
vhost_iotlb_del_range(dev->iotlb, msg->iova,
--
2.39.3
^ permalink raw reply
* [PATCH] vhost-vdpa: propagate set_map error to caller
From: Weimin Xiong @ 2026-07-16 3:00 UTC (permalink / raw)
To: virtualization; +Cc: mst, jasowangio, eperezma, netdev, xiongweimin
From: xiongweimin <xiongweimin@kylinos.cn>
The return value of ops->set_map() is currently ignored when handling
VHOST_IOTLB_BATCH_END. If the backend fails to program the IOTLB,
the VMM incorrectly believes the operation succeeded and may continue
with stale or incorrect mappings.
Save and propagate the error from ops->set_map() in BATCH_END.
Signed-off-by: xiongweimin <xiongweimin@kylinos.cn>
---
drivers/vhost/vdpa.c | 6 +++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index bb96b1aa5..ffbb10a92 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -1297,8 +1297,10 @@ static int vhost_vdpa_process_iotlb_msg(struct vhost_dev *dev, u32 asid,
v->in_batch = true;
break;
case VHOST_IOTLB_BATCH_END:
- if (v->in_batch && ops->set_map)
- ops->set_map(vdpa, asid, iotlb);
+ if (v->in_batch && ops->set_map) {
+ r = ops->set_map(vdpa, asid, iotlb);
+ break;
+ }
v->in_batch = false;
break;
default:
--
2.39.3
^ permalink raw reply related
* [PATCH] vhost-vdpa: reject zero-size unmap
From: Weimin Xiong @ 2026-07-16 3:00 UTC (permalink / raw)
To: virtualization; +Cc: mst, jasowangio, eperezma, netdev, xiongweimin
From: xiongweimin <xiongweimin@kylinos.cn>
Reject unmap requests with size == 0 to prevent iova + size - 1
from underflowing to U64_MAX, which would incorrectly unmap the
entire IOTLB range.
This fix also covers the error rollback path in vhost_vdpa_va_map:
when the first VMA lookup fails, map_iova equals iova, resulting
in a zero-size unmap that would otherwise clear the whole IOTLB.
Signed-off-by: xiongweimin <xiongweimin@kylinos.cn>
---
drivers/vhost/vdpa.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index bb96b1aa5..f49bf1cfb 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -1035,6 +1035,9 @@ static void vhost_vdpa_unmap(struct vhost_vdpa *v,
const struct vdpa_config_ops *ops = vdpa->config;
u32 asid = iotlb_to_asid(iotlb);
+ if (!size)
+ return;
+
vhost_vdpa_iotlb_unmap(v, iotlb, iova, iova + size - 1, asid);
if (ops->set_map) {
--
2.39.3
^ permalink raw reply related
* [PATCH] vhost: reject zero-size IOTLB INVALIDATE
From: Weimin Xiong @ 2026-07-16 3:00 UTC (permalink / raw)
To: virtualization; +Cc: mst, jasowangio, eperezma, netdev, xiongweimin
From: xiongweimin <xiongweimin@kylinos.cn>
Reject VHOST_IOTLB_INVALIDATE messages with size == 0 to prevent
iova + size - 1 from underflowing to U64_MAX, which would
incorrectly delete the entire IOTLB.
Signed-off-by: xiongweimin <xiongweimin@kylinos.cn>
---
drivers/vhost/vhost.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 3c080c454e374cabd7321416ed92c5f7d3135254..xxxxxxxxxx 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -1656,6 +1656,10 @@ static int vhost_process_iotlb_msg(struct vhost_dev *dev, u32 asid,
if (!dev->iotlb) {
ret = -EFAULT;
break;
+ }
+ if (!msg->size) {
+ ret = -EINVAL;
+ break;
}
vhost_vq_meta_reset(dev);
vhost_iotlb_del_range(dev->iotlb, msg->iova,
--
2.39.3
^ permalink raw reply
* [PATCH net v6] tipc: serialize udp bearer replicast list updates
From: Weiming Shi @ 2026-07-16 2:52 UTC (permalink / raw)
To: Jon Maloy, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman
Cc: netdev, tipc-discussion, linux-kernel, Tung Nguyen, xmei5,
Weiming Shi
tipc_udp_rcast_add() and cleanup_bearer() both update ub->rcast.list with
list_add_rcu() / list_del_rcu(), but nothing serializes them. The add runs
from the encap receive softirq (via tipc_udp_rcast_disc()) without
rtnl_lock(), so it can race the cleanup delete and corrupt the list:
list_del corruption. prev->next should be ffff8880298d7ab8,
but was ffff88802449ad38. (prev=ffff888027e3ec98)
kernel BUG at lib/list_debug.c:62!
RIP: __list_del_entry_valid_or_report+0x17a/0x200
Workqueue: events cleanup_bearer
Call Trace:
cleanup_bearer (net/tipc/udp_media.c:811)
process_one_work (kernel/workqueue.c:3302)
worker_thread (kernel/workqueue.c:3466)
The bearer can be enabled from an unprivileged user namespace, as the
TIPCv2 generic-netlink ops carry no GENL_ADMIN_PERM.
Add a spinlock to struct udp_bearer and take it around the list_add_rcu()
in tipc_udp_rcast_add() and the list_del_rcu() loop in cleanup_bearer() so
the two writers can no longer corrupt the list.
Reject a duplicate peer under the same lock before allocating, and remove
tipc_udp_is_known_peer(). The old lockless pre-check in
tipc_udp_rcast_disc() was racy: two softirqs discovering the same peer
could both find it absent and add it twice.
cleanup_bearer() runs from a workqueue after tipc_udp_disable() clears the
bearer's up bit, so an encap softirq can still reach tipc_udp_rcast_add()
and add a peer after cleanup_bearer() has already emptied the list, leaking
that entry when the bearer is freed. Mark the bearer disabled under
rcast_lock once the list is emptied and refuse further additions.
Fixes: ef20cd4dd163 ("tipc: introduce UDP replicast")
Reported-by: Xiang Mei <xmei5@asu.edu>
Suggested-by: Tung Nguyen <tung.quang.nguyen@est.tech>
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
---
v6:
- Add the missing kernel-doc for udp_bearer::disabled to fix a W=1 build
warning reported by the kernel test robot.
v5: (per Tung's review)
- Mark the bearer disabled under rcast_lock in cleanup_bearer() and reject
further tipc_udp_rcast_add() so an encap softirq can't add a peer after
the list has been emptied, which would leak it.
v4:
- Reject a duplicate under rcast_lock before allocating rcast.
v3:
- Do the duplicate check in tipc_udp_rcast_add() under rcast_lock and
remove tipc_udp_is_known_peer().
v2:
- Narrow the lock to the list mutation.
net/tipc/udp_media.c | 56 +++++++++++++++++++++-----------------------
1 file changed, 27 insertions(+), 29 deletions(-)
diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
index 62ae7f5b5..230645cc0 100644
--- a/net/tipc/udp_media.c
+++ b/net/tipc/udp_media.c
@@ -94,6 +94,8 @@ struct udp_replicast {
* @ifindex: local address scope
* @work: used to schedule deferred work on a bearer
* @rcast: associated udp_replicast container
+ * @rcast_lock: serialize updates to @rcast.list against concurrent updaters
+ * @disabled: bearer is being torn down; reject further @rcast.list additions
*/
struct udp_bearer {
struct tipc_bearer __rcu *bearer;
@@ -101,6 +103,8 @@ struct udp_bearer {
u32 ifindex;
struct work_struct work;
struct udp_replicast rcast;
+ spinlock_t rcast_lock;
+ bool disabled;
};
static int tipc_udp_is_mcast_addr(struct udp_media_addr *addr)
@@ -278,26 +282,6 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
return err;
}
-static bool tipc_udp_is_known_peer(struct tipc_bearer *b,
- struct udp_media_addr *addr)
-{
- struct udp_replicast *rcast, *tmp;
- struct udp_bearer *ub;
-
- ub = rcu_dereference_rtnl(b->media_ptr);
- if (!ub) {
- pr_err_ratelimited("UDP bearer instance not found\n");
- return false;
- }
-
- list_for_each_entry_safe(rcast, tmp, &ub->rcast.list, list) {
- if (!memcmp(&rcast->addr, addr, sizeof(struct udp_media_addr)))
- return true;
- }
-
- return false;
-}
-
static int tipc_udp_rcast_add(struct tipc_bearer *b,
struct udp_media_addr *addr)
{
@@ -308,16 +292,34 @@ static int tipc_udp_rcast_add(struct tipc_bearer *b,
if (!ub)
return -ENODEV;
+ spin_lock_bh(&ub->rcast_lock);
+ if (ub->disabled) {
+ spin_unlock_bh(&ub->rcast_lock);
+ return 0;
+ }
+ list_for_each_entry(rcast, &ub->rcast.list, list) {
+ if (!memcmp(&rcast->addr, addr, sizeof(*addr))) {
+ spin_unlock_bh(&ub->rcast_lock);
+ return 0;
+ }
+ }
+
rcast = kmalloc_obj(*rcast, GFP_ATOMIC);
- if (!rcast)
+ if (!rcast) {
+ spin_unlock_bh(&ub->rcast_lock);
return -ENOMEM;
+ }
if (dst_cache_init(&rcast->dst_cache, GFP_ATOMIC)) {
+ spin_unlock_bh(&ub->rcast_lock);
kfree(rcast);
return -ENOMEM;
}
memcpy(&rcast->addr, addr, sizeof(struct udp_media_addr));
+ list_add_rcu(&rcast->list, &ub->rcast.list);
+ b->bcast_addr.broadcast = TIPC_REPLICAST_SUPPORT;
+ spin_unlock_bh(&ub->rcast_lock);
if (ntohs(addr->proto) == ETH_P_IP)
pr_info("New replicast peer: %pI4\n", &rcast->addr.ipv4);
@@ -325,8 +327,6 @@ static int tipc_udp_rcast_add(struct tipc_bearer *b,
else if (ntohs(addr->proto) == ETH_P_IPV6)
pr_info("New replicast peer: %pI6\n", &rcast->addr.ipv6);
#endif
- b->bcast_addr.broadcast = TIPC_REPLICAST_SUPPORT;
- list_add_rcu(&rcast->list, &ub->rcast.list);
return 0;
}
@@ -361,9 +361,6 @@ static int tipc_udp_rcast_disc(struct tipc_bearer *b, struct sk_buff *skb)
return 0;
}
- if (likely(tipc_udp_is_known_peer(b, &src)))
- return 0;
-
return tipc_udp_rcast_add(b, &src);
}
@@ -644,9 +641,6 @@ int tipc_udp_nl_bearer_add(struct tipc_bearer *b, struct nlattr *attr)
return -EINVAL;
}
- if (tipc_udp_is_known_peer(b, &addr))
- return 0;
-
return tipc_udp_rcast_add(b, &addr);
}
@@ -679,6 +673,7 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
return -ENOMEM;
INIT_LIST_HEAD(&ub->rcast.list);
+ spin_lock_init(&ub->rcast_lock);
if (!attrs[TIPC_NLA_BEARER_UDP_OPTS])
goto err;
@@ -819,10 +814,13 @@ static void cleanup_bearer(struct work_struct *work)
struct udp_replicast *rcast, *tmp;
struct tipc_net *tn;
+ spin_lock_bh(&ub->rcast_lock);
list_for_each_entry_safe(rcast, tmp, &ub->rcast.list, list) {
list_del_rcu(&rcast->list);
call_rcu_hurry(&rcast->rcu, rcast_free_rcu);
}
+ ub->disabled = true;
+ spin_unlock_bh(&ub->rcast_lock);
tn = tipc_net(sock_net(ub->sk));
--
2.43.0
^ permalink raw reply related
* [PATCH] ice: parser: use array_size() for table allocation
From: Weimin Xiong @ 2026-07-16 2:51 UTC (permalink / raw)
To: Tony Nguyen, Przemek Kitszel
Cc: intel-wired-lan, netdev, linux-kernel, Andrew Lunn,
David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Weimin Xiong
Use array_size() when calculating the parser table allocation size so an
overflow in the firmware-provided item dimensions is detected before
allocation. Include the overflow helpers explicitly instead of relying on
an indirect include.
Signed-off-by: Weimin Xiong <xiongwm2026@163.com>
---
diff --git a/drivers/net/ethernet/intel/ice/ice_parser.c b/drivers/net/ethernet/intel/ice/ice_parser.c
index f8e69630f..c109d3c32 100644
--- a/drivers/net/ethernet/intel/ice/ice_parser.c
+++ b/drivers/net/ethernet/intel/ice/ice_parser.c
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2024 Intel Corporation */
+#include <linux/overflow.h>
+
#include "ice_common.h"
struct ice_pkg_sect_hdr {
@@ -102,7 +104,7 @@ ice_parser_create_table(struct ice_hw *hw, u32 sect_type,
if (!seg)
return ERR_PTR(-EINVAL);
- table = kzalloc(item_size * length, GFP_KERNEL);
+ table = kzalloc(array_size(item_size, length), GFP_KERNEL);
if (!table)
return ERR_PTR(-ENOMEM);
^ permalink raw reply related
* [PATCH] rds: use krealloc_array() for iovector growth
From: Weimin Xiong @ 2026-07-16 2:51 UTC (permalink / raw)
To: Allison Henderson
Cc: netdev, linux-rdma, rds-devel, linux-kernel, David S . Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
Weimin Xiong
Use krealloc_array() for growing the RDS iovector array. This makes the
array allocation overflow-safe and derives the element size from the
array pointer.
Signed-off-by: Weimin Xiong <xiongwm2026@163.com>
---
diff --git a/net/rds/send.c b/net/rds/send.c
index 68be1bf0e..6a567c97a 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -971,11 +971,8 @@ static int rds_rm_size(struct msghdr *msg, int num_sgs,
return -EINVAL;
if (vct->indx >= vct->len) {
vct->len += vct->incr;
- tmp_iov =
- krealloc(vct->vec,
- vct->len *
- sizeof(struct rds_iov_vector),
- GFP_KERNEL);
+ tmp_iov = krealloc_array(vct->vec, vct->len,
+ sizeof(*vct->vec), GFP_KERNEL);
if (!tmp_iov) {
vct->len -= vct->incr;
return -ENOMEM;
^ permalink raw reply related
* [PATCH] unix: use kvmalloc_array() for BPF iterator batches
From: Weimin Xiong @ 2026-07-16 2:51 UTC (permalink / raw)
To: Kuniyuki Iwashima
Cc: netdev, linux-kernel, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Weimin Xiong
Use kvmalloc_array() instead of open-coding the element-size
multiplication when allocating the Unix-domain BPF iterator batch.
Signed-off-by: Weimin Xiong <xiongwm2026@163.com>
---
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index f7a9d55ee..6664ead46 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -3659,8 +3659,8 @@ static int bpf_iter_unix_realloc_batch(struct bpf_unix_iter_state *iter,
{
struct sock **new_batch;
- new_batch = kvmalloc(sizeof(*new_batch) * new_batch_sz,
- GFP_USER | __GFP_NOWARN);
+ new_batch = kvmalloc_array(new_batch_sz, sizeof(*new_batch),
+ GFP_USER | __GFP_NOWARN);
if (!new_batch)
return -ENOMEM;
^ permalink raw reply related
* [PATCH] tcp: use kvmalloc_array() for BPF iterator batches
From: Weimin Xiong @ 2026-07-16 2:51 UTC (permalink / raw)
To: Eric Dumazet, Neal Cardwell, Kuniyuki Iwashima
Cc: netdev, linux-kernel, David S . Miller, Jakub Kicinski,
Paolo Abeni, Simon Horman, Weimin Xiong
Use kvmalloc_array() instead of open-coding the element-size
multiplication when allocating the TCP BPF iterator batch.
Signed-off-by: Weimin Xiong <xiongwm2026@163.com>
---
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 209ef7522..d184893e5 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2926,8 +2926,8 @@ static int bpf_iter_tcp_realloc_batch(struct bpf_tcp_iter_state *iter,
{
union bpf_tcp_iter_batch_item *new_batch;
- new_batch = kvmalloc(sizeof(*new_batch) * new_batch_sz,
- flags | __GFP_NOWARN);
+ new_batch = kvmalloc_array(new_batch_sz, sizeof(*new_batch),
+ flags | __GFP_NOWARN);
if (!new_batch)
return -ENOMEM;
^ permalink raw reply related
* [PATCH net-next v4 4/4] net: stmmac: dwmac-socfpga: Add support for Agilex5 TSN GMAC with FPGA converter
From: muhammad.nazim.amirul.nazle.asmade @ 2026-07-16 2:19 UTC (permalink / raw)
To: dinguyen, maxime.chevallier
Cc: rmk+kernel, krzk+dt, conor+dt, robh, davem, edumazet, kuba,
pabeni, andrew+netdev, devicetree, linux-arm-kernel, netdev,
linux-kernel
In-Reply-To: <20260716021932.20037-1-muhammad.nazim.amirul.nazle.asmade@altera.com>
From: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
The Agilex5 SoCDK TSN Config2 board uses a GMII-to-RGMII converter
implemented as FPGA soft IP between gmac1 and its PHY. This converter
provides the RGMII TX/RX clock delays, so the MAC interface selector
must be configured for GMII while the PHY is configured without delays.
Add the "altr,socfpga-stmmac-agilex5-tsn" compatible to the match table
and detect it in probe to force GMII for the MAC interface selector and
strip the delay bits from phy_interface so the PHY is not configured to
add delays already provided by the FPGA converter.
Signed-off-by: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
v4: Add Reviewed-by from Andrew Lunn.
drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index 1d7f0a57d288..bf591a68502f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -69,12 +69,13 @@ struct socfpga_dwmac {
void __iomem *tse_pcs_base;
void __iomem *sgmii_adapter_base;
bool f2h_ptp_ref_clk;
+ phy_interface_t mac_interface;
const struct socfpga_dwmac_ops *ops;
};
static phy_interface_t socfpga_get_plat_phymode(struct socfpga_dwmac *dwmac)
{
- return dwmac->plat_dat->phy_interface;
+ return dwmac->mac_interface;
}
static void socfpga_sgmii_config(struct socfpga_dwmac *dwmac, bool enable)
@@ -650,6 +651,15 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
plat_dat->pcs_exit = socfpga_dwmac_pcs_exit;
plat_dat->select_pcs = socfpga_dwmac_select_pcs;
+ dwmac->mac_interface = plat_dat->phy_interface;
+
+ if (of_device_is_compatible(pdev->dev.of_node,
+ "altr,socfpga-stmmac-agilex5-tsn")) {
+ dwmac->mac_interface = PHY_INTERFACE_MODE_GMII;
+ if (phy_interface_mode_is_rgmii(plat_dat->phy_interface))
+ plat_dat->phy_interface = PHY_INTERFACE_MODE_RGMII;
+ }
+
ops->setup_plat_dat(dwmac);
return devm_stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res);
@@ -674,6 +684,7 @@ static const struct of_device_id socfpga_dwmac_match[] = {
{ .compatible = "altr,socfpga-stmmac", .data = &socfpga_gen5_ops },
{ .compatible = "altr,socfpga-stmmac-a10-s10", .data = &socfpga_gen10_ops },
{ .compatible = "altr,socfpga-stmmac-agilex5", .data = &socfpga_agilex5_ops },
+ { .compatible = "altr,socfpga-stmmac-agilex5-tsn", .data = &socfpga_agilex5_ops },
{ }
};
MODULE_DEVICE_TABLE(of, socfpga_dwmac_match);
--
2.43.7
^ permalink raw reply related
* [PATCH v4 3/4] dt-bindings: net: altr,socfpga-stmmac: Add altr,socfpga-stmmac-agilex5-tsn compatible
From: muhammad.nazim.amirul.nazle.asmade @ 2026-07-16 2:19 UTC (permalink / raw)
To: dinguyen, maxime.chevallier
Cc: rmk+kernel, krzk+dt, conor+dt, robh, davem, edumazet, kuba,
pabeni, andrew+netdev, devicetree, linux-arm-kernel, netdev,
linux-kernel
In-Reply-To: <20260716021932.20037-1-muhammad.nazim.amirul.nazle.asmade@altera.com>
From: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
The Agilex5 SoCDK TSN Config2 board uses a GMII-to-RGMII converter
implemented as FPGA soft IP between gmac1 and its PHY. This converter
provides the RGMII TX/RX clock delays. Document a new compatible string
for this MAC variant so the driver can detect it and configure the
interface accordingly.
Signed-off-by: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
---
v4: No changes from v2.
.../devicetree/bindings/net/altr,socfpga-stmmac.yaml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/altr,socfpga-stmmac.yaml b/Documentation/devicetree/bindings/net/altr,socfpga-stmmac.yaml
index 63084f762373..81f030986fa3 100644
--- a/Documentation/devicetree/bindings/net/altr,socfpga-stmmac.yaml
+++ b/Documentation/devicetree/bindings/net/altr,socfpga-stmmac.yaml
@@ -24,6 +24,7 @@ select:
- altr,socfpga-stmmac
- altr,socfpga-stmmac-a10-s10
- altr,socfpga-stmmac-agilex5
+ - altr,socfpga-stmmac-agilex5-tsn
required:
- compatible
@@ -46,6 +47,10 @@ properties:
- items:
- const: altr,socfpga-stmmac-agilex5
- const: snps,dwxgmac-2.10
+ - items:
+ - const: altr,socfpga-stmmac-agilex5-tsn
+ - const: altr,socfpga-stmmac-agilex5
+ - const: snps,dwxgmac-2.10
clocks:
minItems: 1
--
2.43.7
^ permalink raw reply related
* [PATCH v4 2/4] arm64: dts: socfpga: agilex5: Add SoCDK TSN Config2 board
From: muhammad.nazim.amirul.nazle.asmade @ 2026-07-16 2:19 UTC (permalink / raw)
To: dinguyen, maxime.chevallier
Cc: rmk+kernel, krzk+dt, conor+dt, robh, davem, edumazet, kuba,
pabeni, andrew+netdev, devicetree, linux-arm-kernel, netdev,
linux-kernel
In-Reply-To: <20260716021932.20037-1-muhammad.nazim.amirul.nazle.asmade@altera.com>
From: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
Add device tree for the Intel SoCFPGA Agilex5 SoCDK TSN Config2 board
variant. This configuration enables gmac1 as a TSN port alongside the
standard gmac2 Ethernet port.
The TSN port (gmac1) connects to its PHY through a GMII-to-RGMII
converter implemented as FPGA soft IP. This converter provides the
RGMII TX/RX clock delays, so phy-mode is set to "rgmii-id" to reflect
MAC-side delays. A board-specific compatible string is used so the
driver can detect the converter and strip the delay bits before
configuring the PHY.
Signed-off-by: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
---
v4: No changes from v2.
arch/arm64/boot/dts/intel/Makefile | 1 +
.../intel/socfpga_agilex5_socdk_tsn_cfg2.dts | 131 ++++++++++++++++++
2 files changed, 132 insertions(+)
create mode 100644 arch/arm64/boot/dts/intel/socfpga_agilex5_socdk_tsn_cfg2.dts
diff --git a/arch/arm64/boot/dts/intel/Makefile b/arch/arm64/boot/dts/intel/Makefile
index 270c70fdf084..ce7cf3a63275 100644
--- a/arch/arm64/boot/dts/intel/Makefile
+++ b/arch/arm64/boot/dts/intel/Makefile
@@ -8,6 +8,7 @@ dtb-$(CONFIG_ARCH_INTEL_SOCFPGA) += socfpga_agilex_n6000.dtb \
socfpga_agilex5_socdk_013b.dtb \
socfpga_agilex5_socdk_modular.dtb \
socfpga_agilex5_socdk_nand.dtb \
+ socfpga_agilex5_socdk_tsn_cfg2.dtb \
socfpga_agilex72_socdk.dtb \
socfpga_agilex7m_socdk.dtb \
socfpga_n5x_socdk.dtb
diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex5_socdk_tsn_cfg2.dts b/arch/arm64/boot/dts/intel/socfpga_agilex5_socdk_tsn_cfg2.dts
new file mode 100644
index 000000000000..bf13ccfc1faa
--- /dev/null
+++ b/arch/arm64/boot/dts/intel/socfpga_agilex5_socdk_tsn_cfg2.dts
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2026, Altera Corporation
+ */
+#include "socfpga_agilex5.dtsi"
+
+/ {
+ model = "SoCFPGA Agilex5 SoCDK TSN Config2";
+ compatible = "intel,socfpga-agilex5-socdk-tsn-cfg2", "intel,socfpga-agilex5";
+
+ aliases {
+ serial0 = &uart0;
+ ethernet1 = &gmac1;
+ ethernet2 = &gmac2;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ label = "hps_led0";
+ gpios = <&porta 11 GPIO_ACTIVE_HIGH>;
+ };
+
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ /* We expect the bootloader to fill in the reg */
+ reg = <0x0 0x80000000 0x0 0x0>;
+ };
+};
+
+&gpio0 {
+ status = "okay";
+};
+
+&gpio1 {
+ status = "okay";
+};
+
+&gmac1 {
+ status = "okay";
+ compatible = "altr,socfpga-stmmac-agilex5-tsn",
+ "altr,socfpga-stmmac-agilex5",
+ "snps,dwxgmac-2.10";
+ phy-mode = "rgmii-id";
+ phy-handle = <&emac1_phy0>;
+ max-frame-size = <9000>;
+
+ mdio0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dwmac-mdio";
+
+ emac1_phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+};
+
+&gmac2 {
+ status = "okay";
+ phy-mode = "rgmii-id";
+ phy-handle = <&emac2_phy0>;
+ max-frame-size = <9000>;
+
+ mdio0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dwmac-mdio";
+
+ emac2_phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+};
+
+&osc1 {
+ clock-frequency = <25000000>;
+};
+
+&qspi {
+ status = "okay";
+ flash@0 {
+ compatible = "micron,mt25qu02g", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <100000000>;
+ m25p,fast-read;
+ cdns,read-delay = <2>;
+ cdns,tshsl-ns = <50>;
+ cdns,tsd2d-ns = <50>;
+ cdns,tchsh-ns = <4>;
+ cdns,tslch-ns = <4>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ qspi_boot: partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x04200000>;
+ };
+
+ root: partition@4200000 {
+ label = "root";
+ reg = <0x04200000 0x0be00000>;
+ };
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+ disable-over-current;
+};
+
+&watchdog0 {
+ status = "okay";
+};
--
2.43.7
^ permalink raw reply related
* [PATCH v4 1/4] dt-bindings: arm: altera: Add Agilex5 SoCDK TSN Config2 board
From: muhammad.nazim.amirul.nazle.asmade @ 2026-07-16 2:19 UTC (permalink / raw)
To: dinguyen, maxime.chevallier
Cc: rmk+kernel, krzk+dt, conor+dt, robh, davem, edumazet, kuba,
pabeni, andrew+netdev, devicetree, linux-arm-kernel, netdev,
linux-kernel
In-Reply-To: <20260716021932.20037-1-muhammad.nazim.amirul.nazle.asmade@altera.com>
From: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
Add compatible string for the Intel SoCFPGA Agilex5 SoCDK TSN Config2
board variant. This board enables gmac1 as a TSN port with an FPGA
GMII-to-RGMII converter providing the RGMII clock delays.
Signed-off-by: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
v4: Fix wrong email address in Acked-by tag from Krzysztof Kozlowski.
v3: Add missing Acked-by from Krzysztof Kozlowski inadvertently dropped in v2.
v2: Replace mac-mode DT property with compatible string detection.
Use phy-mode = "rgmii-id" to reflect MAC-side delay handling.
Fix Makefile indentation.
Documentation/devicetree/bindings/arm/altera.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/arm/altera.yaml b/Documentation/devicetree/bindings/arm/altera.yaml
index 3030cf46fe74..e431469a7175 100644
--- a/Documentation/devicetree/bindings/arm/altera.yaml
+++ b/Documentation/devicetree/bindings/arm/altera.yaml
@@ -114,6 +114,7 @@ properties:
- intel,socfpga-agilex5-socdk-debug
- intel,socfpga-agilex5-socdk-modular
- intel,socfpga-agilex5-socdk-nand
+ - intel,socfpga-agilex5-socdk-tsn-cfg2
- const: intel,socfpga-agilex5
- description: Agilex72 boards
--
2.43.7
^ permalink raw reply related
* [PATCH v4 0/4] Add Agilex5 SoCDK TSN Config2 board support
From: muhammad.nazim.amirul.nazle.asmade @ 2026-07-16 2:19 UTC (permalink / raw)
To: dinguyen, maxime.chevallier
Cc: rmk+kernel, krzk+dt, conor+dt, robh, davem, edumazet, kuba,
pabeni, andrew+netdev, devicetree, linux-arm-kernel, netdev,
linux-kernel
From: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
This series adds support for the Intel SoCFPGA Agilex5 SoCDK TSN Config2
board variant, which enables gmac1 as a TSN Ethernet port alongside the
standard gmac2 port.
The TSN port (gmac1) connects to its PHY through a GMII-to-RGMII converter
implemented as FPGA soft IP. This converter provides the RGMII TX/RX clock
delays, requiring the MAC interface selector to be configured for GMII while
the PHY-facing interface is configured as RGMII without delay duplication.
This is handled by introducing a new compatible string
"altr,socfpga-stmmac-agilex5-tsn" detected in the driver probe to configure
the interface modes appropriately.
v4:
- Fix wrong email address in Acked-by tag from Krzysztof Kozlowski on patch 1.
- Add Reviewed-by from Andrew Lunn on patch 4.
v3:
- Add missing Acked-by from Krzysztof Kozlowski on patch 1, inadvertently
dropped in v2.
v2:
- Replace mac-mode DT property with compatible string-based detection per
Andrew Lunn's feedback.
- Use phy-mode = "rgmii-id" to correctly reflect MAC-side delay handling.
- Rename compatible string to altr,socfpga-stmmac-agilex5-tsn for
consistency with existing altr,socfpga-stmmac-* compatibles.
- Fix Makefile indentation reported by Krzysztof Kozlowski.
- Add DT binding documentation for new net compatible string (new patch).
Nazim Amirul (4):
dt-bindings: arm: altera: Add Agilex5 SoCDK TSN Config2 board
arm64: dts: socfpga: agilex5: Add SoCDK TSN Config2 board
dt-bindings: net: altr,socfpga-stmmac: Add
altr,socfpga-stmmac-agilex5-tsn compatible
net: stmmac: dwmac-socfpga: Add support for Agilex5 TSN GMAC with FPGA
converter
.../devicetree/bindings/arm/altera.yaml | 1 +
.../bindings/net/altr,socfpga-stmmac.yaml | 5 +
arch/arm64/boot/dts/intel/Makefile | 1 +
.../intel/socfpga_agilex5_socdk_tsn_cfg2.dts | 131 ++++++++++++++++++
.../ethernet/stmicro/stmmac/dwmac-socfpga.c | 13 +-
5 files changed, 150 insertions(+), 1 deletion(-)
create mode 100644 arch/arm64/boot/dts/intel/socfpga_agilex5_socdk_tsn_cfg2.dts
--
2.43.7
^ permalink raw reply
* [PATCH net] ipv4: icmp: fill flow parameters in icmp_route_lookup decoy lookup
From: Eric Dumazet @ 2026-07-16 2:10 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Ido Schimmel, David Ahern, netdev, eric.dumazet,
Eric Dumazet, Muhammad Ziad
When Linux forwards a packet and needs to generate an ICMP error,
icmp_route_lookup() performs a reverse-path relookup. For non-local
destinations, it performs a decoy lookup via ip_route_output_key() to
find the expected egress interface (rt2->dst.dev) before validating the
path with ip_route_input().
Currently, the decoy flow structure (fl4_2) only sets .daddr = fl4_dec.saddr,
leaving .saddr, .flowi4_dscp, .flowi4_proto, .flowi4_mark, and
.flowi4_uid zeroed out.
When policy routing rules (such as ip rule add from $SRC lookup 100, or
dscp/fwmark/ipproto rules) are configured:
1. ip_route_output_key() fails to match the policy rule because saddr and
other key flow selectors are missing in fl4_2.
2. It resolves a route using the default table instead, returning an incorrect
egress netdev.
3. Passing the wrong netdev to ip_route_input() causes strict reverse-path
filtering (rp_filter=1) to fail, logging false-positive "martian source"
warnings and causing the relookup to fail.
Fix this by populating fl4_2 with .saddr = fl4_dec.daddr, .flowi4_dscp,
.flowi4_proto = IPPROTO_ICMP, .flowi4_mark, and .flowi4_uid so that
ip_route_output_key() selects the correct egress interface matching policy
routing rules.
Fixes: 415b3334a21a ("icmp: Fix regression in nexthop resolution during replies.")
Reported-by: Muhammad Ziad <muhzi100@gmail.com>
Closes: https://lore.kernel.org/netdev/CAOAwikA60AYKdFr_UDLyja3oU4hqyAE7uFZWqum5uRdaQsgRYg@mail.gmail.com/
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/ipv4/icmp.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 23e921d313b36b00d8ae5e14846527220c9db32b..2259f643cb0d43ea54819dd831c79807413e0d69 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -548,10 +548,16 @@ static struct rtable *icmp_route_lookup(struct net *net, struct flowi4 *fl4,
if (IS_ERR(rt2))
err = PTR_ERR(rt2);
} else {
- struct flowi4 fl4_2 = {};
+ struct flowi4 fl4_2 = {
+ .daddr = fl4_dec.saddr,
+ .saddr = fl4_dec.daddr,
+ .flowi4_dscp = dscp,
+ .flowi4_proto = IPPROTO_ICMP,
+ .flowi4_mark = mark,
+ .flowi4_uid = sock_net_uid(net, NULL),
+ };
unsigned long orefdst;
- fl4_2.daddr = fl4_dec.saddr;
rt2 = ip_route_output_key(net, &fl4_2);
if (IS_ERR(rt2)) {
err = PTR_ERR(rt2);
--
2.55.0.141.g00534a21ce-goog
^ permalink raw reply related
* Re: [PATCH net-next v3] net: skb: isolate skb data area allocations into a separate bucket
From: Harry Yoo @ 2026-07-16 2:10 UTC (permalink / raw)
To: Pedro Falcato
Cc: Paolo Abeni, David S. Miller, Eric Dumazet, Jakub Kicinski,
Simon Horman, Jason Xing, Kuniyuki Iwashima, netdev, linux-kernel,
linux-hardening, Kees Cook, linux-mm, Vlastimil Babka
In-Reply-To: <aldpAY6nXwgayHL0@pedro-suse.lan>
[-- Attachment #1.1: Type: text/plain, Size: 2815 bytes --]
On 7/15/26 8:07 PM, Pedro Falcato wrote:
> On Wed, Jul 08, 2026 at 10:27:54PM +0900, Harry Yoo wrote:
>> On 7/8/26 8:16 PM, Pedro Falcato wrote:
>>> On Wed, Jul 08, 2026 at 10:30:50AM +0200, Paolo Abeni wrote:
>>>> On 7/2/26 7:07 PM, Pedro Falcato wrote:> @@ -586,6 +586,8 @@ struct
>>>> sk_buff *napi_build_skb(void *data, unsigned int frag_size)
>>>>> }
>>>>> EXPORT_SYMBOL(napi_build_skb);
>>>>>
>>>>> +static kmem_buckets *skb_data_buckets __ro_after_init;
>>>>> +
>>>>> static void *kmalloc_pfmemalloc(size_t obj_size, gfp_t flags, int node)
>>>>> {
>>>>> if (!gfp_pfmemalloc_allowed(flags))
>>>>> @@ -593,7 +595,8 @@ static void *kmalloc_pfmemalloc(size_t obj_size, gfp_t flags, int node)
>>>>> if (!obj_size)
>>>>> return kmem_cache_alloc_node(net_hotdata.skb_small_head_cache,
>>>>> flags, node);
>>>>> - return kmalloc_node_track_caller(obj_size, flags, node);
>>>>> + return kmem_buckets_alloc_node_track_caller(skb_data_buckets, obj_size,
>>>>> + flags, node);
>>>>
>>>> Sashiko noted that some drivers may require GFP_DMA buckets, and the
>>>> above may break them:
>>>>
>>>> https://sashiko.dev/#/patchset/20260702170728.168755-1-pfalcato%40suse.de
>>>
>>> Oh, this is really awkward. Adding linux-mm and slab maintainers for input here.
>>>
>>> Considering the current slab bucketing does not seem to duplicate DMA or
>>> CGROUP caches, could it make sense to duplicate those as well?
>>
>> Could we specify what kmalloc types the user needs when creating
>> kmem_buckets and duplicate caches for the requested kmalloc types only?
>
> Perhaps. But do the users themselves know? alloc_skb() allows users to specify
> random __GFP flags. We're bound to see some random caller do
> alloc_skb(__GFP_ACCOUNT) ;)
Other users don't expose the buckets to drivers, so I thought only
alloc_skb() would create the buckets for each kmalloc type.
> In all honesty, I'm not quite sure what the best way forward here is. The most
> transparent way is to bucket those other kmalloc types as well, but that might
> very trivially result in a lot more caches (and possibly memory usage) for no
> great reason. So perhaps specifying caches might do.
Another direction could be merging those buckets.
If we want to protect kmalloc objects from user-controllable
allocations, can we create buckets for each kmalloc type during the boot
process and let the kmem_buckets users share them?
That doesn't sound like creating too many kmalloc caches, while
providing a decent separation. We already have two buckets users,
one w/ SLAB_ACCOUNT and the other w/o SLAB_ACCOUNT.
If you really want each bucket to have a separate set of caches, you
have to sacrifice some memory for security :)
--
Cheers,
Harry / Hyeonggon
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: ipv4: icmp: icmp_route_lookup() relookups pick wrong netdev with policy routing + strict rp_filter
From: Eric Dumazet @ 2026-07-16 1:50 UTC (permalink / raw)
To: Muhammad Ziad
Cc: netdev, David Ahern, Jakub Kicinski, Paolo Abeni, David S. Miller,
linux-kernel
In-Reply-To: <CANn89iLizNO3MZ4jEfkMkLOhrJUzLW=xDocOHR_mUgb+5BycJw@mail.gmail.com>
On Wed, Jul 15, 2026 at 5:43 PM Eric Dumazet <edumazet@google.com> wrote:
>
> On Wed, Jul 15, 2026 at 5:30 PM Muhammad Ziad <muhzi100@gmail.com> wrote:
> >
> > Hello,
> >
> > There appears to be a bug in mainline Linux in ICMP reverse-path
> > relookup logic inside icmp_route_lookup() (called by __icmp_send())
> > when strict rp_filter setting is in place.
> >
> > When Linux forwards a packet between two interfaces and needs to
> > generate an ICMP error, icmp_route_lookup() performs a "secondary"
> > reverse-path lookup to find a suitable route back towards the original
> > source via ip_route_input(). To simulate the reverse path, the kernel
> > derives the incoming netdev by calling ip_route_output_key() with a
> > decoy flow that has *only* daddr assigned in it:
> >
> > struct flowi4 fl4_2 = {};
> > fl4_2.daddr = fl4_dec.saddr;
> > rt2 = ip_route_output_key(net, &fl4_2); /* no saddr */
> > ...
> > ip_route_input(skb_in, fl4_dec.daddr, fl4_dec.saddr,
> > dscp, rt2->dst.dev);
> >
> > This can lead to a mismatch between rt2->dst.dev and the netdev the
> > real reverse packet would use once routing policy rules are in
> > effect. With strict rp_filter, passing the wrong netdev to
> > ip_route_input() causes the relookup to fail and a "martian source"
> > message to be logged, after which icmp_route_lookup() falls back to
> > the earlier output route lookup (relookup_failed).
> >
> > In such a scenario, I would expect the relookup to use a canonical
> > netdev and the kernel to not produce spurious "martian source" log
> > messages as a result. This suggests the decoy flow would possibly
> > need to carry saddr too so that ip_route_output_key() is able to
> > resolve the right netdev.
> >
> > I tested this on: Ubuntu kernel 6.17.0-35-generic.
> >
> > Here is a reproducer script that sets up two net namespaces: a
> > "forwarder" with two routes to the same dst in separate routing tables
> > picked according to saddr, and a "sender" netns behind it which sends
> > a ping with ttl=1 via the forwarder forcing it to generate an ICMP
> > error as a response which leads to the result explained above:
> >
> > #!/bin/bash
> >
> > if [ "${forwarder_ns:-}" != "1" ]; then
> > exec env forwarder_ns=1 unshare -Urn bash "$0" "$@"
> > fi
> >
> > SRC=10.0.1.2
> > DST=198.51.100.5
> >
> > # Current netns is the "forwarder".
> > # Create a second namespace for the sender.
> > unshare -n sleep 120 &
> > cpid=$!
> > trap 'kill "$cpid" 2>/dev/null || true' EXIT
> > in_ns() { nsenter -t "$cpid" -n "$@"; }
> >
> > # veth r0(router) <-> s0(src)
> > ip link add s0 type veth peer name r0
> > ip link set s0 netns "$cpid"
> > ip link set lo up
> > ip link set r0 up
> > ip addr add 10.0.1.1/24 dev r0
> > ip link add dumA type dummy
> > ip addr add 203.0.113.1/24 dev dumA
> > ip link set dumA up
> > ip link add dumB type dummy
> > ip addr add 192.0.2.1/24 dev dumB
> > ip link set dumB up
> >
> > sysctl -q -w net.ipv4.ip_forward=1
> > for c in all default r0 dumA dumB; do
> > sysctl -q -w "net.ipv4.conf.$c.rp_filter=1"
> > sysctl -q -w "net.ipv4.conf.$c.log_martians=1"
> > done
> >
> > # Destination reachable two ways.
> > # Policy rule diverts traffic FROM src to dumB
> > ip route add 198.51.100.0/24 dev dumA
> > ip route add 198.51.100.0/24 dev dumB table 100
> > ip rule add from "$SRC" lookup 100
> >
> > # sender namespace setup.
> > in_ns ip link set lo up
> > in_ns ip link set s0 up
> > in_ns ip addr add 10.0.1.2/24 dev s0
> > in_ns ip route add default via 10.0.1.1
> >
> > # This will trigger a "martian source" log.
> > in_ns ping -q -c1 -W2 -t1 "$DST" &>/dev/null
> >
> >
> > Happy to test patches or provide additional traces, if needed.
> >
> > Thank you,
> > Mohamed Ghazy
>
> Thanks for the report.
>
> It seems we are lacking more than saddr setting :/
>
> Could you test
>
> diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
> index 23e921d313b36b00d8ae5e14846527220c9db32b..6277e1bf85f304678ff167e8fd2b9239f155ce42
> 100644
> --- a/net/ipv4/icmp.c
> +++ b/net/ipv4/icmp.c
> @@ -548,10 +548,17 @@ static struct rtable *icmp_route_lookup(struct
> net *net, struct flowi4 *fl4,
> if (IS_ERR(rt2))
> err = PTR_ERR(rt2);
> } else {
> - struct flowi4 fl4_2 = {};
> + /* TODO: populate
> + .flowi4_dscp = dscp,
> + .flowi4_mark = mark,
> + .flowi4_uid = sock_net_uid(net, NULL),
> + */
> + struct flowi4 fl4_2 = {
> + .daddr = fl4_dec.saddr,
> + .saddr = fl4_dec.daddr,
> + };
> unsigned long orefdst;
>
> - fl4_2.daddr = fl4_dec.saddr;
> rt2 = ip_route_output_key(net, &fl4_2);
> if (IS_ERR(rt2)) {
> err = PTR_ERR(rt2);
I have tested the following fix, PTAL, thanks.
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 23e921d313b36b00d8ae5e14846527220c9db32b..2259f643cb0d43ea54819dd831c79807413e0d69
100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -548,10 +548,16 @@ static struct rtable *icmp_route_lookup(struct
net *net, struct flowi4 *fl4,
if (IS_ERR(rt2))
err = PTR_ERR(rt2);
} else {
- struct flowi4 fl4_2 = {};
+ struct flowi4 fl4_2 = {
+ .daddr = fl4_dec.saddr,
+ .saddr = fl4_dec.daddr,
+ .flowi4_dscp = dscp,
+ .flowi4_proto = IPPROTO_ICMP,
+ .flowi4_mark = mark,
+ .flowi4_uid = sock_net_uid(net, NULL),
+ };
unsigned long orefdst;
- fl4_2.daddr = fl4_dec.saddr;
rt2 = ip_route_output_key(net, &fl4_2);
if (IS_ERR(rt2)) {
err = PTR_ERR(rt2);
^ permalink raw reply
* Re: [PATCH v7] net: gro: fix double aggregation of flush-marked skbs
From: Shiming Cheng (成诗明) @ 2026-07-16 1:41 UTC (permalink / raw)
To: linux-kernel@vger.kernel.org, dsahern@kernel.org,
imv4bel@gmail.com, linux-mediatek@lists.infradead.org,
alice@isovalent.com, daniel.zahka@gmail.com,
eilaimemedsnaimel@gmail.com, nbd@nbd.name, horms@kernel.org,
kuba@kernel.org, pabeni@redhat.com, edumazet@google.com,
willemdebruijn.kernel@gmail.com, willemb@google.com,
netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
matthias.bgg@gmail.com, davem@davemloft.net,
AngeloGioacchino Del Regno, sd@queasysnail.net
Cc: steffen.klassert@secunet.com, stable@vger.kernel.org,
Lena Wang (王娜)
In-Reply-To: <willemdebruijn.kernel.2801a1401793d@gmail.com>
Hello everyone,
it looks like this has been peeding for a while.
Is there anything else I need to do or follow up on ?
Thanks
On Wed, 2026-07-08 at 22:07 -0400, Willem de Bruijn wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>
>
> Reminder to mark patches [PATCH net v7]
>
> (or PATCH net-next when targeting that tree)
>
> Shiming Cheng wrote:
> > Commit 0ab03f353d36 ("net-gro: Fix GRO flush when receiving a GSO
> > packet.") added a flush check to skb_gro_receive(), but
> > skb_gro_receive_list() lacks the same validation.
> >
> > As a result, packets marked with NAPI_GRO_CB(skb)->flush may still
> > be
> > re-aggregated.
> >
> > This allows already-GRO'd packets with existing frag_list to be
> > re-aggregated into a new GRO session, corrupting the frag_list
> > chain
> > structure. When skb_segment() attempts to unpack these malformed
> > packets,
> > it encounters invalid state and triggers a kernel panic.
> >
> > Scenario (Tethering/Device forwarding):
> > 1. Driver: Generated aggregated packet P1 via LRO with frag_list
> > 2. Dev A: Receives aggregated fraglist packet and flush flag set
> > 3. Dev A: Re-enters GRO, skb_gro_receive_list() is called
> > 4. Missing flush check allows re-aggregation despite flush flag
> > 5. Frag_list chain becomes corrupted (loops or dangling refs)
> > 6. Dev B: TX path calls skb_segment(), crashes on corrupted
> > frag_list
> >
> > Root cause in skb_segment():
> > The check at line ~4891:
> > if (hsize <= 0 && i >= nfrags && skb_headlen(list_skb) &&
> > (skb_headlen(list_skb) == len || sg)) {
> >
> > When frag_list is corrupted by double aggregation, when list_skb
> > is
> > a NULL pointer from skb->next, skb_headlen(list_skb) dereference
> > NULL/corrupted pointers occurs.
> >
> > Call Trace:
> > skb_headlen(NULL skb)
> > skb_segment
> > tcp_gso_segment
> > tcp4_gso_segment
> > inet_gso_segment
> > skb_mac_gso_segment
> > __skb_gso_segment
> > skb_gso_segment
> > validate_xmit_skb
> > validate_xmit_skb_list
> > sch_direct_xmit
> > qdisc_restart
> > __qdisc_run
> > qdisc_run
> > net_tx_action
> >
> > Fix: Add NAPI_GRO_CB(skb)->flush validation to the early-return
> > check in
> > skb_gro_receive_list(), matching the defensive programming pattern
> > of
> > skb_gro_receive().
> >
> > Fixes: 3a1296a38d0c ("net: Support GRO/GSO fraglist chaining.")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Shiming Cheng <shiming.cheng@mediatek.com>
>
> Reviewed-by: Willem de Bruijn <willemb@google.com>
^ permalink raw reply
* Re: [PATCH v4 0/2] bpf, sockmap: handle spurious tcp_msg_wait_data() wakeup
From: Jiayuan Chen @ 2026-07-16 1:30 UTC (permalink / raw)
To: Nnamdi Onyeyiri, jiayuan.chen
Cc: bpf, davem, edumazet, horms, jakub, john.fastabend, kuba, kuniyu,
ncardwell, netdev, pabeni, sashiko-reviews
In-Reply-To: <20260715213538.37229-1-nnamdio@gmail.com>
On 7/16/26 5:35 AM, Nnamdi Onyeyiri wrote:
> Spurious wakeups in tcp_msg_wait_data() isn't being handled by
> tcp_bpf_recvmsg() and tcp_bpf_recvmsg_parser(), leading to unexpected
> EAGAIN errors returned by recvfrom()/recv(). Adding handling for the
> wakeup and a selftest.
>
> This issue was first discovered in an application that adds sockets to
> a sockmap as a way to view the received data. No redirects or any
> other operations are performed.
>
> Sashiko has noted a few other pre-existing issues in the same area
> (https://patch.msgid.link/20260714205118.17DB11F000E9@smtp.kernel.org)
> that can lead to EAGAIN in tcp_bpf_recvmsg() and
> tcp_bpf_recvmsg_parser(). A local run of Sashiko also identified a
> potential issue in tcp_bpf_recvmsg() handling zero-data FIN packets when
> the MSG_PEEK flag is set. To prevent this patchset from growing too
> large, I intend to submit follow up patches to address these once this
> one has been accepted.
>
> Changes in v2:
> - In tcp_bpf_recvmsg, handle signals and the socket closing in the loop.
> - Fix spurious wakeups when SO_RCVTIMEO has been set on the socket.
> - Link to v1: https://patch.msgid.link/ak_rR-Skd8Mvn4mH@localhost.localdomain
>
> Changes in v3:
> - Added the sockmap_recvfrom selftest.
> - Link to v2: https://patch.msgid.link/alFRK66z45eDNZA7@localhost.localdomain
>
> Changes in v4:
> - Fix potential data loss in tcp_bpf_recvmsg() when a FIN or RST has
> been received.
> - Check the return code of pthread_create() in the selftest.
> - Fix race caused by using EXPECT macros in a thread in selftest.
> - Link to v3: https://patch.msgid.link/20260714203927.32289-1-nnamdio@gmail.com
Please do not send a patch by replying to an old thread.
> Signed-off-by: Nnamdi Onyeyiri <nnamdio@gmail.com>
> ---
> Nnamdi Onyeyiri (2):
> bpf, sockmap: handle spurious tcp_msg_wait_data() wakeup
> bpf, sockmap: handle spurious tcp_msg_wait_data() wakeup
Please use a commit subject like "selftests/bpf: add selftest xxx" for
the selftest patch.
>
> net/ipv4/tcp_bpf.c | 69 +++-
> tools/testing/selftests/net/.gitignore | 2 +
> tools/testing/selftests/net/Makefile | 5 +
> .../selftests/net/sockmap_recvfrom.bpf.c | 31 ++
> .../testing/selftests/net/sockmap_recvfrom.c | 299 ++++++++++++++++++
Please use existing test frameworks such as sockmap_basic.c or
sockmap_strp.c.
^ permalink raw reply
* Re: [PATCH net v3] tun/tap & vhost-net: make qdisc backpressure opt-in via IFF_BACKPRESSURE
From: Oliver Sang @ 2026-07-16 1:22 UTC (permalink / raw)
To: Simon Schippers
Cc: oe-lkp, lkp, Brett Sheffield, netdev, linux-kernel, ltp,
Willem de Bruijn, Jason Wang, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Michael S . Tsirkin, Simon Horman,
Jonathan Corbet, Shuah Khan, Andrew Lunn, Tim Gebauer, linux-doc,
oliver.sang
In-Reply-To: <1ecf0eb8-17ef-4f9c-ba87-da69d207e4d4@tu-dortmund.de>
hi, Simon Schippers,
On Wed, Jul 15, 2026 at 04:32:26PM +0200, Simon Schippers wrote:
> On 7/15/26 16:01, kernel test robot wrote:
> >
> >
> > Hello,
> >
> > kernel test robot noticed "ltp.ioctl03.fail" on:
>
> ioctl03.c does not know about IFF_BACKPRESSURE which is introduced here,
> consequently it fails.
> See [1] where it compares TUN features with known_flags.
thanks a lot for information!
>
> Thanks.
>
> [1] Link: https://github.com/linux-test-project/ltp/blob/master/testcases/kernel/syscalls/ioctl/ioctl03.c#L82
>
[...]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox