[PATCH wireless-next v3 2/5] wifi: brcmfmac: support AP isolation to restrict reachability between stations
Gokul Sivakumar <[email protected]>
| Newsgroups | dev.linux.lists.brcm80211,org.kernel.vger.linux-wireless |
|---|---|
| Message-ID | <[email protected]> |
From: Wright Feng <[email protected]> hostapd & wpa_supplicant userspace daemons exposes an AP mode specific config file parameter "ap_isolate" to the user, which is used to control low-level bridging of frames between the stations associated in the BSS. In driver, handle this user setting in the newly defined cfg80211_ops function brcmf_cfg80211_change_bss() by enabling "ap_isolate" IOVAR in the firmware. In AP mode, the "ap_isolate" value from the cfg80211 layer represents, 0 = allow low-level bridging of frames between associated stations 1 = restrict low-level bridging of frames to isolate associated stations The userspace can change more than one AP BSS Parameter in the SET_BSS operation. Incase if any BSS param other than the currently supported "ap_isolate" is passed by userspace, reject the entire SET_BSS operation instead of misleading the userspace that the operation is fully successful. Also add an individual check for the CFG80211_BSS_PARAM_CHANGED_AP_ISOLATE flag, before handling "ap_isolate" value from the userspace. This addresses case where driver unnecessarily checks the value of ap_isolate, even if the userspace did not pass this param in the SET_BSS request. Signed-off-by: Wright Feng <[email protected]> Signed-off-by: Chi-hsien Lin <[email protected]> Signed-off-by: Gokul Sivakumar <[email protected]> --- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index dc2383faddd1..276d08048cbb 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -5933,6 +5933,52 @@ static int brcmf_cfg80211_del_pmk(struct wiphy *wiphy, struct net_device *dev, return brcmf_set_pmk(ifp, NULL, 0); } +static int brcmf_set_ap_bssparam_isolate(struct brcmf_if *ifp, int param_ap_isolate) +{ + int ret = 0, cur_ap_isolate = 0; + + /* In cfg80211, for AP mode, the "param_ap_isolate" value represents + * 0 = allow low-level bridging of frames between associated stations + * 1 = restrict low-level bridging of frames to isolate associated stations + */ + ret = brcmf_fil_iovar_int_get(ifp, "ap_isolate", &cur_ap_isolate); + if (ret < 0) + return ret; + + if (cur_ap_isolate != param_ap_isolate) { + ret = brcmf_fil_iovar_int_set(ifp, "ap_isolate", param_ap_isolate); + if (ret < 0) { + brcmf_err("ap_isolate iovar failed: ret=%d\n", ret); + return ret; + } + } + + return ret; +} + +static int brcmf_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev, + struct bss_parameters *params) +{ + struct brcmf_if *ifp = netdev_priv(dev); + int ret = 0; + + /* Reject the operation if any of the AP BSS params that got changed are not + * supported by the driver for explicit configuration. + */ + if (params->changed & + ~(CFG80211_BSS_PARAM_CHANGED_AP_ISOLATE)) + return -EOPNOTSUPP; + + if (params->changed & + CFG80211_BSS_PARAM_CHANGED_AP_ISOLATE) { + ret = brcmf_set_ap_bssparam_isolate(ifp, params->ap_isolate); + if (ret) + return ret; + } + + return ret; +} + static struct cfg80211_ops brcmf_cfg80211_ops = { .add_virtual_intf = brcmf_cfg80211_add_iface, .del_virtual_intf = brcmf_cfg80211_del_iface, @@ -5980,6 +6026,7 @@ static struct cfg80211_ops brcmf_cfg80211_ops = { .update_connect_params = brcmf_cfg80211_update_conn_params, .set_pmk = brcmf_cfg80211_set_pmk, .del_pmk = brcmf_cfg80211_del_pmk, + .change_bss = brcmf_cfg80211_change_bss, }; struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings) -- 2.47.0