Skip to content

Commit baa951a

Browse files
jmberg-intelkuba-moo
authored andcommitted
mac80211: use the new drop reasons infrastructure
It can be really hard to analyse or debug why packets are going missing in mac80211, so add the needed infrastructure to use use the new per-subsystem drop reasons. We actually use two drop reason subsystems here because of the different handling of frames that are dropped but still go to monitor for old versions of hostapd, and those that are just completely unusable (e.g. crypto failed.) Annotate a few reasons here just to illustrate this, we'll need to go through and annotate more of them later. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 071c0fc commit baa951a

6 files changed

Lines changed: 138 additions & 48 deletions

File tree

include/net/dropreason.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,18 @@ enum skb_drop_reason_subsys {
1111
/** @SKB_DROP_REASON_SUBSYS_CORE: core drop reasons defined above */
1212
SKB_DROP_REASON_SUBSYS_CORE,
1313

14+
/**
15+
* @SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE: mac80211 drop reasons
16+
* for unusable frames, see net/mac80211/drop.h
17+
*/
18+
SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE,
19+
20+
/**
21+
* @SKB_DROP_REASON_SUBSYS_MAC80211_MONITOR: mac80211 drop reasons
22+
* for frames still going to monitor, see net/mac80211/drop.h
23+
*/
24+
SKB_DROP_REASON_SUBSYS_MAC80211_MONITOR,
25+
1426
/** @SKB_DROP_REASON_SUBSYS_NUM: number of subsystems defined */
1527
SKB_DROP_REASON_SUBSYS_NUM
1628
};

net/mac80211/drop.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* mac80211 drop reason list
4+
*
5+
* Copyright (C) 2023 Intel Corporation
6+
*/
7+
8+
#ifndef MAC80211_DROP_H
9+
#define MAC80211_DROP_H
10+
#include <net/dropreason.h>
11+
12+
typedef unsigned int __bitwise ieee80211_rx_result;
13+
14+
#define MAC80211_DROP_REASONS_MONITOR(R) \
15+
R(RX_DROP_M_UNEXPECTED_4ADDR_FRAME) \
16+
R(RX_DROP_M_BAD_BCN_KEYIDX) \
17+
R(RX_DROP_M_BAD_MGMT_KEYIDX) \
18+
/* this line for the trailing \ - add before this */
19+
20+
#define MAC80211_DROP_REASONS_UNUSABLE(R) \
21+
R(RX_DROP_U_MIC_FAIL) \
22+
R(RX_DROP_U_REPLAY) \
23+
R(RX_DROP_U_BAD_MMIE) \
24+
/* this line for the trailing \ - add before this */
25+
26+
/* having two enums allows for checking ieee80211_rx_result use with sparse */
27+
enum ___mac80211_drop_reason {
28+
/* if we get to the end of handlers with RX_CONTINUE this will be the reason */
29+
___RX_CONTINUE = SKB_CONSUMED,
30+
31+
/* this never gets used as an argument to kfree_skb_reason() */
32+
___RX_QUEUED = SKB_NOT_DROPPED_YET,
33+
34+
#define ENUM(x) ___ ## x,
35+
___RX_DROP_MONITOR = SKB_DROP_REASON_SUBSYS_MAC80211_MONITOR <<
36+
SKB_DROP_REASON_SUBSYS_SHIFT,
37+
MAC80211_DROP_REASONS_MONITOR(ENUM)
38+
39+
___RX_DROP_UNUSABLE = SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE <<
40+
SKB_DROP_REASON_SUBSYS_SHIFT,
41+
MAC80211_DROP_REASONS_UNUSABLE(ENUM)
42+
#undef ENUM
43+
};
44+
45+
enum mac80211_drop_reason {
46+
RX_CONTINUE = (__force ieee80211_rx_result)___RX_CONTINUE,
47+
RX_QUEUED = (__force ieee80211_rx_result)___RX_QUEUED,
48+
RX_DROP_MONITOR = (__force ieee80211_rx_result)___RX_DROP_MONITOR,
49+
RX_DROP_UNUSABLE = (__force ieee80211_rx_result)___RX_DROP_UNUSABLE,
50+
#define DEF(x) x = (__force ieee80211_rx_result)___ ## x,
51+
MAC80211_DROP_REASONS_MONITOR(DEF)
52+
MAC80211_DROP_REASONS_UNUSABLE(DEF)
53+
#undef DEF
54+
};
55+
56+
#endif /* MAC80211_DROP_H */

