diff mbox series

[net-next,2/2] inet: ping: avoid skb_clone() dance in ping_rcv()

Message ID 20250226183437.1457318-3-edumazet@google.com (mailing list archive)
State New
Delegated to: Netdev Maintainers
Headers show
Series inet: ping: remove extra skb_clone()/consume_skb() | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 6 of 6 maintainers
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 4 this patch: 4
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 61 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 1 this patch: 1
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2025-02-26--21-00 (tests: 895)

Commit Message

Eric Dumazet Feb. 26, 2025, 6:34 p.m. UTC
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>
---
 net/ipv4/icmp.c |  5 +++--
 net/ipv4/ping.c | 20 +++++---------------
 net/ipv6/icmp.c |  7 ++-----
 3 files changed, 10 insertions(+), 22 deletions(-)
diff mbox series

Patch

diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 058d4c1e300d0c0be7a04fd67e8e39924dfcd2cc..717cb7d3607a1c77a3f54b56d2bb98b1064dd878 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -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;
 	}
 
 	/*
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index 85d09f2ecadcb690f01985771afa37ce2cd0befc..c14baa6589c748026b49416688cbea399e6d461a 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -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);
 
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 4d14ab7f7e99f152cd5f5adaa023f0280957f275..3fd19a84b358d169bbdc351c43ede830c60afcf3 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -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