linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 0/9] net: ip: add skb drop reasons to ip ingress
@ 2022-04-13  8:15 menglong8.dong
  2022-04-13  8:15 ` [PATCH net-next 1/9] skb: add some helpers for skb drop reasons menglong8.dong
                   ` (9 more replies)
  0 siblings, 10 replies; 13+ messages in thread
From: menglong8.dong @ 2022-04-13  8:15 UTC (permalink / raw)
  To: dsahern
  Cc: rostedt, mingo, davem, yoshfuji, kuba, pabeni, benbjiang,
	flyingpeng, imagedong, edumazet, kafai, talalahmad, keescook,
	mengensun, dongli.zhang, linux-kernel, netdev

From: Menglong Dong <imagedong@tencent.com>

In the series "net: use kfree_skb_reason() for ip/udp packet receive",
skb drop reasons are added to the basic ingress path of IPv4. And in
the series "net: use kfree_skb_reason() for ip/neighbour", the egress
paths of IPv4 and IPv6 are handled. Related links:

https://lore.kernel.org/netdev/20220205074739.543606-1-imagedong@tencent.com/
https://lore.kernel.org/netdev/20220226041831.2058437-1-imagedong@tencent.com/

Seems we still have a lot work to do with IP layer, including IPv6 basic
ingress path, IPv4/IPv6 forwarding, IPv6 exthdrs, fragment and defrag,
etc.

In this series, skb drop reasons are added to the basic ingress path of
IPv6 protocol and IPv4/IPv6 packet forwarding. Following functions, which
are used for IPv6 packet receiving are handled:

  ip6_pkt_drop()
  ip6_rcv_core()
  ip6_protocol_deliver_rcu()

And following functions that used for IPv6 TLV parse are handled:

  ip6_parse_tlv()
  ipv6_hop_ra()
  ipv6_hop_ioam()
  ipv6_hop_jumbo()
  ipv6_hop_calipso()
  ipv6_dest_hao()

Besides, ip_forward() and ip6_forward(), which are used for IPv4/IPv6
forwarding, are also handled. And following new drop reasons are added:

  /* host unreachable, corresponding to IPSTATS_MIB_INADDRERRORS */
  SKB_DROP_REASON_IP_INADDRERRORS
  /* network unreachable, corresponding to IPSTATS_MIB_INADDRERRORS */
  SKB_DROP_REASON_IP_INNOROUTES
  /* packet size is too big, corresponding to
   * IPSTATS_MIB_INTOOBIGERRORS
   */
  SKB_DROP_REASON_PKT_TOO_BIG

In order to simply the definition and assignment for
'enum skb_drop_reason', some helper functions are introduced in the 1th
patch. I'm not such if this is necessary, but it makes the code simpler.
For example, we can replace the code:

  if (reason == SKB_DROP_REASON_NOT_SPECIFIED)
          reason = SKB_DROP_REASON_IP_INHDR;

with:

  SKB_DR_OR(reason, IP_INHDR);


In the 6th patch, the statistics for skb in ipv6_hop_jum() is removed,
as I think it is redundant. There are two call chains for
ipv6_hop_jumbo(). The first one is:

  ipv6_destopt_rcv() -> ip6_parse_tlv() -> ipv6_hop_jumbo()

On this call chain, the drop statistics will be done in
ipv6_destopt_rcv() with 'IPSTATS_MIB_INHDRERRORS' if ipv6_hop_jumbo()
returns false.

The second call chain is:

  ip6_rcv_core() -> ipv6_parse_hopopts() -> ip6_parse_tlv()

And the drop statistics will also be done in ip6_rcv_core() with
'IPSTATS_MIB_INHDRERRORS' if ipv6_hop_jumbo() returns false.

Therefore, the statistics in ipv6_hop_jumbo() is redundant, which
means the drop is counted twice. The statistics in ipv6_hop_jumbo()
is almost the same as the outside, except the
'IPSTATS_MIB_INTRUNCATEDPKTS', which seems that we have to ignore it.


======================================================================

Here is a basic test for IPv6 forwarding packet drop that monitored by
'dropwatch' tool:

  drop at: ip6_forward+0x81a/0xb70 (0xffffffff86c73f8a)
  origin: software
  input port ifindex: 7
  timestamp: Wed Apr 13 11:51:06 2022 130010176 nsec
  protocol: 0x86dd
  length: 94
  original length: 94
  drop reason: IP_INADDRERRORS

The origin cause of this case is that IPv6 doesn't allow to forward the
packet with LOCAL-LINK saddr, and results the 'IP_INADDRERRORS' drop
reason.

Menglong Dong (9):
  skb: add some helpers for skb drop reasons
  net: ipv4: add skb drop reasons to ip_error()
  net: ipv6: add skb drop reasons to ip6_pkt_drop()
  net: ip: add skb drop reasons to ip forwarding
  net: icmp: introduce function icmpv6_param_prob_reason()
  net: ipv6: remove redundant statistics in ipv6_hop_jumbo()
  net: ipv6: add skb drop reasons to TLV parse
  net: ipv6: add skb drop reasons to ip6_rcv_core()
  net: ipv6: add skb drop reasons to ip6_protocol_deliver_rcu()

 include/linux/icmpv6.h     | 11 +++++++++--
 include/linux/skbuff.h     | 21 ++++++++++++++++++++
 include/trace/events/skb.h |  3 +++
 net/ipv4/ip_forward.c      | 13 ++++++++++---
 net/ipv4/route.c           |  6 +++++-
 net/ipv6/exthdrs.c         | 39 +++++++++++++++++++++----------------
 net/ipv6/icmp.c            |  7 ++++---
 net/ipv6/ip6_input.c       | 40 ++++++++++++++++++++++++++------------
 net/ipv6/ip6_output.c      |  9 ++++++---
 net/ipv6/route.c           |  6 +++++-
 10 files changed, 113 insertions(+), 42 deletions(-)

-- 
2.35.1


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

* [PATCH net-next 1/9] skb: add some helpers for skb drop reasons
  2022-04-13  8:15 [PATCH net-next 0/9] net: ip: add skb drop reasons to ip ingress menglong8.dong
@ 2022-04-13  8:15 ` menglong8.dong
  2022-04-13  8:15 ` [PATCH net-next 2/9] net: ipv4: add skb drop reasons to ip_error() menglong8.dong
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: menglong8.dong @ 2022-04-13  8:15 UTC (permalink / raw)
  To: dsahern
  Cc: rostedt, mingo, davem, yoshfuji, kuba, pabeni, benbjiang,
	flyingpeng, imagedong, edumazet, kafai, talalahmad, keescook,
	mengensun, dongli.zhang, linux-kernel, netdev

From: Menglong Dong <imagedong@tencent.com>

In order to simply the definition and assignment for
'enum skb_drop_reason', introduce some helpers.

SKB_DR() is used to define a variable of type 'enum skb_drop_reason'
with the 'SKB_DROP_REASON_NOT_SPECIFIED' initial value.

SKB_DR_SET() is used to set the value of the variable. Seems it is
a little useless? But it makes the code shorter.

SKB_DR_OR() is used to set the value of the variable if it is not set
yet, which means its value is SKB_DROP_REASON_NOT_SPECIFIED.

Signed-off-by: Menglong Dong <imagedong@tencent.com>
Reviewed-by: Jiang Biao <benbjiang@tencent.com>
Reviewed-by: Hao Peng <flyingpeng@tencent.com>
---
 include/linux/skbuff.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 9b81ba497665..0cbd6ada957c 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -450,6 +450,18 @@ enum skb_drop_reason {
 	SKB_DROP_REASON_MAX,
 };
 
