netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net v2 1/2] net: ip: add drop reasons when handling ip fragments
  2025-10-24 10:20 [PATCH net v2 0/2] add drop reason when do fragment Yonglong Li
@ 2025-10-24 10:20 ` Yonglong Li
  2025-10-25  0:24   ` Jakub Kicinski
  0 siblings, 1 reply; 7+ messages in thread
From: Yonglong Li @ 2025-10-24 10:20 UTC (permalink / raw)
  To: netdev; +Cc: davem, dsahern, edumazet, pabeni, kuba, horms, liyonglong

1, add new drop reason FRAG_FAILED/FRAG_OUTPUT_FAILED
2, use drop reasons in ip_fragment

Signed-off-by: Yonglong Li <liyonglong@chinatelecom.cn>
---
 include/net/dropreason-core.h |  6 ++++++
 net/ipv4/ip_output.c          | 17 ++++++++++++-----
 2 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/include/net/dropreason-core.h b/include/net/dropreason-core.h
index 58d91cc..4ae042e 100644
--- a/include/net/dropreason-core.h
+++ b/include/net/dropreason-core.h
@@ -99,6 +99,8 @@
 	FN(DUP_FRAG)			\
 	FN(FRAG_REASM_TIMEOUT)		\
 	FN(FRAG_TOO_FAR)		\
+	FN(FRAG_FAILED)			\
+	FN(FRAG_OUTPUT_FAILED)		\
 	FN(TCP_MINTTL)			\
 	FN(IPV6_BAD_EXTHDR)		\
 	FN(IPV6_NDISC_FRAG)		\
@@ -500,6 +502,10 @@ enum skb_drop_reason {
 	 * (/proc/sys/net/ipv4/ipfrag_max_dist)
 	 */
 	SKB_DROP_REASON_FRAG_TOO_FAR,
+	/* do ip/ip6 fragment failed */
+	SKB_DROP_REASON_FRAG_FAILED,
+	/* ip/ip6 fragment output failed */
+	SKB_DROP_REASON_FRAG_OUTPUT_FAILED,
 	/**
 	 * @SKB_DROP_REASON_TCP_MINTTL: ipv4 ttl or ipv6 hoplimit below
 	 * the threshold (IP_MINTTL or IPV6_MINHOPCOUNT).
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index ff11d3a..3e0d21c 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -588,7 +588,7 @@ static int ip_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
 		IP_INC_STATS(net, IPSTATS_MIB_FRAGFAILS);
 		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
 			  htonl(mtu));
-		kfree_skb(skb);
+		kfree_skb_reason(skb, SKB_DROP_REASON_PKT_TOO_BIG);
 		return -EMSGSIZE;
 	}
 
@@ -765,6 +765,7 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
 	struct sk_buff *skb2;
 	u8 tstamp_type = skb->tstamp_type;
 	struct rtable *rt = skb_rtable(skb);
+	SKB_DR_INIT(reason, FRAG_FAILED);
 	unsigned int mtu, hlen, ll_rs;
 	struct ip_fraglist_iter iter;
 	ktime_t tstamp = skb->tstamp;
@@ -773,8 +774,10 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
 
 	/* for offloaded checksums cleanup checksum before fragmentation */
 	if (skb->ip_summed == CHECKSUM_PARTIAL &&
-	    (err = skb_checksum_help(skb)))
+	    (err = skb_checksum_help(skb))) {
+		SKB_DR_SET(reason, IP_CSUM);
 		goto fail;
+	}
 
 	/*
 	 *	Point into the IP datagram header.
@@ -860,6 +863,8 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
 
 			if (!err)
 				IP_INC_STATS(net, IPSTATS_MIB_FRAGCREATES);
+			else
+				SKB_DR_SET(reason, FRAG_OUTPUT_FAILED);
 			if (err || !iter.frag)
 				break;
 
@@ -871,7 +876,7 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
 			return 0;
 		}
 
-		kfree_skb_list(iter.frag);
+		kfree_skb_list_reason(iter.frag, reason);
 
 		IP_INC_STATS(net, IPSTATS_MIB_FRAGFAILS);
 		return err;
@@ -913,8 +918,10 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
 		 */
 		skb_set_delivery_time(skb2, tstamp, tstamp_type);
 		err = output(net, sk, skb2);
