linux/net/mac80211/rx.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright 2002-2005, Instant802 Networks, Inc.
 * Copyright 2005-2006, Devicescape Software, Inc.
 * Copyright 2006-2007	Jiri Benc <[email protected]>
 * Copyright 2007-2010	Johannes Berg <[email protected]>
 * Copyright 2013-2014  Intel Mobile Communications GmbH
 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
 * Copyright (C) 2018-2024 Intel Corporation
 */

#include <linux/jiffies.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/rcupdate.h>
#include <linux/export.h>
#include <linux/kcov.h>
#include <linux/bitops.h>
#include <kunit/visibility.h>
#include <net/mac80211.h>
#include <net/ieee80211_radiotap.h>
#include <asm/unaligned.h>

#include "ieee80211_i.h"
#include "driver-ops.h"
#include "led.h"
#include "mesh.h"
#include "wep.h"
#include "wpa.h"
#include "tkip.h"
#include "wme.h"
#include "rate.h"

/*
 * monitor mode reception
 *
 * This function cleans up the SKB, i.e. it removes all the stuff
 * only useful for monitoring.
 */
static struct sk_buff *ieee80211_clean_skb(struct sk_buff *skb,
					   unsigned int present_fcs_len,
					   unsigned int rtap_space)
{}

static inline bool should_drop_frame(struct sk_buff *skb, int present_fcs_len,
				     unsigned int rtap_space)
{}

static int
ieee80211_rx_radiotap_hdrlen(struct ieee80211_local *local,
			     struct ieee80211_rx_status *status,
			     struct sk_buff *skb)
{}

static void __ieee80211_queue_skb_to_iface(struct ieee80211_sub_if_data *sdata,
					   int link_id,
					   struct sta_info *sta,
					   struct sk_buff *skb)
{}

static void ieee80211_queue_skb_to_iface(struct ieee80211_sub_if_data *sdata,
					 int link_id,
					 struct sta_info *sta,
					 struct sk_buff *skb)
{}

static void ieee80211_handle_mu_mimo_mon(struct ieee80211_sub_if_data *sdata,
					 struct sk_buff *skb,
					 int rtap_space)
{}

/*
 * ieee80211_add_rx_radiotap_header - add radiotap header
 *
 * add a radiotap header containing all the fields which the hardware provided.
 */
static void
ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
				 struct sk_buff *skb,
				 struct ieee80211_rate *rate,
				 int rtap_len, bool has_fcs)
{}

static struct sk_buff *
ieee80211_make_monitor_skb(struct ieee80211_local *local,
			   struct sk_buff **origskb,
			   struct ieee80211_rate *rate,
			   int rtap_space, bool use_origskb)
{}

/*
 * This function copies a received frame to all monitor interfaces and
 * returns a cleaned-up SKB that no longer includes the FCS nor the
 * radiotap header the driver might have added.
 */
static struct sk_buff *
ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
		     struct ieee80211_rate *rate)
{}

static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
{}

/**
 * DOC: Packet alignment
 *
 * Drivers always need to pass packets that are aligned to two-byte boundaries
 * to the stack.
 *
 * Additionally, they should, if possible, align the payload data in a way that
 * guarantees that the contained IP header is aligned to a four-byte
 * boundary. In the case of regular frames, this simply means aligning the
 * payload to a four-byte boundary (because either the IP header is directly
 * contained, or IV/RFC1042 headers that have a length divisible by four are
 * in front of it).  If the payload data is not properly aligned and the
 * architecture doesn't support efficient unaligned operations, mac80211
 * will align the data.
 *
 * With A-MSDU frames, however, the payload data address must yield two modulo
 * four because there are 14-byte 802.3 headers within the A-MSDU frames that
 * push the IP header further back to a multiple of four again. Thankfully, the
 * specs were sane enough this time around to require padding each A-MSDU
 * subframe to a length that is a multiple of four.
 *
 * Padding like Atheros hardware adds which is between the 802.11 header and
 * the payload is not supported; the driver is required to move the 802.11
 * header to be directly in front of the payload in that case.
 */
static void ieee80211_verify_alignment(struct ieee80211_rx_data *rx)
{}


/* rx handlers */

static int ieee80211_is_unicast_robust_mgmt_frame(struct sk_buff *skb)
{}


static int ieee80211_is_multicast_robust_mgmt_frame(struct sk_buff *skb)
{}


/* Get the BIP key index from MMIE; return -1 if this is not a BIP frame */
static int ieee80211_get_mmie_keyidx(struct sk_buff *skb)
{}

