Commit 2f3a247c authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'net-extend-drop-reasons'

Johannes Berg says:

====================
net: extend drop reasons

Here's v4 of the extended drop reasons, with fixes to kernel-doc
and checkpatch.
====================

Link: https://lore.kernel.org/r/20230419125254.20789-1-johannes@sipsolutions.netSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 7ab75456 baa951a1
......@@ -52,7 +52,7 @@
#include <linux/rbtree.h>
#include <net/net_trackers.h>
#include <net/net_debug.h>
#include <net/dropreason.h>
#include <net/dropreason-core.h>
struct netpoll_info;
struct device;
......
......@@ -37,7 +37,7 @@
#include <linux/netfilter/nf_conntrack_common.h>
#endif
#include <net/net_debug.h>
#include <net/dropreason.h>
#include <net/dropreason-core.h>
/**
* DOC: skb checksums
......
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef _LINUX_DROPREASON_CORE_H
#define _LINUX_DROPREASON_CORE_H
#define DEFINE_DROP_REASON(FN, FNe) \
FN(NOT_SPECIFIED) \
FN(NO_SOCKET) \
FN(PKT_TOO_SMALL) \
FN(TCP_CSUM) \
FN(SOCKET_FILTER) \
FN(UDP_CSUM) \
FN(NETFILTER_DROP) \
FN(OTHERHOST) \
FN(IP_CSUM) \
FN(IP_INHDR) \
FN(IP_RPFILTER) \
FN(UNICAST_IN_L2_MULTICAST) \
FN(XFRM_POLICY) \
FN(IP_NOPROTO) \
FN(SOCKET_RCVBUFF) \
FN(PROTO_MEM) \
FN(TCP_MD5NOTFOUND) \
FN(TCP_MD5UNEXPECTED) \
FN(TCP_MD5FAILURE) \
FN(SOCKET_BACKLOG) \
FN(TCP_FLAGS) \
FN(TCP_ZEROWINDOW) \
FN(TCP_OLD_DATA) \
FN(TCP_OVERWINDOW) \
FN(TCP_OFOMERGE) \
FN(TCP_RFC7323_PAWS) \
FN(TCP_INVALID_SEQUENCE) \
FN(TCP_RESET) \
FN(TCP_INVALID_SYN) \
FN(TCP_CLOSE) \
FN(TCP_FASTOPEN) \
FN(TCP_OLD_ACK) \
FN(TCP_TOO_OLD_ACK) \
FN(TCP_ACK_UNSENT_DATA) \
FN(TCP_OFO_QUEUE_PRUNE) \
FN(TCP_OFO_DROP) \
FN(IP_OUTNOROUTES) \
FN(BPF_CGROUP_EGRESS) \
FN(IPV6DISABLED) \
FN(NEIGH_CREATEFAIL) \
FN(NEIGH_FAILED) \
FN(NEIGH_QUEUEFULL) \
FN(NEIGH_DEAD) \
FN(TC_EGRESS) \
FN(QDISC_DROP) \
FN(CPU_BACKLOG) \
FN(XDP) \
FN(TC_INGRESS) \
FN(UNHANDLED_PROTO) \
FN(SKB_CSUM) \
FN(SKB_GSO_SEG) \
FN(SKB_UCOPY_FAULT) \
FN(DEV_HDR) \
FN(DEV_READY) \
FN(FULL_RING) \
FN(NOMEM) \
FN(HDR_TRUNC) \
FN(TAP_FILTER) \
FN(TAP_TXFILTER) \
FN(ICMP_CSUM) \
FN(INVALID_PROTO) \
FN(IP_INADDRERRORS) \
FN(IP_INNOROUTES) \
FN(PKT_TOO_BIG) \
FN(DUP_FRAG) \
FN(FRAG_REASM_TIMEOUT) \
FN(FRAG_TOO_FAR) \
FN(TCP_MINTTL) \
FN(IPV6_BAD_EXTHDR) \
FN(IPV6_NDISC_FRAG) \
FN(IPV6_NDISC_HOP_LIMIT) \
FN(IPV6_NDISC_BAD_CODE) \
FN(IPV6_NDISC_BAD_OPTIONS) \
FN(IPV6_NDISC_NS_OTHERHOST) \
FNe(MAX)
/**
* enum skb_drop_reason - the reasons of skb drops
*
* The reason of skb drop, which is used in kfree_skb_reason().
*/
enum skb_drop_reason {
/**
* @SKB_NOT_DROPPED_YET: skb is not dropped yet (used for no-drop case)
*/
SKB_NOT_DROPPED_YET = 0,
/** @SKB_CONSUMED: packet has been consumed */
SKB_CONSUMED,
/** @SKB_DROP_REASON_NOT_SPECIFIED: drop reason is not specified */
SKB_DROP_REASON_NOT_SPECIFIED,
/** @SKB_DROP_REASON_NO_SOCKET: socket not found */
SKB_DROP_REASON_NO_SOCKET,
/** @SKB_DROP_REASON_PKT_TOO_SMALL: packet size is too small */
SKB_DROP_REASON_PKT_TOO_SMALL,
/** @SKB_DROP_REASON_TCP_CSUM: TCP checksum error */
SKB_DROP_REASON_TCP_CSUM,
/** @SKB_DROP_REASON_SOCKET_FILTER: dropped by socket filter */
SKB_DROP_REASON_SOCKET_FILTER,
/** @SKB_DROP_REASON_UDP_CSUM: UDP checksum error */
SKB_DROP_REASON_UDP_CSUM,
/** @SKB_DROP_REASON_NETFILTER_DROP: dropped by netfilter */
SKB_DROP_REASON_NETFILTER_DROP,
/**
* @SKB_DROP_REASON_OTHERHOST: packet don't belong to current host
* (interface is in promisc mode)
*/
SKB_DROP_REASON_OTHERHOST,
/** @SKB_DROP_REASON_IP_CSUM: IP checksum error */
SKB_DROP_REASON_IP_CSUM,
/**
* @SKB_DROP_REASON_IP_INHDR: there is something wrong with IP header (see
* IPSTATS_MIB_INHDRERRORS)
*/
SKB_DROP_REASON_IP_INHDR,
/**
* @SKB_DROP_REASON_IP_RPFILTER: IP rpfilter validate failed. see the
* document for rp_filter in ip-sysctl.rst for more information
*/
SKB_DROP_REASON_IP_RPFILTER,
/**
* @SKB_DROP_REASON_UNICAST_IN_L2_MULTICAST: destination address of L2 is
* multicast, but L3 is unicast.
*/
SKB_DROP_REASON_UNICAST_IN_L2_MULTICAST,
/** @SKB_DROP_REASON_XFRM_POLICY: xfrm policy check failed */
SKB_DROP_REASON_XFRM_POLICY,
/** @SKB_DROP_REASON_IP_NOPROTO: no support for IP protocol */
SKB_DROP_REASON_IP_NOPROTO,
/** @SKB_DROP_REASON_SOCKET_RCVBUFF: socket receive buff is full */
SKB_DROP_REASON_SOCKET_RCVBUFF,
/**
* @SKB_DROP_REASON_PROTO_MEM: proto memory limition, such as udp packet
* drop out of udp_memory_allocated.
*/
SKB_DROP_REASON_PROTO_MEM,
/**
* @SKB_DROP_REASON_TCP_MD5NOTFOUND: no MD5 hash and one expected,
* corresponding to LINUX_MIB_TCPMD5NOTFOUND
*/
SKB_DROP_REASON_TCP_MD5NOTFOUND,
/**
* @SKB_DROP_REASON_TCP_MD5UNEXPECTED: MD5 hash and we're not expecting
* one, corresponding to LINUX_MIB_TCPMD5UNEXPECTED
*/
SKB_DROP_REASON_TCP_MD5UNEXPECTED,
/**
* @SKB_DROP_REASON_TCP_MD5FAILURE: MD5 hash and its wrong, corresponding
* to LINUX_MIB_TCPMD5FAILURE
*/
SKB_DROP_REASON_TCP_MD5FAILURE,
/**
* @SKB_DROP_REASON_SOCKET_BACKLOG: failed to add skb to socket backlog (
* see LINUX_MIB_TCPBACKLOGDROP)
*/
SKB_DROP_REASON_SOCKET_BACKLOG,
/** @SKB_DROP_REASON_TCP_FLAGS: TCP flags invalid */
SKB_DROP_REASON_TCP_FLAGS,
/**
* @SKB_DROP_REASON_TCP_ZEROWINDOW: TCP receive window size is zero,
* see LINUX_MIB_TCPZEROWINDOWDROP
*/
SKB_DROP_REASON_TCP_ZEROWINDOW,
/**
* @SKB_DROP_REASON_TCP_OLD_DATA: the TCP data reveived is already
* received before (spurious retrans may happened), see
* LINUX_MIB_DELAYEDACKLOST
*/
SKB_DROP_REASON_TCP_OLD_DATA,
/**
* @SKB_DROP_REASON_TCP_OVERWINDOW: the TCP data is out of window,
* the seq of the first byte exceed the right edges of receive
* window
*/
SKB_DROP_REASON_TCP_OVERWINDOW,
/**
* @SKB_DROP_REASON_TCP_OFOMERGE: the data of skb is already in the ofo
* queue, corresponding to LINUX_MIB_TCPOFOMERGE
*/
SKB_DROP_REASON_TCP_OFOMERGE,
/**
* @SKB_DROP_REASON_TCP_RFC7323_PAWS: PAWS check, corresponding to
* LINUX_MIB_PAWSESTABREJECTED
*/
SKB_DROP_REASON_TCP_RFC7323_PAWS,
/** @SKB_DROP_REASON_TCP_INVALID_SEQUENCE: Not acceptable SEQ field */
SKB_DROP_REASON_TCP_INVALID_SEQUENCE,
/** @SKB_DROP_REASON_TCP_RESET: Invalid RST packet */
SKB_DROP_REASON_TCP_RESET,
/**
* @SKB_DROP_REASON_TCP_INVALID_SYN: Incoming packet has unexpected
* SYN flag
*/
SKB_DROP_REASON_TCP_INVALID_SYN,
/** @SKB_DROP_REASON_TCP_CLOSE: TCP socket in CLOSE state */
SKB_DROP_REASON_TCP_CLOSE,
/** @SKB_DROP_REASON_TCP_FASTOPEN: dropped by FASTOPEN request socket */
SKB_DROP_REASON_TCP_FASTOPEN,
/** @SKB_DROP_REASON_TCP_OLD_ACK: TCP ACK is old, but in window */
SKB_DROP_REASON_TCP_OLD_ACK,
/** @SKB_DROP_REASON_TCP_TOO_OLD_ACK: TCP ACK is too old */
SKB_DROP_REASON_TCP_TOO_OLD_ACK,
/**
* @SKB_DROP_REASON_TCP_ACK_UNSENT_DATA: TCP ACK for data we haven't
* sent yet
*/
SKB_DROP_REASON_TCP_ACK_UNSENT_DATA,
/** @SKB_DROP_REASON_TCP_OFO_QUEUE_PRUNE: pruned from TCP OFO queue */
SKB_DROP_REASON_TCP_OFO_QUEUE_PRUNE,
/** @SKB_DROP_REASON_TCP_OFO_DROP: data already in receive queue */
SKB_DROP_REASON_TCP_OFO_DROP,
/** @SKB_DROP_REASON_IP_OUTNOROUTES: route lookup failed */
SKB_DROP_REASON_IP_OUTNOROUTES,
/**
* @SKB_DROP_REASON_BPF_CGROUP_EGRESS: dropped by BPF_PROG_TYPE_CGROUP_SKB
* eBPF program
*/
SKB_DROP_REASON_BPF_CGROUP_EGRESS,
/** @SKB_DROP_REASON_IPV6DISABLED: IPv6 is disabled on the device */
SKB_DROP_REASON_IPV6DISABLED,
/** @SKB_DROP_REASON_NEIGH_CREATEFAIL: failed to create neigh entry */
SKB_DROP_REASON_NEIGH_CREATEFAIL,
/** @SKB_DROP_REASON_NEIGH_FAILED: neigh entry in failed state */
SKB_DROP_REASON_NEIGH_FAILED,
/** @SKB_DROP_REASON_NEIGH_QUEUEFULL: arp_queue for neigh entry is full */
SKB_DROP_REASON_NEIGH_QUEUEFULL,
/** @SKB_DROP_REASON_NEIGH_DEAD: neigh entry is dead */
SKB_DROP_REASON_NEIGH_DEAD,
/** @SKB_DROP_REASON_TC_EGRESS: dropped in TC egress HOOK */
SKB_DROP_REASON_TC_EGRESS,
/**
* @SKB_DROP_REASON_QDISC_DROP: dropped by qdisc when packet outputting (
* failed to enqueue to current qdisc)
*/
SKB_DROP_REASON_QDISC_DROP,
/**
* @SKB_DROP_REASON_CPU_BACKLOG: failed to enqueue the skb to the per CPU
* backlog queue. This can be caused by backlog queue full (see
* netdev_max_backlog in net.rst) or RPS flow limit
*/
SKB_DROP_REASON_CPU_BACKLOG,
/** @SKB_DROP_REASON_XDP: dropped by XDP in input path */
SKB_DROP_REASON_XDP,
/** @SKB_DROP_REASON_TC_INGRESS: dropped in TC ingress HOOK */
SKB_DROP_REASON_TC_INGRESS,
/** @SKB_DROP_REASON_UNHANDLED_PROTO: protocol not implemented or not supported */
SKB_DROP_REASON_UNHANDLED_PROTO,
/** @SKB_DROP_REASON_SKB_CSUM: sk_buff checksum computation error */
SKB_DROP_REASON_SKB_CSUM,
/** @SKB_DROP_REASON_SKB_GSO_SEG: gso segmentation error */
SKB_DROP_REASON_SKB_GSO_SEG,
/**
* @SKB_DROP_REASON_SKB_UCOPY_FAULT: failed to copy data from user space,
* e.g., via zerocopy_sg_from_iter() or skb_orphan_frags_rx()
*/
SKB_DROP_REASON_SKB_UCOPY_FAULT,
/** @SKB_DROP_REASON_DEV_HDR: device driver specific header/metadata is invalid */
SKB_DROP_REASON_DEV_HDR,
/**
* @SKB_DROP_REASON_DEV_READY: the device is not ready to xmit/recv due to
* any of its data structure that is not up/ready/initialized,
* e.g., the IFF_UP is not set, or driver specific tun->tfiles[txq]
* is not initialized
*/
SKB_DROP_REASON_DEV_READY,
/** @SKB_DROP_REASON_FULL_RING: ring buffer is full */
SKB_DROP_REASON_FULL_RING,
/** @SKB_DROP_REASON_NOMEM: error due to OOM */
SKB_DROP_REASON_NOMEM,
/**
* @SKB_DROP_REASON_HDR_TRUNC: failed to trunc/extract the header from
* networking data, e.g., failed to pull the protocol header from
* frags via pskb_may_pull()
*/
SKB_DROP_REASON_HDR_TRUNC,
/**
* @SKB_DROP_REASON_TAP_FILTER: dropped by (ebpf) filter directly attached
* to tun/tap, e.g., via TUNSETFILTEREBPF
*/
SKB_DROP_REASON_TAP_FILTER,
/**
* @SKB_DROP_REASON_TAP_TXFILTER: dropped by tx filter implemented at
* tun/tap, e.g., check_filter()
*/
SKB_DROP_REASON_TAP_TXFILTER,
/** @SKB_DROP_REASON_ICMP_CSUM: ICMP checksum error */
SKB_DROP_REASON_ICMP_CSUM,
/**
* @SKB_DROP_REASON_INVALID_PROTO: the packet doesn't follow RFC 2211,
* such as a broadcasts ICMP_TIMESTAMP
*/
SKB_DROP_REASON_INVALID_PROTO,
/**
* @SKB_DROP_REASON_IP_INADDRERRORS: host unreachable, corresponding to
* IPSTATS_MIB_INADDRERRORS
*/
SKB_DROP_REASON_IP_INADDRERRORS,
/**
* @SKB_DROP_REASON_IP_INNOROUTES: network unreachable, corresponding to
* IPSTATS_MIB_INADDRERRORS
*/
SKB_DROP_REASON_IP_INNOROUTES,
/**
* @SKB_DROP_REASON_PKT_TOO_BIG: packet size is too big (maybe exceed the
* MTU)
*/
SKB_DROP_REASON_PKT_TOO_BIG,
/** @SKB_DROP_REASON_DUP_FRAG: duplicate fragment */
SKB_DROP_REASON_DUP_FRAG,
/** @SKB_DROP_REASON_FRAG_REASM_TIMEOUT: fragment reassembly timeout */
SKB_DROP_REASON_FRAG_REASM_TIMEOUT,
/**
* @SKB_DROP_REASON_FRAG_TOO_FAR: ipv4 fragment too far.
* (/proc/sys/net/ipv4/ipfrag_max_dist)
*/
SKB_DROP_REASON_FRAG_TOO_FAR,
/**
* @SKB_DROP_REASON_TCP_MINTTL: ipv4 ttl or ipv6 hoplimit below
* the threshold (IP_MINTTL or IPV6_MINHOPCOUNT).
*/
SKB_DROP_REASON_TCP_MINTTL,
/** @SKB_DROP_REASON_IPV6_BAD_EXTHDR: Bad IPv6 extension header. */
SKB_DROP_REASON_IPV6_BAD_EXTHDR,
/** @SKB_DROP_REASON_IPV6_NDISC_FRAG: invalid frag (suppress_frag_ndisc). */
SKB_DROP_REASON_IPV6_NDISC_FRAG,
/** @SKB_DROP_REASON_IPV6_NDISC_HOP_LIMIT: invalid hop limit. */
SKB_DROP_REASON_IPV6_NDISC_HOP_LIMIT,
/** @SKB_DROP_REASON_IPV6_NDISC_BAD_CODE: invalid NDISC icmp6 code. */
SKB_DROP_REASON_IPV6_NDISC_BAD_CODE,
/** @SKB_DROP_REASON_IPV6_NDISC_BAD_OPTIONS: invalid NDISC options. */
SKB_DROP_REASON_IPV6_NDISC_BAD_OPTIONS,
/**
* @SKB_DROP_REASON_IPV6_NDISC_NS_OTHERHOST: NEIGHBOUR SOLICITATION
* for another host.
*/
SKB_DROP_REASON_IPV6_NDISC_NS_OTHERHOST,
/**
* @SKB_DROP_REASON_MAX: the maximum of core drop reasons, which
* shouldn't be used as a real 'reason' - only for tracing code gen
*/
SKB_DROP_REASON_MAX,
/**
* @SKB_DROP_REASON_SUBSYS_MASK: subsystem mask in drop reasons,
* see &enum skb_drop_reason_subsys
*/
SKB_DROP_REASON_SUBSYS_MASK = 0xffff0000,
};
#define SKB_DROP_REASON_SUBSYS_SHIFT 16
#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 || \
name == SKB_NOT_DROPPED_YET) \
SKB_DR_SET(name, reason); \
} while (0)
#endif
......@@ -2,362 +2,42 @@
#ifndef _LINUX_DROPREASON_H
#define _LINUX_DROPREASON_H
#define DEFINE_DROP_REASON(FN, FNe) \
FN(NOT_SPECIFIED) \
FN(NO_SOCKET) \
FN(PKT_TOO_SMALL) \
FN(TCP_CSUM) \
FN(SOCKET_FILTER) \
FN(UDP_CSUM) \
FN(NETFILTER_DROP) \
FN(OTHERHOST) \
FN(IP_CSUM) \
FN(IP_INHDR) \
FN(IP_RPFILTER) \
FN(UNICAST_IN_L2_MULTICAST) \
FN(XFRM_POLICY) \
FN(IP_NOPROTO) \
FN(SOCKET_RCVBUFF) \
FN(PROTO_MEM) \
FN(TCP_MD5NOTFOUND) \
FN(TCP_MD5UNEXPECTED) \
FN(TCP_MD5FAILURE) \
FN(SOCKET_BACKLOG) \
FN(TCP_FLAGS) \
FN(TCP_ZEROWINDOW) \
FN(TCP_OLD_DATA) \
FN(TCP_OVERWINDOW) \
FN(TCP_OFOMERGE) \
FN(TCP_RFC7323_PAWS) \
FN(TCP_INVALID_SEQUENCE) \
FN(TCP_RESET) \
FN(TCP_INVALID_SYN) \
FN(TCP_CLOSE) \
FN(TCP_FASTOPEN) \
FN(TCP_OLD_ACK) \
FN(TCP_TOO_OLD_ACK) \
FN(TCP_ACK_UNSENT_DATA) \
FN(TCP_OFO_QUEUE_PRUNE) \
FN(TCP_OFO_DROP) \
FN(IP_OUTNOROUTES) \
FN(BPF_CGROUP_EGRESS) \
FN(IPV6DISABLED) \
FN(NEIGH_CREATEFAIL) \
FN(NEIGH_FAILED) \
FN(NEIGH_QUEUEFULL) \
FN(NEIGH_DEAD) \
FN(TC_EGRESS) \
FN(QDISC_DROP) \
FN(CPU_BACKLOG) \
FN(XDP) \
FN(TC_INGRESS) \
FN(UNHANDLED_PROTO) \
FN(SKB_CSUM) \
FN(SKB_GSO_SEG) \
FN(SKB_UCOPY_FAULT) \
FN(DEV_HDR) \
FN(DEV_READY) \
FN(FULL_RING) \
FN(NOMEM) \
FN(HDR_TRUNC) \
FN(TAP_FILTER) \
FN(TAP_TXFILTER) \
FN(ICMP_CSUM) \
FN(INVALID_PROTO) \
FN(IP_INADDRERRORS) \
FN(IP_INNOROUTES) \
FN(PKT_TOO_BIG) \
FN(DUP_FRAG) \
FN(FRAG_REASM_TIMEOUT) \
FN(FRAG_TOO_FAR) \
FN(TCP_MINTTL) \
FN(IPV6_BAD_EXTHDR) \
FN(IPV6_NDISC_FRAG) \
FN(IPV6_NDISC_HOP_LIMIT) \
FN(IPV6_NDISC_BAD_CODE) \
FN(IPV6_NDISC_BAD_OPTIONS) \
FN(IPV6_NDISC_NS_OTHERHOST) \
FNe(MAX)
#include <net/dropreason-core.h>
/**
* enum skb_drop_reason - the reasons of skb drops
*
* The reason of skb drop, which is used in kfree_skb_reason().
* enum skb_drop_reason_subsys - subsystem tag for (extended) drop reasons
*/
enum skb_drop_reason {
/**
* @SKB_NOT_DROPPED_YET: skb is not dropped yet (used for no-drop case)
*/
SKB_NOT_DROPPED_YET = 0,
/** @SKB_CONSUMED: packet has been consumed */
SKB_CONSUMED,
/** @SKB_DROP_REASON_NOT_SPECIFIED: drop reason is not specified */
SKB_DROP_REASON_NOT_SPECIFIED,
/** @SKB_DROP_REASON_NO_SOCKET: socket not found */
SKB_DROP_REASON_NO_SOCKET,
/** @SKB_DROP_REASON_PKT_TOO_SMALL: packet size is too small */
SKB_DROP_REASON_PKT_TOO_SMALL,
/** @SKB_DROP_REASON_TCP_CSUM: TCP checksum error */
SKB_DROP_REASON_TCP_CSUM,
/** @SKB_DROP_REASON_SOCKET_FILTER: dropped by socket filter */
SKB_DROP_REASON_SOCKET_FILTER,
/** @SKB_DROP_REASON_UDP_CSUM: UDP checksum error */
SKB_DROP_REASON_UDP_CSUM,
/** @SKB_DROP_REASON_NETFILTER_DROP: dropped by netfilter */
SKB_DROP_REASON_NETFILTER_DROP,
/**
* @SKB_DROP_REASON_OTHERHOST: packet don't belong to current host
* (interface is in promisc mode)
*/
SKB_DROP_REASON_OTHERHOST,
/** @SKB_DROP_REASON_IP_CSUM: IP checksum error */
SKB_DROP_REASON_IP_CSUM,
/**
* @SKB_DROP_REASON_IP_INHDR: there is something wrong with IP header (see
* IPSTATS_MIB_INHDRERRORS)
*/
SKB_DROP_REASON_IP_INHDR,
/**
* @SKB_DROP_REASON_IP_RPFILTER: IP rpfilter validate failed. see the
* document for rp_filter in ip-sysctl.rst for more information
*/
SKB_DROP_REASON_IP_RPFILTER,
/**
* @SKB_DROP_REASON_UNICAST_IN_L2_MULTICAST: destination address of L2 is
* multicast, but L3 is unicast.
*/
SKB_DROP_REASON_UNICAST_IN_L2_MULTICAST,
/** @SKB_DROP_REASON_XFRM_POLICY: xfrm policy check failed */
SKB_DROP_REASON_XFRM_POLICY,
/** @SKB_DROP_REASON_IP_NOPROTO: no support for IP protocol */
SKB_DROP_REASON_IP_NOPROTO,
/** @SKB_DROP_REASON_SOCKET_RCVBUFF: socket receive buff is full */
SKB_DROP_REASON_SOCKET_RCVBUFF,
/**
* @SKB_DROP_REASON_PROTO_MEM: proto memory limition, such as udp packet
* drop out of udp_memory_allocated.
*/
SKB_DROP_REASON_PROTO_MEM,
/**
* @SKB_DROP_REASON_TCP_MD5NOTFOUND: no MD5 hash and one expected,
* corresponding to LINUX_MIB_TCPMD5NOTFOUND
*/
SKB_DROP_REASON_TCP_MD5NOTFOUND,
/**
* @SKB_DROP_REASON_TCP_MD5UNEXPECTED: MD5 hash and we're not expecting
* one, corresponding to LINUX_MIB_TCPMD5UNEXPECTED
*/
SKB_DROP_REASON_TCP_MD5UNEXPECTED,
/**
* @SKB_DROP_REASON_TCP_MD5FAILURE: MD5 hash and its wrong, corresponding
* to LINUX_MIB_TCPMD5FAILURE
*/
SKB_DROP_REASON_TCP_MD5FAILURE,
/**
* @SKB_DROP_REASON_SOCKET_BACKLOG: failed to add skb to socket backlog (
* see LINUX_MIB_TCPBACKLOGDROP)
*/
SKB_DROP_REASON_SOCKET_BACKLOG,
/** @SKB_DROP_REASON_TCP_FLAGS: TCP flags invalid */
SKB_DROP_REASON_TCP_FLAGS,
/**
* @SKB_DROP_REASON_TCP_ZEROWINDOW: TCP receive window size is zero,
* see LINUX_MIB_TCPZEROWINDOWDROP
*/
SKB_DROP_REASON_TCP_ZEROWINDOW,
/**
* @SKB_DROP_REASON_TCP_OLD_DATA: the TCP data reveived is already
* received before (spurious retrans may happened), see
* LINUX_MIB_DELAYEDACKLOST
*/
SKB_DROP_REASON_TCP_OLD_DATA,
/**
* @SKB_DROP_REASON_TCP_OVERWINDOW: the TCP data is out of window,
* the seq of the first byte exceed the right edges of receive
* window
*/
SKB_DROP_REASON_TCP_OVERWINDOW,
/**
* @SKB_DROP_REASON_TCP_OFOMERGE: the data of skb is already in the ofo
* queue, corresponding to LINUX_MIB_TCPOFOMERGE
*/
SKB_DROP_REASON_TCP_OFOMERGE,
/**
* @SKB_DROP_REASON_TCP_RFC7323_PAWS: PAWS check, corresponding to
* LINUX_MIB_PAWSESTABREJECTED
*/
SKB_DROP_REASON_TCP_RFC7323_PAWS,
/** @SKB_DROP_REASON_TCP_INVALID_SEQUENCE: Not acceptable SEQ field */
SKB_DROP_REASON_TCP_INVALID_SEQUENCE,
/** @SKB_DROP_REASON_TCP_RESET: Invalid RST packet */
SKB_DROP_REASON_TCP_RESET,
/**
* @SKB_DROP_REASON_TCP_INVALID_SYN: Incoming packet has unexpected
* SYN flag
*/
SKB_DROP_REASON_TCP_INVALID_SYN,
/** @SKB_DROP_REASON_TCP_CLOSE: TCP socket in CLOSE state */
SKB_DROP_REASON_TCP_CLOSE,
/** @SKB_DROP_REASON_TCP_FASTOPEN: dropped by FASTOPEN request socket */
SKB_DROP_REASON_TCP_FASTOPEN,
/** @SKB_DROP_REASON_TCP_OLD_ACK: TCP ACK is old, but in window */
SKB_DROP_REASON_TCP_OLD_ACK,
/** @SKB_DROP_REASON_TCP_TOO_OLD_ACK: TCP ACK is too old */
SKB_DROP_REASON_TCP_TOO_OLD_ACK,
/**
* @SKB_DROP_REASON_TCP_ACK_UNSENT_DATA: TCP ACK for data we haven't
* sent yet
*/
SKB_DROP_REASON_TCP_ACK_UNSENT_DATA,
/** @SKB_DROP_REASON_TCP_OFO_QUEUE_PRUNE: pruned from TCP OFO queue */
SKB_DROP_REASON_TCP_OFO_QUEUE_PRUNE,
/** @SKB_DROP_REASON_TCP_OFO_DROP: data already in receive queue */
SKB_DROP_REASON_TCP_OFO_DROP,
/** @SKB_DROP_REASON_IP_OUTNOROUTES: route lookup failed */
SKB_DROP_REASON_IP_OUTNOROUTES,
/**
* @SKB_DROP_REASON_BPF_CGROUP_EGRESS: dropped by BPF_PROG_TYPE_CGROUP_SKB
* eBPF program
*/
SKB_DROP_REASON_BPF_CGROUP_EGRESS,
/** @SKB_DROP_REASON_IPV6DISABLED: IPv6 is disabled on the device */
SKB_DROP_REASON_IPV6DISABLED,
/** @SKB_DROP_REASON_NEIGH_CREATEFAIL: failed to create neigh entry */
SKB_DROP_REASON_NEIGH_CREATEFAIL,
/** @SKB_DROP_REASON_NEIGH_FAILED: neigh entry in failed state */
SKB_DROP_REASON_NEIGH_FAILED,
/** @SKB_DROP_REASON_NEIGH_QUEUEFULL: arp_queue for neigh entry is full */
SKB_DROP_REASON_NEIGH_QUEUEFULL,
/** @SKB_DROP_REASON_NEIGH_DEAD: neigh entry is dead */
SKB_DROP_REASON_NEIGH_DEAD,
/** @SKB_DROP_REASON_TC_EGRESS: dropped in TC egress HOOK */
SKB_DROP_REASON_TC_EGRESS,
/**
* @SKB_DROP_REASON_QDISC_DROP: dropped by qdisc when packet outputting (
* failed to enqueue to current qdisc)
*/
SKB_DROP_REASON_QDISC_DROP,
/**
* @SKB_DROP_REASON_CPU_BACKLOG: failed to enqueue the skb to the per CPU
* backlog queue. This can be caused by backlog queue full (see
* netdev_max_backlog in net.rst) or RPS flow limit
*/
SKB_DROP_REASON_CPU_BACKLOG,
/** @SKB_DROP_REASON_XDP: dropped by XDP in input path */
SKB_DROP_REASON_XDP,
/** @SKB_DROP_REASON_TC_INGRESS: dropped in TC ingress HOOK */
SKB_DROP_REASON_TC_INGRESS,
/** @SKB_DROP_REASON_UNHANDLED_PROTO: protocol not implemented or not supported */
SKB_DROP_REASON_UNHANDLED_PROTO,
/** @SKB_DROP_REASON_SKB_CSUM: sk_buff checksum computation error */
SKB_DROP_REASON_SKB_CSUM,
/** @SKB_DROP_REASON_SKB_GSO_SEG: gso segmentation error */
SKB_DROP_REASON_SKB_GSO_SEG,
/**
* @SKB_DROP_REASON_SKB_UCOPY_FAULT: failed to copy data from user space,
* e.g., via zerocopy_sg_from_iter() or skb_orphan_frags_rx()
*/
SKB_DROP_REASON_SKB_UCOPY_FAULT,
/** @SKB_DROP_REASON_DEV_HDR: device driver specific header/metadata is invalid */
SKB_DROP_REASON_DEV_HDR,
/**
* @SKB_DROP_REASON_DEV_READY: the device is not ready to xmit/recv due to
* any of its data structure that is not up/ready/initialized,
* e.g., the IFF_UP is not set, or driver specific tun->tfiles[txq]
* is not initialized
*/
SKB_DROP_REASON_DEV_READY,
/** @SKB_DROP_REASON_FULL_RING: ring buffer is full */
SKB_DROP_REASON_FULL_RING,
/** @SKB_DROP_REASON_NOMEM: error due to OOM */
SKB_DROP_REASON_NOMEM,
/**
* @SKB_DROP_REASON_HDR_TRUNC: failed to trunc/extract the header from
* networking data, e.g., failed to pull the protocol header from
* frags via pskb_may_pull()
*/
SKB_DROP_REASON_HDR_TRUNC,
/**
* @SKB_DROP_REASON_TAP_FILTER: dropped by (ebpf) filter directly attached
* to tun/tap, e.g., via TUNSETFILTEREBPF
*/
SKB_DROP_REASON_TAP_FILTER,
/**
* @SKB_DROP_REASON_TAP_TXFILTER: dropped by tx filter implemented at
* tun/tap, e.g., check_filter()
*/
SKB_DROP_REASON_TAP_TXFILTER,
/** @SKB_DROP_REASON_ICMP_CSUM: ICMP checksum error */
SKB_DROP_REASON_ICMP_CSUM,
/**
* @SKB_DROP_REASON_INVALID_PROTO: the packet doesn't follow RFC 2211,
* such as a broadcasts ICMP_TIMESTAMP
*/
SKB_DROP_REASON_INVALID_PROTO,
/**
* @SKB_DROP_REASON_IP_INADDRERRORS: host unreachable, corresponding to
* IPSTATS_MIB_INADDRERRORS
*/
SKB_DROP_REASON_IP_INADDRERRORS,
/**
* @SKB_DROP_REASON_IP_INNOROUTES: network unreachable, corresponding to
* IPSTATS_MIB_INADDRERRORS
*/
SKB_DROP_REASON_IP_INNOROUTES,
/**
* @SKB_DROP_REASON_PKT_TOO_BIG: packet size is too big (maybe exceed the
* MTU)
*/
SKB_DROP_REASON_PKT_TOO_BIG,
/** @SKB_DROP_REASON_DUP_FRAG: duplicate fragment */
SKB_DROP_REASON_DUP_FRAG,
/** @SKB_DROP_REASON_FRAG_REASM_TIMEOUT: fragment reassembly timeout */
SKB_DROP_REASON_FRAG_REASM_TIMEOUT,
/**
* @SKB_DROP_REASON_FRAG_TOO_FAR: ipv4 fragment too far.
* (/proc/sys/net/ipv4/ipfrag_max_dist)
*/
SKB_DROP_REASON_FRAG_TOO_FAR,
enum skb_drop_reason_subsys {
/** @SKB_DROP_REASON_SUBSYS_CORE: core drop reasons defined above */
SKB_DROP_REASON_SUBSYS_CORE,
/**
* @SKB_DROP_REASON_TCP_MINTTL: ipv4 ttl or ipv6 hoplimit below
* the threshold (IP_MINTTL or IPV6_MINHOPCOUNT).
*/
SKB_DROP_REASON_TCP_MINTTL,
/** @SKB_DROP_REASON_IPV6_BAD_EXTHDR: Bad IPv6 extension header. */
SKB_DROP_REASON_IPV6_BAD_EXTHDR,
/** @SKB_DROP_REASON_IPV6_NDISC_FRAG: invalid frag (suppress_frag_ndisc). */
SKB_DROP_REASON_IPV6_NDISC_FRAG,
/** @SKB_DROP_REASON_IPV6_NDISC_HOP_LIMIT: invalid hop limit. */
SKB_DROP_REASON_IPV6_NDISC_HOP_LIMIT,
/** @SKB_DROP_REASON_IPV6_NDISC_BAD_CODE: invalid NDISC icmp6 code. */
SKB_DROP_REASON_IPV6_NDISC_BAD_CODE,
/** @SKB_DROP_REASON_IPV6_NDISC_BAD_OPTIONS: invalid NDISC options. */
SKB_DROP_REASON_IPV6_NDISC_BAD_OPTIONS,
/** @SKB_DROP_REASON_IPV6_NDISC_NS_OTHERHOST: NEIGHBOUR SOLICITATION
* for another host.
* @SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE: mac80211 drop reasons
* for unusable frames, see net/mac80211/drop.h
*/
SKB_DROP_REASON_IPV6_NDISC_NS_OTHERHOST,
SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE,
/**
* @SKB_DROP_REASON_MAX: the maximum of drop reason, which shouldn't be
* used as a real 'reason'
* @SKB_DROP_REASON_SUBSYS_MAC80211_MONITOR: mac80211 drop reasons
* for frames still going to monitor, see net/mac80211/drop.h
*/
SKB_DROP_REASON_MAX,
SKB_DROP_REASON_SUBSYS_MAC80211_MONITOR,
/** @SKB_DROP_REASON_SUBSYS_NUM: number of subsystems defined */
SKB_DROP_REASON_SUBSYS_NUM
};
struct drop_reason_list {
const char * const *reasons;
size_t n_reasons;
};
#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 || \
name == SKB_NOT_DROPPED_YET) \
SKB_DR_SET(name, reason); \
} while (0)
/* Note: due to dynamic registrations, access must be under RCU */
extern const struct drop_reason_list __rcu *
drop_reasons_by_subsys[SKB_DROP_REASON_SUBSYS_NUM];
extern const char * const drop_reasons[];
void drop_reasons_register_subsys(enum skb_drop_reason_subsys subsys,
const struct drop_reason_list *list);
void drop_reasons_unregister_subsys(enum skb_drop_reason_subsys subsys);
#endif
......@@ -7,7 +7,7 @@
#include <linux/in6.h>
#include <linux/rbtree_types.h>
#include <linux/refcount.h>
#include <net/dropreason.h>
#include <net/dropreason-core.h>
/* Per netns frag queues directory */
struct fqdir {
......
......@@ -21,6 +21,7 @@
#include <linux/workqueue.h>
#include <linux/netlink.h>
#include <linux/net_dropmon.h>
#include <linux/bitfield.h>
#include <linux/percpu.h>
#include <linux/timer.h>
#include <linux/bitops.h>
......@@ -29,6 +30,7 @@
#include <net/genetlink.h>
#include <net/netevent.h>
#include <net/flow_offload.h>
#include <net/dropreason.h>
#include <net/devlink.h>
#include <trace/events/skb.h>
......@@ -504,8 +506,6 @@ static void net_dm_packet_trace_kfree_skb_hit(void *ignore,
if (!nskb)
return;
if (unlikely(reason >= SKB_DROP_REASON_MAX || reason <= 0))
reason = SKB_DROP_REASON_NOT_SPECIFIED;
cb = NET_DM_SKB_CB(nskb);
cb->reason = reason;
cb->pc = location;
......@@ -552,9 +552,9 @@ static size_t net_dm_in_port_size(void)
}
#define NET_DM_MAX_SYMBOL_LEN 40
#define NET_DM_MAX_REASON_LEN 50
static size_t net_dm_packet_report_size(size_t payload_len,
enum skb_drop_reason reason)
static size_t net_dm_packet_report_size(size_t payload_len)
{
size_t size;
......@@ -576,7 +576,7 @@ static size_t net_dm_packet_report_size(size_t payload_len,
/* NET_DM_ATTR_PROTO */
nla_total_size(sizeof(u16)) +
/* NET_DM_ATTR_REASON */
nla_total_size(strlen(drop_reasons[reason]) + 1) +
nla_total_size(NET_DM_MAX_REASON_LEN + 1) +
/* NET_DM_ATTR_PAYLOAD */
nla_total_size(payload_len);
}
......@@ -610,6 +610,8 @@ static int net_dm_packet_report_fill(struct sk_buff *msg, struct sk_buff *skb,
size_t payload_len)
{
struct net_dm_skb_cb *cb = NET_DM_SKB_CB(skb);
const struct drop_reason_list *list = NULL;
unsigned int subsys, subsys_reason;
char buf[NET_DM_MAX_SYMBOL_LEN];
struct nlattr *attr;
void *hdr;
......@@ -627,9 +629,24 @@ static int net_dm_packet_report_fill(struct sk_buff *msg, struct sk_buff *skb,
NET_DM_ATTR_PAD))
goto nla_put_failure;
rcu_read_lock();
subsys = u32_get_bits(cb->reason, SKB_DROP_REASON_SUBSYS_MASK);
if (subsys < SKB_DROP_REASON_SUBSYS_NUM)
list = rcu_dereference(drop_reasons_by_subsys[subsys]);
subsys_reason = cb->reason & ~SKB_DROP_REASON_SUBSYS_MASK;
if (!list ||
subsys_reason >= list->n_reasons ||
!list->reasons[subsys_reason] ||
strlen(list->reasons[subsys_reason]) > NET_DM_MAX_REASON_LEN) {
list = rcu_dereference(drop_reasons_by_subsys[SKB_DROP_REASON_SUBSYS_CORE]);
subsys_reason = SKB_DROP_REASON_NOT_SPECIFIED;
}
if (nla_put_string(msg, NET_DM_ATTR_REASON,
drop_reasons[cb->reason]))
list->reasons[subsys_reason])) {
rcu_read_unlock();
goto nla_put_failure;
}
rcu_read_unlock();
snprintf(buf, sizeof(buf), "%pS", cb->pc);
if (nla_put_string(msg, NET_DM_ATTR_SYMBOL, buf))
......@@ -687,9 +704,7 @@ static void net_dm_packet_report(struct sk_buff *skb)
if (net_dm_trunc_len)
payload_len = min_t(size_t, net_dm_trunc_len, payload_len);
msg = nlmsg_new(net_dm_packet_report_size(payload_len,
NET_DM_SKB_CB(skb)->reason),
GFP_KERNEL);
msg = nlmsg_new(net_dm_packet_report_size(payload_len), GFP_KERNEL);
if (!msg)
goto out;
......
......@@ -58,6 +58,7 @@
#include <linux/scatterlist.h>
#include <linux/errqueue.h>
#include <linux/prefetch.h>
#include <linux/bitfield.h>
#include <linux/if_vlan.h>
#include <linux/mpls.h>
#include <linux/kcov.h>
......@@ -72,6 +73,7 @@
#include <net/mptcp.h>
#include <net/mctp.h>
#include <net/page_pool.h>
#include <net/dropreason.h>
#include <linux/uaccess.h>
#include <trace/events/skb.h>
......@@ -122,11 +124,59 @@ EXPORT_SYMBOL(sysctl_max_skb_frags);
#undef FN
#define FN(reason) [SKB_DROP_REASON_##reason] = #reason,
const char * const drop_reasons[] = {
static const char * const drop_reasons[] = {
[SKB_CONSUMED] = "CONSUMED",
DEFINE_DROP_REASON(FN, FN)
};
EXPORT_SYMBOL(drop_reasons);
static const struct drop_reason_list drop_reasons_core = {
.reasons = drop_reasons,
.n_reasons = ARRAY_SIZE(drop_reasons),
};
const struct drop_reason_list __rcu *
drop_reasons_by_subsys[SKB_DROP_REASON_SUBSYS_NUM] = {
[SKB_DROP_REASON_SUBSYS_CORE] = RCU_INITIALIZER(&drop_reasons_core),
};
EXPORT_SYMBOL(drop_reasons_by_subsys);
/**
* drop_reasons_register_subsys - register another drop reason subsystem
* @subsys: the subsystem to register, must not be the core
* @list: the list of drop reasons within the subsystem, must point to
* a statically initialized list
*/
void drop_reasons_register_subsys(enum skb_drop_reason_subsys subsys,
const struct drop_reason_list *list)
{
if (WARN(subsys <= SKB_DROP_REASON_SUBSYS_CORE ||
subsys >= ARRAY_SIZE(drop_reasons_by_subsys),
"invalid subsystem %d\n", subsys))
return;
/* must point to statically allocated memory, so INIT is OK */
RCU_INIT_POINTER(drop_reasons_by_subsys[subsys], list);
}
EXPORT_SYMBOL_GPL(drop_reasons_register_subsys);
/**
* drop_reasons_unregister_subsys - unregister a drop reason subsystem
* @subsys: the subsystem to remove, must not be the core
*
* Note: This will synchronize_rcu() to ensure no users when it returns.
*/
void drop_reasons_unregister_subsys(enum skb_drop_reason_subsys subsys)
{
if (WARN(subsys <= SKB_DROP_REASON_SUBSYS_CORE ||
subsys >= ARRAY_SIZE(drop_reasons_by_subsys),
"invalid subsystem %d\n", subsys))
return;
RCU_INIT_POINTER(drop_reasons_by_subsys[subsys], NULL);
synchronize_rcu();
}
EXPORT_SYMBOL_GPL(drop_reasons_unregister_subsys);
/**
* skb_panic - private function for out-of-line support
......@@ -986,7 +1036,10 @@ bool __kfree_skb_reason(struct sk_buff *skb, enum skb_drop_reason reason)
if (unlikely(!skb_unref(skb)))
return false;
DEBUG_NET_WARN_ON_ONCE(reason <= 0 || reason >= SKB_DROP_REASON_MAX);
DEBUG_NET_WARN_ON_ONCE(reason == SKB_NOT_DROPPED_YET ||
u32_get_bits(reason,
SKB_DROP_REASON_SUBSYS_MASK) >=
SKB_DROP_REASON_SUBSYS_NUM);
if (reason == SKB_CONSUMED)
trace_consume_skb(skb, __builtin_return_address(0));
......
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* mac80211 drop reason list
*
* Copyright (C) 2023 Intel Corporation
*/
#ifndef MAC80211_DROP_H
#define MAC80211_DROP_H
#include <net/dropreason.h>
typedef unsigned int __bitwise ieee80211_rx_result;
#define MAC80211_DROP_REASONS_MONITOR(R) \
R(RX_DROP_M_UNEXPECTED_4ADDR_FRAME) \
R(RX_DROP_M_BAD_BCN_KEYIDX) \
R(RX_DROP_M_BAD_MGMT_KEYIDX) \
/* this line for the trailing \ - add before this */
#define MAC80211_DROP_REASONS_UNUSABLE(R) \
R(RX_DROP_U_MIC_FAIL) \
R(RX_DROP_U_REPLAY) \
R(RX_DROP_U_BAD_MMIE) \
/* this line for the trailing \ - add before this */
/* having two enums allows for checking ieee80211_rx_result use with sparse */
enum ___mac80211_drop_reason {
/* if we get to the end of handlers with RX_CONTINUE this will be the reason */
___RX_CONTINUE = SKB_CONSUMED,
/* this never gets used as an argument to kfree_skb_reason() */
___RX_QUEUED = SKB_NOT_DROPPED_YET,
#define ENUM(x) ___ ## x,
___RX_DROP_MONITOR = SKB_DROP_REASON_SUBSYS_MAC80211_MONITOR <<
SKB_DROP_REASON_SUBSYS_SHIFT,
MAC80211_DROP_REASONS_MONITOR(ENUM)
___RX_DROP_UNUSABLE = SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE <<
SKB_DROP_REASON_SUBSYS_SHIFT,
MAC80211_DROP_REASONS_UNUSABLE(ENUM)
#undef ENUM
};
enum mac80211_drop_reason {
RX_CONTINUE = (__force ieee80211_rx_result)___RX_CONTINUE,
RX_QUEUED = (__force ieee80211_rx_result)___RX_QUEUED,
RX_DROP_MONITOR = (__force ieee80211_rx_result)___RX_DROP_MONITOR,
RX_DROP_UNUSABLE = (__force ieee80211_rx_result)___RX_DROP_UNUSABLE,
#define DEF(x) x = (__force ieee80211_rx_result)___ ## x,
MAC80211_DROP_REASONS_MONITOR(DEF)
MAC80211_DROP_REASONS_UNUSABLE(DEF)
#undef DEF
};
#endif /* MAC80211_DROP_H */
......@@ -33,6 +33,7 @@
#include "key.h"
#include "sta_info.h"
#include "debug.h"
#include "drop.h"
extern const struct cfg80211_ops mac80211_config_ops;
......@@ -170,13 +171,6 @@ struct ieee80211_tx_data {
unsigned int flags;
};
typedef unsigned __bitwise ieee80211_rx_result;
#define RX_CONTINUE ((__force ieee80211_rx_result) 0u)
#define RX_DROP_UNUSABLE ((__force ieee80211_rx_result) 1u)
#define RX_DROP_MONITOR ((__force ieee80211_rx_result) 2u)
#define RX_QUEUED ((__force ieee80211_rx_result) 3u)
/**
* enum ieee80211_packet_rx_flags - packet RX flags
* @IEEE80211_RX_AMSDU: a-MSDU packet
......
......@@ -22,6 +22,7 @@
#include <linux/bitmap.h>
#include <linux/inetdevice.h>
#include <net/net_namespace.h>
#include <net/dropreason.h>
#include <net/cfg80211.h>
#include <net/addrconf.h>
......@@ -1542,6 +1543,28 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
}
EXPORT_SYMBOL(ieee80211_free_hw);
static const char * const drop_reasons_monitor[] = {
#define V(x) #x,
[0] = "RX_DROP_MONITOR",
MAC80211_DROP_REASONS_MONITOR(V)
};
static struct drop_reason_list drop_reason_list_monitor = {
.reasons = drop_reasons_monitor,
.n_reasons = ARRAY_SIZE(drop_reasons_monitor),
};
static const char * const drop_reasons_unusable[] = {
[0] = "RX_DROP_UNUSABLE",
MAC80211_DROP_REASONS_UNUSABLE(V)
#undef V
};
static struct drop_reason_list drop_reason_list_unusable = {
.reasons = drop_reasons_unusable,
.n_reasons = ARRAY_SIZE(drop_reasons_unusable),
};
static int __init ieee80211_init(void)
{
struct sk_buff *skb;
......@@ -1559,6 +1582,11 @@ static int __init ieee80211_init(void)
if (ret)
goto err_netdev;
drop_reasons_register_subsys(SKB_DROP_REASON_SUBSYS_MAC80211_MONITOR,
&drop_reason_list_monitor);
drop_reasons_register_subsys(SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE,
&drop_reason_list_unusable);
return 0;
err_netdev:
rc80211_minstrel_exit();
......@@ -1574,6 +1602,9 @@ static void __exit ieee80211_exit(void)
ieee80211_iface_exit();
drop_reasons_unregister_subsys(SKB_DROP_REASON_SUBSYS_MAC80211_MONITOR);
drop_reasons_unregister_subsys(SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE);
rcu_barrier();
}
......
......@@ -1826,7 +1826,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
cfg80211_rx_unexpected_4addr_frame(
rx->sdata->dev, sta->sta.addr,
GFP_ATOMIC);
return RX_DROP_MONITOR;
return RX_DROP_M_UNEXPECTED_4ADDR_FRAME;
}
/*
* Update counter and free packet here to avoid
......@@ -1961,7 +1961,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev,
skb->data,
skb->len);
return RX_DROP_MONITOR; /* unexpected BIP keyidx */
return RX_DROP_M_BAD_BCN_KEYIDX;
}
rx->key = ieee80211_rx_get_bigtk(rx, mmie_keyidx);
......@@ -1975,7 +1975,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
if (mmie_keyidx < NUM_DEFAULT_KEYS ||
mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
return RX_DROP_MONITOR; /* unexpected BIP keyidx */
return RX_DROP_M_BAD_MGMT_KEYIDX; /* unexpected BIP keyidx */
if (rx->link_sta) {
if (ieee80211_is_group_privacy_action(skb) &&
test_sta_flag(rx->sta, WLAN_STA_MFP))
......@@ -3960,7 +3960,8 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
}
static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
struct ieee80211_rate *rate)
struct ieee80211_rate *rate,
ieee80211_rx_result reason)
{
struct ieee80211_sub_if_data *sdata;
struct ieee80211_local *local = rx->local;
......@@ -4024,42 +4025,38 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
}
out_free_skb:
dev_kfree_skb(skb);
kfree_skb_reason(skb, (__force u32)reason);
}
static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
ieee80211_rx_result res)
{
switch (res) {
case RX_DROP_MONITOR:
I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop);
if (rx->sta)
rx->link_sta->rx_stats.dropped++;
fallthrough;
case RX_CONTINUE: {
struct ieee80211_rate *rate = NULL;
struct ieee80211_supported_band *sband;
struct ieee80211_rx_status *status;
status = IEEE80211_SKB_RXCB((rx->skb));
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
struct ieee80211_supported_band *sband;
struct ieee80211_rate *rate = NULL;
sband = rx->local->hw.wiphy->bands[status->band];
if (status->encoding == RX_ENC_LEGACY)
rate = &sband->bitrates[status->rate_idx];
if (res == RX_QUEUED) {
I802_DEBUG_INC(rx->sdata->local->rx_handlers_queued);
return;
}
ieee80211_rx_cooked_monitor(rx, rate);
break;
}
case RX_DROP_UNUSABLE:
if (res != RX_CONTINUE) {
I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop);
if (rx->sta)
rx->link_sta->rx_stats.dropped++;
dev_kfree_skb(rx->skb);
break;
case RX_QUEUED:
I802_DEBUG_INC(rx->sdata->local->rx_handlers_queued);
break;
}
if (u32_get_bits((__force u32)res, SKB_DROP_REASON_SUBSYS_MASK) ==
SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE) {
kfree_skb_reason(rx->skb, (__force u32)res);
return;
}
sband = rx->local->hw.wiphy->bands[status->band];
if (status->encoding == RX_ENC_LEGACY)
rate = &sband->bitrates[status->rate_idx];
ieee80211_rx_cooked_monitor(rx, rate, res);
}
static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
......
......@@ -550,7 +550,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx,
if (res < 0 ||
(!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) {
key->u.ccmp.replays++;
return RX_DROP_UNUSABLE;
return RX_DROP_U_REPLAY;
}
if (!(status->flag & RX_FLAG_DECRYPTED)) {
......@@ -564,7 +564,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx,
skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
data_len,
skb->data + skb->len - mic_len))
return RX_DROP_UNUSABLE;
return RX_DROP_U_MIC_FAIL;
}
memcpy(key->u.ccmp.rx_pn[queue], pn, IEEE80211_CCMP_PN_LEN);
......@@ -746,7 +746,7 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx)
if (res < 0 ||
(!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) {
key->u.gcmp.replays++;
return RX_DROP_UNUSABLE;
return RX_DROP_U_REPLAY;
}
if (!(status->flag & RX_FLAG_DECRYPTED)) {
......@@ -761,7 +761,7 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx)
data_len,
skb->data + skb->len -
IEEE80211_GCMP_MIC_LEN))
return RX_DROP_UNUSABLE;
return RX_DROP_U_MIC_FAIL;
}
memcpy(key->u.gcmp.rx_pn[queue], pn, IEEE80211_GCMP_PN_LEN);
......@@ -930,13 +930,13 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx)
(skb->data + skb->len - sizeof(*mmie));
if (mmie->element_id != WLAN_EID_MMIE ||
mmie->length != sizeof(*mmie) - 2)
return RX_DROP_UNUSABLE; /* Invalid MMIE */
return RX_DROP_U_BAD_MMIE; /* Invalid MMIE */
bip_ipn_swap(ipn, mmie->sequence_number);
if (memcmp(ipn, key->u.aes_cmac.rx_pn, 6) <= 0) {
key->u.aes_cmac.replays++;
return RX_DROP_UNUSABLE;
return RX_DROP_U_REPLAY;
}
if (!(status->flag & RX_FLAG_DECRYPTED)) {
......@@ -946,7 +946,7 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx)
skb->data + 24, skb->len - 24, mic);
if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
key->u.aes_cmac.icverrors++;
return RX_DROP_UNUSABLE;
return RX_DROP_U_MIC_FAIL;
}
}
......@@ -986,7 +986,7 @@ ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx)
if (memcmp(ipn, key->u.aes_cmac.rx_pn, 6) <= 0) {
key->u.aes_cmac.replays++;
return RX_DROP_UNUSABLE;
return RX_DROP_U_REPLAY;
}
if (!(status->flag & RX_FLAG_DECRYPTED)) {
......@@ -996,7 +996,7 @@ ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx)
skb->data + 24, skb->len - 24, mic);
if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
key->u.aes_cmac.icverrors++;
return RX_DROP_UNUSABLE;
return RX_DROP_U_MIC_FAIL;
}
}
......@@ -1079,13 +1079,13 @@ ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx)
(skb->data + skb->len - sizeof(*mmie));
if (mmie->element_id != WLAN_EID_MMIE ||
mmie->length != sizeof(*mmie) - 2)
return RX_DROP_UNUSABLE; /* Invalid MMIE */
return RX_DROP_U_BAD_MMIE; /* Invalid MMIE */
bip_ipn_swap(ipn, mmie->sequence_number);
if (memcmp(ipn, key->u.aes_gmac.rx_pn, 6) <= 0) {
key->u.aes_gmac.replays++;
return RX_DROP_UNUSABLE;
return RX_DROP_U_REPLAY;
}
if (!(status->flag & RX_FLAG_DECRYPTED)) {
......@@ -1104,7 +1104,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx)
crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
key->u.aes_gmac.icverrors++;
kfree(mic);
return RX_DROP_UNUSABLE;
return RX_DROP_U_MIC_FAIL;
}
kfree(mic);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment