Commit 4aaa4895 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'ip-neigh-skb-reason'

Menglong Dong says:

====================
net: use kfree_skb_reason() for ip/neighbour

In the series "net: use kfree_skb_reason() for ip/udp packet receive",
reasons for skb drops are added to the packet receive process of IP
layer. Link:

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



And in the first patch of this series, skb drop reasons are added to
the packet egress path of IP layer. As kfree_skb() is not used frequent,
I commit these changes at once and didn't create a patch for every
functions that involed. Following functions are handled:

__ip_queue_xmit()
ip_finish_output()
ip_mc_finish_output()
ip6_output()
ip6_finish_output()
ip6_finish_output2()

Following new drop reasons are introduced (what they mean can be seen
in the document of them):

SKB_DROP_REASON_IP_OUTNOROUTES
SKB_DROP_REASON_BPF_CGROUP_EGRESS
SKB_DROP_REASON_IPV6DISABLED
SKB_DROP_REASON_NEIGH_CREATEFAIL

In the 2th and 3th patches, kfree_skb_reason() is used in neighbour
subsystem instead of kfree_skb(). __neigh_event_send() and
arp_error_report() are involed, and following new drop reasons are
introduced:

SKB_DROP_REASON_NEIGH_FAILED
SKB_DROP_REASON_NEIGH_QUEUEFULL
SKB_DROP_REASON_NEIGH_DEAD

Changes since v2:
- fix typo in the 1th patch of 'SKB_DROP_REASON_IPV6DSIABLED' reported
  by Roman

Changes since v1:
- introduce SKB_DROP_REASON_NEIGH_CREATEFAIL for some path in the 1th
  patch
- introduce SKB_DROP_REASON_NEIGH_DEAD in the 2th patch
- simplify the document for the new drop reasons, as David Ahern
  suggested
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 0cc70c6e 56d4b4e4
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -380,6 +380,20 @@ enum skb_drop_reason {
					 * the ofo queue, corresponding to
					 * LINUX_MIB_TCPOFOMERGE
					 */
	SKB_DROP_REASON_IP_OUTNOROUTES,	/* route lookup failed */
	SKB_DROP_REASON_BPF_CGROUP_EGRESS,	/* dropped by
						 * BPF_PROG_TYPE_CGROUP_SKB
						 * eBPF program
						 */
	SKB_DROP_REASON_IPV6DISABLED,	/* IPv6 is disabled on the device */
	SKB_DROP_REASON_NEIGH_CREATEFAIL,	/* failed to create neigh
						 * entry
						 */
	SKB_DROP_REASON_NEIGH_FAILED,	/* neigh entry in failed state */
	SKB_DROP_REASON_NEIGH_QUEUEFULL,	/* arp_queue for neigh
						 * entry is full
						 */
	SKB_DROP_REASON_NEIGH_DEAD,	/* neigh entry is dead */
	SKB_DROP_REASON_MAX,
};

+8 −0
Original line number Diff line number Diff line
@@ -37,6 +37,14 @@
	EM(SKB_DROP_REASON_TCP_OLD_DATA, TCP_OLD_DATA)		\
	EM(SKB_DROP_REASON_TCP_OVERWINDOW, TCP_OVERWINDOW)	\
	EM(SKB_DROP_REASON_TCP_OFOMERGE, TCP_OFOMERGE)		\
	EM(SKB_DROP_REASON_IP_OUTNOROUTES, IP_OUTNOROUTES)	\
	EM(SKB_DROP_REASON_BPF_CGROUP_EGRESS,			\
	   BPF_CGROUP_EGRESS)					\
	EM(SKB_DROP_REASON_IPV6DISABLED, IPV6DISABLED)		\
	EM(SKB_DROP_REASON_NEIGH_CREATEFAIL, NEIGH_CREATEFAIL)	\
	EM(SKB_DROP_REASON_NEIGH_FAILED, NEIGH_FAILED)		\
	EM(SKB_DROP_REASON_NEIGH_QUEUEFULL, NEIGH_QUEUEFULL)	\
	EM(SKB_DROP_REASON_NEIGH_DEAD, NEIGH_DEAD)		\
	EMe(SKB_DROP_REASON_MAX, MAX)

#undef EM
+3 −3
Original line number Diff line number Diff line
@@ -1171,7 +1171,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb,
			neigh->updated = jiffies;
			write_unlock_bh(&neigh->lock);

			kfree_skb(skb);
			kfree_skb_reason(skb, SKB_DROP_REASON_NEIGH_FAILED);
			return 1;
		}
	} else if (neigh->nud_state & NUD_STALE) {
@@ -1193,7 +1193,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb,
				if (!buff)
					break;
				neigh->arp_queue_len_bytes -= buff->truesize;
				kfree_skb(buff);
				kfree_skb_reason(buff, SKB_DROP_REASON_NEIGH_QUEUEFULL);
				NEIGH_CACHE_STAT_INC(neigh->tbl, unres_discards);
			}
			skb_dst_force(skb);
@@ -1215,7 +1215,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb,
	if (neigh->nud_state & NUD_STALE)
		goto out_unlock_bh;
	write_unlock_bh(&neigh->lock);
	kfree_skb(skb);
	kfree_skb_reason(skb, SKB_DROP_REASON_NEIGH_DEAD);
	trace_neigh_event_send_dead(neigh, 1);
	return 1;
}
+1 −1
Original line number Diff line number Diff line
@@ -293,7 +293,7 @@ static int arp_constructor(struct neighbour *neigh)
static void arp_error_report(struct neighbour *neigh, struct sk_buff *skb)
{
	dst_link_failure(skb);
	kfree_skb(skb);
	kfree_skb_reason(skb, SKB_DROP_REASON_NEIGH_FAILED);
}

/* Create and send an arp packet. */
+4 −4
Original line number Diff line number Diff line
@@ -233,7 +233,7 @@ static int ip_finish_output2(struct net *net, struct sock *sk, struct sk_buff *s

	net_dbg_ratelimited("%s: No header cache and no neighbour!\n",
			    __func__);
	kfree_skb(skb);
	kfree_skb_reason(skb, SKB_DROP_REASON_NEIGH_CREATEFAIL);
	return -EINVAL;
}

@@ -317,7 +317,7 @@ static int ip_finish_output(struct net *net, struct sock *sk, struct sk_buff *sk
	case NET_XMIT_CN:
		return __ip_finish_output(net, sk, skb) ? : ret;
	default:
		kfree_skb(skb);
		kfree_skb_reason(skb, SKB_DROP_REASON_BPF_CGROUP_EGRESS);
		return ret;
	}
}
@@ -337,7 +337,7 @@ static int ip_mc_finish_output(struct net *net, struct sock *sk,
	case NET_XMIT_SUCCESS:
		break;
	default:
		kfree_skb(skb);
		kfree_skb_reason(skb, SKB_DROP_REASON_BPF_CGROUP_EGRESS);
		return ret;
	}

@@ -536,7 +536,7 @@ int __ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
no_route:
	rcu_read_unlock();
	IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
	kfree_skb(skb);
	kfree_skb_reason(skb, SKB_DROP_REASON_IP_OUTNOROUTES);
	return -EHOSTUNREACH;
}
EXPORT_SYMBOL(__ip_queue_xmit);
Loading