+#define SKB_DR_INIT(name, reason)				\
+	enum skb_drop_reason name = SKB_DROP_REASON_##reason
+#define SKB_DR(name)						\
+	SKB_DR_INIT(name, NOT_SPECIFIED)
+#define SKB_DR_SET(name, reason)				\
+	(name = SKB_DROP_REASON_##reason)
+#define SKB_DR_OR(name, reason)					\
+	do {							\
+		if (name == SKB_DROP_REASON_NOT_SPECIFIED)	\
+			SKB_DR_SET(name, reason);		\
+	} while (0)
+
 /* To allow 64K frame to be packed as single skb without frag_list we
  * require 64K/PAGE_SIZE pages plus 1 additional page to allow for
  * buffers which do not start on a page boundary.
-- 
2.35.1


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

* [PATCH net-next 2/9] net: ipv4: add skb drop reasons to ip_error()
  2022-04-13  8:15 [PATCH net-next 0/9] net: ip: add skb drop reasons to ip ingress menglong8.dong
  2022-04-13  8:15 ` [PATCH net-next 1/9] skb: add some helpers for skb drop reasons menglong8.dong
@ 2022-04-13  8:15 ` menglong8.dong
  2022-04-13  8:15 ` [PATCH net-next 3/9] net: ipv6: add skb drop reasons to ip6_pkt_drop() menglong8.dong
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: menglong8.dong @ 2022-04-13  8:15 UTC (permalink / raw)
  To: dsahern
  Cc: rostedt, mingo, davem, yoshfuji, kuba, pabeni, benbjiang,
	flyingpeng, imagedong, edumazet, kafai, talalahmad, keescook,
	mengensun, dongli.zhang, linux-kernel, netdev

From: Menglong Dong <imagedong@tencent.com>

Eventually, I find out the handler function for inputting route lookup
fail: ip_error().

The drop reasons we used in ip_error() are almost corresponding to
IPSTATS_MIB_*, and following new reasons are introduced:

SKB_DROP_REASON_IP_INADDRERRORS
SKB_DROP_REASON_IP_INNOROUTES

Isn't the name SKB_DROP_REASON_IP_HOSTUNREACH and
SKB_DROP_REASON_IP_NETUNREACH more accurate? To make them corresponding
to IPSTATS_MIB_*, we keep their name still.

Signed-off-by: Menglong Dong <imagedong@tencent.com>
Reviewed-by: Jiang Biao <benbjiang@tencent.com>
Reviewed-by: Hao Peng <flyingpeng@tencent.com>
---
 include/linux/skbuff.h     | 6 ++++++
 include/trace/events/skb.h | 2 ++
 net/ipv4/route.c           | 6 +++++-
 3 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 0cbd6ada957c..886e83ac4b70 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -447,6 +447,12 @@ enum skb_drop_reason {
 					 * 2211, such as a broadcasts
 					 * ICMP_TIMESTAMP
 					 */
+	SKB_DROP_REASON_IP_INADDRERRORS,	/* host unreachable, corresponding
+						 * to IPSTATS_MIB_INADDRERRORS
+						 */
+	SKB_DROP_REASON_IP_INNOROUTES,	/* network unreachable, corresponding
+					 * to IPSTATS_MIB_INADDRERRORS
+					 */
 	SKB_DROP_REASON_MAX,
 };
 
diff --git a/include/trace/events/skb.h b/include/trace/events/skb.h
index 42647114fffe..0acac7e5a019 100644
--- a/include/trace/events/skb.h
+++ b/include/trace/events/skb.h
@@ -63,6 +63,8 @@
 	EM(SKB_DROP_REASON_TAP_TXFILTER, TAP_TXFILTER)		\
 	EM(SKB_DROP_REASON_ICMP_CSUM, ICMP_CSUM)		\
 	EM(SKB_DROP_REASON_INVALID_PROTO, INVALID_PROTO)	\
+	EM(SKB_DROP_REASON_IP_INADDRERRORS, IP_INADDRERRORS)	\
+	EM(SKB_DROP_REASON_IP_INNOROUTES, IP_INNOROUTES)	\
 	EMe(SKB_DROP_REASON_MAX, MAX)
 
 #undef EM
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 98c6f3429593..0b581ee5c000 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -945,6 +945,7 @@ static int ip_error(struct sk_buff *skb)
 	struct inet_peer *peer;
 	unsigned long now;
 	struct net *net;
+	SKB_DR(reason);
 	bool send;
 	int code;
 
@@ -964,10 +965,12 @@ static int ip_error(struct sk_buff *skb)
 	if (!IN_DEV_FORWARD(in_dev)) {
 		switch (rt->dst.error) {
 		case EHOSTUNREACH:
+			SKB_DR_SET(reason, IP_INADDRERRORS);
 			__IP_INC_STATS(net, IPSTATS_MIB_INADDRERRORS);
 			break;
 
 		case ENETUNREACH:
+			SKB_DR_SET(reason, IP_INNOROUTES);
 			__IP_INC_STATS(net, IPSTATS_MIB_INNOROUTES);
 			break;
 		}
@@ -983,6 +986,7 @@ static int ip_error(struct sk_buff *skb)
 		break;
 	case ENETUNREACH:
 		code = ICMP_NET_UNREACH;
+		SKB_DR_SET(reason, IP_INNOROUTES);
 		__IP_INC_STATS(net, IPSTATS_MIB_INNOROUTES);
 		break;
 	case EACCES:
@@ -1009,7 +1013,7 @@ static int ip_error(struct sk_buff *skb)
 	if (send)
 		icmp_send(skb, ICMP_DEST_UNREACH, code, 0);
 
-out:	kfree_skb(skb);
+out:	kfree_skb_reason(skb, reason);
 	return 0;
 }
 
-- 
2.35.1


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

* [PATCH net-next 3/9] net: ipv6: add skb drop reasons to ip6_pkt_drop()
  2022-04-13  8:15 [PATCH net-next 0/9] net: ip: add skb drop reasons to ip ingress menglong8.dong
  2022-04-13  8:15 ` [PATCH net-next 1/9] skb: add some helpers for skb drop reasons menglong8.dong
  2022-04-13  8:15 ` [PATCH net-next 2/9] net: ipv4: add skb drop reasons to ip_error() menglong8.dong
@ 2022-04-13  8:15 ` menglong8.dong
  2022-04-13  8:15 ` [PATCH net-next 4/9] net: ip: add skb drop reasons to ip forwarding menglong8.dong
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: menglong8.dong @ 2022-04-13  8:15 UTC (permalink / raw)
  To: dsahern
  Cc: rostedt, mingo, davem, yoshfuji, kuba, pabeni, benbjiang,
	flyingpeng, imagedong, edumazet, kafai, talalahmad, keescook,
	mengensun, dongli.zhang, linux-kernel, netdev

From: Menglong Dong <imagedong@tencent.com>

Replace kfree_skb() used in ip6_pkt_drop() with kfree_skb_reason().
No new reason is added.

Signed-off-by: Menglong Dong <imagedong@tencent.com>
Reviewed-by: Jiang Biao <benbjiang@tencent.com>
Reviewed-by: Hao Peng <flyingpeng@tencent.com>
---
 net/ipv6/route.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 169e9df6d172..9471ab4421c8 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -4482,6 +4482,7 @@ static int ip6_pkt_drop(struct sk_buff *skb, u8 code, int ipstats_mib_noroutes)
 	struct dst_entry *dst = skb_dst(skb);
 	struct net *net = dev_net(dst->dev);
 	struct inet6_dev *idev;