net/mac80211/ieee80211_i.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "key.h"
3434
#include "sta_info.h"
3535
#include "debug.h"
36+
#include "drop.h"
3637

3738
extern const struct cfg80211_ops mac80211_config_ops;
3839

@@ -170,13 +171,6 @@ struct ieee80211_tx_data {
170171
unsigned int flags;
171172
};
172173

173-
174-
typedef unsigned __bitwise ieee80211_rx_result;
175-
#define RX_CONTINUE ((__force ieee80211_rx_result) 0u)
176-
#define RX_DROP_UNUSABLE ((__force ieee80211_rx_result) 1u)
177-
#define RX_DROP_MONITOR ((__force ieee80211_rx_result) 2u)
178-
#define RX_QUEUED ((__force ieee80211_rx_result) 3u)
179-
180174
/**
181175
* enum ieee80211_packet_rx_flags - packet RX flags
182176
* @IEEE80211_RX_AMSDU: a-MSDU packet

net/mac80211/main.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/bitmap.h>
2323
#include <linux/inetdevice.h>
2424
#include <net/net_namespace.h>
25+
#include <net/dropreason.h>
2526
#include <net/cfg80211.h>
2627
#include <net/addrconf.h>
2728

@@ -1542,6 +1543,28 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
15421543
}
15431544
EXPORT_SYMBOL(ieee80211_free_hw);
15441545

1546+
static const char * const drop_reasons_monitor[] = {
1547+
#define V(x) #x,
1548+
[0] = "RX_DROP_MONITOR",
1549+
MAC80211_DROP_REASONS_MONITOR(V)
1550+
};
1551+
1552+
static struct drop_reason_list drop_reason_list_monitor = {
1553+
.reasons = drop_reasons_monitor,
1554+
.n_reasons = ARRAY_SIZE(drop_reasons_monitor),
1555+
};
1556+
1557+
static const char * const drop_reasons_unusable[] = {
1558+
[0] = "RX_DROP_UNUSABLE",
1559+
MAC80211_DROP_REASONS_UNUSABLE(V)
1560+
#undef V
1561+
};
1562+
1563+
static struct drop_reason_list drop_reason_list_unusable = {
1564+
.reasons = drop_reasons_unusable,
1565+
.n_reasons = ARRAY_SIZE(drop_reasons_unusable),
1566+
};
1567+
15451568
static int __init ieee80211_init(void)
15461569
{
15471570
struct sk_buff *skb;
@@ -1559,6 +1582,11 @@ static int __init ieee80211_init(void)
15591582
if (ret)
15601583
goto err_netdev;
15611584

1585+
drop_reasons_register_subsys(SKB_DROP_REASON_SUBSYS_MAC80211_MONITOR,
1586+
&drop_reason_list_monitor);
1587+
drop_reasons_register_subsys(SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE,
1588+
&drop_reason_list_unusable);
1589+
15621590
return 0;
15631591
err_netdev:
15641592
rc80211_minstrel_exit();
@@ -1574,6 +1602,9 @@ static void __exit ieee80211_exit(void)
15741602

15751603
ieee80211_iface_exit();
15761604

1605+
drop_reasons_unregister_subsys(SKB_DROP_REASON_SUBSYS_MAC80211_MONITOR);
1606+
drop_reasons_unregister_subsys(SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE);
1607+
15771608
rcu_barrier();
15781609
}
15791610

net/mac80211/rx.c

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1826,7 +1826,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
18261826
cfg80211_rx_unexpected_4addr_frame(
18271827
rx->sdata->dev, sta->sta.addr,
18281828
GFP_ATOMIC);
1829-
return RX_DROP_MONITOR;
1829+
return RX_DROP_M_UNEXPECTED_4ADDR_FRAME;
18301830
}
18311831
/*
18321832
* Update counter and free packet here to avoid
@@ -1961,7 +1961,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
19611961
cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev,
19621962
skb->data,
19631963
skb->len);
1964-
return RX_DROP_MONITOR; /* unexpected BIP keyidx */
1964+
return RX_DROP_M_BAD_BCN_KEYIDX;
19651965
}
19661966

