Commit 090119a3 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'inet-ping-remove-extra-skb_clone-consume_skb'

Eric Dumazet says:

====================
inet: ping: remove extra skb_clone()/consume_skb()

First patch in the series moves ICMP_EXT_ECHOREPLY handling in icmp_rcv()
to prepare the second patch.

The second patch removes one skb_clone()/consume_skb() pair
when processing ICMP_EXT_REPLY packets. Some people
use hundreds of "ping -fq ..." to stress hosts :)
====================

Link: https://patch.msgid.link/20250226183437.1457318-1-edumazet@google.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 8e7e3d97 a7e38208
Loading
Loading
Loading
Loading
+17 −16
Original line number Diff line number Diff line
@@ -1248,22 +1248,6 @@ int icmp_rcv(struct sk_buff *skb)
		goto reason_check;
	}

	if (icmph->type == ICMP_EXT_ECHOREPLY) {
		reason = ping_rcv(skb);
		goto reason_check;
	}

	/*
	 *	18 is the highest 'known' ICMP type. Anything else is a mystery
	 *
	 *	RFC 1122: 3.2.2  Unknown ICMP messages types MUST be silently
	 *		  discarded.
	 */
	if (icmph->type > NR_ICMP_TYPES) {
		reason = SKB_DROP_REASON_UNHANDLED_PROTO;
		goto error;
	}

	/*
	 *	Parse the ICMP message
	 */
@@ -1290,6 +1274,23 @@ int icmp_rcv(struct sk_buff *skb)
		}
	}

	if (icmph->type == ICMP_EXT_ECHOREPLY ||
	    icmph->type == ICMP_ECHOREPLY) {
		reason = ping_rcv(skb);
		return reason ? NET_RX_DROP : NET_RX_SUCCESS;
	}

	/*
	 *	18 is the highest 'known' ICMP type. Anything else is a mystery
	 *
	 *	RFC 1122: 3.2.2  Unknown ICMP messages types MUST be silently
	 *		  discarded.
	 */
	if (icmph->type > NR_ICMP_TYPES) {
		reason = SKB_DROP_REASON_UNHANDLED_PROTO;
		goto error;
	}

	reason = icmp_pointers[icmph->type].handler(skb);
reason_check:
	if (!reason)  {
+5 −15
Original line number Diff line number Diff line
@@ -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);

		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");
	if (sk)
		return __ping_queue_rcv_skb(sk, skb);

	return reason;
	kfree_skb_reason(skb, SKB_DROP_REASON_NO_SOCKET);
	return SKB_DROP_REASON_NO_SOCKET;
}
EXPORT_SYMBOL_GPL(ping_rcv);

+2 −5
Original line number Diff line number Diff line
@@ -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