+	SKB_DR(reason);
 	int type;
 
 	if (netif_is_l3_master(skb->dev) ||
@@ -4494,11 +4495,14 @@ static int ip6_pkt_drop(struct sk_buff *skb, u8 code, int ipstats_mib_noroutes)
 	case IPSTATS_MIB_INNOROUTES:
 		type = ipv6_addr_type(&ipv6_hdr(skb)->daddr);
 		if (type == IPV6_ADDR_ANY) {
+			SKB_DR_SET(reason, IP_INADDRERRORS);
 			IP6_INC_STATS(net, idev, IPSTATS_MIB_INADDRERRORS);
 			break;
 		}
+		SKB_DR_SET(reason, IP_INNOROUTES);
 		fallthrough;
 	case IPSTATS_MIB_OUTNOROUTES:
+		SKB_DR_OR(reason, IP_OUTNOROUTES);
 		IP6_INC_STATS(net, idev, ipstats_mib_noroutes);
 		break;
 	}
@@ -4508,7 +4512,7 @@ static int ip6_pkt_drop(struct sk_buff *skb, u8 code, int ipstats_mib_noroutes)
 		skb_dst_drop(skb);
 
 	icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0);
-	kfree_skb(skb);
+	kfree_skb_reason(skb, reason);
 	return 0;
 }
 
-- 
2.35.1


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

* [PATCH net-next 4/9] net: ip: add skb drop reasons to ip forwarding
  2022-04-13  8:15 [PATCH net-next 0/9] net: ip: add skb drop reasons to ip ingress menglong8.dong
                   ` (2 preceding siblings ...)
  2022-04-13  8:15 ` [PATCH net-next 3/9] net: ipv6: add skb drop reasons to ip6_pkt_drop() menglong8.dong
@ 2022-04-13  8:15 ` menglong8.dong
  2022-04-13  8:15 ` [PATCH net-next 5/9] net: icmp: introduce function icmpv6_param_prob_reason() menglong8.dong
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: menglong8.dong @ 2022-04-13  8:15 UTC (permalink / raw)
  To: dsahern
  Cc: rostedt, mingo, davem, yoshfuji, kuba, pabeni, benbjiang,
	flyingpeng, imagedong, edumazet, kafai, talalahmad, keescook,
	mengensun, dongli.zhang, linux-kernel, netdev

From: Menglong Dong <imagedong@tencent.com>

Replace kfree_skb() which is used in ip6_forward() and ip_forward()
with kfree_skb_reason().

The new drop reason 'SKB_DROP_REASON_PKT_TOO_BIG' is introduced for
the case that the length of the packet exceeds MTU and can't
fragment.

Signed-off-by: Menglong Dong <imagedong@tencent.com>
Reviewed-by: Jiang Biao <benbjiang@tencent.com>
Reviewed-by: Hao Peng <flyingpeng@tencent.com>
---
 include/linux/skbuff.h     |  3 +++
 include/trace/events/skb.h |  1 +
 net/ipv4/ip_forward.c      | 13 ++++++++++---
 net/ipv6/ip6_output.c      |  9 ++++++---
 4 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 886e83ac4b70..0ef11df1bc67 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -453,6 +453,9 @@ enum skb_drop_reason {
 	SKB_DROP_REASON_IP_INNOROUTES,	/* network unreachable, corresponding
 					 * to IPSTATS_MIB_INADDRERRORS
 					 */
+	SKB_DROP_REASON_PKT_TOO_BIG,	/* packet size is too big (maybe exceed
+					 * the MTU)
+					 */
 	SKB_DROP_REASON_MAX,
 };
 
diff --git a/include/trace/events/skb.h b/include/trace/events/skb.h
index 0acac7e5a019..2da72a9a5764 100644
--- a/include/trace/events/skb.h
+++ b/include/trace/events/skb.h
@@ -65,6 +65,7 @@
 	EM(SKB_DROP_REASON_INVALID_PROTO, INVALID_PROTO)	\
 	EM(SKB_DROP_REASON_IP_INADDRERRORS, IP_INADDRERRORS)	\
 	EM(SKB_DROP_REASON_IP_INNOROUTES, IP_INNOROUTES)	\
+	EM(SKB_DROP_REASON_PKT_TOO_BIG, PKT_TOO_BIG)		\
 	EMe(SKB_DROP_REASON_MAX, MAX)
 
 #undef EM
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c
index 92ba3350274b..e3aa436a1bdf 100644
--- a/net/ipv4/ip_forward.c
+++ b/net/ipv4/ip_forward.c
@@ -90,6 +90,7 @@ int ip_forward(struct sk_buff *skb)
 	struct rtable *rt;	/* Route we use */
 	struct ip_options *opt	= &(IPCB(skb)->opt);
 	struct net *net;
+	SKB_DR(reason);
 
 	/* that should never happen */
 	if (skb->pkt_type != PACKET_HOST)
@@ -101,8 +102,10 @@ int ip_forward(struct sk_buff *skb)
 	if (skb_warn_if_lro(skb))
 		goto drop;
 
-	if (!xfrm4_policy_check(NULL, XFRM_POLICY_FWD, skb))
+	if (!xfrm4_policy_check(NULL, XFRM_POLICY_FWD, skb)) {
+		SKB_DR_SET(reason, XFRM_POLICY);
 		goto drop;
+	}
 
 	if (IPCB(skb)->opt.router_alert && ip_call_ra_chain(skb))
 		return NET_RX_SUCCESS;
@@ -118,8 +121,10 @@ int ip_forward(struct sk_buff *skb)
 	if (ip_hdr(skb)->ttl <= 1)
 		goto too_many_hops;
 
-	if (!xfrm4_route_forward(skb))
+	if (!xfrm4_route_forward(skb)) {
+		SKB_DR_SET(reason, XFRM_POLICY);
 		goto drop;
+	}
 
 	rt = skb_rtable(skb);
 
@@ -132,6 +137,7 @@ int ip_forward(struct sk_buff *skb)
 		IP_INC_STATS(net, IPSTATS_MIB_FRAGFAILS);
 		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
 			  htonl(mtu));
+		SKB_DR_SET(reason, PKT_TOO_BIG);
 		goto drop;
 	}
 
@@ -169,7 +175,8 @@ int ip_forward(struct sk_buff *skb)
 	/* Tell the sender its packet died... */
 	__IP_INC_STATS(net, IPSTATS_MIB_INHDRERRORS);
 	icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0);
+	SKB_DR_SET(reason, IP_INHDR);
 drop:
-	kfree_skb(skb);
+	kfree_skb_reason(skb, reason);
 	return NET_RX_DROP;
 }
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index e23f058166af..3e729cee6486 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -469,6 +469,7 @@ int ip6_forward(struct sk_buff *skb)
 	struct inet6_skb_parm *opt = IP6CB(skb);
 	struct net *net = dev_net(dst->dev);
 	struct inet6_dev *idev;
+	SKB_DR(reason);
 	u32 mtu;
 
 	idev = __in6_dev_get_safely(dev_get_by_index_rcu(net, IP6CB(skb)->iif));
@@ -518,7 +519,7 @@ int ip6_forward(struct sk_buff *skb)
 		icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 0);
 		__IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
 
-		kfree_skb(skb);
+		kfree_skb_reason(skb, SKB_DROP_REASON_IP_INHDR);
 		return -ETIMEDOUT;
 	}
 
@@ -537,6 +538,7 @@ int ip6_forward(struct sk_buff *skb)
 
 	if (!xfrm6_route_forward(skb)) {
 		__IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS);
+		SKB_DR_SET(reason, XFRM_POLICY);
 		goto drop;
 	}
 	dst = skb_dst(skb);
@@ -596,7 +598,7 @@ int ip6_forward(struct sk_buff *skb)
 		__IP6_INC_STATS(net, idev, IPSTATS_MIB_INTOOBIGERRORS);
 		__IP6_INC_STATS(net, ip6_dst_idev(dst),
 				IPSTATS_MIB_FRAGFAILS);
-		kfree_skb(skb);
+		kfree_skb_reason(skb, SKB_DROP_REASON_PKT_TOO_BIG);
 		return -EMSGSIZE;
 	}
 