19671967
rx->key = ieee80211_rx_get_bigtk(rx, mmie_keyidx);
@@ -1975,7 +1975,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
19751975

19761976
if (mmie_keyidx < NUM_DEFAULT_KEYS ||
19771977
mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
1978-
return RX_DROP_MONITOR; /* unexpected BIP keyidx */
1978+
return RX_DROP_M_BAD_MGMT_KEYIDX; /* unexpected BIP keyidx */
19791979
if (rx->link_sta) {
19801980
if (ieee80211_is_group_privacy_action(skb) &&
19811981
test_sta_flag(rx->sta, WLAN_STA_MFP))
@@ -3960,7 +3960,8 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
39603960
}
39613961

39623962
static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
3963-
struct ieee80211_rate *rate)
3963+
struct ieee80211_rate *rate,
3964+
ieee80211_rx_result reason)
39643965
{
39653966
struct ieee80211_sub_if_data *sdata;
39663967
struct ieee80211_local *local = rx->local;
@@ -4024,42 +4025,38 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
40244025
}
40254026

40264027
out_free_skb:
4027-
dev_kfree_skb(skb);
4028+
kfree_skb_reason(skb, (__force u32)reason);
40284029
}
40294030

40304031
static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
40314032
ieee80211_rx_result res)
40324033
{
4033-
switch (res) {
4034-
case RX_DROP_MONITOR:
4035-
I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop);
4036-
if (rx->sta)
4037-
rx->link_sta->rx_stats.dropped++;
4038-
fallthrough;
4039-
case RX_CONTINUE: {
4040-
struct ieee80211_rate *rate = NULL;
4041-
struct ieee80211_supported_band *sband;
4042-
struct ieee80211_rx_status *status;
4043-
4044-
status = IEEE80211_SKB_RXCB((rx->skb));
4034+
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
4035+
struct ieee80211_supported_band *sband;
4036+
struct ieee80211_rate *rate = NULL;
40454037

4046-
sband = rx->local->hw.wiphy->bands[status->band];
4047-
if (status->encoding == RX_ENC_LEGACY)
4048-
rate = &sband->bitrates[status->rate_idx];
4038+
if (res == RX_QUEUED) {
4039+
I802_DEBUG_INC(rx->sdata->local->rx_handlers_queued);
4040+
return;
4041+
}
40494042

4050-
ieee80211_rx_cooked_monitor(rx, rate);
4051-
break;
4052-
}
4053-
case RX_DROP_UNUSABLE:
4043+
if (res != RX_CONTINUE) {
40544044
I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop);
40554045
if (rx->sta)
40564046
rx->link_sta->rx_stats.dropped++;
4057-
dev_kfree_skb(rx->skb);
4058-
break;
4059-
case RX_QUEUED:
4060-
I802_DEBUG_INC(rx->sdata->local->rx_handlers_queued);
4061-
break;
40624047
}
4048+
4049+
if (u32_get_bits((__force u32)res, SKB_DROP_REASON_SUBSYS_MASK) ==
4050+
SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE) {
4051+
kfree_skb_reason(rx->skb, (__force u32)res);
4052+
return;
4053+
}
4054+
4055+
sband = rx->local->hw.wiphy->bands[status->band];
4056+
if (status->encoding == RX_ENC_LEGACY)
4057+
rate = &sband->bitrates[status->rate_idx];
4058+
4059+
ieee80211_rx_cooked_monitor(rx, rate, res);
40634060
}
40644061

40654062
static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,

