Thread (4 messages) flat view 4 messages, 2 authors, 7d ago
COOLING7d

[PATCH net] udp: resubmit encap packets for secondary mcast sockets

From: Mariano Baragiola <hidden>
Date: 2026-09-18 15:36:11
Also in: lkml
Subsystem: networking [general], the rest, user datagram protocol (udp) · Maintainers: "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds, Willem de Bruijn

Multicast delivery clones packets for listeners after the first one.
Commit 3cb8d4b9bfeb ("udp: fix encapsulation packet resubmit in multicast
deliver") fixed encapsulation packet resubmission for the primary
listener by propagating positive return values from udp_queue_rcv_skb()
to the outer IP layer. However, it left the loop over secondary matching
sockets unchanged.

When an encapsulation receive handler requests protocol resubmission for
a clone (ret > 0), the secondary delivery loop currently calls
consume_skb(nskb), silently dropping the packet.

Resubmit cloned IPv4 and IPv6 packets directly to the returned protocol
via ip_protocol_deliver_rcu() and ip6_protocol_deliver_rcu(..., true),
matching the ownership and resubmission conventions used in the
segmented GSO paths.

Fixes: 3cb8d4b9bfeb ("udp: fix encapsulation packet resubmit in multicast deliver")
Signed-off-by: Mariano Baragiola <redacted>
---
 net/ipv4/udp.c | 5 +++--
 net/ipv6/udp.c | 5 +++--
 2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index bb8cfc62cb00..d79be57854e3 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2522,8 +2522,9 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
 			__UDP_INC_STATS(net, UDP_MIB_INERRORS);
 			continue;
 		}
-		if (udp_queue_rcv_skb(sk, nskb) > 0)
-			consume_skb(nskb);
+		ret = udp_queue_rcv_skb(sk, nskb);
+		if (ret > 0)
+			ip_protocol_deliver_rcu(net, nskb, ret);
 	}
 
 	/* Also lookup *:port if we are using hash2 and haven't done so yet. */
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 93478d1ad576..ca8d0a1844d2 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1001,8 +1001,9 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
 			continue;
 		}
 
-		if (udpv6_queue_rcv_skb(sk, nskb) > 0)
-			consume_skb(nskb);
+		ret = udpv6_queue_rcv_skb(sk, nskb);
+		if (ret > 0)
+			ip6_protocol_deliver_rcu(net, nskb, ret, true);
 	}
 
 	/* Also lookup *:port if we are using hash2 and haven't done so yet. */
-- 
2.55.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help