@@ -618,8 +620,9 @@ int ip6_forward(struct sk_buff *skb)
 
 error:
 	__IP6_INC_STATS(net, idev, IPSTATS_MIB_INADDRERRORS);
+	SKB_DR_SET(reason, IP_INADDRERRORS);
 drop:
-	kfree_skb(skb);
+	kfree_skb_reason(skb, reason);
 	return -EINVAL;
 }
 
-- 
2.35.1


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

* [PATCH net-next 5/9] net: icmp: introduce function icmpv6_param_prob_reason()
  2022-04-13  8:15 [PATCH net-next 0/9] net: ip: add skb drop reasons to ip ingress menglong8.dong
                   ` (3 preceding siblings ...)
  2022-04-13  8:15 ` [PATCH net-next 4/9] net: ip: add skb drop reasons to ip forwarding menglong8.dong
@ 2022-04-13  8:15 ` menglong8.dong
  2022-04-13  8:15 ` [PATCH net-next 6/9] net: ipv6: remove redundant statistics in ipv6_hop_jumbo() menglong8.dong
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: menglong8.dong @ 2022-04-13  8:15 UTC (permalink / raw)
  To: dsahern
  Cc: rostedt, mingo, davem, yoshfuji, kuba, pabeni, benbjiang,
	flyingpeng, imagedong, edumazet, kafai, talalahmad, keescook,
	mengensun, dongli.zhang, linux-kernel, netdev

From: Menglong Dong <imagedong@tencent.com>

In order to add the skb drop reasons support to icmpv6_param_prob(),
introduce the function icmpv6_param_prob_reason() and make
icmpv6_param_prob() an inline call to it. This new function will be
used in the following patches.

Signed-off-by: Menglong Dong <imagedong@tencent.com>
Reviewed-by: Jiang Biao <benbjiang@tencent.com>
Reviewed-by: Hao Peng <flyingpeng@tencent.com>
---
 include/linux/icmpv6.h | 11 +++++++++--
 net/ipv6/icmp.c        |  7 ++++---
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h
index 9055cb380ee2..db0f4fcfdaf4 100644
--- a/include/linux/icmpv6.h
+++ b/include/linux/icmpv6.h
@@ -79,8 +79,9 @@ extern int				icmpv6_init(void);
 extern int				icmpv6_err_convert(u8 type, u8 code,
 							   int *err);
 extern void				icmpv6_cleanup(void);
-extern void				icmpv6_param_prob(struct sk_buff *skb,
-							  u8 code, int pos);
+extern void				icmpv6_param_prob_reason(struct sk_buff *skb,
+								 u8 code, int pos,
+								 enum skb_drop_reason reason);
 
 struct flowi6;
 struct in6_addr;
@@ -91,6 +92,12 @@ extern void				icmpv6_flow_init(struct sock *sk,
 							 const struct in6_addr *daddr,
 							 int oif);
 
+static inline void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos)
+{
+	icmpv6_param_prob_reason(skb, code, pos,
+				 SKB_DROP_REASON_NOT_SPECIFIED);
+}
+
 static inline bool icmpv6_is_err(int type)
 {
 	switch (type) {
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 01c8003c9fc9..61770220774e 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -629,12 +629,13 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
 }
 EXPORT_SYMBOL(icmp6_send);
 
-/* Slightly more convenient version of icmp6_send.
+/* Slightly more convenient version of icmp6_send with drop reasons.
  */
-void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos)
+void icmpv6_param_prob_reason(struct sk_buff *skb, u8 code, int pos,
+			      enum skb_drop_reason reason)
 {
 	icmp6_send(skb, ICMPV6_PARAMPROB, code, pos, NULL, IP6CB(skb));
-	kfree_skb(skb);
+	kfree_skb_reason(skb, reason);
 }
 
 /* Generate icmpv6 with type/code ICMPV6_DEST_UNREACH/ICMPV6_ADDR_UNREACH
-- 
2.35.1


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

* [PATCH net-next 6/9] net: ipv6: remove redundant statistics in ipv6_hop_jumbo()
  2022-04-13  8:15 [PATCH net-next 0/9] net: ip: add skb drop reasons to ip ingress menglong8.dong
                   ` (4 preceding siblings ...)
  2022-04-13  8:15 ` [PATCH net-next 5/9] net: icmp: introduce function icmpv6_param_prob_reason() menglong8.dong
@ 2022-04-13  8:15 ` menglong8.dong
  2022-04-13  8:15 ` [PATCH net-next 7/9] net: ipv6: add skb drop reasons to TLV parse menglong8.dong
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: menglong8.dong @ 2022-04-13  8:15 UTC (permalink / raw)
  To: dsahern
  Cc: rostedt, mingo, davem, yoshfuji, kuba, pabeni, benbjiang,
	flyingpeng, imagedong, edumazet, kafai, talalahmad, keescook,
	mengensun, dongli.zhang, linux-kernel, netdev

From: Menglong Dong <imagedong@tencent.com>

There are two call chains for ipv6_hop_jumbo(). The first one is:

ipv6_destopt_rcv() -> ip6_parse_tlv() -> ipv6_hop_jumbo()

On this call chain, the drop statistics will be done in
ipv6_destopt_rcv() with 'IPSTATS_MIB_INHDRERRORS' if ipv6_hop_jumbo()
returns false.

The second call chain is:

ip6_rcv_core() -> ipv6_parse_hopopts() -> ip6_parse_tlv()

And the drop statistics will also be done in ip6_rcv_core() with
'IPSTATS_MIB_INHDRERRORS' if ipv6_hop_jumbo() returns false.

Therefore, the statistics in ipv6_hop_jumbo() is redundant, which
means the drop is counted twice. The statistics in ipv6_hop_jumbo()
is almost the same as the outside, except the
'IPSTATS_MIB_INTRUNCATEDPKTS', which seems that we have to ignore it.

Signed-off-by: Menglong Dong <imagedong@tencent.com>
Reviewed-by: Jiang Biao <benbjiang@tencent.com>
Reviewed-by: Hao Peng <flyingpeng@tencent.com>
---
 net/ipv6/exthdrs.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 658d5eabaf7e..31318ee62d29 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -997,33 +997,26 @@ static bool ipv6_hop_ioam(struct sk_buff *skb, int optoff)
 static bool ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
 {
 	const unsigned char *nh = skb_network_header(skb);
-	struct inet6_dev *idev = __in6_dev_get_safely(skb->dev);
-	struct net *net = ipv6_skb_net(skb);
 	u32 pkt_len;
 
 	if (nh[optoff + 1] != 4 || (optoff & 3) != 2) {
 		net_dbg_ratelimited("ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
 				    nh[optoff+1]);
-		__IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
 		goto drop;
 	}
 
 	pkt_len = ntohl(*(__be32 *)(nh + optoff + 2));
 	if (pkt_len <= IPV6_MAXPLEN) {
-		__IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
 		return false;
 	}
 	if (ipv6_hdr(skb)->payload_len) {
-		__IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
 		return false;
 	}
 
-	if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
-		__IP6_INC_STATS(net, idev, IPSTATS_MIB_INTRUNCATEDPKTS);
+	if (pkt_len > skb->len - sizeof(struct ipv6hdr))
 		goto drop;
-	}
 
 	if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr)))
 		goto drop;
-- 
2.35.1


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

* [PATCH net-next 7/9] net: ipv6: add skb drop reasons to TLV parse
  2022-04-13  8:15 [PATCH net-next 0/9] net: ip: add skb drop reasons to ip ingress menglong8.dong
                   ` (5 preceding siblings ...)
  2022-04-13  8:15 ` [PATCH net-next 6/9] net: ipv6: remove redundant statistics in ipv6_hop_jumbo() menglong8.dong
@ 2022-04-13  8:15 ` menglong8.dong
  2022-04-13  8:15 ` [PATCH net-next 8/9] net: ipv6: add skb drop reasons to ip6_rcv_core() menglong8.dong
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: menglong8.dong @ 2022-04-13  8:15 UTC (permalink / raw)
  To: dsahern
  Cc: rostedt, mingo, davem, yoshfuji, kuba, pabeni, benbjiang,
	flyingpeng, imagedong, edumazet, kafai, talalahmad, keescook,
	mengensun, dongli.zhang, linux-kernel, netdev

From: Menglong Dong <imagedong@tencent.com>

Replace kfree_skb() used in TLV encoded option header parsing with
kfree_skb_reason(). Following functions are involved:

ip6_parse_tlv()
ipv6_hop_ra()
ipv6_hop_ioam()
ipv6_hop_jumbo()
ipv6_hop_calipso()
ipv6_dest_hao()

Most skb drops during this process are regarded as 'InHdrErrors',
as 'IPSTATS_MIB_INHDRERRORS' is used when ip6_parse_tlv() fails,
which make we use 'SKB_DROP_REASON_IP_INHDR' correspondingly.

However, 'IP_INHDR' is a relatively general reason. Therefore, we
can use other reasons with higher priority in some cases. For example,
'SKB_DROP_REASON_UNHANDLED_PROTO' is used for unknown TLV options.

Signed-off-by: Menglong Dong <imagedong@tencent.com>
Reviewed-by: Jiang Biao <benbjiang@tencent.com>
Reviewed-by: Hao Peng <flyingpeng@tencent.com>
---
 net/ipv6/exthdrs.c | 36 ++++++++++++++++++++++++------------
 1 file changed, 24 insertions(+), 12 deletions(-)

diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 31318ee62d29..e670cf2fe85d 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -90,12 +90,13 @@ static bool ip6_tlvopt_unknown(struct sk_buff *skb, int optoff,
 			break;
 		fallthrough;
 	case 2: /* send ICMP PARM PROB regardless and drop packet */
