inet: ping: avoid skb_clone() dance in ping_rcv()

ping_rcv() callers currently call skb_free() or consume_skb(),
forcing ping_rcv() to clone the skb.

After this patch ping_rcv() is now 'consuming' the original skb,
either moving to a socket receive queue, or dropping it.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20250226183437.1457318-3-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Eric Dumazet 2025-02-26 18:34:37 +00:00 committed by Jakub Kicinski
parent daeb6a8f3b
commit a7e38208fe
3 changed files with 10 additions and 22 deletions

View File

@ -1274,9 +1274,10 @@ int icmp_rcv(struct sk_buff *skb)
}
}
if (icmph->type == ICMP_EXT_ECHOREPLY) {
if (icmph->type == ICMP_EXT_ECHOREPLY ||
icmph->type == ICMP_ECHOREPLY) {
reason = ping_rcv(skb);
goto reason_check;
return reason ? NET_RX_DROP : NET_RX_SUCCESS;
}
/*

View File

@ -966,10 +966,9 @@ EXPORT_SYMBOL_GPL(ping_queue_rcv_skb);
enum skb_drop_reason ping_rcv(struct sk_buff *skb)
{
enum skb_drop_reason reason = SKB_DROP_REASON_NO_SOCKET;
struct sock *sk;
struct net *net = dev_net(skb->dev);
struct icmphdr *icmph = icmp_hdr(skb);
struct sock *sk;
/* We assume the packet has already been checked by icmp_rcv */
@ -980,20 +979,11 @@ enum skb_drop_reason ping_rcv(struct sk_buff *skb)
skb_push(skb, skb->data - (u8 *)icmph);
sk = ping_lookup(net, skb, ntohs(icmph->un.echo.id));
if (sk) {
struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
if (sk)
return __ping_queue_rcv_skb(sk, skb);
pr_debug("rcv on socket %p\n", sk);
if (skb2)
reason = __ping_queue_rcv_skb(sk, skb2);
else
reason = SKB_DROP_REASON_NOMEM;
}
if (reason)
pr_debug("no socket, dropping\n");
return reason;
kfree_skb_reason(skb, SKB_DROP_REASON_NO_SOCKET);
return SKB_DROP_REASON_NO_SOCKET;
}
EXPORT_SYMBOL_GPL(ping_rcv);

View File

@ -957,12 +957,9 @@ static int icmpv6_rcv(struct sk_buff *skb)
break;
case ICMPV6_ECHO_REPLY:
reason = ping_rcv(skb);
break;
case ICMPV6_EXT_ECHO_REPLY:
reason = ping_rcv(skb);
break;
ping_rcv(skb);
return 0;
case ICMPV6_PKT_TOOBIG:
/* BUGGG_FUTURE: if packet contains rthdr, we cannot update