static int ieee80211_get_keyid(struct sk_buff *skb)
{}

static ieee80211_rx_result ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
{}

static inline bool ieee80211_rx_reorder_ready(struct tid_ampdu_rx *tid_agg_rx,
					      int index)
{}

static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata,
					    struct tid_ampdu_rx *tid_agg_rx,
					    int index,
					    struct sk_buff_head *frames)
{}

static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata,
					     struct tid_ampdu_rx *tid_agg_rx,
					     u16 head_seq_num,
					     struct sk_buff_head *frames)
{}

/*
 * Timeout (in jiffies) for skb's that are waiting in the RX reorder buffer. If
 * the skb was added to the buffer longer than this time ago, the earlier
 * frames that have not yet been received are assumed to be lost and the skb
 * can be released for processing. This may also release other skb's from the
 * reorder buffer if there are no additional gaps between the frames.
 *
 * Callers must hold tid_agg_rx->reorder_lock.
 */
#define HT_RX_REORDER_BUF_TIMEOUT

static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
					  struct tid_ampdu_rx *tid_agg_rx,
					  struct sk_buff_head *frames)
{}

/*
 * As this function belongs to the RX path it must be under
 * rcu_read_lock protection. It returns false if the frame
 * can be processed immediately, true if it was consumed.
 */
static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata,
					     struct tid_ampdu_rx *tid_agg_rx,
					     struct sk_buff *skb,
					     struct sk_buff_head *frames)
{}

/*
 * Reorder MPDUs from A-MPDUs, keeping them on a buffer. Returns
 * true if the MPDU was buffered, false if it should be processed.
 */
static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
				       struct sk_buff_head *frames)
{}

static ieee80211_rx_result debug_noinline
ieee80211_rx_h_check_dup(struct ieee80211_rx_data *rx)
{}

static ieee80211_rx_result debug_noinline
ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
{}


static ieee80211_rx_result debug_noinline
ieee80211_rx_h_check_more_data(struct ieee80211_rx_data *rx)
{}

static void sta_ps_start(struct sta_info *sta)
{}

static void sta_ps_end(struct sta_info *sta)
{}

int ieee80211_sta_ps_transition(struct ieee80211_sta *pubsta, bool start)
{}
EXPORT_SYMBOL();

void ieee80211_sta_pspoll(struct ieee80211_sta *pubsta)
{}
EXPORT_SYMBOL();

void ieee80211_sta_uapsd_trigger(struct ieee80211_sta *pubsta, u8 tid)
{}
EXPORT_SYMBOL();

static ieee80211_rx_result debug_noinline
ieee80211_rx_h_uapsd_and_pspoll(struct ieee80211_rx_data *rx)
{}

static ieee80211_rx_result debug_noinline
ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
{} /* ieee80211_rx_h_sta_process */

static struct ieee80211_key *
ieee80211_rx_get_bigtk(struct ieee80211_rx_data *rx, int idx)
{}

static ieee80211_rx_result debug_noinline
ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
{}

void ieee80211_init_frag_cache(struct ieee80211_fragment_cache *cache)
{}

void ieee80211_destroy_frag_cache(struct ieee80211_fragment_cache *cache)
{}

static inline struct ieee80211_fragment_entry *
ieee80211_reassemble_add(struct ieee80211_fragment_cache *cache,
			 unsigned int frag, unsigned int seq, int rx_queue,
			 struct sk_buff **skb)
{}

static inline struct ieee80211_fragment_entry *
ieee80211_reassemble_find(struct ieee80211_fragment_cache *cache,
			  unsigned int frag, unsigned int seq,
			  int rx_queue, struct ieee80211_hdr *hdr)
{}

static bool requires_sequential_pn(struct ieee80211_rx_data *rx, __le16 fc)
{}

static ieee80211_rx_result debug_noinline
ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
{}

static int ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx)
{}

static int ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc)
{}

VISIBLE_IF_MAC80211_KUNIT ieee80211_rx_result
ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
{}
EXPORT_SYMBOL_IF_MAC80211_KUNIT();

static ieee80211_rx_result
__ieee80211_data_to_8023(struct ieee80211_rx_data *rx, bool *port_control)
{}

bool ieee80211_is_our_addr(struct ieee80211_sub_if_data *sdata,
			   const u8 *addr, int *out_link_id)
{}

/*
 * requires that rx->skb is a frame with ethernet header
 */
static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc)
{}

static void ieee80211_deliver_skb_to_local_stack(struct sk_buff *skb,
						 struct ieee80211_rx_data *rx)
{}