-		icmpv6_param_prob(skb, ICMPV6_UNK_OPTION, optoff);
+		icmpv6_param_prob_reason(skb, ICMPV6_UNK_OPTION, optoff,
+					 SKB_DROP_REASON_UNHANDLED_PROTO);
 		return false;
 	}
 
 drop:
-	kfree_skb(skb);
+	kfree_skb_reason(skb, SKB_DROP_REASON_UNHANDLED_PROTO);
 	return false;
 }
 
@@ -218,7 +219,7 @@ static bool ip6_parse_tlv(bool hopbyhop,
 	if (len == 0)
 		return true;
 bad:
-	kfree_skb(skb);
+	kfree_skb_reason(skb, SKB_DROP_REASON_IP_INHDR);
 	return false;
 }
 
@@ -232,6 +233,7 @@ static bool ipv6_dest_hao(struct sk_buff *skb, int optoff)
 	struct ipv6_destopt_hao *hao;
 	struct inet6_skb_parm *opt = IP6CB(skb);
 	struct ipv6hdr *ipv6h = ipv6_hdr(skb);
+	SKB_DR(reason);
 	int ret;
 
 	if (opt->dsthao) {
@@ -246,19 +248,23 @@ static bool ipv6_dest_hao(struct sk_buff *skb, int optoff)
 	if (hao->length != 16) {
 		net_dbg_ratelimited("hao invalid option length = %d\n",
 				    hao->length);
+		SKB_DR_SET(reason, IP_INHDR);
 		goto discard;
 	}
 
 	if (!(ipv6_addr_type(&hao->addr) & IPV6_ADDR_UNICAST)) {
 		net_dbg_ratelimited("hao is not an unicast addr: %pI6\n",
 				    &hao->addr);
+		SKB_DR_SET(reason, INVALID_PROTO);
 		goto discard;
 	}
 
 	ret = xfrm6_input_addr(skb, (xfrm_address_t *)&ipv6h->daddr,
 			       (xfrm_address_t *)&hao->addr, IPPROTO_DSTOPTS);
-	if (unlikely(ret < 0))
+	if (unlikely(ret < 0)) {
+		SKB_DR_SET(reason, XFRM_POLICY);
 		goto discard;
+	}
 
 	if (skb_cloned(skb)) {
 		if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
@@ -281,7 +287,7 @@ static bool ipv6_dest_hao(struct sk_buff *skb, int optoff)
 	return true;
 
  discard:
-	kfree_skb(skb);
+	kfree_skb_reason(skb, reason);
 	return false;
 }
 #endif
@@ -934,7 +940,7 @@ static bool ipv6_hop_ra(struct sk_buff *skb, int optoff)
 	}
 	net_dbg_ratelimited("ipv6_hop_ra: wrong RA length %d\n",
 			    nh[optoff + 1]);
-	kfree_skb(skb);
+	kfree_skb_reason(skb, SKB_DROP_REASON_IP_INHDR);
 	return false;
 }
 
@@ -988,7 +994,7 @@ static bool ipv6_hop_ioam(struct sk_buff *skb, int optoff)
 	return true;
 
 drop:
-	kfree_skb(skb);
+	kfree_skb_reason(skb, SKB_DROP_REASON_IP_INHDR);
 	return false;
 }
 
@@ -997,26 +1003,32 @@ static bool ipv6_hop_ioam(struct sk_buff *skb, int optoff)
 static bool ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
 {
 	const unsigned char *nh = skb_network_header(skb);
+	SKB_DR(reason);
 	u32 pkt_len;
 
 	if (nh[optoff + 1] != 4 || (optoff & 3) != 2) {
 		net_dbg_ratelimited("ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
 				    nh[optoff+1]);
+		SKB_DR_SET(reason, IP_INHDR);
 		goto drop;
 	}
 
 	pkt_len = ntohl(*(__be32 *)(nh + optoff + 2));
 	if (pkt_len <= IPV6_MAXPLEN) {
-		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
+		icmpv6_param_prob_reason(skb, ICMPV6_HDR_FIELD, optoff + 2,
+					 SKB_DROP_REASON_IP_INHDR);
 		return false;
 	}
 	if (ipv6_hdr(skb)->payload_len) {
-		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
+		icmpv6_param_prob_reason(skb, ICMPV6_HDR_FIELD, optoff,
+					 SKB_DROP_REASON_IP_INHDR);
 		return false;
 	}
 
-	if (pkt_len > skb->len - sizeof(struct ipv6hdr))
+	if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
+		SKB_DR_SET(reason, PKT_TOO_SMALL);
 		goto drop;
+	}
 
 	if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr)))
 		goto drop;
@@ -1025,7 +1037,7 @@ static bool ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
 	return true;
 
 drop:
-	kfree_skb(skb);
+	kfree_skb_reason(skb, reason);
 	return false;
 }
 
@@ -1047,7 +1059,7 @@ static bool ipv6_hop_calipso(struct sk_buff *skb, int optoff)
 	return true;
 
 drop:
-	kfree_skb(skb);
+	kfree_skb_reason(skb, SKB_DROP_REASON_IP_INHDR);
 	return false;
 }
 
-- 
2.35.1


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

* [PATCH net-next 8/9] net: ipv6: add skb drop reasons to ip6_rcv_core()
  2022-04-13  8:15 [PATCH net-next 0/9] net: ip: add skb drop reasons to ip ingress menglong8.dong
                   ` (6 preceding siblings ...)
  2022-04-13  8:15 ` [PATCH net-next 7/9] net: ipv6: add skb drop reasons to TLV parse menglong8.dong
@ 2022-04-13  8:15 ` menglong8.dong
  2022-04-13 20:40   ` Eric Dumazet
  2022-04-13  8:16 ` [PATCH net-next 9/9] net: ipv6: add skb drop reasons to ip6_protocol_deliver_rcu() menglong8.dong
  2022-04-13 13:30 ` [PATCH net-next 0/9] net: ip: add skb drop reasons to ip ingress patchwork-bot+netdevbpf
  9 siblings, 1 reply; 13+ messages in thread
From: menglong8.dong @ 2022-04-13  8:15 UTC (permalink / raw)
  To: dsahern
  Cc: rostedt, mingo, davem, yoshfuji, kuba, pabeni, benbjiang,
	flyingpeng, imagedong, edumazet, kafai, talalahmad, keescook,
	mengensun, dongli.zhang, linux-kernel, netdev

From: Menglong Dong <imagedong@tencent.com>

Replace kfree_skb() used in ip6_rcv_core() with kfree_skb_reason().
No new drop reasons are added.

Seems now we use 'SKB_DROP_REASON_IP_INHDR' for too many case during
ipv6 header parse or check, just like what 'IPSTATS_MIB_INHDRERRORS'
do. Will it be too general and hard to know what happened?

Signed-off-by: Menglong Dong <imagedong@tencent.com>
Reviewed-by: Jiang Biao <benbjiang@tencent.com>
Reviewed-by: Hao Peng <flyingpeng@tencent.com>
---
 net/ipv6/ip6_input.c | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index b4880c7c84eb..1b925ecb26e9 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -145,13 +145,14 @@ static void ip6_list_rcv_finish(struct net *net, struct sock *sk,
 static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev,
 				    struct net *net)
 {
+	enum skb_drop_reason reason;
 	const struct ipv6hdr *hdr;
 	u32 pkt_len;
 	struct inet6_dev *idev;
 
 	if (skb->pkt_type == PACKET_OTHERHOST) {
 		dev_core_stats_rx_otherhost_dropped_inc(skb->dev);
-		kfree_skb(skb);
+		kfree_skb_reason(skb, SKB_DROP_REASON_OTHERHOST);
 		return NULL;
 	}
 
@@ -161,9 +162,12 @@ static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev,
 
 	__IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_IN, skb->len);
 
+	SKB_DR_SET(reason, NOT_SPECIFIED);
 	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL ||
 	    !idev || unlikely(idev->cnf.disable_ipv6)) {
 		__IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS);
+		if (unlikely(idev->cnf.disable_ipv6))
+			SKB_DR_SET(reason, IPV6DISABLED);
 		goto drop;
 	}
 
@@ -187,8 +191,10 @@ static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev,
 
 	hdr = ipv6_hdr(skb);
 
