Re: [v5 7/8] rsi: add module parameter operating mode
Amitkumar Karwarwrites: > From: Prameela Rani Garnepudi > > Operating mode determines the support for other protocols. > This is made as module parameter for better usage. > > Signed-off-by: Prameela Rani Garnepudi > Signed-off-by: Siva Rebbagondla > Signed-off-by: Amitkumar Karwar [...] > +/* Default operating mode is wlan STA + BT */ > +static u16 dev_oper_mode = DEV_OPMODE_STA_BT_DUAL; > +module_param(dev_oper_mode, ushort, 0444); > +MODULE_PARM_DESC(dev_oper_mode, > + "1[Wi-Fi], 4[BT], 8[BT LE], 5[Wi-Fi STA + BT classic]\n" > + "9[Wi-Fi STA + BT LE], 13[Wi-Fi STA + BT classic + BT LE]\n" > + "6[AP + BT classic], 14[AP + BT classic + BT LE]"); I really wish that we have nl80211 interface for configuring btcoex. We have been talking about that for years but nobody has implemented it :( -- Kalle Valo
Re: [v5 6/8] rsi: handle BT traffic in driver
Amitkumar Karwarwrites: > From: Siva Rebbagondla > > BT frames are passed through coex and hal modules to BUS. > After firmware is loaded, based on the operating mode CARD > READY frame comes for each protocol. When BT card ready is > received, BT attach is called. > Protocol operations are exchanged between the modules > at initialization time. > > Signed-off-by: Siva Rebbagondla > Signed-off-by: Prameela Rani Garnepudi > Signed-off-by: Amitkumar Karwar > --- > v5: Same as v3, v4 > v3: bt_ops need not be present structure g_proto_ops. It is removed. > v2: WLAN module depends on BT module. Updated in Kconfig > --- > drivers/net/wireless/rsi/Kconfig| 2 +- > drivers/net/wireless/rsi/rsi_91x_coex.c | 4 ++- > drivers/net/wireless/rsi/rsi_91x_core.c | 16 > drivers/net/wireless/rsi/rsi_91x_hal.c | 39 > + > drivers/net/wireless/rsi/rsi_91x_main.c | 31 +++ > drivers/net/wireless/rsi/rsi_91x_sdio_ops.c | 1 + > drivers/net/wireless/rsi/rsi_common.h | 1 + > drivers/net/wireless/rsi/rsi_hal.h | 10 > drivers/net/wireless/rsi/rsi_main.h | 3 +++ > 9 files changed, 100 insertions(+), 7 deletions(-) > > diff --git a/drivers/net/wireless/rsi/Kconfig > b/drivers/net/wireless/rsi/Kconfig > index 7c5e4ca..ad72c80 100644 > --- a/drivers/net/wireless/rsi/Kconfig > +++ b/drivers/net/wireless/rsi/Kconfig > @@ -13,7 +13,7 @@ if WLAN_VENDOR_RSI > > config RSI_91X > tristate "Redpine Signals Inc 91x WLAN driver support" > - depends on MAC80211 > + depends on MAC80211 && BT_RSI I think this is evil, now the wlan driver cannot be enabled unless the bluetooth driver is enabled. And if I'm understanding correctly it won't even show up in the menuconfig. A much nicer approach would be that btcoex is just disabled in the wlan driver if BT_RSI is disabled. -- Kalle Valo
Re: [v5 4/8] rsi: add coex support
Amitkumar Karwarwrites: > From: Prameela Rani Garnepudi > > With BT support, driver has to handle two streams of data > (i.e. wlan and BT). Actual coex implementation is in firmware. > Coex module just schedule the packets to firmware by taking them > from the corresponding paths. > > Structures for module and protocol operations are introduced for > this purpose. Protocol operations structure is global structure > which can be shared among different modules. Initialization of > coex and operating mode values is moved to rsi_91x_init(). > > Signed-off-by: Prameela Rani Garnepudi > Signed-off-by: Siva Rebbagondla > Signed-off-by: Amitkumar Karwar [...] > +static void rsi_coex_sched_tx_pkts(struct rsi_coex_ctrl_block *coex_cb) > +{ > + enum rsi_coex_queues coex_q; > + struct sk_buff *skb; > + > + while (1) { > + coex_q = rsi_coex_determine_coex_q(coex_cb); > + rsi_dbg(INFO_ZONE, "queue = %d\n", coex_q); > + > + if (coex_q == RSI_COEX_Q_INVALID) { > + rsi_dbg(DATA_TX_ZONE, "No more pkt\n"); > + break; > + } > + > + if (coex_q == RSI_COEX_Q_BT) > + skb = skb_dequeue(_cb->coex_tx_qs[RSI_COEX_Q_BT]); > + } > +} Neverending loops are dangerous in kernel. Can you put a limit so that if there's a bug the loop will not run forever? -- Kalle Valo
Re: [v5 5/8] Bluetooth: btrsi: add new rsi bluetooth driver
Marcel Holtmannwrites: >> Redpine bluetooth driver is a thin driver which depends on >> 'rsi_91x' driver for transmitting and receiving packets >> to/from device. It creates hci interface when attach() is >> called from 'rsi_91x' module. >> >> Signed-off-by: Prameela Rani Garnepudi >> Signed-off-by: Siva Rebbagondla >> Signed-off-by: Amitkumar Karwar [...] >> +module_init(rsi_91x_bt_module_init); >> +module_exit(rsi_91x_bt_module_exit); >> +MODULE_AUTHOR("Redpine Signals Inc"); >> +MODULE_DESCRIPTION("RSI BT driver"); >> +MODULE_SUPPORTED_DEVICE("RSI-BT"); >> +MODULE_LICENSE("Dual BSD/GPL”); > > Acked-by: Marcel Holtmann > Reviewed-by: Marcel Holtmann So how should we handle the logistics, should all these go via wireless-drivers-next tree or what's the plan? -- Kalle Valo
Re: [v5 4/8] rsi: add coex support
Amitkumar Karwarwrites: > From: Prameela Rani Garnepudi > > With BT support, driver has to handle two streams of data > (i.e. wlan and BT). Actual coex implementation is in firmware. > Coex module just schedule the packets to firmware by taking them > from the corresponding paths. > > Structures for module and protocol operations are introduced for > this purpose. Protocol operations structure is global structure > which can be shared among different modules. Initialization of > coex and operating mode values is moved to rsi_91x_init(). > > Signed-off-by: Prameela Rani Garnepudi > Signed-off-by: Siva Rebbagondla > Signed-off-by: Amitkumar Karwar [...] > @@ -270,6 +271,7 @@ struct rsi_common { > u8 obm_ant_sel_val; > int tx_power; > u8 ant_in_use; > + struct semaphore tx_bus_lock; Do you really need to use semaphore? I think nowadays the preference is to use something other than semaphores. Also calling it tx_bus_lock is IMHO misleading, tx_bus_sema would be nicer. -- Kalle Valo
Re: [v5 3/8] rsi: add header file rsi_header
Amitkumar Karwarwrites: > From: Prameela Rani Garnepudi > > The common parameters used by wlan and bt modules are added > to a new header file "rsi_header.h" defined in '/include/linux' > > Signed-off-by: Prameela Rani Garnepudi > Signed-off-by: Siva Rebbagondla > Signed-off-by: Amitkumar Karwar [...] > diff --git a/include/linux/rsi_header.h b/include/linux/rsi_header.h > new file mode 100644 > index 000..16a447b > --- /dev/null > +++ b/include/linux/rsi_header.h > @@ -0,0 +1,34 @@ > +/** > + * Copyright (c) 2017 Redpine Signals Inc. > + * > + * Permission to use, copy, modify, and/or distribute this software for any > + * purpose with or without fee is hereby granted, provided that the above > + * copyright notice and this permission notice appear in all copies. > + * > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + */ > + > +#ifndef __RSI_HEADER_H__ > +#define __RSI_HEADER_H__ > + > +/* HAL queue information */ > +#define RSI_COEX_Q 0x0 > +#define RSI_BT_Q 0x2 > +#define RSI_WLAN_Q 0x3 > +#define RSI_WIFI_MGMT_Q 0x4 > +#define RSI_WIFI_DATA_Q 0x5 > +#define RSI_BT_MGMT_Q0x6 > +#define RSI_BT_DATA_Q0x7 > + > +enum rsi_host_intf { > + RSI_HOST_INTF_SDIO = 0, > + RSI_HOST_INTF_USB > +}; > + > +#endif The name of the header "rsi_header.h" looks odd. The ".h" prefix already tells that it's a header file, no need to repeat that in the filename. But also calling it "rsi.h" feels a bit weird, it's not really very specific. Would "rsi_91x.h" (from rsi_91x.ko) be any better? Also I'm not sure about the location (include/linux), is that really the correct place to have a header file shared by a wireless and bluetooth driver? Anyone know? Or would include/net be better? -- Kalle Valo
Re: rtl8821ae keep alive not set, connection lost
On Wed, Jan 31, 2018 at 11:06:12AM -0600, Larry Finger wrote: > On 09/12/2017 05:09 PM, James Cameron wrote: > >Summary: 40b368af4b75 ("rtlwifi: Fix alignment issues") breaks > >rtl8821ae keep alive, causing "Connection to AP lost" and deauth, > >but why? > > > >Wireless connection is lost after a few seconds or minutes, on > >every OLPC NL3 laptop with rtl8821ae, with any stable kernel after > >4.10.1, and any kernel with 40b368af4b75. > > > >dmesg contains > > > > wlp2s0: Connection to AP 2c:b0:5d:a6:86:eb lost > > > >iw event shows > > > > wlp2s0: del station 2c:b0:5d:a6:86:eb > > wlp2s0 (phy #0): deauth 74:c6:3b:09:b5:0d -> 2c:b0:5d:a6:86:eb reason 4: > > Disassociated due to inactivity > > wlp2s0 (phy #0): disconnected (local request) > > > >Workaround is to bounce the link, then reconnect; > > > > ip link set wlp2s0 down > > ip link set wlp2s0 up > > iw dev wlp2s0 connect qz > > > >A nearby monitor host captures a deauthentication packet sent by > >the device. > > > >Bisection showed cause is 40b368af4b75 ("rtlwifi: Fix alignment > >issues") which changes the width of DBI register read. > > > >On the face of it, 40b368af4b75 looks correct, especially compared > >against same function in rtl8723be. > > > >I've no idea why reverting fixes the problem. I'm hoping someone > >here might speculate and suggest ways to test. > > > >As keep alive is set through this path, my guess is that keep alive > >is not being set in the device. Or perhaps reading 16-bits > >perturbs another register. Is there a way to test? > > > >http://dev.laptop.org/~quozl/z/1drtGD.txt dmesg of 4.13 > > > >http://dev.laptop.org/~quozl/z/1drt7c.txt dmesg with 4.13 and > >revert of 40b368af4b75 > > James, > > I'm afraid we are needing to revisit this problem again. Changing > that 8-bit read to a 16-bit version causes an unaligned memory > reference in AARCH64, thus we will need to re-revert. To prevent > problems on systems such as yours, PK plans to turn off ASPM > capability and backdoor in certain platforms that will be listed in > a quirks table. Please report the output of 'dmidecode -t system' > for you affected system(s). Thanks for letting me know. We made three production runs, and I'm waiting to get a hold of the dmidecode for two of them. This may take some weeks; we have to find stock and ship it, or we have to ask our contract manufacturer (CM) if they have kept data or units. I've dmidecode for one production run. http://dev.laptop.org/~quozl/z/1eh7JF.txt (my unit nl3-e) I've dmidecode for prototypes, but they have clearly been programmed badly. We did not ask our CM for Windows compatibility, so they may have had no step to verify the data. We also went through several iterations to get serial numbers assigned, so the data I have does not have good provenance. http://dev.laptop.org/~quozl/z/1eh7EE.txt (my unit nl3-c) http://dev.laptop.org/~quozl/z/1eh7EV.txt (my unit nl3-d) http://dev.laptop.org/~quozl/z/1eh7He.txt (my unit nl3-a) http://dev.laptop.org/~quozl/z/1eh8DR.txt (my unit nl3-b) > We hope you will be able to test any proposed patches. Yes, can do. I've just tested v4.15. However, I'm concerned about your plan to use quirks; 1. turning off ASPM may decrease run time on battery, which if it is significant, across several thousand laptops will yield generator fuel or solar budget failure; can the power impact be quantified? 2. why not keep ASPM enabled, and use 8-bit when quirked, or on x86_64, or when not AARCH64? 3. why not find the underlying problem; PK is in the same company as the device firmware engineers, so it should be possible for them to find out why 16-bit access causes the device firmware to hang? We drew a blank trying to reach firmware engineers through our CM and module maker; perhaps we were not large or noisy enough. 4. it's not just me; there are others who have reported similar problems, so won't re-reverting affect them? They haven't engaged in the process as thoroughly, and may not be in the quirks table. You also reproduced the problem with different hardware. > Thanks, > > Larry -- James Cameron http://quozl.netrek.org/
Re: [v5 1/8] rsi: add rx control block to handle rx packets in USB
Amitkumar Karwarwrites: > From: Prameela Rani Garnepudi > > Rx bluetooth endpoint shall be added in further patches. Rx control > block is introduced here to handle Rx packets properly. Separate > function is written to initialize the RX control blocks. > > Signed-off-by: Prameela Rani Garnepudi > Signed-off-by: Siva Rebbagondla > Signed-off-by: Amitkumar Karwar [...] > +static int rsi_usb_init_rx(struct rsi_hw *adapter) > +{ > + struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; > + struct rx_usb_ctrl_block *rx_cb; > + u8 idx; > + > + for (idx = 0; idx < MAX_RX_URBS; idx++) { > + rx_cb = >rx_cb[idx]; > + > + rx_cb->rx_buffer = kzalloc(RSI_USB_BUF_SIZE * 2, > +GFP_KERNEL | GFP_DMA); Do you really need GFP_DMA? From the documentation: "GFP_DMA exists for historical reasons and should be avoided where possible." -- Kalle Valo
QCA9531 Question
Hello, I have two Atheros AP147 QCA9531 SoC, the radio is connected to the WMAC. I am running OpenWRT Trunk on them and for some reason the TX/RX is incredibly low. The first AP147 is low powered, No xPA Bias and only has 20dB of output power. Ath9k appears to run correctly, meaning I can bring up station/AP. However when I scan, it see's nothing. When I bring up an AP, the AP doesn't transmit. The second AP147 has an xPA Bias level of 13. This time I can scan on a station interface but everything it see's is incredibly low. The TX Power is also very very low. With the xPA, this is supposed to run at 26 dB. Is there a register a register that I can toggle to enable the QCA9531 internal PA/LNA? It's like ath9k is not enabling the internal PA/LNA correctly. The odd thing is, I have other QCA9531 boards ( Mikrotik based ) and they run fine on OpenWRT Trunk. I'm not sure what the difference is... Any insight would be much appreciated. I posted some details on the LEDE forum: https://forum.lede-project.org/t/ap147-010-qca9531-wmac-tx-power-issue/11126/2 -- Davey
Re: [RFC v3 0/6] EAPoL over NL80211
Hi Johannes, On 01/31/2018 04:00 PM, Johannes Berg wrote: Looks pretty good! Some comments over in separate emails. Maybe you should consider reordering: [1/6] keep [2/6] keep [3/6] introduce TX (now patch 5) [4/6] introduce RX (now patch 3) modify this to require TX from the driver in order to be able to set the new flag [5/6] add TX to mac80211 [6/6] add RX to mac80211 and set the flag Ok, you don't really have to do that, since you only set the flag in the last patch anyway, but that'd make it better to add the check that requires TX, so you don't have to do that in the TX patch and modify the RX portion again. Err, Johannes Berg presents: Fun with Flags ;) So I re-read this about half a dozen times and I think I figured out what you wanted. It seems you mean different flags in 4/6 and 6/6. I reordered V4 with my interpretation. Doesn't quite look like the above, but hopefully I groked what you wanted correctly. I didn't put in the extra owner check on the tx operation since it wasn't clear whether you wanted that or not. Thanks for the review. Regards, -Denis
[RFC v4 6/6] mac80211: Send control port frames over nl80211
If userspace requested control port frames to go over 80211, then do so. The control packets are intercepted just prior to delivery of the packet to the underlying network device. Pre-authentication type frames (protocol: 0x88c7) are also forwarded over nl80211. Signed-off-by: Denis Kenzior--- net/mac80211/cfg.c | 2 ++ net/mac80211/ieee80211_i.h | 1 + net/mac80211/main.c| 2 ++ net/mac80211/mlme.c| 2 ++ net/mac80211/rx.c | 33 - 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index fb3cf38d674f..71cb45e517b0 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -925,6 +925,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, */ sdata->control_port_protocol = params->crypto.control_port_ethertype; sdata->control_port_no_encrypt = params->crypto.control_port_no_encrypt; + sdata->control_port_over_nl80211 = false; sdata->encrypt_headroom = ieee80211_cs_headroom(sdata->local, >crypto, sdata->vif.type); @@ -934,6 +935,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, params->crypto.control_port_ethertype; vlan->control_port_no_encrypt = params->crypto.control_port_no_encrypt; + vlan->control_port_over_nl80211 = false; vlan->encrypt_headroom = ieee80211_cs_headroom(sdata->local, >crypto, diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index c78f30555b6d..c71d2eded1f2 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -899,6 +899,7 @@ struct ieee80211_sub_if_data { u16 sequence_number; __be16 control_port_protocol; bool control_port_no_encrypt; + bool control_port_over_nl80211; int encrypt_headroom; atomic_t num_tx_queued; diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 0785d04a80bc..e5a51267c75d 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -554,6 +554,8 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, NL80211_FEATURE_USERSPACE_MPM | NL80211_FEATURE_FULL_AP_CLIENT_STATE; wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_STA); + wiphy_ext_feature_set(wiphy, + NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211); if (!ops->hw_scan) wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN | diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 39b660b9a908..fc71a906939b 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -4830,6 +4830,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, sdata->control_port_protocol = req->crypto.control_port_ethertype; sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt; + sdata->control_port_over_nl80211 = + req->crypto.control_port_over_nl80211; sdata->encrypt_headroom = ieee80211_cs_headroom(local, >crypto, sdata->vif.type); diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index e755f93ad735..c152fc318c11 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2243,6 +2243,32 @@ static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc) return true; } +static void ieee80211_deliver_skb_to_local_stack(struct sk_buff *skb, +struct ieee80211_rx_data *rx) +{ + struct ieee80211_sub_if_data *sdata = rx->sdata; + struct net_device *dev = sdata->dev; + + if (unlikely((skb->protocol == sdata->control_port_protocol || + skb->protocol == cpu_to_be16(ETH_P_PREAUTH)) && +sdata->control_port_over_nl80211)) { + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + bool noencrypt = status->flag & RX_FLAG_DECRYPTED; + struct ethhdr *ehdr = eth_hdr(skb); + + cfg80211_rx_control_port(dev, skb->data, skb->len, +ehdr->h_source, +be16_to_cpu(skb->protocol), noencrypt); + dev_kfree_skb(skb); + } else { + /* deliver to local stack */ + if (rx->napi) + napi_gro_receive(rx->napi, skb); + else + netif_receive_skb(skb); + } +} + /* * requires that rx->skb is a frame with ethernet header */ @@ -2327,13 +2353,10 @@ ieee80211_deliver_skb(struct ieee80211_rx_data
[RFC v4 3/6] nl80211: Implement TX of control port frames
This commit implements the TX side of NL80211_CMD_CONTROL_PORT_FRAME. Userspace provides the raw EAPoL frame using NL80211_ATTR_FRAME. Userspace should also provide the destination address and the protocol type to use when sending the frame. This is used to implement TX of Pre-authentication frames. If CONTROL_PORT_ETHERTYPE_NO_ENCRYPT is specified, then the driver will be asked not to encrypt the outgoing frame. A new EXT_FEATURE flag is introduced so that nl80211 code can check whether a given wiphy has capability to pass EAPoL frames over NL80211. Signed-off-by: Denis Kenzior--- include/net/cfg80211.h | 9 +++ include/uapi/linux/nl80211.h | 3 +++ net/wireless/nl80211.c | 63 +++- net/wireless/rdev-ops.h | 15 +++ net/wireless/trace.h | 26 ++ 5 files changed, 115 insertions(+), 1 deletion(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index f3102c6745fd..e1686421fdd7 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2958,6 +2958,9 @@ struct cfg80211_external_auth_params { * * @external_auth: indicates result of offloaded authentication processing from * user space + * + * @tx_control_port: TX a control port frame (EAPoL). The noencrypt parameter + * tells the driver that the frame should not be encrypted. */ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); @@ -3253,6 +3256,12 @@ struct cfg80211_ops { const u8 *aa); int (*external_auth)(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_external_auth_params *params); + + int (*tx_control_port)(struct wiphy *wiphy, + struct net_device *dev, + const u8 *buf, size_t len, + const u8 *dest, const __be16 proto, + const bool noencrypt); }; /* diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 31fc88cb0a2c..5842b3954cfd 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -5009,6 +5009,8 @@ enum nl80211_feature_flags { * @NL80211_EXT_FEATURE_LOW_SPAN_SCAN: Driver supports low span scan. * @NL80211_EXT_FEATURE_LOW_POWER_SCAN: Driver supports low power scan. * @NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN: Driver supports high accuracy scan. + * @NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211: Driver supports sending and + * receiving control port frames over NL80211 instead of the netdevice. * * @NUM_NL80211_EXT_FEATURES: number of extended features. * @MAX_NL80211_EXT_FEATURES: highest extended feature index. @@ -5039,6 +5041,7 @@ enum nl80211_ext_feature_index { NL80211_EXT_FEATURE_LOW_SPAN_SCAN, NL80211_EXT_FEATURE_LOW_POWER_SCAN, NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN, + NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211, /* add new features before the definition below */ NUM_NL80211_EXT_FEATURES, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index bffbd2cd2fc3..645c072cc4a3 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -12515,6 +12515,60 @@ static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info) return rdev_external_auth(rdev, dev, ); } +static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct wireless_dev *wdev = dev->ieee80211_ptr; + const u8 *buf; + size_t len; + u8 *dest; + u16 proto; + bool noencrypt; + int err; + + if (!wiphy_ext_feature_isset(>wiphy, + NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211)) + return -EOPNOTSUPP; + + if (!rdev->ops->tx_control_port) + return -EOPNOTSUPP; + + if (!info->attrs[NL80211_ATTR_FRAME] || + !info->attrs[NL80211_ATTR_MAC] || + !info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) + return -EINVAL; + + wdev_lock(wdev); + + switch (wdev->iftype) { + case NL80211_IFTYPE_STATION: + if (wdev->current_bss) + break; + err = -ENOTCONN; + goto out; + default: + err = -EOPNOTSUPP; + goto out; + } + + wdev_unlock(wdev); + + buf = nla_data(info->attrs[NL80211_ATTR_FRAME]); + len = nla_len(info->attrs[NL80211_ATTR_FRAME]); + dest = nla_data(info->attrs[NL80211_ATTR_MAC]); + proto = nla_get_u16(info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]); + noencrypt = + nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]); + +
[RFC v4 4/6] nl80211: Add CONTROL_PORT_OVER_NL80211 attribute
Signed-off-by: Denis Kenzior--- include/net/cfg80211.h | 3 +++ include/uapi/linux/nl80211.h | 14 +- net/wireless/nl80211.c | 13 + 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index e1686421fdd7..ccc501cc6ffc 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -646,6 +646,8 @@ struct survey_info { * allowed through even on unauthorized ports * @control_port_no_encrypt: TRUE to prevent encryption of control port * protocol frames. + * @control_port_over_nl80211: TRUE if userspace expects to exchange control + * port frames over NL80211 instead of the network interface. * @wep_keys: static WEP keys, if not NULL points to an array of * CFG80211_MAX_WEP_KEYS WEP keys * @wep_tx_key: key index (0..3) of the default TX static WEP key @@ -661,6 +663,7 @@ struct cfg80211_crypto_settings { bool control_port; __be16 control_port_ethertype; bool control_port_no_encrypt; + bool control_port_over_nl80211; struct key_params *wep_keys; int wep_tx_key; const u8 *psk; diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 5842b3954cfd..d6016afbfdd7 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -542,7 +542,8 @@ * IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_USE_MFP, * %NL80211_ATTR_MAC, %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT, * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE, - * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT, %NL80211_ATTR_MAC_HINT, and + * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT, + * %NL80211_ATTR_CONTROL_PORT_OVER_NL80211, %NL80211_ATTR_MAC_HINT, and * %NL80211_ATTR_WIPHY_FREQ_HINT. * If included, %NL80211_ATTR_MAC and %NL80211_ATTR_WIPHY_FREQ are * restrictions on BSS selection, i.e., they effectively prevent roaming @@ -1488,6 +1489,15 @@ enum nl80211_commands { * @NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT: When included along with * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE, indicates that the custom * ethertype frames used for key negotiation must not be encrypted. + * @NL80211_ATTR_CONTROL_PORT_OVER_NL80211: A flag indicating whether control + * port frames (e.g. of type given in %NL80211_ATTR_CONTROL_PORT_ETHERTYPE) + * will be sent directly to the network interface or sent via the NL80211 + * socket. If this attribute is missing, then legacy behavior of sending + * control port frames directly to the network interface is used. If the + * flag is included, then control port frames are sent over NL80211 instead + * using %CMD_CONTROL_PORT_FRAME. If control port routing over NL80211 is + * to be used then userspace must also use the %NL80211_ATTR_SOCKET_OWNER + * flag. * * @NL80211_ATTR_TESTDATA: Testmode data blob, passed through to the driver. * We recommend using nested, driver-specific attributes within this. @@ -2640,6 +2650,8 @@ enum nl80211_attrs { NL80211_ATTR_NSS, + NL80211_ATTR_CONTROL_PORT_OVER_NL80211, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 645c072cc4a3..fbc6c3ddb5f9 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -286,6 +286,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG }, [NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 }, [NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG }, + [NL80211_ATTR_CONTROL_PORT_OVER_NL80211] = { .type = NLA_FLAG }, [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG }, [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 }, [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 }, @@ -8225,6 +8226,18 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, } else settings->control_port_ethertype = cpu_to_be16(ETH_P_PAE); + if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) { + if (!info->attrs[NL80211_ATTR_SOCKET_OWNER]) + return -EINVAL; + + if (!rdev->ops->tx_control_port || + !wiphy_ext_feature_isset(>wiphy, + NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211)) + return -EOPNOTSUPP; + + settings->control_port_over_nl80211 = true; + } + if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) { void *data; int len, i; -- 2.13.5
[RFC v4 1/6] uapi: Add 802.11 Preauthentication to if_ether
This adds 0x88c7 protocol type to if_ether. Signed-off-by: Denis Kenzior--- include/uapi/linux/if_ether.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h index f8cb5760ea4f..54585906e50a 100644 --- a/include/uapi/linux/if_ether.h +++ b/include/uapi/linux/if_ether.h @@ -89,6 +89,7 @@ #define ETH_P_AOE 0x88A2 /* ATA over Ethernet*/ #define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */ #define ETH_P_802_EX1 0x88B5 /* 802.1 Local Experimental 1. */ +#define ETH_P_PREAUTH 0x88C7 /* 802.11 Preauthentication */ #define ETH_P_TIPC 0x88CA /* TIPC */ #define ETH_P_MACSEC 0x88E5 /* 802.1ae MACsec */ #define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */ -- 2.13.5
[RFC v4 5/6] mac80211: Add support for tx_control_port
Signed-off-by: Denis Kenzior--- net/mac80211/cfg.c | 1 + net/mac80211/ieee80211_i.h | 3 +++ net/mac80211/tx.c | 46 ++ 3 files changed, 50 insertions(+) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 46028e12e216..fb3cf38d674f 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -3785,4 +3785,5 @@ const struct cfg80211_ops mac80211_config_ops = { .add_nan_func = ieee80211_add_nan_func, .del_nan_func = ieee80211_del_nan_func, .set_multicast_to_unicast = ieee80211_set_multicast_to_unicast, + .tx_control_port = ieee80211_tx_control_port, }; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 26900025de2f..c78f30555b6d 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1734,6 +1734,9 @@ void ieee80211_check_fast_xmit(struct sta_info *sta); void ieee80211_check_fast_xmit_all(struct ieee80211_local *local); void ieee80211_check_fast_xmit_iface(struct ieee80211_sub_if_data *sdata); void ieee80211_clear_fast_xmit(struct sta_info *sta); +int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev, + const u8 *buf, size_t len, + const u8 *dest, __be16 proto, bool unencrypted); /* HT */ void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 25904af38839..99934bc3cd83 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -4754,3 +4754,49 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, ieee80211_xmit(sdata, NULL, skb); local_bh_enable(); } + +int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev, + const u8 *buf, size_t len, + const u8 *dest, __be16 proto, bool unencrypted) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_local *local = sdata->local; + struct sk_buff *skb; + struct ethhdr *ehdr; + u32 flags; + + /* Only accept CONTROL_PORT_PROTOCOL configured in CONNECT/ASSOCIATE +* or Pre-Authentication +*/ + if (proto != sdata->control_port_protocol && + proto != cpu_to_be16(ETH_P_PREAUTH)) + return -EINVAL; + + if (unencrypted) + flags = IEEE80211_TX_INTFL_DONT_ENCRYPT; + else + flags = 0; + + skb = dev_alloc_skb(local->hw.extra_tx_headroom + + sizeof(struct ethhdr) + len); + if (!skb) + return -ENOMEM; + + skb_reserve(skb, local->hw.extra_tx_headroom + sizeof(struct ethhdr)); + + skb_put_data(skb, buf, len); + + ehdr = skb_push(skb, sizeof(struct ethhdr)); + memcpy(ehdr->h_dest, dest, ETH_ALEN); + memcpy(ehdr->h_source, sdata->vif.addr, ETH_ALEN); + ehdr->h_proto = proto; + + skb->dev = dev; + skb->protocol = htons(ETH_P_802_3); + skb_reset_network_header(skb); + skb_reset_mac_header(skb); + + __ieee80211_subif_start_xmit(skb, skb->dev, flags); + + return 0; +} -- 2.13.5
[RFC v4 2/6] nl80211: Add CMD_CONTROL_PORT_FRAME API
This commit also adds cfg80211_rx_control_port function. This is used to generate a CMD_CONTROL_PORT_FRAME event out to userspace. The conn_owner_nlportid is used as the unicast destination. This means that userspace must specify NL80211_ATTR_SOCKET_OWNER flag if control port over nl80211 routing is requested in NL80211_CMD_CONNECT or NL80211_CMD_ASSOCIATE Signed-off-by: Denis Kenzior--- include/net/cfg80211.h | 22 + include/uapi/linux/nl80211.h | 13 ++ net/wireless/nl80211.c | 58 net/wireless/trace.h | 21 4 files changed, 114 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 7d49cd0cf92d..f3102c6745fd 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -5690,6 +5690,28 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, /** + * cfg80211_rx_control_port - notification about a received control port frame + * @dev: The device the frame matched to + * @buf: control port frame + * @len: length of the frame data + * @addr: The peer from which the frame was received + * @proto: frame protocol, typically PAE or Pre-authentication + * @unencrypted: Whether the frame was received unencrypted + * + * This function is used to inform userspace about a received control port + * frame. It should only be used if userspace indicated it wants to receive + * control port frames over NL80211. + * + * The frame is the data portion of the 802.3 or 802.11 data frame with all + * network layer headers removed (e.g. the raw EAPoL frame). + * + * Return: %true if the frame was passed to userspace + */ +bool cfg80211_rx_control_port(struct net_device *dev, + const u8 *buf, size_t len, + const u8 *addr, u16 proto, bool unencrypted); + +/** * cfg80211_cqm_rssi_notify - connection quality monitoring rssi event * @dev: network device * @rssi_event: the triggered RSSI event diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index ca3d5a613fc0..31fc88cb0a2c 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -990,6 +990,17 @@ * _CMD_CONNECT or _CMD_ROAM. If the 4 way handshake failed * _CMD_DISCONNECT should be indicated instead. * + * @NL80211_CMD_CONTROL_PORT_FRAME: Control Port (e.g. PAE) frame TX request + * and RX notification. This command is used both as a request to transmit + * a control port frame and as a notification that a control port frame + * has been received. %NL80211_ATTR_FRAME is used to specify the + * frame contents. The frame is the raw EAPoL data, without ethernet or + * 802.11 headers. + * When used as an event indication %NL80211_ATTR_CONTROL_PORT_ETHERTYPE, + * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT and %NL80211_ATTR_MAC are added + * indicating the protocol type of the received frame; whether the frame + * was received unencrypted and the MAC address of the peer respectively. + * * @NL80211_CMD_RELOAD_REGDB: Request that the regdb firmware file is reloaded. * * @NL80211_CMD_EXTERNAL_AUTH: This interface is exclusively defined for host @@ -1228,6 +1239,8 @@ enum nl80211_commands { NL80211_CMD_STA_OPMODE_CHANGED, + NL80211_CMD_CONTROL_PORT_FRAME, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index cc6ec5bab676..bffbd2cd2fc3 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -14549,6 +14549,64 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, } EXPORT_SYMBOL(cfg80211_mgmt_tx_status); +static int __nl80211_rx_control_port(struct net_device *dev, +const u8 *buf, size_t len, +const u8 *addr, u16 proto, +bool unencrypted, gfp_t gfp) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); + struct sk_buff *msg; + void *hdr; + u32 nlportid = READ_ONCE(wdev->conn_owner_nlportid); + + if (!nlportid) + return -ENOENT; + + msg = nlmsg_new(100 + len, gfp); + if (!msg) + return -ENOMEM; + + hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONTROL_PORT_FRAME); + if (!hdr) { + nlmsg_free(msg); + return -ENOMEM; + } + + if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || + nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || + nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev), + NL80211_ATTR_PAD) || + nla_put(msg, NL80211_ATTR_FRAME, len, buf) || + nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) || +
[RFC v4 0/6] EAPoL over NL80211
This patchset adds support for running 802.11 authentication mechanisms (e.g. 802.1X, 4-Way Handshake, etc) over NL80211 instead of putting them onto the network device. This has the advantage of fixing several long-standing race conditions that result from userspace operating on multiple transports in order to manage a 802.11 connection (e.g. NL80211 and wireless netdev, wlan0, etc). For example, userspace would sometimes see 4-Way handshake packets before NL80211 signaled that the connection has been established. Leading to ugly hacks or having the STA wait for retransmissions from the AP. This also provides a way to mitigate a particularly nasty race condition where the encryption key could be set prior to the 4-way handshake packet 4/4 being sent. This would result in the packet being sent encrypted and discarded by the peer. The mitigation strategy for this race is for userspace to explicitly tell the kernel that a particular EAPoL packet should not be encrypted. To make this possible this patchset introduces a new NL80211 command and several new attributes. A userspace that is capable of processing EAPoL packets over NL80211 includes a new NL80211_ATTR_CONTROL_PORT_OVER_NL80211 attribute in its NL80211_CMD_ASSOCIATE or NL80211_CMD_CONNECT requests being sent to the kernel. The previously added NL80211_ATTR_SOCKET_OWNER attribute must also be included. The latter is used by the kernel to send NL80211_CMD_CONTROL_PORT_FRAME notifications back to userspace via a netlink unicast. If the NL80211_ATTR_CONTROL_PORT_OVER_NL80211 attribute is not specified, then legacy behavior is kept and control port packets continue to flow over the network interface. If control port over nl80211 transport is requested, then control port packets are intercepted just prior to being handed to the network device and sent over netlink via the NL80211_CMD_CONTROL_PORT_FRAME notification. NL80211_ATTR_CONTROL_PORT_ETHERTYPE and NL80211_ATTR_MAC are included to specify the control port frame protocol and source address respectively. If the control port frame was received unencrypted then NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT flag is also included. NL80211_ATTR_FRAME attribute contains the raw control port frame with all transport layer headers stripped (e.g. this would be the raw EAPoL frame). Userspace can reply to control port frames either via legacy methods (by sending frames to the network device) or via NL80211_CMD_CONTROL_PORT_FRAME request. Userspace would included NL80211_ATTR_FRAME with the raw control port frame as well as NL80211_Attr_MAC and NL80211_ATTR_CONTROL_PORT_ETHERTYPE attributes to specify the destination address and protocol respectively. This allows Pre-Authentication (protocol 0x88c7) frames to be sent via this mechanism as well. Finally, NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT flag can be included to tell the driver to send the frame unencrypted, e.g. for 4-Way handshake 4/4 frames. The proposed patchset has been tested in a mac80211_hwsim based environment with hostapd and iwd. ChangeLog v4 - Reordered the patches to make sure that: when CONTROL_PORT_OVER_NL80211 is provided by userspace, nl80211 checks that both EXT_FEATURE bit is set and the tx_control_port is present in rdev ops. - Fixed up various issues Johannes found in his review v3 - Added ETH_P_PREAUTH to if_ether.h - Moved NL80211 feature bit from wiphy features to ext features - Addressed various comments from Johannes v2 - Added WIPHY_FLAG_CONTROL_PORT_OVER_NL80211 flag. This is a capability flag used by the drivers, e.g. that the driver supports control port over nl80211 capability. This capability is now checked when CONTROL_PORT_OVER_NL80211 is requested. - mac80211 rx path now forwards Pre-Authentication frames over NL80211 as well, if requested. Tweaked the signature of cfg80211_rx_control_port. - TX path reworked completely. tx_control_port method has been introduced to cfg80211_ops. An implementation of tx_control_port for mac80211 was added. Denis Kenzior (6): uapi: Add 802.11 Preauthentication to if_ether nl80211: Add CMD_CONTROL_PORT_FRAME API nl80211: Implement TX of control port frames nl80211: Add CONTROL_PORT_OVER_NL80211 attribute mac80211: Add support for tx_control_port mac80211: Send control port frames over nl80211 include/net/cfg80211.h| 34 +++ include/uapi/linux/if_ether.h | 1 + include/uapi/linux/nl80211.h | 30 +- net/mac80211/cfg.c| 3 + net/mac80211/ieee80211_i.h| 4 ++ net/mac80211/main.c | 2 + net/mac80211/mlme.c | 2 + net/mac80211/rx.c | 33 +-- net/mac80211/tx.c | 46 +++ net/wireless/nl80211.c| 134 +- net/wireless/rdev-ops.h | 15 + net/wireless/trace.h | 47 +++ 12 files changed, 344 insertions(+), 7 deletions(-) -- 2.13.5
lockdep warning in mac80211/tx.c, 4.13.16+ kernel, ath9k related
Hello, This first splat comes from this code: static ieee80211_tx_result debug_noinline ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) { struct ieee80211_key *key; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) tx->key = NULL; else if (tx->sta && ### line 605 ### (key = rcu_dereference(tx->sta->ptk[tx->sta->ptk_idx]))) tx->key = key; else if (ieee80211_is_group_privacy_action(tx->skb) && (key = rcu_dereference(tx->sdata->default_multicast_key))) tx->key = key; else if (ieee80211_is_mgmt(hdr->frame_control) && is_multicast_ether_addr(hdr->addr1) && ieee80211_is_robust_mgmt_frame(tx->skb) && (key = rcu_dereference(tx->sdata->default_mgmt_key))) tx->key = key; else if (is_multicast_ether_addr(hdr->addr1) && (key = rcu_dereference(tx->sdata->default_multicast_key))) tx->key = key; else if (!is_multicast_ether_addr(hdr->addr1) && ### line 619 ### (key = rcu_dereference(tx->sdata->default_unicast_key))) tx->key = key; else tx->key = NULL; This ath9k has some local modifications, including removal of the airtime fairness logic that was breaking my test case very quickly, so could be my fault of course. Full tree is here: https://github.com/greearb/linux-ct-4.13 Any idea why this might be complaining? Test case is to bring up 200 virtual stations on each of 6 radios and then randomly restart the stations and/or APs they are connected to. I'm trying to shake out stability bugs and such... 30917 Jan 31 15:21:01 2u-6n kernel: = 30918 Jan 31 15:21:01 2u-6n kernel: WARNING: suspicious RCU usage 30919 Jan 31 15:21:01 2u-6n kernel: 4.13.16+ #2 Tainted: GW O 30920 Jan 31 15:21:01 2u-6n kernel: - 30921 Jan 31 15:21:01 2u-6n kernel: /home/greearb/git/linux-4.13.dev.y/net/mac80211/tx.c:605 suspicious rcu_dereference_check() usage! 30922 Jan 31 15:21:01 2u-6n kernel: 30923 other info that might help us debug this: 30924 Jan 31 15:21:01 2u-6n kernel: 30925 rcu_scheduler_active = 2, debug_locks = 1 30926 Jan 31 15:21:01 2u-6n kernel: 5 locks held by ip/19628: 30927 Jan 31 15:21:01 2u-6n kernel: #0: (rtnl_mutex){+.+.+.}, at: [] rtnetlink_rcv+0x16/0x30 30928 Jan 31 15:21:01 2u-6n kernel: #1: (>mtx){+.+.+.}, at: [] cfg80211_leave+0x1d/0x40 [cfg80211] 30929 Jan 31 15:21:01 2u-6n kernel: #2: (>sta_mtx){+.+.+.}, at: [] __sta_info_flush+0x7c/0x170 [mac80211] 30930 Jan 31 15:21:01 2u-6n kernel: #3: (&(>axq_lock)->rlock){+.-...}, at: [] ath_tx_node_cleanup+0x66/0x160 [ath9k] 30931 Jan 31 15:21:01 2u-6n kernel: #4: (&(>lock)->rlock){+.-...}, at: [] ieee80211_tx_dequeue+0x45/0xca0 [mac80211] 30932 Jan 31 15:21:01 2u-6n kernel: 30933 stack backtrace: 30934 Jan 31 15:21:01 2u-6n kernel: CPU: 1 PID: 19628 Comm: ip Tainted: G W O4.13.16+ #2 30935 Jan 31 15:21:01 2u-6n kernel: Hardware name: Iron_Systems,Inc CS-CAD-2U-A02/X10SRL-F, BIOS 2.0b 05/02/2017 30936 Jan 31 15:21:01 2u-6n kernel: Call Trace: 30937 Jan 31 15:21:01 2u-6n kernel: dump_stack+0x85/0xc7 30938 Jan 31 15:21:01 2u-6n kernel: lockdep_rcu_suspicious+0xc5/0x100 30939 Jan 31 15:21:01 2u-6n kernel: ieee80211_tx_h_select_key+0x1c9/0x4e0 [mac80211] 30940 Jan 31 15:21:01 2u-6n kernel: ieee80211_tx_dequeue+0x376/0xca0 [mac80211] 30941 Jan 31 15:21:01 2u-6n kernel: ath_tid_dequeue+0x9c/0x110 [ath9k] 30942 Jan 31 15:21:01 2u-6n kernel: ath_tx_node_cleanup+0xa4/0x160 [ath9k] 30943 Jan 31 15:21:01 2u-6n kernel: ath9k_sta_state+0x6b/0x1e0 [ath9k] 30944 Jan 31 15:21:01 2u-6n kernel: drv_sta_state+0xad/0xa80 [mac80211] 30945 Jan 31 15:21:01 2u-6n kernel: __sta_info_destroy_part2+0x178/0x1d0 [mac80211] 30946 Jan 31 15:21:01 2u-6n kernel: __sta_info_flush+0xef/0x170 [mac80211] 30947 Jan 31 15:21:01 2u-6n kernel: ieee80211_set_disassoc+0xc6/0x400 [mac80211] 30948 Jan 31 15:21:01 2u-6n kernel: ieee80211_mgd_deauth+0x2f6/0x830 [mac80211] 30949 Jan 31 15:21:01 2u-6n kernel: ieee80211_deauth+0x13/0x20 [mac80211] 30950 Jan 31 15:21:01 2u-6n kernel: cfg80211_mlme_deauth+0x16b/0x3e0 [cfg80211] 30951 Jan 31 15:21:01 2u-6n kernel: cfg80211_mlme_down+0x6d/0xa0 [cfg80211] 30952 Jan 31 15:21:01 2u-6n kernel: cfg80211_disconnect+0x2f4/0x3f0 [cfg80211] 30953 Jan 31 15:21:01 2u-6n kernel: ? kfree+0x24d/0x2b0 30954 Jan 31 15:21:01 2u-6n kernel: __cfg80211_leave+0x134/0x190 [cfg80211] 30955 Jan 31 15:21:01 2u-6n kernel: cfg80211_leave+0x28/0x40 [cfg80211] 30956 Jan 31 15:21:01 2u-6n kernel:
[PATCH] mt76x2: remove warnings in mt76x2_mac_write_txwi()
Fix following sparse warnings in mt76x2_mac_write_txwi: - drivers/net/wireless/mediatek/mt76/mt76x2_mac.c:201:26: warning: incorrect type in assignment (different base types) - drivers/net/wireless/mediatek/mt76/mt76x2_mac.c:201:26: expected restricted __le32 [usertype] iv - drivers/net/wireless/mediatek/mt76/mt76x2_mac.c:201:26: got unsigned int [unsigned] [usertype] - drivers/net/wireless/mediatek/mt76/mt76x2_mac.c:202:27: warning: incorrect type in assignment (different base types) - drivers/net/wireless/mediatek/mt76/mt76x2_mac.c:202:27: expected restricted __le32 [usertype] eiv - drivers/net/wireless/mediatek/mt76/mt76x2_mac.c:202:27: got unsigned int [unsigned] [usertype] Fixes: 23405236460b ("mt76: fix transmission of encrypted management frames") Signed-off-by: Lorenzo Bianconi--- drivers/net/wireless/mediatek/mt76/mt76x2_mac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c index 6c30b5eaa9ca..279cd8717806 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c @@ -198,8 +198,8 @@ void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x2_txwi *txwi, ccmp_pn[5] = pn >> 24; ccmp_pn[6] = pn >> 32; ccmp_pn[7] = pn >> 40; - txwi->iv = *((u32 *) _pn[0]); - txwi->eiv = *((u32 *) _pn[1]); + txwi->iv = *((__le32 *)_pn[0]); + txwi->eiv = *((__le32 *)_pn[1]); } spin_lock_bh(>mt76.lock); -- 2.14.3
Re: [PATCH 3/6] nl80211: Add CMD_CONTROL_PORT_FRAME API
On Wed, 2018-01-31 at 16:01 -0600, Denis Kenzior wrote: > Hi Johannes, > > > > + * @NL80211_CMD_CONTROL_PORT_FRAME: Control Port (e.g. PAE) frame TX > > > request > > > + * and RX notification. This command is used both as a request to > > > transmit > > > + * a control port frame and as a notification that a control port > > > frame > > > + * has been received. %NL80211_ATTR_FRAME is used to specify the > > > + * frame contents. The frame is the raw EAPoL data, without > > > ethernet or > > > + * 802.11 headers. > > > > Never mind, so it's without Ethernet header. Is that really desirable > > though? I mean, it could be that the Ethernet address even matters (not > > sure) and it'd probably be easier to handle in (existing) userspace > > where Ethernet frames are expected now? > > I also include the from address inside the NL80211 message as ATTR_MAC. > The protocol as well. I wrote the docs first and never updated the > little details afterwards. Will fix. Good point, I could've seen that. Still not sure it makes a big difference, but I guess it doesn't really matter that much (though in a sense it'd be easier to take Ethernet header apart than putting it back together - but even that can be done in place in the message buffer) > > > + nla_put_failure: > > > + genlmsg_cancel(msg, hdr); > > > > nit: there's no point in cancelling if you free it (immediately). > > Just following some existing code, but will fix. Yeah I just never got around to cleaning up that antipattern ... I'll make an spatch. johannes
Re: [PATCH 3/6] nl80211: Add CMD_CONTROL_PORT_FRAME API
Hi Johannes, + * @NL80211_CMD_CONTROL_PORT_FRAME: Control Port (e.g. PAE) frame TX request + * and RX notification. This command is used both as a request to transmit + * a control port frame and as a notification that a control port frame + * has been received. %NL80211_ATTR_FRAME is used to specify the + * frame contents. The frame is the raw EAPoL data, without ethernet or + * 802.11 headers. Never mind, so it's without Ethernet header. Is that really desirable though? I mean, it could be that the Ethernet address even matters (not sure) and it'd probably be easier to handle in (existing) userspace where Ethernet frames are expected now? I also include the from address inside the NL80211 message as ATTR_MAC. The protocol as well. I wrote the docs first and never updated the little details afterwards. Will fix. + nla_put_failure: + genlmsg_cancel(msg, hdr); nit: there's no point in cancelling if you free it (immediately). Just following some existing code, but will fix. +bool cfg80211_rx_control_port(struct net_device *dev, + const u8 *buf, size_t len, + const u8 *addr, u16 proto, bool unencrypted) +{ + bool ret; + + trace_cfg80211_rx_control_port(dev, buf, len, addr, proto, unencrypted); + ret = __nl80211_rx_control_port(dev, buf, len, addr, proto, + unencrypted, GFP_ATOMIC); + trace_cfg80211_return_bool(ret); this seems wrong - you return -ERROR from __nl80211_rx_control_port() so you need either to pass that on as an integer to the caller, or put an == 0 here or something? "Return: %true if the frame was passed to userspace" Yep, will fix. Regards, -Denis
Re: [PATCH 5/6] nl80211: Implement TX of control port frames
On Wed, 2018-01-31 at 15:58 -0600, Denis Kenzior wrote: > > Actually, then again, that's awkward because doing events and commands > > on the same socket doesn't mix all _that_ well. Perhaps we just need to > > fix that problem in libnl or something and be done with it ... > > > > There are no issues on our side.. I guess you don't use libnl then :-) It doesn't exactly make it easy to receive events while waiting for an ACK. johannes
Re: [RFC v3 0/6] EAPoL over NL80211
Looks pretty good! Some comments over in separate emails. Maybe you should consider reordering: [1/6] keep [2/6] keep [3/6] introduce TX (now patch 5) [4/6] introduce RX (now patch 3) modify this to require TX from the driver in order to be able to set the new flag [5/6] add TX to mac80211 [6/6] add RX to mac80211 and set the flag Ok, you don't really have to do that, since you only set the flag in the last patch anyway, but that'd make it better to add the check that requires TX, so you don't have to do that in the TX patch and modify the RX portion again. johannes
Re: [PATCH 5/6] nl80211: Implement TX of control port frames
Hi Johannes, On 01/31/2018 03:53 PM, Johannes Berg wrote: +static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct wireless_dev *wdev = dev->ieee80211_ptr; + const u8 *buf; + size_t len; + u8 *dest; + u16 proto; + bool noencrypt; + int err; + + if (!wiphy_ext_feature_isset(>wiphy, + NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211)) + return -EOPNOTSUPP; + + if (!rdev->ops->tx_control_port) + return -EOPNOTSUPP; I wonder if maybe we should accept this command only from the socket owner? Is there a use case for something else? Yes I thought about adding such a check as I think it wouldn't make sense to accept control port frames from any other application besides the socket owner. However the socket owner stuff was a bit controversial, so I left it out. I would support adding this check... Actually, then again, that's awkward because doing events and commands on the same socket doesn't mix all _that_ well. Perhaps we just need to fix that problem in libnl or something and be done with it ... There are no issues on our side.. Regards, -Denis
Re: [PATCH 5/6] nl80211: Implement TX of control port frames
> +static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info > *info) > +{ > + struct cfg80211_registered_device *rdev = info->user_ptr[0]; > + struct net_device *dev = info->user_ptr[1]; > + struct wireless_dev *wdev = dev->ieee80211_ptr; > + const u8 *buf; > + size_t len; > + u8 *dest; > + u16 proto; > + bool noencrypt; > + int err; > + > + if (!wiphy_ext_feature_isset(>wiphy, > + > NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211)) > + return -EOPNOTSUPP; > + > + if (!rdev->ops->tx_control_port) > + return -EOPNOTSUPP; I wonder if maybe we should accept this command only from the socket owner? Is there a use case for something else? Actually, then again, that's awkward because doing events and commands on the same socket doesn't mix all _that_ well. Perhaps we just need to fix that problem in libnl or something and be done with it ... johannes
Re: [PATCH 5/6] nl80211: Implement TX of control port frames
On Wed, 2018-01-31 at 15:33 -0600, Denis Kenzior wrote: > > + return rdev_tx_control_port(rdev, dev, buf, len, > + dest, cpu_to_be16(proto), noencrypt); You're passing __be16 here > +++ b/net/wireless/rdev-ops.h > @@ -714,6 +714,21 @@ static inline int rdev_mgmt_tx(struct > cfg80211_registered_device *rdev, > return ret; > } > > +static inline int rdev_tx_control_port(struct cfg80211_registered_device > *rdev, > +struct net_device *dev, > +const void *buf, size_t len, > +const u8 *dest, u16 proto, > +const bool noencrypt) but have u16 here - doesn't that make sparse unhappy? Should also declare the API as __be16. johannes
Re: [PATCH 4/6] mac80211: Send control port frames over nl80211
On Wed, 2018-01-31 at 15:33 -0600, Denis Kenzior wrote: > > + if (!cfg80211_rx_control_port(dev, skb->data, skb->len, > + ehdr->h_source, > + be16_to_cpu(skb->protocol), > + noencrypt)) > + dev_kfree_skb(skb); Err, you should free it unconditionally, no? You don't do anything with the skb afterwards, since you can't get into the else branch and deliver it to the netdev now, so afaict it'd be leaked if not freed? Which explains why you didn't notice the error in the previous patch, it was making this code correct by freeing it all the time (never hitting an error, presumably, and even if you wouldn't notice the small leaks) johannes
Re: [PATCH 3/6] nl80211: Add CMD_CONTROL_PORT_FRAME API
On Wed, 2018-01-31 at 15:33 -0600, Denis Kenzior wrote: > > /** > + * cfg80211_rx_control_port - inform userspace about a received control port > + * frame, e.g. EAPoL. This is used if userspace has specified it wants to > + * receive control port frames over NL80211. nitpick - the short description must fit on a single line, you can have a longer description separately (after the arguments, I'd probably even put it after the return) > + * @dev: The device the frame matched to > + * @buf: control port frame > + * @len: length of the frame data You should document what exactly is in this frame data? Should it be with the ethernet header removed? It would seem easier if it's with the ethernet header included, but then why do you need the proto argument? > + * @NL80211_CMD_CONTROL_PORT_FRAME: Control Port (e.g. PAE) frame TX request > + * and RX notification. This command is used both as a request to transmit > + * a control port frame and as a notification that a control port frame > + * has been received. %NL80211_ATTR_FRAME is used to specify the > + * frame contents. The frame is the raw EAPoL data, without ethernet or > + * 802.11 headers. Never mind, so it's without Ethernet header. Is that really desirable though? I mean, it could be that the Ethernet address even matters (not sure) and it'd probably be easier to handle in (existing) userspace where Ethernet frames are expected now? > + nla_put_failure: > + genlmsg_cancel(msg, hdr); nit: there's no point in cancelling if you free it (immediately). > +bool cfg80211_rx_control_port(struct net_device *dev, > + const u8 *buf, size_t len, > + const u8 *addr, u16 proto, bool unencrypted) > +{ > + bool ret; > + > + trace_cfg80211_rx_control_port(dev, buf, len, addr, proto, unencrypted); > + ret = __nl80211_rx_control_port(dev, buf, len, addr, proto, > + unencrypted, GFP_ATOMIC); > + trace_cfg80211_return_bool(ret); this seems wrong - you return -ERROR from __nl80211_rx_control_port() so you need either to pass that on as an integer to the caller, or put an == 0 here or something? "Return: %true if the frame was passed to userspace" johannes
[PATCH 5/6] nl80211: Implement TX of control port frames
This commit implements the TX side of NL80211_CMD_CONTROL_PORT_FRAME. Userspace provides the raw EAPoL frame using NL80211_ATTR_FRAME. Userspace should also provide the destination address and the protocol type to use when sending the frame. This is used to implement TX of Pre-authentication frames. If CONTROL_PORT_ETHERTYPE_NO_ENCRYPT is specified, then the driver will be asked not to encrypt the outgoing frame. Signed-off-by: Denis Kenzior--- include/net/cfg80211.h | 9 +++ net/wireless/nl80211.c | 63 - net/wireless/rdev-ops.h | 15 net/wireless/trace.h| 25 4 files changed, 111 insertions(+), 1 deletion(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 60a38543b830..dc6d37b40574 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2961,6 +2961,9 @@ struct cfg80211_external_auth_params { * * @external_auth: indicates result of offloaded authentication processing from * user space + * + * @tx_control_port: TX a control port frame (EAPoL). The noencrypt parameter + * tells the driver that the frame should not be encrypted. */ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); @@ -3256,6 +3259,12 @@ struct cfg80211_ops { const u8 *aa); int (*external_auth)(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_external_auth_params *params); + + int (*tx_control_port)(struct wiphy *wiphy, + struct net_device *dev, + const u8 *buf, size_t len, + const u8 *dest, const u16 proto, + const bool noencrypt); }; /* diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 840dada2cca3..ed5752a99951 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -12527,6 +12527,60 @@ static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info) return rdev_external_auth(rdev, dev, ); } +static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct wireless_dev *wdev = dev->ieee80211_ptr; + const u8 *buf; + size_t len; + u8 *dest; + u16 proto; + bool noencrypt; + int err; + + if (!wiphy_ext_feature_isset(>wiphy, + NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211)) + return -EOPNOTSUPP; + + if (!rdev->ops->tx_control_port) + return -EOPNOTSUPP; + + if (!info->attrs[NL80211_ATTR_FRAME] || + !info->attrs[NL80211_ATTR_MAC] || + !info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) + return -EINVAL; + + wdev_lock(wdev); + + switch (wdev->iftype) { + case NL80211_IFTYPE_STATION: + if (wdev->current_bss) + break; + err = -ENOTCONN; + goto out; + default: + err = -EOPNOTSUPP; + goto out; + } + + wdev_unlock(wdev); + + buf = nla_data(info->attrs[NL80211_ATTR_FRAME]); + len = nla_len(info->attrs[NL80211_ATTR_FRAME]); + dest = nla_data(info->attrs[NL80211_ATTR_MAC]); + proto = nla_get_u16(info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]); + noencrypt = + nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]); + + return rdev_tx_control_port(rdev, dev, buf, len, + dest, cpu_to_be16(proto), noencrypt); + + out: + wdev_unlock(wdev); + return err; +} + #define NL80211_FLAG_NEED_WIPHY0x01 #define NL80211_FLAG_NEED_NETDEV 0x02 #define NL80211_FLAG_NEED_RTNL 0x04 @@ -13430,7 +13484,14 @@ static const struct genl_ops nl80211_ops[] = { .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, - + { + .cmd = NL80211_CMD_CONTROL_PORT_FRAME, + .doit = nl80211_tx_control_port, + .policy = nl80211_policy, + .flags = GENL_UNS_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, + }, }; static struct genl_family nl80211_fam __ro_after_init = { diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index 84f23ae015fc..ced82e2350f4 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h @@ -714,6 +714,21 @@ static inline int rdev_mgmt_tx(struct cfg80211_registered_device *rdev, return ret; } +static inline int rdev_tx_control_port(struct
[PATCH 4/6] mac80211: Send control port frames over nl80211
If userspace requested control port frames to go over 80211, then do so. The control packets are intercepted just prior to delivery of the packet to the underlying network device. Pre-authentication type frames (protocol: 0x88c7) are also forwarded over nl80211. Signed-off-by: Denis Kenzior--- net/mac80211/cfg.c | 2 ++ net/mac80211/ieee80211_i.h | 1 + net/mac80211/mlme.c| 2 ++ net/mac80211/rx.c | 34 +- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 46028e12e216..f53bfb27295f 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -925,6 +925,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, */ sdata->control_port_protocol = params->crypto.control_port_ethertype; sdata->control_port_no_encrypt = params->crypto.control_port_no_encrypt; + sdata->control_port_over_nl80211 = false; sdata->encrypt_headroom = ieee80211_cs_headroom(sdata->local, >crypto, sdata->vif.type); @@ -934,6 +935,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, params->crypto.control_port_ethertype; vlan->control_port_no_encrypt = params->crypto.control_port_no_encrypt; + vlan->control_port_over_nl80211 = false; vlan->encrypt_headroom = ieee80211_cs_headroom(sdata->local, >crypto, diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 26900025de2f..6f91aea6a4cb 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -899,6 +899,7 @@ struct ieee80211_sub_if_data { u16 sequence_number; __be16 control_port_protocol; bool control_port_no_encrypt; + bool control_port_over_nl80211; int encrypt_headroom; atomic_t num_tx_queued; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 39b660b9a908..fc71a906939b 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -4830,6 +4830,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, sdata->control_port_protocol = req->crypto.control_port_ethertype; sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt; + sdata->control_port_over_nl80211 = + req->crypto.control_port_over_nl80211; sdata->encrypt_headroom = ieee80211_cs_headroom(local, >crypto, sdata->vif.type); diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index e755f93ad735..c3abf9e44079 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2243,6 +2243,33 @@ static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc) return true; } +static void ieee80211_deliver_skb_to_local_stack(struct sk_buff *skb, +struct ieee80211_rx_data *rx) +{ + struct ieee80211_sub_if_data *sdata = rx->sdata; + struct net_device *dev = sdata->dev; + + if (unlikely((skb->protocol == sdata->control_port_protocol || + skb->protocol == cpu_to_be16(ETH_P_PREAUTH)) && +sdata->control_port_over_nl80211)) { + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + bool noencrypt = status->flag & RX_FLAG_DECRYPTED; + struct ethhdr *ehdr = eth_hdr(skb); + + if (!cfg80211_rx_control_port(dev, skb->data, skb->len, + ehdr->h_source, + be16_to_cpu(skb->protocol), + noencrypt)) + dev_kfree_skb(skb); + } else { + /* deliver to local stack */ + if (rx->napi) + napi_gro_receive(rx->napi, skb); + else + netif_receive_skb(skb); + } +} + /* * requires that rx->skb is a frame with ethernet header */ @@ -2327,13 +2354,10 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) #endif if (skb) { - /* deliver to local stack */ skb->protocol = eth_type_trans(skb, dev); memset(skb->cb, 0, sizeof(skb->cb)); - if (rx->napi) - napi_gro_receive(rx->napi, skb); - else - netif_receive_skb(skb); + + ieee80211_deliver_skb_to_local_stack(skb, rx); } if (xmit_skb) { -- 2.13.5
[PATCH 3/6] nl80211: Add CMD_CONTROL_PORT_FRAME API
This commit also adds cfg80211_rx_control_port function. This is used to generate a CMD_CONTROL_PORT_FRAME event out to userspace. The conn_owner_nlportid is used as the unicast destination. This means that userspace must specify NL80211_ATTR_SOCKET_OWNER flag if control port over nl80211 routing is requested in NL80211_CMD_CONNECT or NL80211_CMD_ASSOCIATE Signed-off-by: Denis Kenzior--- include/net/cfg80211.h | 17 + include/uapi/linux/nl80211.h | 15 +++ net/wireless/nl80211.c | 59 net/wireless/trace.h | 21 4 files changed, 112 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index fb369947aefb..60a38543b830 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -5693,6 +5693,23 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, /** + * cfg80211_rx_control_port - inform userspace about a received control port + * frame, e.g. EAPoL. This is used if userspace has specified it wants to + * receive control port frames over NL80211. + * @dev: The device the frame matched to + * @buf: control port frame + * @len: length of the frame data + * @addr: The peer from which the frame was received + * @proto: frame protocol, typically PAE or Pre-authentication + * @unencrypted: Whether the frame was received unencrypted + * + * Return: %true if the frame was passed to userspace + */ +bool cfg80211_rx_control_port(struct net_device *dev, + const u8 *buf, size_t len, + const u8 *addr, u16 proto, bool unencrypted); + +/** * cfg80211_cqm_rssi_notify - connection quality monitoring rssi event * @dev: network device * @rssi_event: the triggered RSSI event diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 20b35ba6721f..3a9d4364d383 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -991,6 +991,17 @@ * _CMD_CONNECT or _CMD_ROAM. If the 4 way handshake failed * _CMD_DISCONNECT should be indicated instead. * + * @NL80211_CMD_CONTROL_PORT_FRAME: Control Port (e.g. PAE) frame TX request + * and RX notification. This command is used both as a request to transmit + * a control port frame and as a notification that a control port frame + * has been received. %NL80211_ATTR_FRAME is used to specify the + * frame contents. The frame is the raw EAPoL data, without ethernet or + * 802.11 headers. + * When used as an event indication %NL80211_ATTR_CONTROL_PORT_ETHERTYPE, + * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT and %NL80211_ATTR_MAC are added + * indicating the protocol type of the received frame; whether the frame + * was received unencrypted and the MAC address of the peer respectively. + * * @NL80211_CMD_RELOAD_REGDB: Request that the regdb firmware file is reloaded. * * @NL80211_CMD_EXTERNAL_AUTH: This interface is exclusively defined for host @@ -1229,6 +1240,8 @@ enum nl80211_commands { NL80211_CMD_STA_OPMODE_CHANGED, + NL80211_CMD_CONTROL_PORT_FRAME, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ @@ -1476,6 +1489,8 @@ enum nl80211_commands { * @NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT: When included along with * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE, indicates that the custom * ethertype frames used for key negotiation must not be encrypted. + * When included in %NL80211_CMD_CONTROL_PORT_FRAME it means that the + * control port frame was received unencrypted. * @NL80211_ATTR_CONTROL_PORT_OVER_NL80211: A flag indicating whether control * port frames (e.g. of type given in %NL80211_ATTR_CONTROL_PORT_ETHERTYPE) * will be sent directly to the network interface or sent via the NL80211 diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 0c389044a4d3..840dada2cca3 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -14561,6 +14561,65 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, } EXPORT_SYMBOL(cfg80211_mgmt_tx_status); +static int __nl80211_rx_control_port(struct net_device *dev, +const u8 *buf, size_t len, +const u8 *addr, u16 proto, +bool unencrypted, gfp_t gfp) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); + struct sk_buff *msg; + void *hdr; + u32 nlportid = READ_ONCE(wdev->conn_owner_nlportid); + + if (!nlportid) + return -ENOENT; + + msg = nlmsg_new(100 + len, gfp); + if (!msg) + return -ENOMEM; + + hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONTROL_PORT_FRAME); + if (!hdr) { + nlmsg_free(msg); + return
[PATCH 2/6] nl80211: Add CONTROL_PORT_OVER_NL80211 attribute
Signed-off-by: Denis Kenzior--- include/net/cfg80211.h | 3 +++ include/uapi/linux/nl80211.h | 17 - net/wireless/nl80211.c | 12 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 7d49cd0cf92d..fb369947aefb 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -646,6 +646,8 @@ struct survey_info { * allowed through even on unauthorized ports * @control_port_no_encrypt: TRUE to prevent encryption of control port * protocol frames. + * @control_port_over_nl80211: TRUE if userspace expects to exchange control + * port frames over NL80211 instead of the network interface. * @wep_keys: static WEP keys, if not NULL points to an array of * CFG80211_MAX_WEP_KEYS WEP keys * @wep_tx_key: key index (0..3) of the default TX static WEP key @@ -661,6 +663,7 @@ struct cfg80211_crypto_settings { bool control_port; __be16 control_port_ethertype; bool control_port_no_encrypt; + bool control_port_over_nl80211; struct key_params *wep_keys; int wep_tx_key; const u8 *psk; diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index ca3d5a613fc0..20b35ba6721f 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -542,7 +542,8 @@ * IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_USE_MFP, * %NL80211_ATTR_MAC, %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT, * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE, - * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT, %NL80211_ATTR_MAC_HINT, and + * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT, + * %NL80211_ATTR_CONTROL_PORT_OVER_NL80211, %NL80211_ATTR_MAC_HINT, and * %NL80211_ATTR_WIPHY_FREQ_HINT. * If included, %NL80211_ATTR_MAC and %NL80211_ATTR_WIPHY_FREQ are * restrictions on BSS selection, i.e., they effectively prevent roaming @@ -1475,6 +1476,15 @@ enum nl80211_commands { * @NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT: When included along with * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE, indicates that the custom * ethertype frames used for key negotiation must not be encrypted. + * @NL80211_ATTR_CONTROL_PORT_OVER_NL80211: A flag indicating whether control + * port frames (e.g. of type given in %NL80211_ATTR_CONTROL_PORT_ETHERTYPE) + * will be sent directly to the network interface or sent via the NL80211 + * socket. If this attribute is missing, then legacy behavior of sending + * control port frames directly to the network interface is used. If the + * flag is included, then control port frames are sent over NL80211 instead + * using %CMD_CONTROL_PORT_FRAME. If control port routing over NL80211 is + * to be used then userspace must also use the %NL80211_ATTR_SOCKET_OWNER + * flag. * * @NL80211_ATTR_TESTDATA: Testmode data blob, passed through to the driver. * We recommend using nested, driver-specific attributes within this. @@ -2627,6 +2637,8 @@ enum nl80211_attrs { NL80211_ATTR_NSS, + NL80211_ATTR_CONTROL_PORT_OVER_NL80211, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -4996,6 +5008,8 @@ enum nl80211_feature_flags { * @NL80211_EXT_FEATURE_LOW_SPAN_SCAN: Driver supports low span scan. * @NL80211_EXT_FEATURE_LOW_POWER_SCAN: Driver supports low power scan. * @NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN: Driver supports high accuracy scan. + * @NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211: Driver supports sending and + * receiving control port frames over NL80211 instead of the netdevice. * * @NUM_NL80211_EXT_FEATURES: number of extended features. * @MAX_NL80211_EXT_FEATURES: highest extended feature index. @@ -5026,6 +5040,7 @@ enum nl80211_ext_feature_index { NL80211_EXT_FEATURE_LOW_SPAN_SCAN, NL80211_EXT_FEATURE_LOW_POWER_SCAN, NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN, + NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211, /* add new features before the definition below */ NUM_NL80211_EXT_FEATURES, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index cc6ec5bab676..0c389044a4d3 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -286,6 +286,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG }, [NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 }, [NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG }, + [NL80211_ATTR_CONTROL_PORT_OVER_NL80211] = { .type = NLA_FLAG }, [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG }, [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 }, [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 }, @@ -8225,6 +8226,17 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, }
[PATCH 6/6] mac80211: Add support for tx_control_port
Signed-off-by: Denis Kenzior--- net/mac80211/cfg.c | 1 + net/mac80211/ieee80211_i.h | 3 +++ net/mac80211/main.c| 2 ++ net/mac80211/tx.c | 46 ++ 4 files changed, 52 insertions(+) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index f53bfb27295f..71cb45e517b0 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -3787,4 +3787,5 @@ const struct cfg80211_ops mac80211_config_ops = { .add_nan_func = ieee80211_add_nan_func, .del_nan_func = ieee80211_del_nan_func, .set_multicast_to_unicast = ieee80211_set_multicast_to_unicast, + .tx_control_port = ieee80211_tx_control_port, }; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 6f91aea6a4cb..be444305ef06 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1735,6 +1735,9 @@ void ieee80211_check_fast_xmit(struct sta_info *sta); void ieee80211_check_fast_xmit_all(struct ieee80211_local *local); void ieee80211_check_fast_xmit_iface(struct ieee80211_sub_if_data *sdata); void ieee80211_clear_fast_xmit(struct sta_info *sta); +int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev, + const u8 *buf, size_t len, + const u8 *dest, u16 proto, bool unencrypted); /* HT */ void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 0785d04a80bc..e5a51267c75d 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -554,6 +554,8 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, NL80211_FEATURE_USERSPACE_MPM | NL80211_FEATURE_FULL_AP_CLIENT_STATE; wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_STA); + wiphy_ext_feature_set(wiphy, + NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211); if (!ops->hw_scan) wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN | diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 25904af38839..031b27fa752c 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -4754,3 +4754,49 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, ieee80211_xmit(sdata, NULL, skb); local_bh_enable(); } + +int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev, + const u8 *buf, size_t len, + const u8 *dest, u16 proto, bool unencrypted) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_local *local = sdata->local; + struct sk_buff *skb; + struct ethhdr *ehdr; + u32 flags; + + /* Only accept CONTROL_PORT_PROTOCOL configured in CONNECT/ASSOCIATE +* or Pre-Authentication +*/ + if (proto != sdata->control_port_protocol && + proto != cpu_to_be16(ETH_P_PREAUTH)) + return -EINVAL; + + if (unencrypted) + flags = IEEE80211_TX_INTFL_DONT_ENCRYPT; + else + flags = 0; + + skb = dev_alloc_skb(local->hw.extra_tx_headroom + + sizeof(struct ethhdr) + len); + if (!skb) + return -ENOMEM; + + skb_reserve(skb, local->hw.extra_tx_headroom + sizeof(struct ethhdr)); + + skb_put_data(skb, buf, len); + + ehdr = skb_push(skb, sizeof(struct ethhdr)); + memcpy(ehdr->h_dest, dest, ETH_ALEN); + memcpy(ehdr->h_source, sdata->vif.addr, ETH_ALEN); + ehdr->h_proto = proto; + + skb->dev = dev; + skb->protocol = htons(ETH_P_802_3); + skb_reset_network_header(skb); + skb_reset_mac_header(skb); + + __ieee80211_subif_start_xmit(skb, skb->dev, flags); + + return 0; +} -- 2.13.5
[PATCH 1/6] uapi: Add 802.11 Preauthentication to if_ether
This adds 0x88c7 protocol type to if_ether. Signed-off-by: Denis Kenzior--- include/uapi/linux/if_ether.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h index f8cb5760ea4f..54585906e50a 100644 --- a/include/uapi/linux/if_ether.h +++ b/include/uapi/linux/if_ether.h @@ -89,6 +89,7 @@ #define ETH_P_AOE 0x88A2 /* ATA over Ethernet*/ #define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */ #define ETH_P_802_EX1 0x88B5 /* 802.1 Local Experimental 1. */ +#define ETH_P_PREAUTH 0x88C7 /* 802.11 Preauthentication */ #define ETH_P_TIPC 0x88CA /* TIPC */ #define ETH_P_MACSEC 0x88E5 /* 802.1ae MACsec */ #define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */ -- 2.13.5
[RFC v3 0/6] EAPoL over NL80211
This patchset adds support for running 802.11 authentication mechanisms (e.g. 802.1X, 4-Way Handshake, etc) over NL80211 instead of putting them onto the network device. This has the advantage of fixing several long-standing race conditions that result from userspace operating on multiple transports in order to manage a 802.11 connection (e.g. NL80211 and wireless netdev, wlan0, etc). For example, userspace would sometimes see 4-Way handshake packets before NL80211 signaled that the connection has been established. Leading to ugly hacks or having the STA wait for retransmissions from the AP. This also provides a way to mitigate a particularly nasty race condition where the encryption key could be set prior to the 4-way handshake packet 4/4 being sent. This would result in the packet being sent encrypted and discarded by the peer. The mitigation strategy for this race is for userspace to explicitly tell the kernel that a particular EAPoL packet should not be encrypted. To make this possible this patchset introduces a new NL80211 command and several new attributes. A userspace that is capable of processing EAPoL packets over NL80211 includes a new NL80211_ATTR_CONTROL_PORT_OVER_NL80211 attribute in its NL80211_CMD_ASSOCIATE or NL80211_CMD_CONNECT requests being sent to the kernel. The previously added NL80211_ATTR_SOCKET_OWNER attribute must also be included. The latter is used by the kernel to send NL80211_CMD_CONTROL_PORT_FRAME notifications back to userspace via a netlink unicast. If the NL80211_ATTR_CONTROL_PORT_OVER_NL80211 attribute is not specified, then legacy behavior is kept and control port packets continue to flow over the network interface. If control port over nl80211 transport is requested, then control port packets are intercepted just prior to being handed to the network device and sent over netlink via the NL80211_CMD_CONTROL_PORT_FRAME notification. NL80211_ATTR_CONTROL_PORT_ETHERTYPE and NL80211_ATTR_MAC are included to specify the control port frame protocol and source address respectively. If the control port frame was received unencrypted then NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT flag is also included. NL80211_ATTR_FRAME attribute contains the raw control port frame with all transport layer headers stripped (e.g. this would be the raw EAPoL frame). Userspace can reply to control port frames either via legacy methods (by sending frames to the network device) or via NL80211_CMD_CONTROL_PORT_FRAME request. Userspace would included NL80211_ATTR_FRAME with the raw control port frame as well as NL80211_Attr_MAC and NL80211_ATTR_CONTROL_PORT_ETHERTYPE attributes to specify the destination address and protocol respectively. This allows Pre-Authentication (protocol 0x88c7) frames to be sent via this mechanism as well. Finally, NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT flag can be included to tell the driver to send the frame unencrypted, e.g. for 4-Way handshake 4/4 frames. The proposed patchset has been tested in a mac80211_hwsim based environment with hostapd and iwd. ChangeLog v3 - Added ETH_P_PREAUTH to if_ether.h - Moved NL80211 feature bit from wiphy features to ext features - Addressed various comments from Johannes v2 - Added WIPHY_FLAG_CONTROL_PORT_OVER_NL80211 flag. This is a capability flag used by the drivers, e.g. that the driver supports control port over nl80211 capability. This capability is now checked when CONTROL_PORT_OVER_NL80211 is requested. - mac80211 rx path now forwards Pre-Authentication frames over NL80211 as well, if requested. Tweaked the signature of cfg80211_rx_control_port. - TX path reworked completely. tx_control_port method has been introduced to cfg80211_ops. An implementation of tx_control_port for mac80211 was added. Denis Kenzior (6): uapi: Add 802.11 Preauthentication to if_ether nl80211: Add CONTROL_PORT_OVER_NL80211 attribute nl80211: Add CMD_CONTROL_PORT_FRAME API mac80211: Send control port frames over nl80211 nl80211: Implement TX of control port frames mac80211: Add support for tx_control_port include/net/cfg80211.h| 29 + include/uapi/linux/if_ether.h | 1 + include/uapi/linux/nl80211.h | 32 +- net/mac80211/cfg.c| 3 + net/mac80211/ieee80211_i.h| 4 ++ net/mac80211/main.c | 2 + net/mac80211/mlme.c | 2 + net/mac80211/rx.c | 34 +-- net/mac80211/tx.c | 46 +++ net/wireless/nl80211.c| 134 +- net/wireless/rdev-ops.h | 15 + net/wireless/trace.h | 46 +++ 12 files changed, 341 insertions(+), 7 deletions(-) -- 2.13.5
Re: [PATCH] brcmfmac: detect & reject faked packet generated by a firmware
On 1/31/2018 5:14 PM, Hante Meuleman wrote: It is an 802.2 frame, more specifically a LLC XID frames. So why it exists? And more over, why would we crash as an result? Decoding info can be found here: https://www.cisco.com/c/en/us/support/docs/ibm-technologies/logical-link-control-llc/12247-45.html#con3 The frame was likely sent by the stack from remote site PC, should be possible to capture with tcpdump. I've seen these frames before, but don’t know what they are for. The frame appears to be correctly encoded. The ethertype, is not a type, but a len field. The only protocol with such a short len allowed is llc, see also Could it be related to the fact that the interface is put in a bridge and hence the device is put in promiscuous mode? Anyway, I did not read anything about a firmware crash. Just that clients could not associate. Regards, Arend
Re: [PATCH] brcmfmac: detect & reject faked packet generated by a firmware
On 2018-01-30 12:30, Arend van Spriel wrote: On 1/30/2018 10:09 AM, Rafał Miłecki wrote: From: Rafał MiłeckiWhen using 4366b1 and 4366c0 chipsets with more recent firmwares 1) 10.10 (TOB) (r663589) 2) 10.10.122.20 (r683106) respectively, it is impossible to use brcmfmac with interface in AP mode. With the AP interface bridged and multicast used, no STA will be able to associate; the STA will be immediately disassociated when attempting to associate. Debugging revealed this to be caused by a "faked" packet (generated by firmware), that is passed to the networking subsystem and then back to the firmware. Fortunately this packet is easily identified and can be detected and ignored as a workaround for misbehaving firmware. Signed-off-by: Rafał Miłecki --- .../wireless/broadcom/brcm80211/brcmfmac/core.c| 46 ++ 1 file changed, 46 insertions(+) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index 930e423f83a8..a98ba9bbc7fe 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -323,8 +323,54 @@ void brcmf_txflowblock_if(struct brcmf_if *ifp, spin_unlock_irqrestore(>netif_stop_lock, flags); } +/** + * brcmf_is_valid_skb - validates skb received from the hardware + * + * @skb: skb to check + * + * Sometimes firmware/hardware can generate broken packets that aren't real or + * valid and their skb-s shouldn't be passed up to the networking subsystem. + * + * Firmwares for 43602a1, 4366b1 and 4366c0 are known to *generate* a faked 6 B + * packet whenever a STA associates. The purpose of this fake packet remains + * unknown but it is clearly not data coming from a station. As such it + * shouldn't be passed to the networking subsystem. + * + * Normally such a packet would simply be ignored, but this is not the case with + * more recent 4366b1 and 4366c0 firmwares. These firmwares seem to explicitly + * check for this packet and will reject (disassociate) the station, making it + * impossible to connect to the AP at all. This can happen when using a bridged + * interface with multicasting. Such a scenario apparently isn't tested (or + * supported) by Broadcom's internal team. + */ +static bool brcmf_is_valid_skb(struct sk_buff *skb) +{ + const u8 fw_faked_packet[6] __aligned(2) = { + 0x00, 0x01, 0xaf, 0x81, 0x01, 0x00, + }; +#if !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) + const u16 *a = (const u16 *)skb->data; + const u16 *b = (const u16 *)fw_faked_packet; +#endif + + if (skb->len != 6) + return true; + +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) + return !!(((*(const u32 *)skb->data) ^ (*(const u32 *)fw_faked_packet)) | + ((*(const u16 *)(skb->data + 4)) ^ (*(const u16 *)(fw_faked_packet + 4; +#else + return !!((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])); +#endif +} The code above does look very much like ether_addr_equal(). Why not use that instead of reinventing it. You're right about ether_addr_equal(), I wasn't sure if that is acceptable to use it for comparing any 6 bytes data. I know it'd work, it's just not what it was designed for. Kalle? void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb) { + if (!brcmf_is_valid_skb(skb)) { + brcmu_pkt_buf_free_skb(skb); Maybe we should add a driver stat for this although I better have a look into the root cause of this. It seems there are following stats fields we can use: 1) rx_errors 2) rx_dropped 3) rx_length_errors 4) rx_over_errors 5) rx_crc_errors 6) rx_frame_errors 7) rx_fifo_errors 8) rx_missed_errors Which one do you think may fit this case the best?
Re: rtl8821ae keep alive not set, connection lost
On 09/12/2017 05:09 PM, James Cameron wrote: Summary: 40b368af4b75 ("rtlwifi: Fix alignment issues") breaks rtl8821ae keep alive, causing "Connection to AP lost" and deauth, but why? Wireless connection is lost after a few seconds or minutes, on every OLPC NL3 laptop with rtl8821ae, with any stable kernel after 4.10.1, and any kernel with 40b368af4b75. dmesg contains wlp2s0: Connection to AP 2c:b0:5d:a6:86:eb lost iw event shows wlp2s0: del station 2c:b0:5d:a6:86:eb wlp2s0 (phy #0): deauth 74:c6:3b:09:b5:0d -> 2c:b0:5d:a6:86:eb reason 4: Disassociated due to inactivity wlp2s0 (phy #0): disconnected (local request) Workaround is to bounce the link, then reconnect; ip link set wlp2s0 down ip link set wlp2s0 up iw dev wlp2s0 connect qz A nearby monitor host captures a deauthentication packet sent by the device. Bisection showed cause is 40b368af4b75 ("rtlwifi: Fix alignment issues") which changes the width of DBI register read. On the face of it, 40b368af4b75 looks correct, especially compared against same function in rtl8723be. I've no idea why reverting fixes the problem. I'm hoping someone here might speculate and suggest ways to test. As keep alive is set through this path, my guess is that keep alive is not being set in the device. Or perhaps reading 16-bits perturbs another register. Is there a way to test? http://dev.laptop.org/~quozl/z/1drtGD.txt dmesg of 4.13 http://dev.laptop.org/~quozl/z/1drt7c.txt dmesg with 4.13 and revert of 40b368af4b75 James, I'm afraid we are needing to revisit this problem again. Changing that 8-bit read to a 16-bit version causes an unaligned memory reference in AARCH64, thus we will need to re-revert. To prevent problems on systems such as yours, PK plans to turn off ASPM capability and backdoor in certain platforms that will be listed in a quirks table. Please report the output of 'dmidecode -t system' for you affected system(s). We hope you will be able to test any proposed patches. Thanks, Larry
RE: [PATCH] brcmfmac: detect & reject faked packet generated by a firmware
It is an 802.2 frame, more specifically a LLC XID frames. So why it exists? And more over, why would we crash as an result? Decoding info can be found here: https://www.cisco.com/c/en/us/support/docs/ibm-technologies/logical-link-control-llc/12247-45.html#con3 The frame was likely sent by the stack from remote site PC, should be possible to capture with tcpdump. I've seen these frames before, but don’t know what they are for. The frame appears to be correctly encoded. The ethertype, is not a type, but a len field. The only protocol with such a short len allowed is llc, see also https://www.savvius.com/networking-glossary/ethernet/frame_formats/ So it is 802.2 (also known as LLC) Regads, Hante -Original Message- From: Arend van Spriel [mailto:arend.vanspr...@broadcom.com] Sent: Wednesday, January 31, 2018 3:20 PM To: Rafał Miłecki Cc: Rafał Miłecki; Kalle Valo; Franky Lin; Hante Meuleman; Chi-Hsien Lin; Wright Feng; Pieter-Paul Giesberts; linux-wireless@vger.kernel.org; brcm80211-dev-list@broadcom.com; brcm80211-dev-l...@cypress.com Subject: Re: [PATCH] brcmfmac: detect & reject faked packet generated by a firmware On 1/31/2018 2:14 PM, Rafał Miłecki wrote: > On 2018-01-30 12:47, Arend van Spriel wrote: >> On 1/30/2018 10:09 AM, Rafał Miłecki wrote: >>> From: Rafał Miłecki>>> >>> When using 4366b1 and 4366c0 chipsets with more recent firmwares >>> 1) 10.10 (TOB) (r663589) >>> 2) 10.10.122.20 (r683106) >>> respectively, it is impossible to use brcmfmac with interface in AP >>> mode. With the AP interface bridged and multicast used, no STA will >>> be able to associate; the STA will be immediately disassociated when >>> attempting to associate. >>> >>> Debugging revealed this to be caused by a "faked" packet (generated >>> by firmware), that is passed to the networking subsystem and then >>> back to the firmware. Fortunately this packet is easily identified >>> and can be detected and ignored as a workaround for misbehaving >>> firmware. >> >> I am actually wondering what this packet is. Have you checked in >> brcmf_msgbuf_process_rx_complete(). I am curious what buflen is there >> and what eth_type_trans() will do to the packet, ie. what protocol. >> As everything should be 802.3 we could/should add a length check of >> 14 bytes. > > Did you find anything? I was going to say no, but below I see I misinterpreted your commit message and thought we were getting 6 bytes from firmware, but it is 6 bytes + ETH_HLEN. > I got some debugging info, hopefully this is what you expected and more ... :-) > [ 144.356648] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.msgtype: > 0x12 > [ 144.363559] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.ifidx: > 0x00 > [ 144.370374] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.flags: > 0x80 > [ 144.377179] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.rsvd0: > 0x00 > [ 144.383986] brcmfmac: [brcmf_msgbuf_process_rx_complete] > msg.request_id: 0x0041 > [ 144.391661] brcmfmac: [brcmf_msgbuf_process_rx_complete] > compl_hdr.status: 0x > [ 144.399156] brcmfmac: [brcmf_msgbuf_process_rx_complete] > compl_hdr.flow_ring_id: 0x > [ 144.407179] brcmfmac: [brcmf_msgbuf_process_rx_complete] > metadata_len: 0x > [ 144.414334] brcmfmac: [brcmf_msgbuf_process_rx_complete] data_len: > 0x0014 > [ 144.421227] brcmfmac: [brcmf_msgbuf_process_rx_complete] data_offset: > 0x > [ 144.428288] brcmfmac: [brcmf_msgbuf_process_rx_complete] flags: > 0x0001 > [ 144.434918] brcmfmac: [brcmf_msgbuf_process_rx_complete] rx_status_0: > 0x > [ 144.442334] brcmfmac: [brcmf_msgbuf_process_rx_complete] rx_status_1: > 0x > [ 144.449750] brcmfmac: [brcmf_msgbuf_process_rx_complete] rsvd0: > 0x0001 > [ 144.456724] brcmfmac: [brcmf_msgbuf_process_rx_complete] skb->data: > ff ff ff ff ff ff ec 10 7b 5f ?? ?? 00 06 00 01 af 81 01 > 00 [ 144.467883] brcmfmac: [brcmf_msgbuf_process_rx_complete] > skb->protocol: 0x0400 Not sure what protocol that is. Can not find it in if_ether.h. Will look in our firmware repo for it. Thanks, Arend > (just masked 2 bytes of my MAC) > > > diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c > b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c > index 1bd4b96..08cdcaf 100644 > --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c > +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c > @@ -1172,7 +1172,43 @@ brcmf_msgbuf_process_rx_complete(struct > brcmf_msgbuf *msgbuf, void *buf) > return; > } > > +if (skb->len == ETH_HLEN + 6) { > +uint8_t *data; > +int i; > + > +pr_info("[%s] msg.msgtype:\t0x%02x\n", __func__, > rx_complete->msg.msgtype); > +pr_info("[%s] msg.ifidx:\t\t0x%02x\n", __func__, > rx_complete->msg.ifidx); > +pr_info("[%s] msg.flags:\t\t0x%02x\n",
Re: [PATCH] wireless: zd1211rw: remove redundant assignment of pointer 'q'
On Wed, Jan 31, 2018 at 02:58:57PM +0200, Andy Shevchenko wrote: > On Tue, Jan 30, 2018 at 8:25 PM, Colin Kingwrote: > > From: Colin Ian King > > > > Pointer q is initialized and then almost immediately afterwards being > > re-assigned the same value. Remove the second redundant assignment. > > > > Don't you see strange that in the same context of the patch two users > of q are present? > > How did you test this? > The patch is obviously correct, I don't understand the question. regards, dan carpenter
Re: ath9k will not tx packets sometimes.
Am 31.01.2018 um 14:46 schrieb Toke Høiland-Jørgensen: Sebastian Gottschallwrites: Am 31.01.2018 um 12:50 schrieb Toke Høiland-Jørgensen: Sebastian Gottschall writes: Am 30.01.2018 um 19:55 schrieb Toke Høiland-Jørgensen: Ben Greear writes: I'm actually working on reworking that whole scheduler logic, and move some of it into mac80211. Could you test this (WiP) patch and see if that has the same problem? It had some serious conflicts in ath10k, due to my local changes, so I did not actually test this. Can send you a version without the ath10k changes tomorrow if you'd like to test - but will try to reproduce myself as well... But, a revert of the atf patches (a6e56d749 and 63fefa050) appear to have resolved the issue. I'll test more with these reverted, and maybe will have time to work more on actually fixing upstream code next time I move to a newer kernel (and/or after your pending changes get in). Ah, that narrows it down some. Well, that is the code I'm hacking on currently anyway, so let's see if we can't get it fixed as part of that series :) i have some addition information for you maybe. in the same timeframe i noticed a increased memory usage for ath9k devices. maybe that helps. so i hit memory boundaries on embedded devices with dual interfaces and just 32 mb ram now which wasnt the case before is this patch worth to try from my side? This is probably because of the added queue space. Which is sort of by design. In 3ff23cd5654b9c8f4d567caa73439b4c39fbeaae we lowered the default limit for non-VHT devices to 4MB. But if you have several PHYs on a very memory constrained device you could still run out I guess. `echo fq_memory_limit 2097152 > /sys/kernel/debug/ieee80211/phy0/aqm` would limit it to 2MB for that phy... what if i tried that already? :-) Hmm, then it's maybe a bug? Changing the limit makes no difference at all? Does your build include 0bfe649fbb133? What are values of the maybe it makes a change but i run into oom after a while as well counters in /sys/kernel/debug/ieee80211/phy0/aqm ? i will check the current state in the next days. havent checked it over the last 2 months on the affected device -Toke -- Mit freundlichen Grüssen / Regards Sebastian Gottschall / CTO NewMedia-NET GmbH - DD-WRT Firmensitz: Stubenwaldallee 21a, 64625 Bensheim Registergericht: Amtsgericht Darmstadt, HRB 25473 Geschäftsführer: Peter Steinhäuser, Christian Scheele http://www.dd-wrt.com email: s.gottsch...@dd-wrt.com Tel.: +496251-582650 / Fax: +496251-5826565
Re: [PATCH v4 2/3] mac80211_hwsim: add nl_err_msg in hwsim_new_radio in netlink case
Am 31.01.2018 um 13:05 schrieb Johannes Berg: > On Tue, 2018-01-30 at 10:47 +0100, Benjamin Beichler wrote: > >> It should not be triggered because of already existing macs, I added it >> for somehow completeness, but you can leave it out. > Sure. > >> After having again a look on it, there could be an -ENOMEM on >> rhashtable_insert. Maybe it's better to explicitly catch only -EEXIST >> and print for the rest an generic error. Do you agree ? > Nah, that's unlikely enough ... and you get -ENOMEM back in userspace > too. > > That said, good thing I looked at this - you forgot a set of braces :-) Damn ... but fortunately you saw it. As you already accepted it, I don't need to send new patches :-D > johannes > thanks for your efforts! Benjamin -- M.Sc. Benjamin Beichler Universität Rostock, Fakultät für Informatik und Elektrotechnik Institut für Angewandte Mikroelektronik und Datentechnik University of Rostock, Department of CS and EE Institute of Applied Microelectronics and CE Richard-Wagner-Straße 31 18119 Rostock Deutschland/Germany phone: +49 (0) 381 498 - 7278 email: benjamin.beich...@uni-rostock.de www: http://www.imd.uni-rostock.de/ smime.p7s Description: S/MIME Cryptographic Signature
Re: [PATCH] brcmfmac: detect & reject faked packet generated by a firmware
On 1/31/2018 2:14 PM, Rafał Miłecki wrote: On 2018-01-30 12:47, Arend van Spriel wrote: On 1/30/2018 10:09 AM, Rafał Miłecki wrote: From: Rafał MiłeckiWhen using 4366b1 and 4366c0 chipsets with more recent firmwares 1) 10.10 (TOB) (r663589) 2) 10.10.122.20 (r683106) respectively, it is impossible to use brcmfmac with interface in AP mode. With the AP interface bridged and multicast used, no STA will be able to associate; the STA will be immediately disassociated when attempting to associate. Debugging revealed this to be caused by a "faked" packet (generated by firmware), that is passed to the networking subsystem and then back to the firmware. Fortunately this packet is easily identified and can be detected and ignored as a workaround for misbehaving firmware. I am actually wondering what this packet is. Have you checked in brcmf_msgbuf_process_rx_complete(). I am curious what buflen is there and what eth_type_trans() will do to the packet, ie. what protocol. As everything should be 802.3 we could/should add a length check of 14 bytes. Did you find anything? I was going to say no, but below I see I misinterpreted your commit message and thought we were getting 6 bytes from firmware, but it is 6 bytes + ETH_HLEN. I got some debugging info, hopefully this is what you expected and more ... :-) [ 144.356648] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.msgtype: 0x12 [ 144.363559] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.ifidx: 0x00 [ 144.370374] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.flags: 0x80 [ 144.377179] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.rsvd0: 0x00 [ 144.383986] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.request_id: 0x0041 [ 144.391661] brcmfmac: [brcmf_msgbuf_process_rx_complete] compl_hdr.status: 0x [ 144.399156] brcmfmac: [brcmf_msgbuf_process_rx_complete] compl_hdr.flow_ring_id: 0x [ 144.407179] brcmfmac: [brcmf_msgbuf_process_rx_complete] metadata_len: 0x [ 144.414334] brcmfmac: [brcmf_msgbuf_process_rx_complete] data_len: 0x0014 [ 144.421227] brcmfmac: [brcmf_msgbuf_process_rx_complete] data_offset: 0x [ 144.428288] brcmfmac: [brcmf_msgbuf_process_rx_complete] flags: 0x0001 [ 144.434918] brcmfmac: [brcmf_msgbuf_process_rx_complete] rx_status_0: 0x [ 144.442334] brcmfmac: [brcmf_msgbuf_process_rx_complete] rx_status_1: 0x [ 144.449750] brcmfmac: [brcmf_msgbuf_process_rx_complete] rsvd0: 0x0001 [ 144.456724] brcmfmac: [brcmf_msgbuf_process_rx_complete] skb->data: ff ff ff ff ff ff ec 10 7b 5f ?? ?? 00 06 00 01 af 81 01 00 [ 144.467883] brcmfmac: [brcmf_msgbuf_process_rx_complete] skb->protocol: 0x0400 Not sure what protocol that is. Can not find it in if_ether.h. Will look in our firmware repo for it. Thanks, Arend (just masked 2 bytes of my MAC) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c index 1bd4b96..08cdcaf 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c @@ -1172,7 +1172,43 @@ brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf) return; } +if (skb->len == ETH_HLEN + 6) { +uint8_t *data; +int i; + +pr_info("[%s] msg.msgtype:\t0x%02x\n", __func__, rx_complete->msg.msgtype); +pr_info("[%s] msg.ifidx:\t\t0x%02x\n", __func__, rx_complete->msg.ifidx); +pr_info("[%s] msg.flags:\t\t0x%02x\n", __func__, rx_complete->msg.flags); +pr_info("[%s] msg.rsvd0:\t\t0x%02x\n", __func__, rx_complete->msg.rsvd0); +pr_info("[%s] msg.request_id:\t0x%08x\n", __func__, le32_to_cpu(rx_complete->msg.request_id)); + +pr_info("[%s] compl_hdr.status:\t0x%04x\n", __func__, le16_to_cpu(rx_complete->compl_hdr.status)); +pr_info("[%s] compl_hdr.flow_ring_id:\t0x%04x\n", __func__, le16_to_cpu(rx_complete->compl_hdr.flow_ring_id)); + +pr_info("[%s] metadata_len:\t0x%04x\n", __func__, le16_to_cpu(rx_complete->metadata_len)); +pr_info("[%s] data_len:\t\t0x%04x\n", __func__, le16_to_cpu(rx_complete->data_len)); +pr_info("[%s] data_offset:\t0x%04x\n", __func__, le16_to_cpu(rx_complete->data_offset)); +pr_info("[%s] flags:\t\t0x%04x\n", __func__, le16_to_cpu(rx_complete->flags)); +pr_info("[%s] rx_status_0:\t0x%08x\n", __func__, le32_to_cpu(rx_complete->rx_status_0)); +pr_info("[%s] rx_status_1:\t0x%08x\n", __func__, le32_to_cpu(rx_complete->rx_status_1)); +pr_info("[%s] rsvd0:\t\t0x%08x\n", __func__, le32_to_cpu(rx_complete->rsvd0)); + +data = skb->data; +pr_info("[%s] skb->data:\t\t", __func__); +for (i = 0; i < 32 && i < skb->len; i++) { +pr_cont("%02x ", data[i]); +if (i % 4 == 3) +
Re: [PATCH] brcmfmac: detect & reject faked packet generated by a firmware
On 1/31/2018 2:11 PM, Rafał Miłecki wrote: void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb) { +if (!brcmf_is_valid_skb(skb)) { +brcmu_pkt_buf_free_skb(skb); Maybe we should add a driver stat for this although I better have a look into the root cause of this. It seems there are following stats fields we can use: 1) rx_errors 2) rx_dropped 3) rx_length_errors 4) rx_over_errors 5) rx_crc_errors 6) rx_frame_errors 7) rx_fifo_errors 8) rx_missed_errors Which one do you think may fit this case the best? Those are actually netdev stats, right? Not sure I want to have those, but if any I would say 3) fits best. Regards, Arend
Re: [PATCH] brcmfmac: detect & reject faked packet generated by a firmware
On 2018-01-30 12:47, Arend van Spriel wrote: On 1/30/2018 10:09 AM, Rafał Miłecki wrote: From: Rafał MiłeckiWhen using 4366b1 and 4366c0 chipsets with more recent firmwares 1) 10.10 (TOB) (r663589) 2) 10.10.122.20 (r683106) respectively, it is impossible to use brcmfmac with interface in AP mode. With the AP interface bridged and multicast used, no STA will be able to associate; the STA will be immediately disassociated when attempting to associate. Debugging revealed this to be caused by a "faked" packet (generated by firmware), that is passed to the networking subsystem and then back to the firmware. Fortunately this packet is easily identified and can be detected and ignored as a workaround for misbehaving firmware. I am actually wondering what this packet is. Have you checked in brcmf_msgbuf_process_rx_complete(). I am curious what buflen is there and what eth_type_trans() will do to the packet, ie. what protocol. As everything should be 802.3 we could/should add a length check of 14 bytes. Did you find anything? I got some debugging info, hopefully this is what you expected [ 144.356648] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.msgtype: 0x12 [ 144.363559] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.ifidx: 0x00 [ 144.370374] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.flags: 0x80 [ 144.377179] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.rsvd0: 0x00 [ 144.383986] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.request_id: 0x0041 [ 144.391661] brcmfmac: [brcmf_msgbuf_process_rx_complete] compl_hdr.status: 0x [ 144.399156] brcmfmac: [brcmf_msgbuf_process_rx_complete] compl_hdr.flow_ring_id: 0x [ 144.407179] brcmfmac: [brcmf_msgbuf_process_rx_complete] metadata_len: 0x [ 144.414334] brcmfmac: [brcmf_msgbuf_process_rx_complete] data_len: 0x0014 [ 144.421227] brcmfmac: [brcmf_msgbuf_process_rx_complete] data_offset: 0x [ 144.428288] brcmfmac: [brcmf_msgbuf_process_rx_complete] flags: 0x0001 [ 144.434918] brcmfmac: [brcmf_msgbuf_process_rx_complete] rx_status_0: 0x [ 144.442334] brcmfmac: [brcmf_msgbuf_process_rx_complete] rx_status_1: 0x [ 144.449750] brcmfmac: [brcmf_msgbuf_process_rx_complete] rsvd0: 0x0001 [ 144.456724] brcmfmac: [brcmf_msgbuf_process_rx_complete] skb->data: ff ff ff ff ff ff ec 10 7b 5f ?? ?? 00 06 00 01 af 81 01 00 [ 144.467883] brcmfmac: [brcmf_msgbuf_process_rx_complete] skb->protocol: 0x0400 (just masked 2 bytes of my MAC) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c index 1bd4b96..08cdcaf 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c @@ -1172,7 +1172,43 @@ brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf) return; } + if (skb->len == ETH_HLEN + 6) { + uint8_t *data; + int i; + + pr_info("[%s] msg.msgtype:\t0x%02x\n", __func__, rx_complete->msg.msgtype); + pr_info("[%s] msg.ifidx:\t\t0x%02x\n", __func__, rx_complete->msg.ifidx); + pr_info("[%s] msg.flags:\t\t0x%02x\n", __func__, rx_complete->msg.flags); + pr_info("[%s] msg.rsvd0:\t\t0x%02x\n", __func__, rx_complete->msg.rsvd0); + pr_info("[%s] msg.request_id:\t0x%08x\n", __func__, le32_to_cpu(rx_complete->msg.request_id)); + + pr_info("[%s] compl_hdr.status:\t0x%04x\n", __func__, le16_to_cpu(rx_complete->compl_hdr.status)); + pr_info("[%s] compl_hdr.flow_ring_id:\t0x%04x\n", __func__, le16_to_cpu(rx_complete->compl_hdr.flow_ring_id)); + + pr_info("[%s] metadata_len:\t0x%04x\n", __func__, le16_to_cpu(rx_complete->metadata_len)); + pr_info("[%s] data_len:\t\t0x%04x\n", __func__, le16_to_cpu(rx_complete->data_len)); + pr_info("[%s] data_offset:\t0x%04x\n", __func__, le16_to_cpu(rx_complete->data_offset)); + pr_info("[%s] flags:\t\t0x%04x\n", __func__, le16_to_cpu(rx_complete->flags)); + pr_info("[%s] rx_status_0:\t0x%08x\n", __func__, le32_to_cpu(rx_complete->rx_status_0)); + pr_info("[%s] rx_status_1:\t0x%08x\n", __func__, le32_to_cpu(rx_complete->rx_status_1)); + pr_info("[%s] rsvd0:\t\t0x%08x\n", __func__, le32_to_cpu(rx_complete->rsvd0)); + + data = skb->data; + pr_info("[%s] skb->data:\t\t", __func__); + for (i = 0; i < 32 && i < skb->len; i++) { + pr_cont("%02x ", data[i]); + if (i % 4 == 3) + pr_cont(" "); + } + pr_cont("\n"); + } + skb->protocol = eth_type_trans(skb, ifp->ndev); + + if (skb->len == 6) { + pr_info("[%s] skb->protocol:\t0x%04x\n", __func__, skb->protocol); + } + brcmf_netif_rx(ifp, skb);
Re: ath9k will not tx packets sometimes.
Sebastian Gottschallwrites: > Am 31.01.2018 um 12:50 schrieb Toke Høiland-Jørgensen: >> Sebastian Gottschall writes: >> >>> Am 30.01.2018 um 19:55 schrieb Toke Høiland-Jørgensen: Ben Greear writes: >> I'm actually working on reworking that whole scheduler logic, and move >> some of it into mac80211. Could you test this (WiP) patch and see if >> that has the same problem? > It had some serious conflicts in ath10k, due to my local changes, so > I did not actually test this. Can send you a version without the ath10k changes tomorrow if you'd like to test - but will try to reproduce myself as well... > But, a revert of the atf patches (a6e56d749 and 63fefa050) appear to > have resolved the issue. I'll test more with these reverted, and maybe > will have time to work more on actually fixing upstream code next time > I move to a newer kernel (and/or after your pending changes get in). Ah, that narrows it down some. Well, that is the code I'm hacking on currently anyway, so let's see if we can't get it fixed as part of that series :) >>> i have some addition information for you maybe. in the same timeframe i >>> noticed a increased memory usage for ath9k devices. >>> maybe that helps. so i hit memory boundaries on embedded devices with >>> dual interfaces and just 32 mb ram now which wasnt the case before >>> is this patch worth to try from my side? >> This is probably because of the added queue space. Which is sort of by >> design. In 3ff23cd5654b9c8f4d567caa73439b4c39fbeaae we lowered the >> default limit for non-VHT devices to 4MB. But if you have several PHYs >> on a very memory constrained device you could still run out I guess. >> >> `echo fq_memory_limit 2097152 > /sys/kernel/debug/ieee80211/phy0/aqm` >> would limit it to 2MB for that phy... > what if i tried that already? :-) Hmm, then it's maybe a bug? Changing the limit makes no difference at all? Does your build include 0bfe649fbb133? What are values of the counters in /sys/kernel/debug/ieee80211/phy0/aqm ? -Toke
Re: ath9k will not tx packets sometimes.
Am 31.01.2018 um 12:50 schrieb Toke Høiland-Jørgensen: Sebastian Gottschallwrites: Am 30.01.2018 um 19:55 schrieb Toke Høiland-Jørgensen: Ben Greear writes: I'm actually working on reworking that whole scheduler logic, and move some of it into mac80211. Could you test this (WiP) patch and see if that has the same problem? It had some serious conflicts in ath10k, due to my local changes, so I did not actually test this. Can send you a version without the ath10k changes tomorrow if you'd like to test - but will try to reproduce myself as well... But, a revert of the atf patches (a6e56d749 and 63fefa050) appear to have resolved the issue. I'll test more with these reverted, and maybe will have time to work more on actually fixing upstream code next time I move to a newer kernel (and/or after your pending changes get in). Ah, that narrows it down some. Well, that is the code I'm hacking on currently anyway, so let's see if we can't get it fixed as part of that series :) i have some addition information for you maybe. in the same timeframe i noticed a increased memory usage for ath9k devices. maybe that helps. so i hit memory boundaries on embedded devices with dual interfaces and just 32 mb ram now which wasnt the case before is this patch worth to try from my side? This is probably because of the added queue space. Which is sort of by design. In 3ff23cd5654b9c8f4d567caa73439b4c39fbeaae we lowered the default limit for non-VHT devices to 4MB. But if you have several PHYs on a very memory constrained device you could still run out I guess. `echo fq_memory_limit 2097152 > /sys/kernel/debug/ieee80211/phy0/aqm` would limit it to 2MB for that phy... what if i tried that already? :-) Sebastian -Toke -- Mit freundlichen Grüssen / Regards Sebastian Gottschall / CTO NewMedia-NET GmbH - DD-WRT Firmensitz: Stubenwaldallee 21a, 64625 Bensheim Registergericht: Amtsgericht Darmstadt, HRB 25473 Geschäftsführer: Peter Steinhäuser, Christian Scheele http://www.dd-wrt.com email: s.gottsch...@dd-wrt.com Tel.: +496251-582650 / Fax: +496251-5826565
Re: [PATCH] wireless: zd1211rw: remove redundant assignment of pointer 'q'
On Tue, Jan 30, 2018 at 8:25 PM, Colin Kingwrote: > From: Colin Ian King > > Pointer q is initialized and then almost immediately afterwards being > re-assigned the same value. Remove the second redundant assignment. > Don't you see strange that in the same context of the patch two users of q are present? How did you test this? > Cleans up clang warning: > drivers/net/wireless/zydas/zd1211rw/zd_mac.c:503:23: warning: Value > stored to 'q' during its initialization is never read > - q = >ack_wait_queue; > spin_lock_irqsave(>lock, flags); > > skb_queue_walk(q, skb) { -- With Best Regards, Andy Shevchenko
Re: [PATCH v4 2/3] mac80211_hwsim: add nl_err_msg in hwsim_new_radio in netlink case
On Tue, 2018-01-30 at 10:47 +0100, Benjamin Beichler wrote: > It should not be triggered because of already existing macs, I added it > for somehow completeness, but you can leave it out. Sure. > After having again a look on it, there could be an -ENOMEM on > rhashtable_insert. Maybe it's better to explicitly catch only -EEXIST > and print for the rest an generic error. Do you agree ? Nah, that's unlikely enough ... and you get -ENOMEM back in userspace too. That said, good thing I looked at this - you forgot a set of braces :-) johannes
[PATCH] ath10k: Add sta rx packet stats per tid
Added per tid sta counters for the following - Total number MSDUs received from firmware - Number of MSDUs received with errors like decryption, crc, mic ,etc. - Number of MSDUs dropped in the driver - A-MPDU/A-MSDU subframe stats - Number of MSDUS passed to mac80211 All stats other than A-MPDU stats are only for received data frames. A-MPDU stats might have stats for management frames when monitor interface is active where management frames are notified both in wmi and HTT interfaces. These per tid stats can be enabled with tid bitmask through a debugfs like below echo > /sys/kernel/debug/ieee80211/phyX/ath10k/sta_tid_stats_mask tid 16 (tid_bitmask 0x1) is used for non-qos data/management frames The stats are read from /sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations//dump_tid_stats Sample output: To enable rx stats for tid 0, 5 and 6, echo 0x0061 > /sys/kernel/debug/ieee80211/phy0/ath10k/sta_tid_stats_mask cat /sys/kernel/debug/ieee80211/phy0/netdev\:wlan15/stations/8c\:fd\:f0\:0a\:8e\:df/dump_tid_stats Driver Rx pkt stats per tid, ([tid] count) -- MSDUs from FW [00] 2567[05] 3178[06] 1089 MSDUs unchained [00] 0 [05] 0 [06] 0 MSDUs locally dropped:chained [00] 0 [05] 0 [06] 0 MSDUs locally dropped:filtered [00] 0 [05] 0 [06] 0 MSDUs queued for mac80211 [00] 2567[05] 3178[06] 1089 MSDUs with error:fcs_err[00] 0 [05] 0 [06] 2 MSDUs with error:tkip_err [00] 0 [05] 0 [06] 0 MSDUs with error:crypt_err [00] 0 [05] 0 [06] 0 MSDUs with error:peer_idx_inval [00] 0 [05] 0 [06] 0 A-MPDU num subframes upto 10[00] 2567[05] 3178[06] 1087 A-MPDU num subframes 11-20 [00] 0 [05] 0 [06] 0 A-MPDU num subframes 21-30 [00] 0 [05] 0 [06] 0 A-MPDU num subframes 31-40 [00] 0 [05] 0 [06] 0 A-MPDU num subframes 41-50 [00] 0 [05] 0 [06] 0 A-MPDU num subframes 51-60 [00] 0 [05] 0 [06] 0 A-MPDU num subframes >60[00] 0 [05] 0 [06] 0 A-MSDU num subframes 1 [00] 2567[05] 3178[06] 1089 A-MSDU num subframes 2 [00] 0 [05] 0 [06] 0 A-MSDU num subframes 3 [00] 0 [05] 0 [06] 0 A-MSDU num subframes 4 [00] 0 [05] 0 [06] 0 A-MSDU num subframes >4 [00] 0 [05] 0 [06] 0 Signed-off-by: Vasanthakumar Thiagarajan--- drivers/net/wireless/ath/ath10k/core.h| 45 drivers/net/wireless/ath/ath10k/debug.c | 48 + drivers/net/wireless/ath/ath10k/debug.h | 31 +++ drivers/net/wireless/ath/ath10k/debugfs_sta.c | 286 ++ drivers/net/wireless/ath/ath10k/htt_rx.c | 71 ++- 5 files changed, 471 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index fe6b30356d3b..c624b96f8b84 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -354,6 +355,45 @@ struct ath10k_txq { unsigned long num_push_allowed; }; +enum ath10k_pkt_rx_err { + ATH10K_PKT_RX_ERR_FCS, + ATH10K_PKT_RX_ERR_TKIP, + ATH10K_PKT_RX_ERR_CRYPT, + ATH10K_PKT_RX_ERR_PEER_IDX_INVAL, + ATH10K_PKT_RX_ERR_MAX, +}; + +enum ath10k_ampdu_subfrm_num { + ATH10K_AMPDU_SUBFRM_NUM_10, + ATH10K_AMPDU_SUBFRM_NUM_20, + ATH10K_AMPDU_SUBFRM_NUM_30, + ATH10K_AMPDU_SUBFRM_NUM_40, + ATH10K_AMPDU_SUBFRM_NUM_50, + ATH10K_AMPDU_SUBFRM_NUM_60, + ATH10K_AMPDU_SUBFRM_NUM_MORE, + ATH10K_AMPDU_SUBFRM_NUM_MAX, +}; + +enum ath10k_amsdu_subfrm_num { + ATH10K_AMSDU_SUBFRM_NUM_1, + ATH10K_AMSDU_SUBFRM_NUM_2, + ATH10K_AMSDU_SUBFRM_NUM_3, + ATH10K_AMSDU_SUBFRM_NUM_4, + ATH10K_AMSDU_SUBFRM_NUM_MORE, + ATH10K_AMSDU_SUBFRM_NUM_MAX, +}; + +struct ath10k_sta_tid_stats { + unsigned long int rx_pkt_from_fw; + unsigned long int rx_pkt_unchained; + unsigned long int rx_pkt_drop_chained; + unsigned long int rx_pkt_drop_filter; + unsigned long int rx_pkt_err[ATH10K_PKT_RX_ERR_MAX]; + unsigned long int rx_pkt_queued_for_mac; + unsigned long int rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_MAX]; +
Re: ath9k will not tx packets sometimes.
Sebastian Gottschallwrites: > Am 30.01.2018 um 19:55 schrieb Toke Høiland-Jørgensen: >> Ben Greear writes: >> I'm actually working on reworking that whole scheduler logic, and move some of it into mac80211. Could you test this (WiP) patch and see if that has the same problem? >>> It had some serious conflicts in ath10k, due to my local changes, so >>> I did not actually test this. >> Can send you a version without the ath10k changes tomorrow if you'd like >> to test - but will try to reproduce myself as well... >> >>> But, a revert of the atf patches (a6e56d749 and 63fefa050) appear to >>> have resolved the issue. I'll test more with these reverted, and maybe >>> will have time to work more on actually fixing upstream code next time >>> I move to a newer kernel (and/or after your pending changes get in). >> Ah, that narrows it down some. Well, that is the code I'm hacking on >> currently anyway, so let's see if we can't get it fixed as part of that >> series :) > i have some addition information for you maybe. in the same timeframe i > noticed a increased memory usage for ath9k devices. > maybe that helps. so i hit memory boundaries on embedded devices with > dual interfaces and just 32 mb ram now which wasnt the case before > is this patch worth to try from my side? This is probably because of the added queue space. Which is sort of by design. In 3ff23cd5654b9c8f4d567caa73439b4c39fbeaae we lowered the default limit for non-VHT devices to 4MB. But if you have several PHYs on a very memory constrained device you could still run out I guess. `echo fq_memory_limit 2097152 > /sys/kernel/debug/ieee80211/phy0/aqm` would limit it to 2MB for that phy... -Toke
[PATCHv3 2/2] mac80211: Add support to notify ht/vht opmode modification.
This will add support to send an event to a userspace application whenever station advertise its ht/vht opmode modification through an action frame. Signed-off-by: Tamizh chelvam--- v3: * Initialized the sta_opmode_info structure variable before using net/mac80211/rx.c | 14 ++ net/mac80211/vht.c | 9 + 2 files changed, 23 insertions(+) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index fd58061..e755f93 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2848,6 +2848,7 @@ static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata, case WLAN_HT_ACTION_SMPS: { struct ieee80211_supported_band *sband; enum ieee80211_smps_mode smps_mode; + struct sta_opmode_info sta_opmode = {}; /* convert to HT capability */ switch (mgmt->u.action.u.ht_smps.smps_control) { @@ -2868,17 +2869,24 @@ static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata, if (rx->sta->sta.smps_mode == smps_mode) goto handled; rx->sta->sta.smps_mode = smps_mode; + sta_opmode.smps_mode = smps_mode; + sta_opmode.changed = STA_OPMODE_SMPS_MODE_CHANGED; sband = rx->local->hw.wiphy->bands[status->band]; rate_control_rate_update(local, sband, rx->sta, IEEE80211_RC_SMPS_CHANGED); + cfg80211_sta_opmode_change_notify(sdata->dev, + rx->sta->addr, + _opmode, + GFP_KERNEL); goto handled; } case WLAN_HT_ACTION_NOTIFY_CHANWIDTH: { struct ieee80211_supported_band *sband; u8 chanwidth = mgmt->u.action.u.ht_notify_cw.chanwidth; enum ieee80211_sta_rx_bandwidth max_bw, new_bw; + struct sta_opmode_info sta_opmode = {}; /* If it doesn't support 40 MHz it can't change ... */ if (!(rx->sta->sta.ht_cap.cap & @@ -2899,9 +2907,15 @@ static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata, rx->sta->sta.bandwidth = new_bw; sband = rx->local->hw.wiphy->bands[status->band]; + sta_opmode.bw = new_bw; + sta_opmode.changed = STA_OPMODE_MAX_BW_CHANGED; rate_control_rate_update(local, sband, rx->sta, IEEE80211_RC_BW_CHANGED); + cfg80211_sta_opmode_change_notify(sdata->dev, + rx->sta->addr, + _opmode, + GFP_KERNEL); goto handled; } default: diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c index b9276ac..5714dee 100644 --- a/net/mac80211/vht.c +++ b/net/mac80211/vht.c @@ -447,6 +447,7 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, enum nl80211_band band) { enum ieee80211_sta_rx_bandwidth new_bw; + struct sta_opmode_info sta_opmode = {}; u32 changed = 0; u8 nss; @@ -460,7 +461,9 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, if (sta->sta.rx_nss != nss) { sta->sta.rx_nss = nss; + sta_opmode.rx_nss = nss; changed |= IEEE80211_RC_NSS_CHANGED; + sta_opmode.changed |= STA_OPMODE_N_SS_CHANGED; } switch (opmode & IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK) { @@ -481,9 +484,15 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, new_bw = ieee80211_sta_cur_vht_bw(sta); if (new_bw != sta->sta.bandwidth) { sta->sta.bandwidth = new_bw; + sta_opmode.bw = new_bw; changed |= IEEE80211_RC_BW_CHANGED; + sta_opmode.changed |= STA_OPMODE_MAX_BW_CHANGED; } + if (sta_opmode.changed) + cfg80211_sta_opmode_change_notify(sdata->dev, sta->addr, + _opmode, GFP_KERNEL); + return changed; } -- 1.9.1
[PATCHv3 1/2] cfg80211: Add support to notify station's opmode change to userspace
ht/vht action frames will be sent to AP from station to notify change of its ht/vht opmode(max bandwidth, smps mode or nss) modified values. Currently these valuse used by driver/firmware for rate control algorithm. This patch introduces NL80211_CMD_STA_OPMODE_CHANGED command to notify those modified/current supported values(max bandwidth, smps mode, max nss) to userspace application. This will be useful for the application like steering, which closely monitoring station's capability changes. Since the application has taken these values during station association. Signed-off-by: Tamizh chelvam--- v3: * Initialized the sta_opmode_info structure variable before using v2: * Addressed Johannes's comments include/net/cfg80211.h | 43 ++ include/uapi/linux/nl80211.h | 12 ++ net/wireless/nl80211.c | 55 3 files changed, 110 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 81174f9..81caf86 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -3517,6 +3517,35 @@ enum wiphy_vendor_command_flags { }; /** + * enum wiphy_opmode_flag - Station's ht/vht operation mode information flags + * + * @STA_OPMODE_MAX_BW_CHANGED: Max Bandwidth changed + * @STA_OPMODE_SMPS_MODE_CHANGED: SMPS mode changed + * @STA_OPMODE_N_SS_CHANGED: max N_SS (number of spatial streams) changed + * + */ +enum wiphy_opmode_flag { + STA_OPMODE_MAX_BW_CHANGED = BIT(0), + STA_OPMODE_SMPS_MODE_CHANGED= BIT(1), + STA_OPMODE_N_SS_CHANGED = BIT(2), +}; + +/** + * struct sta_opmode_info - Station's ht/vht operation mode information + * @changed: contains value from wiphy_opmode_flag + * @smps_mode: New SMPS mode of a station + * @bw: new max bandwidth value of a station + * @rx_nss: new rx_nss value of a station + */ + +struct sta_opmode_info { + u32 changed; + u8 smps_mode; + u8 bw; + u8 rx_nss; +}; + +/** * struct wiphy_vendor_command - vendor command definition * @info: vendor command identifying information, as used in nl80211 * @flags: flags, see wiphy_vendor_command_flags @@ -5685,6 +5714,20 @@ void cfg80211_radar_event(struct wiphy *wiphy, struct cfg80211_chan_def *chandef, gfp_t gfp); /** + * cfg80211_sta_opmode_change_notify - STA's ht/vht operation mode change event + * @dev: network device + * @mac: MAC address of a station which opmode got modified + * @sta_opmode: station's current opmode value + * @gfp: context flags + * + * Driver should call this function when station's opmode modified via action + * frame. + */ +void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac, + struct sta_opmode_info *sta_opmode, + gfp_t gfp); + +/** * cfg80211_cac_event - Channel availability check (CAC) event * @netdev: network device * @chandef: chandef for the current channel diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index c587a61..b3b449f 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -992,6 +992,11 @@ * * @NL80211_CMD_RELOAD_REGDB: Request that the regdb firmware file is reloaded. * + * @NL80211_CMD_STA_OPMODE_CHANGED: An event that notify station's + * ht opmode or vht opmode changes using any of _ATTR_SMPS_MODE, + * _ATTR_CHANNEL_WIDTH,_ATTR_NSS attributes with its + * address(specified in _ATTR_MAC). + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -1198,6 +1203,8 @@ enum nl80211_commands { NL80211_CMD_RELOAD_REGDB, + NL80211_CMD_STA_OPMODE_CHANGED, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ @@ -2153,6 +2160,9 @@ enum nl80211_commands { * @NL80211_ATTR_PMKR0_NAME: PMK-R0 Name for offloaded FT. * @NL80211_ATTR_PORT_AUTHORIZED: (reserved) * + * @NL80211_ATTR_NSS: Station's New/updated RX_NSS value notified using this + * u8 attribute. This is used with %NL80211_CMD_STA_OPMODE_CHANGED. + * * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use @@ -2579,6 +2589,8 @@ enum nl80211_attrs { NL80211_ATTR_PMKR0_NAME, NL80211_ATTR_PORT_AUTHORIZED, + NL80211_ATTR_NSS, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index ab0c687..733259f 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -14887,6 +14887,61 @@ void cfg80211_ch_switch_started_notify(struct net_device *dev, nlmsg_free(msg); } +void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac, +
RE: [PATCH v3 2/3] cfg80211/nl80211: Optional authentication offload to userspace
On Tue, Jan 30, 2018 at 1:23 PM, Johannes Bergwrote: > On Thu, 2018-01-25 at 17:13 +0200, Jouni Malinen wrote: >> >> + if (nla_get_flag(info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])) >> + connect.flags |= CONNECT_REQ_EXTERNAL_AUTH_SUPPORT; > > It seems like here we should check for connection owner, no? > > If you say yes, I can edit that in. I guess you are referring netlink socket owner. Yes , we do agree with you and Thanks a lot for adding this check. Regards, Srinivas.