/*
 * requires that rx->skb is a frame with ethernet header
 */
static void
ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
{}

#ifdef CONFIG_MAC80211_MESH
static bool
ieee80211_rx_mesh_fast_forward(struct ieee80211_sub_if_data *sdata,
			       struct sk_buff *skb, int hdrlen)
{}
#endif

static ieee80211_rx_result
ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta,
		       struct sk_buff *skb)
{}

static ieee80211_rx_result debug_noinline
__ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset)
{}

static ieee80211_rx_result debug_noinline
ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
{}

static ieee80211_rx_result debug_noinline
ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
{}

static ieee80211_rx_result debug_noinline
ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
{}

static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata,
					   struct ieee80211_mgmt *mgmt,
					   size_t len)
{}

static void
ieee80211_rx_check_bss_color_collision(struct ieee80211_rx_data *rx)
{}

static ieee80211_rx_result debug_noinline
ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
{}

static bool
ieee80211_process_rx_twt_action(struct ieee80211_rx_data *rx)
{}

static ieee80211_rx_result debug_noinline
ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
{}

static ieee80211_rx_result debug_noinline
ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx)
{}

static ieee80211_rx_result debug_noinline
ieee80211_rx_h_action_post_userspace(struct ieee80211_rx_data *rx)
{}

static ieee80211_rx_result debug_noinline
ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx)
{}

static ieee80211_rx_result debug_noinline
ieee80211_rx_h_ext(struct ieee80211_rx_data *rx)
{}

static ieee80211_rx_result debug_noinline
ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
{}

static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
					struct ieee80211_rate *rate,
					ieee80211_rx_result reason)
{}

static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
					 ieee80211_rx_result res)
{}

static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
				  struct sk_buff_head *frames)
{}

static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx)
{}

static bool
ieee80211_rx_is_valid_sta_link_id(struct ieee80211_sta *sta, u8 link_id)
{}

static bool ieee80211_rx_data_set_link(struct ieee80211_rx_data *rx,
				       u8 link_id)
{}

static bool ieee80211_rx_data_set_sta(struct ieee80211_rx_data *rx,
				      struct sta_info *sta, int link_id)
{}

/*
 * This function makes calls into the RX path, therefore
 * it has to be invoked under RCU read lock.
 */
void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
{}

void ieee80211_mark_rx_ba_filtered_frames(struct ieee80211_sta *pubsta, u8 tid,
					  u16 ssn, u64 filtered,
					  u16 received_mpdus)
{}
EXPORT_SYMBOL();

/* main receive path */

static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr)
{}

static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
{}

void ieee80211_check_fast_rx(struct sta_info *sta)
{}

void ieee80211_clear_fast_rx(struct sta_info *sta)
{}

void __ieee80211_check_fast_rx_iface(struct ieee80211_sub_if_data *sdata)
{}

void ieee80211_check_fast_rx_iface(struct ieee80211_sub_if_data *sdata)
{}

static void ieee80211_rx_8023(struct ieee80211_rx_data *rx,
			      struct ieee80211_fast_rx *fast_rx,
			      int orig_len)
{}

static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
				     struct ieee80211_fast_rx *fast_rx)
{}

/*
 * This function returns whether or not the SKB
 * was destined for RX processing or not, which,
 * if consume is true, is equivalent to whether
 * or not the skb was consumed.
 */
static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
					    struct sk_buff *skb, bool consume)
{}

static void __ieee80211_rx_handle_8023(struct ieee80211_hw *hw,
				       struct ieee80211_sta *pubsta,
				       struct sk_buff *skb,
				       struct list_head *list)
{}

static bool ieee80211_rx_for_interface(struct ieee80211_rx_data *rx,
				       struct sk_buff *skb, bool consume)
{}

/*
 * This is the actual Rx frames handler. as it belongs to Rx path it must
 * be called with rcu_read_lock protection.
 */
static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
					 struct ieee80211_sta *pubsta,
					 struct sk_buff *skb,
					 struct list_head *list)
{}

/*
 * This is the receive path handler. It is called by a low level driver when an
 * 802.11 MPDU is received from the hardware.
 */
void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
		       struct sk_buff *skb, struct list_head *list)
{}
EXPORT_SYMBOL();

void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
		       struct sk_buff *skb, struct napi_struct *napi)
{}
EXPORT_SYMBOL();

/* This is a version of the rx handler that can be called from hard irq
 * context. Post the skb on the queue and schedule the tasklet */
void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb)
{}
EXPORT_SYMBOL();