-	if (hdr->version != 6)
+	if (hdr->version != 6) {
+		SKB_DR_SET(reason, UNHANDLED_PROTO);
 		goto err;
+	}
 
 	__IP6_ADD_STATS(net, idev,
 			IPSTATS_MIB_NOECTPKTS +
@@ -226,8 +232,10 @@ static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev,
 	if (!ipv6_addr_is_multicast(&hdr->daddr) &&
 	    (skb->pkt_type == PACKET_BROADCAST ||
 	     skb->pkt_type == PACKET_MULTICAST) &&
-	    idev->cnf.drop_unicast_in_l2_multicast)
+	    idev->cnf.drop_unicast_in_l2_multicast) {
+		SKB_DR_SET(reason, UNICAST_IN_L2_MULTICAST);
 		goto err;
+	}
 
 	/* RFC4291 2.7
 	 * Nodes must not originate a packet to a multicast address whose scope
@@ -256,12 +264,11 @@ static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev,
 		if (pkt_len + sizeof(struct ipv6hdr) > skb->len) {
 			__IP6_INC_STATS(net,
 					idev, IPSTATS_MIB_INTRUNCATEDPKTS);
+			SKB_DR_SET(reason, PKT_TOO_SMALL);
 			goto drop;
 		}
-		if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr))) {
-			__IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
-			goto drop;
-		}
+		if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr)))
+			goto err;
 		hdr = ipv6_hdr(skb);
 	}
 
@@ -282,9 +289,10 @@ static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev,
 	return skb;
 err:
 	__IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
+	SKB_DR_OR(reason, IP_INHDR);
 drop:
 	rcu_read_unlock();
-	kfree_skb(skb);
+	kfree_skb_reason(skb, reason);
 	return NULL;
 }
 
-- 
2.35.1


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

* [PATCH net-next 9/9] net: ipv6: add skb drop reasons to ip6_protocol_deliver_rcu()
  2022-04-13  8:15 [PATCH net-next 0/9] net: ip: add skb drop reasons to ip ingress menglong8.dong
                   ` (7 preceding siblings ...)
  2022-04-13  8:15 ` [PATCH net-next 8/9] net: ipv6: add skb drop reasons to ip6_rcv_core() menglong8.dong
@ 2022-04-13  8:16 ` menglong8.dong
  2022-04-13 13:30 ` [PATCH net-next 0/9] net: ip: add skb drop reasons to ip ingress patchwork-bot+netdevbpf
  9 siblings, 0 replies; 13+ messages in thread
From: menglong8.dong @ 2022-04-13  8:16 UTC (permalink / raw)
  To: dsahern
  Cc: rostedt, mingo, davem, yoshfuji, kuba, pabeni, benbjiang,
	flyingpeng, imagedong, edumazet, kafai, talalahmad, keescook,
	mengensun, dongli.zhang, linux-kernel, netdev

From: Menglong Dong <imagedong@tencent.com>

Replace kfree_skb() used in ip6_protocol_deliver_rcu() with
kfree_skb_reason().

No new reasons are added.

Some paths are ignored, as they are not common, such as encapsulation
on non-final protocol.

Signed-off-by: Menglong Dong <imagedong@tencent.com>
Reviewed-by: Jiang Biao <benbjiang@tencent.com>
Reviewed-by: Hao Peng <flyingpeng@tencent.com>
---
 net/ipv6/ip6_input.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 1b925ecb26e9..126ae3aa67e1 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -362,6 +362,7 @@ void ip6_protocol_deliver_rcu(struct net *net, struct sk_buff *skb, int nexthdr,
 	const struct inet6_protocol *ipprot;
 	struct inet6_dev *idev;
 	unsigned int nhoff;
+	SKB_DR(reason);
 	bool raw;
 
 	/*
@@ -421,12 +422,16 @@ void ip6_protocol_deliver_rcu(struct net *net, struct sk_buff *skb, int nexthdr,
 			if (ipv6_addr_is_multicast(&hdr->daddr) &&
 			    !ipv6_chk_mcast_addr(dev, &hdr->daddr,
 						 &hdr->saddr) &&
-			    !ipv6_is_mld(skb, nexthdr, skb_network_header_len(skb)))
+			    !ipv6_is_mld(skb, nexthdr, skb_network_header_len(skb))) {
+				SKB_DR_SET(reason, IP_INADDRERRORS);
 				goto discard;
+			}
 		}
 		if (!(ipprot->flags & INET6_PROTO_NOPOLICY) &&
-		    !xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
+		    !xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
+			SKB_DR_SET(reason, XFRM_POLICY);
 			goto discard;
+		}
 
 		ret = INDIRECT_CALL_2(ipprot->handler, tcp_v6_rcv, udpv6_rcv,
 				      skb);
@@ -452,8 +457,11 @@ void ip6_protocol_deliver_rcu(struct net *net, struct sk_buff *skb, int nexthdr,
 						IPSTATS_MIB_INUNKNOWNPROTOS);
 				icmpv6_send(skb, ICMPV6_PARAMPROB,
 					    ICMPV6_UNK_NEXTHDR, nhoff);
+				SKB_DR_SET(reason, IP_NOPROTO);
+			} else {
+				SKB_DR_SET(reason, XFRM_POLICY);
 			}
-			kfree_skb(skb);
+			kfree_skb_reason(skb, reason);
 		} else {
 			__IP6_INC_STATS(net, idev, IPSTATS_MIB_INDELIVERS);
 			consume_skb(skb);
@@ -463,7 +471,7 @@ void ip6_protocol_deliver_rcu(struct net *net, struct sk_buff *skb, int nexthdr,
 
 discard:
 	__IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS);
-	kfree_skb(skb);
+	kfree_skb_reason(skb, reason);
 }
 
 static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
-- 
2.35.1


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

* Re: [PATCH net-next 0/9] net: ip: add skb drop reasons to ip ingress
  2022-04-13  8:15 [PATCH net-next 0/9] net: ip: add skb drop reasons to ip ingress menglong8.dong
                   ` (8 preceding siblings ...)
  2022-04-13  8:16 ` [PATCH net-next 9/9] net: ipv6: add skb drop reasons to ip6_protocol_deliver_rcu() menglong8.dong
@ 2022-04-13 13:30 ` patchwork-bot+netdevbpf
  9 siblings, 0 replies; 13+ messages in thread
From: patchwork-bot+netdevbpf @ 2022-04-13 13:30 UTC (permalink / raw)
  To: Menglong Dong
  Cc: dsahern, rostedt, mingo, davem, yoshfuji, kuba, pabeni,
	benbjiang, flyingpeng, imagedong, edumazet, kafai, talalahmad,
	keescook, mengensun, dongli.zhang, linux-kernel, netdev

Hello:

This series was applied to netdev/net-next.git (master)
by David S. Miller <davem@davemloft.net>:

On Wed, 13 Apr 2022 16:15:51 +0800 you wrote:
> From: Menglong Dong <imagedong@tencent.com>
> 
> In the series "net: use kfree_skb_reason() for ip/udp packet receive",
> skb drop reasons are added to the basic ingress path of IPv4. And in
> the series "net: use kfree_skb_reason() for ip/neighbour", the egress
> paths of IPv4 and IPv6 are handled. Related links:
> 
> [...]

Here is the summary with links:
  - [net-next,1/9] skb: add some helpers for skb drop reasons
    https://git.kernel.org/netdev/net-next/c/d6d3146ce532
  - [net-next,2/9] net: ipv4: add skb drop reasons to ip_error()
    https://git.kernel.org/netdev/net-next/c/c4eb664191b4
  - [net-next,3/9] net: ipv6: add skb drop reasons to ip6_pkt_drop()
    https://git.kernel.org/netdev/net-next/c/3ae42cc8092b
  - [net-next,4/9] net: ip: add skb drop reasons to ip forwarding
    https://git.kernel.org/netdev/net-next/c/2edc1a383fda
  - [net-next,5/9] net: icmp: introduce function icmpv6_param_prob_reason()
    https://git.kernel.org/netdev/net-next/c/1ad6d548e2a4
  - [net-next,6/9] net: ipv6: remove redundant statistics in ipv6_hop_jumbo()
    https://git.kernel.org/netdev/net-next/c/bba98083499f
  - [net-next,7/9] net: ipv6: add skb drop reasons to TLV parse
    https://git.kernel.org/netdev/net-next/c/7d9dbdfbfdc5
  - [net-next,8/9] net: ipv6: add skb drop reasons to ip6_rcv_core()
    https://git.kernel.org/netdev/net-next/c/4daf841a2ef3
  - [net-next,9/9] net: ipv6: add skb drop reasons to ip6_protocol_deliver_rcu()
    https://git.kernel.org/netdev/net-next/c/eeab7e7ff43e

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



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

* Re: [PATCH net-next 8/9] net: ipv6: add skb drop reasons to ip6_rcv_core()
  2022-04-13  8:15 ` [PATCH net-next 8/9] net: ipv6: add skb drop reasons to ip6_rcv_core() menglong8.dong
@ 2022-04-13 20:40   ` Eric Dumazet
  2022-04-14  1:20     ` Menglong Dong
  0 siblings, 1 reply; 13+ messages in thread
From: Eric Dumazet @ 2022-04-13 20:40 UTC (permalink / raw)
  To: menglong8.dong, dsahern
  Cc: rostedt, mingo, davem, yoshfuji, kuba, pabeni, benbjiang,
	flyingpeng, imagedong, edumazet, kafai, talalahmad, keescook,
	mengensun, dongli.zhang, linux-kernel, netdev


On 4/13/22 01:15, menglong8.dong@gmail.com wrote:
> From: Menglong Dong <imagedong@tencent.com>
>
> Replace kfree_skb() used in ip6_rcv_core() with kfree_skb_reason().
> No new drop reasons are added.
>
> Seems now we use 'SKB_DROP_REASON_IP_INHDR' for too many case during
> ipv6 header parse or check, just like what 'IPSTATS_MIB_INHDRERRORS'
> do. Will it be too general and hard to know what happened?
>
> Signed-off-by: Menglong Dong <imagedong@tencent.com>
> Reviewed-by: Jiang Biao <benbjiang@tencent.com>
> Reviewed-by: Hao Peng <flyingpeng@tencent.com>
> ---
>   net/ipv6/ip6_input.c | 24 ++++++++++++++++--------
>   1 file changed, 16 insertions(+), 8 deletions(-)
>
> diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
> index b4880c7c84eb..1b925ecb26e9 100644
> --- a/net/ipv6/ip6_input.c
> +++ b/net/ipv6/ip6_input.c
> @@ -145,13 +145,14 @@ static void ip6_list_rcv_finish(struct net *net, struct sock *sk,
>   static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev,
>   				    struct net *net)
>   {
> +	enum skb_drop_reason reason;
>   	const struct ipv6hdr *hdr;
>   	u32 pkt_len;
>   	struct inet6_dev *idev;
>   
>   	if (skb->pkt_type == PACKET_OTHERHOST) {
>   		dev_core_stats_rx_otherhost_dropped_inc(skb->dev);
> -		kfree_skb(skb);
> +		kfree_skb_reason(skb, SKB_DROP_REASON_OTHERHOST);
>   		return NULL;
>   	}
>   
> @@ -161,9 +162,12 @@ static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev,
>   
>   	__IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_IN, skb->len);
>   
> +	SKB_DR_SET(reason, NOT_SPECIFIED);
>   	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL ||
>   	    !idev || unlikely(idev->cnf.disable_ipv6)) {
>   		__IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS);
> +		if (unlikely(idev->cnf.disable_ipv6))

idev can be NULL here (according to surrounding code), and we crash :/



> +			SKB_DR_SET(reason, IPV6DISABLED);
>   		goto drop;
>   	}
>   
> @@ -187,8 +191,10 @@ static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev,
>   
>   	hdr = ipv6_hdr(skb);
>   
> -	if (hdr->version != 6)
> +	if (hdr->version != 6) {
> +		SKB_DR_SET(reason, UNHANDLED_PROTO);
>   		goto err;
> +	}
>   
>   	__IP6_ADD_STATS(net, idev,
>   			IPSTATS_MIB_NOECTPKTS +
> @@ -226,8 +232,10 @@ static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev,
>   	if (!ipv6_addr_is_multicast(&hdr->daddr) &&
>   	    (skb->pkt_type == PACKET_BROADCAST ||
>   	     skb->pkt_type == PACKET_MULTICAST) &&
> -	    idev->cnf.drop_unicast_in_l2_multicast)
> +	    idev->cnf.drop_unicast_in_l2_multicast) {
> +		SKB_DR_SET(reason, UNICAST_IN_L2_MULTICAST);
>   		goto err;
> +	}
>   
>   	/* RFC4291 2.7
>   	 * Nodes must not originate a packet to a multicast address whose scope
> @@ -256,12 +264,11 @@ static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev,
>   		if (pkt_len + sizeof(struct ipv6hdr) > skb->len) {
>   			__IP6_INC_STATS(net,
>   					idev, IPSTATS_MIB_INTRUNCATEDPKTS);
> +			SKB_DR_SET(reason, PKT_TOO_SMALL);
>   			goto drop;
>   		}
> -		if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr))) {
> -			__IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
> -			goto drop;
> -		}
> +		if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr)))
> +			goto err;
>   		hdr = ipv6_hdr(skb);
>   	}
>   
> @@ -282,9 +289,10 @@ static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev,
>   	return skb;
>   err:
>   	__IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
> +	SKB_DR_OR(reason, IP_INHDR);
>   drop:
>   	rcu_read_unlock();
> -	kfree_skb(skb);
> +	kfree_skb_reason(skb, reason);
>   	return NULL;
>   }
>   

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

* Re: [PATCH net-next 8/9] net: ipv6: add skb drop reasons to ip6_rcv_core()
  2022-04-13 20:40   ` Eric Dumazet
@ 2022-04-14  1:20     ` Menglong Dong
  0 siblings, 0 replies; 13+ messages in thread
From: Menglong Dong @ 2022-04-14  1:20 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: David Ahern, Steven Rostedt, Ingo Molnar, David Miller,
	Hideaki YOSHIFUJI, Jakub Kicinski, Paolo Abeni, Biao Jiang,
	Hao Peng, Menglong Dong, Eric Dumazet, Martin Lau, Talal Ahmad,
	Kees Cook, Mengen Sun, dongli.zhang, LKML, netdev

On Thu, Apr 14, 2022 at 4:41 AM Eric Dumazet <edumazet@gmail.com> wrote:
>
>
> On 4/13/22 01:15, menglong8.dong@gmail.com wrote:
> > From: Menglong Dong <imagedong@tencent.com>
> >
> > Replace kfree_skb() used in ip6_rcv_core() with kfree_skb_reason().
> > No new drop reasons are added.
> >
> > Seems now we use 'SKB_DROP_REASON_IP_INHDR' for too many case during
> > ipv6 header parse or check, just like what 'IPSTATS_MIB_INHDRERRORS'
> > do. Will it be too general and hard to know what happened?
> >
> > Signed-off-by: Menglong Dong <imagedong@tencent.com>
> > Reviewed-by: Jiang Biao <benbjiang@tencent.com>
> > Reviewed-by: Hao Peng <flyingpeng@tencent.com>
> > ---
> >   net/ipv6/ip6_input.c | 24 ++++++++++++++++--------
> >   1 file changed, 16 insertions(+), 8 deletions(-)
> >
> > diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
> > index b4880c7c84eb..1b925ecb26e9 100644
> > --- a/net/ipv6/ip6_input.c
> > +++ b/net/ipv6/ip6_input.c
> > @@ -145,13 +145,14 @@ static void ip6_list_rcv_finish(struct net *net, struct sock *sk,
> >   static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev,
> >                                   struct net *net)
> >   {
> > +     enum skb_drop_reason reason;
> >       const struct ipv6hdr *hdr;
> >       u32 pkt_len;
> >       struct inet6_dev *idev;
> >
> >       if (skb->pkt_type == PACKET_OTHERHOST) {
> >               dev_core_stats_rx_otherhost_dropped_inc(skb->dev);
> > -             kfree_skb(skb);
> > +             kfree_skb_reason(skb, SKB_DROP_REASON_OTHERHOST);
> >               return NULL;
> >       }
> >
> > @@ -161,9 +162,12 @@ static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev,
> >
> >       __IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_IN, skb->len);
> >
> > +     SKB_DR_SET(reason, NOT_SPECIFIED);
> >       if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL ||
> >           !idev || unlikely(idev->cnf.disable_ipv6)) {
> >               __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS);
> > +             if (unlikely(idev->cnf.disable_ipv6))
>
> idev can be NULL here (according to surrounding code), and we crash :/

Yeah, you are right :)

Thanks for your fix!

>
>
>
> > +                     SKB_DR_SET(reason, IPV6DISABLED);
> >               goto drop;
> >       }
> >
> > @@ -187,8 +191,10 @@ static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev,
> >
> >       hdr = ipv6_hdr(skb);
> >
> > -     if (hdr->version != 6)
> > +     if (hdr->version != 6) {
> > +             SKB_DR_SET(reason, UNHANDLED_PROTO);
> >               goto err;
> > +     }
> >
> >       __IP6_ADD_STATS(net, idev,
> >                       IPSTATS_MIB_NOECTPKTS +
> > @@ -226,8 +232,10 @@ static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev,
> >       if (!ipv6_addr_is_multicast(&hdr->daddr) &&
> >           (skb->pkt_type == PACKET_BROADCAST ||
> >            skb->pkt_type == PACKET_MULTICAST) &&
> > -         idev->cnf.drop_unicast_in_l2_multicast)
> > +         idev->cnf.drop_unicast_in_l2_multicast) {
> > +             SKB_DR_SET(reason, UNICAST_IN_L2_MULTICAST);
> >               goto err;
> > +     }
> >
> >       /* RFC4291 2.7
> >        * Nodes must not originate a packet to a multicast address whose scope
> > @@ -256,12 +264,11 @@ static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev,
> >               if (pkt_len + sizeof(struct ipv6hdr) > skb->len) {
> >                       __IP6_INC_STATS(net,
> >                                       idev, IPSTATS_MIB_INTRUNCATEDPKTS);
> > +                     SKB_DR_SET(reason, PKT_TOO_SMALL);
> >                       goto drop;
> >               }
> > -             if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr))) {
> > -                     __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
> > -                     goto drop;
> > -             }
> > +             if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr)))
> > +                     goto err;
> >               hdr = ipv6_hdr(skb);
> >       }
> >
> > @@ -282,9 +289,10 @@ static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev,
> >       return skb;
> >   err:
> >       __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
> > +     SKB_DR_OR(reason, IP_INHDR);
> >   drop:
> >       rcu_read_unlock();
> > -     kfree_skb(skb);
> > +     kfree_skb_reason(skb, reason);
> >       return NULL;
> >   }
> >

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

end of thread, other threads:[~2022-04-14  1:20 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-13  8:15 [PATCH net-next 0/9] net: ip: add skb drop reasons to ip ingress menglong8.dong
2022-04-13  8:15 ` [PATCH net-next 1/9] skb: add some helpers for skb drop reasons menglong8.dong
2022-04-13  8:15 ` [PATCH net-next 2/9] net: ipv4: add skb drop reasons to ip_error() menglong8.dong
2022-04-13  8:15 ` [PATCH net-next 3/9] net: ipv6: add skb drop reasons to ip6_pkt_drop() menglong8.dong
2022-04-13  8:15 ` [PATCH net-next 4/9] net: ip: add skb drop reasons to ip forwarding menglong8.dong
2022-04-13  8:15 ` [PATCH net-next 5/9] net: icmp: introduce function icmpv6_param_prob_reason() menglong8.dong
2022-04-13  8:15 ` [PATCH net-next 6/9] net: ipv6: remove redundant statistics in ipv6_hop_jumbo() menglong8.dong
2022-04-13  8:15 ` [PATCH net-next 7/9] net: ipv6: add skb drop reasons to TLV parse menglong8.dong
2022-04-13  8:15 ` [PATCH net-next 8/9] net: ipv6: add skb drop reasons to ip6_rcv_core() menglong8.dong
2022-04-13 20:40   ` Eric Dumazet
2022-04-14  1:20     ` Menglong Dong
2022-04-13  8:16 ` [PATCH net-next 9/9] net: ipv6: add skb drop reasons to ip6_protocol_deliver_rcu() menglong8.dong
2022-04-13 13:30 ` [PATCH net-next 0/9] net: ip: add skb drop reasons to ip ingress patchwork-bot+netdevbpf

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).