net/mac80211/wpa.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx,
550550
if (res < 0 ||
551551
(!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) {
552552
key->u.ccmp.replays++;
553-
return RX_DROP_UNUSABLE;
553+
return RX_DROP_U_REPLAY;
554554
}
555555

556556
if (!(status->flag & RX_FLAG_DECRYPTED)) {
@@ -564,7 +564,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx,
564564
skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
565565
data_len,
566566
skb->data + skb->len - mic_len))
567-
return RX_DROP_UNUSABLE;
567+
return RX_DROP_U_MIC_FAIL;
568568
}
569569

570570
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)
746746
if (res < 0 ||
747747
(!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) {
748748
key->u.gcmp.replays++;
749-
return RX_DROP_UNUSABLE;
749+
return RX_DROP_U_REPLAY;
750750
}
751751

752752
if (!(status->flag & RX_FLAG_DECRYPTED)) {
@@ -761,7 +761,7 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx)
761761
data_len,
762762
skb->data + skb->len -
763763
IEEE80211_GCMP_MIC_LEN))
764-
return RX_DROP_UNUSABLE;
764+
return RX_DROP_U_MIC_FAIL;
765765
}
766766

767767
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)
930930
(skb->data + skb->len - sizeof(*mmie));
931931
if (mmie->element_id != WLAN_EID_MMIE ||
932932
mmie->length != sizeof(*mmie) - 2)
933-
return RX_DROP_UNUSABLE; /* Invalid MMIE */
933+
return RX_DROP_U_BAD_MMIE; /* Invalid MMIE */
934934

935935
bip_ipn_swap(ipn, mmie->sequence_number);
936936

937937
if (memcmp(ipn, key->u.aes_cmac.rx_pn, 6) <= 0) {
938938
key->u.aes_cmac.replays++;
939-
return RX_DROP_UNUSABLE;
939+
return RX_DROP_U_REPLAY;
940940
}
941941

942942
if (!(status->flag & RX_FLAG_DECRYPTED)) {
@@ -946,7 +946,7 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx)
946946
skb->data + 24, skb->len - 24, mic);
947947
if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
948948
key->u.aes_cmac.icverrors++;
949-
return RX_DROP_UNUSABLE;
949+
return RX_DROP_U_MIC_FAIL;
950950
}
951951
}
952952

@@ -986,7 +986,7 @@ ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx)
986986

987987
if (memcmp(ipn, key->u.aes_cmac.rx_pn, 6) <= 0) {
988988
key->u.aes_cmac.replays++;
989-
return RX_DROP_UNUSABLE;
989+
return RX_DROP_U_REPLAY;
990990
}
991991

992992
if (!(status->flag & RX_FLAG_DECRYPTED)) {
@@ -996,7 +996,7 @@ ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx)
996996
skb->data + 24, skb->len - 24, mic);
997997
if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
998998
key->u.aes_cmac.icverrors++;
999-
return RX_DROP_UNUSABLE;
999+
return RX_DROP_U_MIC_FAIL;
10001000
}
10011001
}
10021002

@@ -1079,13 +1079,13 @@ ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx)
10791079
(skb->data + skb->len - sizeof(*mmie));
10801080
if (mmie->element_id != WLAN_EID_MMIE ||
10811081
mmie->length != sizeof(*mmie) - 2)
1082-
return RX_DROP_UNUSABLE; /* Invalid MMIE */
1082+
return RX_DROP_U_BAD_MMIE; /* Invalid MMIE */
10831083

10841084
bip_ipn_swap(ipn, mmie->sequence_number);
10851085

10861086
if (memcmp(ipn, key->u.aes_gmac.rx_pn, 6) <= 0) {
10871087
key->u.aes_gmac.replays++;
1088-
return RX_DROP_UNUSABLE;
1088+
return RX_DROP_U_REPLAY;
10891089
}
10901090

10911091
if (!(status->flag & RX_FLAG_DECRYPTED)) {
@@ -1104,7 +1104,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx)
11041104
crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
11051105
key->u.aes_gmac.icverrors++;
11061106
kfree(mic);
1107-
return RX_DROP_UNUSABLE;
1107+
return RX_DROP_U_MIC_FAIL;
11081108
}
11091109
kfree(mic);
11101110
}

0 commit comments

Comments
 (0)