-		if (err)
+		if (err) {
+			SKB_DR_SET(reason, FRAG_OUTPUT_FAILED);
 			goto fail;
+		}
 
 		IP_INC_STATS(net, IPSTATS_MIB_FRAGCREATES);
 	}
@@ -923,7 +930,7 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
 	return err;
 
 fail:
-	kfree_skb(skb);
+	kfree_skb_reason(skb, reason);
 	IP_INC_STATS(net, IPSTATS_MIB_FRAGFAILS);
 	return err;
 }
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH net v2 1/2] net: ip: add drop reasons when handling ip fragments
  2025-10-24 10:20 ` [PATCH net v2 1/2] net: ip: add drop reasons when handling ip fragments Yonglong Li
@ 2025-10-25  0:24   ` Jakub Kicinski
  0 siblings, 0 replies; 7+ messages in thread
From: Jakub Kicinski @ 2025-10-25  0:24 UTC (permalink / raw)
  To: Yonglong Li; +Cc: netdev, davem, dsahern, edumazet, pabeni, horms

On Fri, 24 Oct 2025 18:20:11 +0800 Yonglong Li wrote:
> Subject: [PATCH net v2 1/2] net: ip: add drop reasons when handling ip fragments

net-next, please read the whole doc Eric linked

> 1, add new drop reason FRAG_FAILED/FRAG_OUTPUT_FAILED
> 2, use drop reasons in ip_fragment

Personally IDK if this is sufficiently semantically significant
to warrant merging. FRAG_FAILED means "unidentified error during
fragmentation"? ip_frag_next() only returns -ENOMEM and
SKB_DROP_REASON_NOMEM already exists, so just use that.

FRAG_OUTPUT_FAILED means something failed in output so it'd be more
meaningful to figure out what failed there, instead of adding 
a bunch of ${CALLER}_OUTPUT_FAILED

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH net v2 0/2] add drop reason when do fragment
@ 2025-10-27  2:32 Yonglong Li
  2025-10-27  2:32 ` [PATCH net v2 1/2] net: ip: add drop reasons when handling ip fragments Yonglong Li
  2025-10-27  2:32 ` [PATCH net v2 2/2] net: ipv6: use drop reasons in ip6_fragment Yonglong Li
  0 siblings, 2 replies; 7+ messages in thread
From: Yonglong Li @ 2025-10-27  2:32 UTC (permalink / raw)
  To: netdev; +Cc: davem, dsahern, edumazet, pabeni, kuba, horms, liyonglong

Add two new drop reasons FRAG_FAILED, FRAG_OUTPUT_FAILED.
And use drop reasons to trace do fragment.


Reasons show up as:

perf record -e skb:kfree_skb -a; perf script

  swapper 0 [005] 154.086537: skb:kfree_skb: ... location=ip6_fragment reason: PKT_TOO_BIG
  swapper 0 [005] 154.086540: skb:kfree_skb: ... location=ip6_fragment reason: PKT_TOO_BIG
  swapper 0 [005] 154.086544: skb:kfree_skb: ... location=ip6_fragment reason: PKT_TOO_BIG

Yonglong Li (2):
  net: ip: add drop reasons when handling ip fragments
  net: ipv6: use drop reasons in ip6_fragment

 include/net/dropreason-core.h |  6 ++++++
 net/ipv4/ip_output.c          | 17 ++++++++++++-----
 net/ipv6/ip6_output.c         | 16 ++++++++++++----
 3 files changed, 30 insertions(+), 9 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH net v2 1/2] net: ip: add drop reasons when handling ip fragments
  2025-10-27  2:32 [PATCH net v2 0/2] add drop reason when do fragment Yonglong Li
