Commit 0d92efde authored by Donald Hunter's avatar Donald Hunter Committed by Jakub Kicinski
Browse files

Add skb drop reasons to IPv6 UDP receive path



Enumerate the skb drop reasons in the receive path for IPv6 UDP packets.

Signed-off-by: default avatarDonald Hunter <donald.hunter@redhat.com>
Link: https://lore.kernel.org/r/20220926120350.14928-1-donald.hunter@gmail.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent ab7ea1e7
Loading
Loading
Loading
Loading
+16 −6
Original line number Diff line number Diff line
@@ -650,16 +650,20 @@ static int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
	rc = __udp_enqueue_schedule_skb(sk, skb);
	if (rc < 0) {
		int is_udplite = IS_UDPLITE(sk);
		enum skb_drop_reason drop_reason;

		/* Note that an ENOMEM error is charged twice */
		if (rc == -ENOMEM)
		if (rc == -ENOMEM) {
			UDP6_INC_STATS(sock_net(sk),
					 UDP_MIB_RCVBUFERRORS, is_udplite);
		else
			drop_reason = SKB_DROP_REASON_SOCKET_RCVBUFF;
		} else {
			UDP6_INC_STATS(sock_net(sk),
				       UDP_MIB_MEMERRORS, is_udplite);
			drop_reason = SKB_DROP_REASON_PROTO_MEM;
		}
		UDP6_INC_STATS(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
		kfree_skb(skb);
		kfree_skb_reason(skb, drop_reason);
		return -1;
	}

@@ -675,11 +679,14 @@ static __inline__ int udpv6_err(struct sk_buff *skb,

static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
{
	enum skb_drop_reason drop_reason = SKB_DROP_REASON_NOT_SPECIFIED;
	struct udp_sock *up = udp_sk(sk);
	int is_udplite = IS_UDPLITE(sk);

	if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
	if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) {
		drop_reason = SKB_DROP_REASON_XFRM_POLICY;
		goto drop;
	}

	if (static_branch_unlikely(&udpv6_encap_needed_key) && up->encap_type) {
		int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);
@@ -738,8 +745,10 @@ static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
	    udp_lib_checksum_complete(skb))
		goto csum_error;

	if (sk_filter_trim_cap(sk, skb, sizeof(struct udphdr)))
	if (sk_filter_trim_cap(sk, skb, sizeof(struct udphdr))) {
		drop_reason = SKB_DROP_REASON_SOCKET_FILTER;
		goto drop;
	}

	udp_csum_pull_header(skb);

@@ -748,11 +757,12 @@ static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
	return __udpv6_queue_rcv_skb(sk, skb);

csum_error:
	drop_reason = SKB_DROP_REASON_UDP_CSUM;
	__UDP6_INC_STATS(sock_net(sk), UDP_MIB_CSUMERRORS, is_udplite);
drop:
	__UDP6_INC_STATS(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
	atomic_inc(&sk->sk_drops);
	kfree_skb(skb);
	kfree_skb_reason(skb, drop_reason);
	return -1;
}