mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 10:01:39 -05:00
net: preserve MSG_ZEROCOPY with forwarding
MSG_ZEROCOPY data must be copied before data is queued to local sockets, to avoid indefinite timeout until memory release. This test is performed by skb_orphan_frags_rx, which is called when looping an egress skb to packet sockets, error queue or ingress path. To preserve zerocopy for skbs that are looped to ingress but are then forwarded to an egress device rather than delivered locally, defer this last check until an skb enters the local IP receive path. This is analogous to existing behavior of skb_clear_delivery_time. Signed-off-by: Willem de Bruijn <willemb@google.com> Link: https://patch.msgid.link/20250630194312.1571410-2-willemdebruijn.kernel@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
04b1d18c5b
commit
d2527ad3a9
@@ -5937,8 +5937,6 @@ static int __netif_receive_skb_core(struct sk_buff **pskb, bool pfmemalloc,
|
||||
}
|
||||
|
||||
if (pt_prev) {
|
||||
if (unlikely(skb_orphan_frags_rx(skb, GFP_ATOMIC)))
|
||||
goto drop;
|
||||
*ppt_prev = pt_prev;
|
||||
} else {
|
||||
drop:
|
||||
|
||||
@@ -226,6 +226,12 @@ void ip_protocol_deliver_rcu(struct net *net, struct sk_buff *skb, int protocol)
|
||||
|
||||
static int ip_local_deliver_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
if (unlikely(skb_orphan_frags_rx(skb, GFP_ATOMIC))) {
|
||||
__IP_INC_STATS(net, IPSTATS_MIB_INDISCARDS);
|
||||
kfree_skb_reason(skb, SKB_DROP_REASON_NOMEM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
skb_clear_delivery_time(skb);
|
||||
__skb_pull(skb, skb_network_header_len(skb));
|
||||
|
||||
|
||||
@@ -478,6 +478,13 @@ void ip6_protocol_deliver_rcu(struct net *net, struct sk_buff *skb, int nexthdr,
|
||||
|
||||
static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
if (unlikely(skb_orphan_frags_rx(skb, GFP_ATOMIC))) {
|
||||
__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
|
||||
IPSTATS_MIB_INDISCARDS);
|
||||
kfree_skb_reason(skb, SKB_DROP_REASON_NOMEM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
skb_clear_delivery_time(skb);
|
||||
ip6_protocol_deliver_rcu(net, skb, 0, false);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user