@ 2025-10-27  2:32 ` Yonglong Li
  2025-10-28  7:34   ` YonglongLi
  2025-10-27  2:32 ` [PATCH net v2 2/2] net: ipv6: use drop reasons in ip6_fragment Yonglong Li
  1 sibling, 1 reply; 7+ messages in thread
From: Yonglong Li @ 2025-10-27  2:32 UTC (permalink / raw)
  To: netdev; +Cc: davem, dsahern, edumazet, pabeni, kuba, horms, liyonglong

1, add new drop reason FRAG_FAILED/FRAG_OUTPUT_FAILED
2, use drop reasons in ip_fragment

Signed-off-by: Yonglong Li <liyonglong@chinatelecom.cn>
---
 include/net/dropreason-core.h |  6 ++++++
 net/ipv4/ip_output.c          | 17 ++++++++++++-----
 2 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/include/net/dropreason-core.h b/include/net/dropreason-core.h
index 58d91cc..4ae042e 100644
--- a/include/net/dropreason-core.h
+++ b/include/net/dropreason-core.h
@@ -99,6 +99,8 @@
 	FN(DUP_FRAG)			\
 	FN(FRAG_REASM_TIMEOUT)		\
 	FN(FRAG_TOO_FAR)		\
+	FN(FRAG_FAILED)			\
+	FN(FRAG_OUTPUT_FAILED)		\
 	FN(TCP_MINTTL)			\
 	FN(IPV6_BAD_EXTHDR)		\
 	FN(IPV6_NDISC_FRAG)		\
@@ -500,6 +502,10 @@ enum skb_drop_reason {
 	 * (/proc/sys/net/ipv4/ipfrag_max_dist)
 	 */
 	SKB_DROP_REASON_FRAG_TOO_FAR,
+	/* do ip/ip6 fragment failed */
+	SKB_DROP_REASON_FRAG_FAILED,
+	/* ip/ip6 fragment output failed */
+	SKB_DROP_REASON_FRAG_OUTPUT_FAILED,
 	/**
 	 * @SKB_DROP_REASON_TCP_MINTTL: ipv4 ttl or ipv6 hoplimit below
 	 * the threshold (IP_MINTTL or IPV6_MINHOPCOUNT).
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index ff11d3a..2eab175 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -588,7 +588,7 @@ static int ip_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
 		IP_INC_STATS(net, IPSTATS_MIB_FRAGFAILS);
 		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
 			  htonl(mtu));
-		kfree_skb(skb);
+		kfree_skb_reason(skb, SKB_DROP_REASON_PKT_TOO_BIG);
 		return -EMSGSIZE;
 	}
 
@@ -765,6 +765,7 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
 	struct sk_buff *skb2;
 	u8 tstamp_type = skb->tstamp_type;
 	struct rtable *rt = skb_rtable(skb);
+	SKB_DR_INIT(reason, FRAG_FAILED);
 	unsigned int mtu, hlen, ll_rs;
 	struct ip_fraglist_iter iter;
 	ktime_t tstamp = skb->tstamp;
@@ -773,8 +774,10 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
 
 	/* for offloaded checksums cleanup checksum before fragmentation */
 	if (skb->ip_summed == CHECKSUM_PARTIAL &&
-	    (err = skb_checksum_help(skb)))
+	    (err = skb_checksum_help(skb))) {
+		SKB_DR_SET(reason, SKB_CSUM);
 		goto fail;
+	}
 
 	/*
 	 *	Point into the IP datagram header.
@@ -860,6 +863,8 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
 
 			if (!err)
 				IP_INC_STATS(net, IPSTATS_MIB_FRAGCREATES);
+			else
+				SKB_DR_SET(reason, FRAG_OUTPUT_FAILED);
 			if (err || !iter.frag)
 				break;
 
@@ -871,7 +876,7 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
 			return 0;
 		}
 
-		kfree_skb_list(iter.frag);
+		kfree_skb_list_reason(iter.frag, reason);
 
 		IP_INC_STATS(net, IPSTATS_MIB_FRAGFAILS);
 		return err;
@@ -913,8 +918,10 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
 		 */
 		skb_set_delivery_time(skb2, tstamp, tstamp_type);
 		err = output(net, sk, skb2);
-		if (err)
+		if (err) {
+			SKB_DR_SET(reason, FRAG_OUTPUT_FAILED);
 			goto fail;
+		}
 
 		IP_INC_STATS(net, IPSTATS_MIB_FRAGCREATES);
 	}
@@ -923,7 +930,7 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
 	return err;
 
 fail:
-	kfree_skb(skb);
+	kfree_skb_reason(skb, reason);
 	IP_INC_STATS(net, IPSTATS_MIB_FRAGFAILS);
 	return err;
 }
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH net v2 2/2] net: ipv6: use drop reasons in ip6_fragment
  2025-10-27  2:32 [PATCH net v2 0/2] add drop reason when do fragment Yonglong Li
  2025-10-27  2:32 ` [PATCH net v2 1/2] net: ip: add drop reasons when handling ip fragments Yonglong Li
@ 2025-10-27  2:32 ` Yonglong Li
  1 sibling, 0 replies; 7+ messages in thread
From: Yonglong Li @ 2025-10-27  2:32 UTC (permalink / raw)
  To: netdev; +Cc: davem, dsahern, edumazet, pabeni, kuba, horms, liyonglong

use drop reasons in ip6_output like ip_fragment/ip_do_fragment

Signed-off-by: Yonglong Li <liyonglong@chinatelecom.cn>
---
 net/ipv6/ip6_output.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index f904739e..31dea51 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -879,6 +879,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
 	struct ipv6_pinfo *np = skb->sk && !dev_recursion_level() ?
 				inet6_sk(skb->sk) : NULL;
 	u8 tstamp_type = skb->tstamp_type;
+	SKB_DR_INIT(reason, FRAG_FAILED);
 	struct ip6_frag_state state;
 	unsigned int mtu, hlen, nexthdr_offset;
 	ktime_t tstamp = skb->tstamp;
@@ -925,8 +926,10 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
 				    &ipv6_hdr(skb)->saddr);
 
 	if (skb->ip_summed == CHECKSUM_PARTIAL &&
-	    (err = skb_checksum_help(skb)))
+	    (err = skb_checksum_help(skb))) {
+		SKB_DR_SET(reason, SKB_CSUM);
 		goto fail;
+	}
 
 	prevhdr = skb_network_header(skb) + nexthdr_offset;
 	hroom = LL_RESERVED_SPACE(rt->dst.dev);
@@ -979,6 +982,8 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
 			if (!err)
 				IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
 					      IPSTATS_MIB_FRAGCREATES);
+			else
+				SKB_DR_SET(reason, FRAG_OUTPUT_FAILED);
 
 			if (err || !iter.frag)
 				break;
@@ -995,7 +1000,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
 			return 0;
 		}
 
-		kfree_skb_list(iter.frag);
+		kfree_skb_list_reason(iter.frag, reason);
 
 		IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
 			      IPSTATS_MIB_FRAGFAILS);
@@ -1037,8 +1042,10 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
 		 */
 		skb_set_delivery_time(frag, tstamp, tstamp_type);
 		err = output(net, sk, frag);
-		if (err)
+		if (err) {
+			SKB_DR_SET(reason, FRAG_OUTPUT_FAILED);
 			goto fail;
+		}
 
 		IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
 			      IPSTATS_MIB_FRAGCREATES);
@@ -1050,12 +1057,13 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
 
 fail_toobig:
 	icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+	SKB_DR_SET(reason, PKT_TOO_BIG);
 	err = -EMSGSIZE;
 
 fail:
 	IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
 		      IPSTATS_MIB_FRAGFAILS);
-	kfree_skb(skb);
+	kfree_skb_reason(skb, reason);
 	return err;
 }
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH net v2 1/2] net: ip: add drop reasons when handling ip fragments
  2025-10-27  2:32 ` [PATCH net v2 1/2] net: ip: add drop reasons when handling ip fragments Yonglong Li
@ 2025-10-28  7:34   ` YonglongLi
  2025-10-29  0:05     ` Jakub Kicinski
  0 siblings, 1 reply; 7+ messages in thread
From: YonglongLi @ 2025-10-28  7:34 UTC (permalink / raw)
  To: kuba; +Cc: netdev, edumazet, horms

Hi Jakub,

Thank you for your response. I'm sorry for the late reply.
‌My email system seems to have some issues, and I loss  your reply msg.
I get your response information from web page: https://lore.kernel.org/netdev.


> Personally IDK if this is sufficiently semantically significant
> to warrant merging. FRAG_FAILED means "unidentified error during
> fragmentation"? ip_frag_next() only returns -ENOMEM and
> SKB_DROP_REASON_NOMEM already exists, so just use that.

Yes, I agree. use NOMEM instead of FRAG_FAILED.


> FRAG_OUTPUT_FAILED means something failed in output so it'd be more
> meaningful to figure out what failed there, instead of adding
> a bunch of ${CALLER}_OUTPUT_FAILED

The skb send failed in output() is frag skb, The skb droped outside of output() is the
origin skb. I think if we want to get detail drop reason we can use kfree_skb_reason
in output() (maybe anther patch set in future).
In my opinion, drop reason of the origin skb outside of output() can be not so meaningfull.


-- 
Li YongLong


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH net v2 1/2] net: ip: add drop reasons when handling ip fragments
  2025-10-28  7:34   ` YonglongLi
@ 2025-10-29  0:05     ` Jakub Kicinski
  0 siblings, 0 replies; 7+ messages in thread
From: Jakub Kicinski @ 2025-10-29  0:05 UTC (permalink / raw)
  To: YonglongLi; +Cc: netdev, edumazet, horms

On Tue, 28 Oct 2025 15:34:48 +0800 YonglongLi wrote:
> Hi Jakub,
> 
> Thank you for your response. I'm sorry for the late reply.
> ‌My email system seems to have some issues, and I loss  your reply msg.
> I get your response information from web page: https://lore.kernel.org/netdev.

So you resent the patches again? Please learn to use the ML correctly.

Also, again the subject tag should be [PATCH net-next] here not net

> > FRAG_OUTPUT_FAILED means something failed in output so it'd be more
> > meaningful to figure out what failed there, instead of adding
> > a bunch of ${CALLER}_OUTPUT_FAILED  
> 
> The skb send failed in output() is frag skb, The skb droped outside of output() is the
> origin skb. I think if we want to get detail drop reason we can use kfree_skb_reason
> in output() (maybe anther patch set in future).
> In my opinion, drop reason of the origin skb outside of output() can be not so meaningfull.

Do you have practical examples of output() failing? Are they in any way
related to the skb being fragmented? My intuition is that they would
not be, hence the fragmentation is not very relevant.

If the output() failed because there's something _special_ about
fragmented datagrams -- I'd agree with you. So let's see some
examples..
-- 
pw-bot: cr

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2025-10-29  0:05 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-27  2:32 [PATCH net v2 0/2] add drop reason when do fragment Yonglong Li
2025-10-27  2:32 ` [PATCH net v2 1/2] net: ip: add drop reasons when handling ip fragments Yonglong Li
2025-10-28  7:34   ` YonglongLi
2025-10-29  0:05     ` Jakub Kicinski
2025-10-27  2:32 ` [PATCH net v2 2/2] net: ipv6: use drop reasons in ip6_fragment Yonglong Li
  -- strict thread matches above, loose matches on Subject: below --
2025-10-24 10:20 [PATCH net v2 0/2] add drop reason when do fragment Yonglong Li
2025-10-24 10:20 ` [PATCH net v2 1/2] net: ip: add drop reasons when handling ip fragments Yonglong Li
2025-10-25  0:24   ` Jakub Kicinski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).