From: Aloka Dixit <alokad@codeaurora.org>
To: johannes@sipsolutions.net
Cc: linux-wireless@vger.kernel.org, John Crispin <john@phrozen.org>,
Aloka Dixit <alokad@codeaurora.org>,
kernel test robot <lkp@intel.com>,
Dan Carpenter <dan.carpenter@oracle.com>
Subject: [PATCH v9 1/4] nl80211: add basic multiple bssid support
Date: Wed, 10 Mar 2021 10:26:01 -0800 [thread overview]
Message-ID: <20210310182604.8858-2-alokad@codeaurora.org> (raw)
In-Reply-To: <20210310182604.8858-1-alokad@codeaurora.org>
From: John Crispin <john@phrozen.org>
This patch adds support for passing the multiple bssid config to the
kernel when an AP gets started. If the BSS is non-transmitting we need
to pass
* the ifidx of the transmitting parent
* the BSS index in the set
* the BSS count of the set
* flag indicating if we want to do EMA
* the multiple bssid elements as an array inside the beacon data
This allows use to generate multiple bssid beacons as well as EMA ones.
Signed-off-by: John Crispin <john@phrozen.org>
Co-developed-by: Aloka Dixit <alokad@codeaurora.org>
Signed-off-by: Aloka Dixit <alokad@codeaurora.org>
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
---
v9: Added check around kfree(params.acl)
Corrected comment descriptions for NL80211_EXT_FEATURE_MULTIPLE_BSSID_AP
and max_profile_periodicity
v8: Addition of NL80211_EXT_FEATURE_MULTIPLE_BSSID_AP,
NL80211_EXT_FEATURE_EMA_AP and wiphy parameters max_num_vaps,
max_profile_periodicity exposed to the application.
include/net/cfg80211.h | 47 ++++++
include/uapi/linux/nl80211.h | 84 +++++++++++
net/wireless/nl80211.c | 280 ++++++++++++++++++++++++++++++-----
3 files changed, 371 insertions(+), 40 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 911fae42b0c0..7755a04a6de6 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -485,6 +485,21 @@ struct ieee80211_supported_band {
const struct ieee80211_sband_iftype_data *iftype_data;
};
+/**
+ * struct cfg80211_multiple_bssid - AP settings for multi bssid
+ *
+ * @index: the index of this AP in the multi bssid group.
+ * @count: the total number of multi bssid peer APs.
+ * @parent: non-transmitted BSSs transmitted parents index
+ * @ema: Shall the beacons be sent out in EMA mode.
+ */
+struct cfg80211_multiple_bssid {
+ u8 index;
+ u8 count;
+ u32 parent;
+ bool ema;
+};
+
/**
* ieee80211_get_sband_iftype_data - return sband data for a given iftype
* @sband: the sband to search for the STA on
@@ -1032,6 +1047,23 @@ struct cfg80211_crypto_settings {
enum nl80211_sae_pwe_mechanism sae_pwe;
};
+/**
+ * struct cfg80211_multiple_bssid_data - Multiple BSSID elements
+ *
+ * @cnt: Number of elements in array %elems.
+ *
+ * @elems: Array of multiple BSSID element(s) to be added into Beacon frames.
+ * @elems.data: Data for multiple BSSID elements.
+ * @elems.len: Length of data.
+ */
+struct cfg80211_multiple_bssid_data {
+ u8 cnt;
+ struct {
+ u8 *data;
+ size_t len;
+ } elems[];
+};
+
/**
* struct cfg80211_beacon_data - beacon data
* @head: head portion of beacon (before TIM IE)
@@ -1058,6 +1090,7 @@ struct cfg80211_crypto_settings {
* Token (measurement type 11)
* @lci_len: LCI data length
* @civicloc_len: Civic location data length
+ * @multiple_bssid: multiple_bssid elements
*/
struct cfg80211_beacon_data {
const u8 *head, *tail;
@@ -1076,6 +1109,8 @@ struct cfg80211_beacon_data {
size_t probe_resp_len;
size_t lci_len;
size_t civicloc_len;
+
+ struct cfg80211_multiple_bssid_data *multiple_bssid;
};
struct mac_address {
@@ -1181,6 +1216,7 @@ enum cfg80211_ap_settings_flags {
* @he_oper: HE operation IE (or %NULL if HE isn't enabled)
* @fils_discovery: FILS discovery transmission parameters
* @unsol_bcast_probe_resp: Unsolicited broadcast probe response parameters
+ * @multiple_bssid: AP settings for multiple bssid.
*/
struct cfg80211_ap_settings {
struct cfg80211_chan_def chandef;
@@ -1213,6 +1249,7 @@ struct cfg80211_ap_settings {
struct cfg80211_he_bss_color he_bss_color;
struct cfg80211_fils_discovery fils_discovery;
struct cfg80211_unsol_bcast_probe_resp unsol_bcast_probe_resp;
+ struct cfg80211_multiple_bssid multiple_bssid;
};
/**
@@ -4941,6 +4978,11 @@ struct wiphy_iftype_akm_suites {
* configuration through the %NL80211_TID_CONFIG_ATTR_RETRY_SHORT and
* %NL80211_TID_CONFIG_ATTR_RETRY_LONG attributes
* @sar_capa: SAR control capabilities
+ *
+ * @multiple_bssid: Describes device's multiple BSSID config support
+ * @multiple_bssid.max_num_vaps: Maximum number of VAPS supported by the driver
+ * @multiple_bssid.max_profile_periodicity: Maximum EMA profile periodicity
+ * supported by the driver
*/
struct wiphy {
struct mutex mtx;
@@ -5083,6 +5125,11 @@ struct wiphy {
const struct cfg80211_sar_capa *sar_capa;
+ struct {
+ u8 max_num_vaps;
+ u8 max_profile_periodicity;
+ } multiple_bssid;
+
char priv[] __aligned(NETDEV_ALIGN);
};
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index ac78da99fccd..740bae5369ac 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2557,6 +2557,19 @@ enum nl80211_commands {
* disassoc events to indicate that an immediate reconnect to the AP
* is desired.
*
+ * @NL80211_ATTR_MULTIPLE_BSSID_CONFIG: Optional parameter to configure
+ * multiple BSSID and enhanced multi-BSSID advertisements.
+ * This attribute is also used to advertise the maximum number of VAPs
+ * supported by the driver to the application. It is a nested attribute,
+ * see &enum nl80211_multiple_bssid_config_attributes.
+ *
+ * @NL80211_ATTR_MULTIPLE_BSSID_ELEMS: Optional parameter for multiple BSSID
+ * elements data. This attribute is also used to advertise the maximum
+ * profile periodicity supported by the driver to the application, if
+ * enhanced multi-BSS advertisements (EMA) feature is enabled.
+ * It is a nested attribute, see
+ * &enum nl80211_multiple_bssid_elems_attributes.
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3054,6 +3067,9 @@ enum nl80211_attrs {
NL80211_ATTR_DISABLE_HE,
+ NL80211_ATTR_MULTIPLE_BSSID_CONFIG,
+ NL80211_ATTR_MULTIPLE_BSSID_ELEMS,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -5937,6 +5953,11 @@ enum nl80211_feature_flags {
* @NL80211_EXT_FEATURE_BEACON_RATE_HE: Driver supports beacon rate
* configuration (AP/mesh) with HE rates.
*
+ * @NL80211_EXT_FEATURE_MULTIPLE_BSSID_AP: Driver/device supports multiple
+ * BSSID advertisements.
+ * @NL80211_EXT_FEATURE_EMA_AP: Driver/device supports enhanced multiple BSSID
+ * advertisements (EMA).
+ *
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
*/
@@ -5998,6 +6019,8 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_FILS_DISCOVERY,
NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP,
NL80211_EXT_FEATURE_BEACON_RATE_HE,
+ NL80211_EXT_FEATURE_MULTIPLE_BSSID_AP,
+ NL80211_EXT_FEATURE_EMA_AP,
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
@@ -7277,4 +7300,65 @@ enum nl80211_sar_specs_attrs {
NL80211_SAR_ATTR_SPECS_MAX = __NL80211_SAR_ATTR_SPECS_LAST - 1,
};
+/**
+ * enum nl80211_multiple_bssid_config_attributes - Attributes to configure
+ * multiple BSSID and enhanced multi-BSSID advertisements.
+ *
+ * @__NL80211_MULTIPLE_BSSID_CONFIG_ATTR_INVALID: Invalid
+ *
+ * @NL80211_MULTIPLE_BSSID_CONFIG_ATTR_PARENT: For a non-transmitted BSSID, this
+ * attribute provides the interface index (u32) of the transmitted profile
+ * in the multiple BSSID set.
+ *
+ * @NL80211_MULTIPLE_BSSID_CONFIG_ATTR_INDEX: The index of this BSS (u8) inside
+ * multiple BSSID set.
+ *
+ * @NL80211_MULTIPLE_BSSID_CONFIG_ATTR_COUNT: Total number of BSSs (u8) in the
+ * multiple BSSID set.
+ *
+ * @NL80211_MULTIPLE_BSSID_CONFIG_ATTR_EMA: Flag to indicate if enhanced multi-BSSID
+ * advertisements (EMA) feature is enabled.
+ * If set to 1, elements provided through attribute
+ * %NL80211_ATTR_MULTIPLE_BSSID_ELEMS are split into multiple beacons.
+ * Otherwise, all elements will be included in every beacon.
+ *
+ * @__NL80211_MULTIPLE_BSSID_CONFIG_ATTR_LAST: Internal
+ * @NL80211_MULTIPLE_BSSID_CONFIG_ATTR_MAX: highest attribute
+ */
+enum nl80211_multiple_bssid_config_attributes {
+ __NL80211_MULTIPLE_BSSID_CONFIG_ATTR_INVALID,
+
+ NL80211_MULTIPLE_BSSID_CONFIG_ATTR_PARENT,
+ NL80211_MULTIPLE_BSSID_CONFIG_ATTR_INDEX,
+ NL80211_MULTIPLE_BSSID_CONFIG_ATTR_COUNT,
+ NL80211_MULTIPLE_BSSID_CONFIG_ATTR_EMA,
+
+ /* keep last */
+ __NL80211_MULTIPLE_BSSID_CONFIG_ATTR_LAST,
+ NL80211_MULTIPLE_BSSID_CONFIG_ATTR_MAX =
+ __NL80211_MULTIPLE_BSSID_CONFIG_ATTR_LAST - 1,
+};
+
+/**
+ * enum nl80211_multiple_bssid_elems_attributes - Attributes used to pass
+ * multiple BSSID elements data.
+ *
+ * @__NL80211_MULTIPLE_BSSID_ELEMS_ATTR_INVALID: Invalid
+ *
+ * @NL80211_MULTIPLE_BSSID_ELEMS_ATTR_COUNT: Number of multiple BSSID
+ * elements (u8).
+ *
+ * @NL80211_MULTIPLE_BSSID_ELEMS_ATTR_DATA: Array of multiple BSSID elements.
+ */
+enum nl80211_multiple_bssid_elems_attributes {
+ __NL80211_MULTIPLE_BSSID_ELEMS_ATTR_INVALID,
+
+ NL80211_MULTIPLE_BSSID_ELEMS_ATTR_COUNT,
+ NL80211_MULTIPLE_BSSID_ELEMS_ATTR_DATA,
+
+ __NL80211_MULTIPLE_BSSID_ELEMS_ATTR_LAST,
+ NL80211_MULTIPLE_BSSID_ELEMS_ATTR_MAX =
+ __NL80211_MULTIPLE_BSSID_ELEMS_ATTR_LAST - 1,
+};
+
#endif /* __LINUX_NL80211_H */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 521d36bb0803..9ff33fc3967d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -431,6 +431,20 @@ sar_policy[NL80211_SAR_ATTR_MAX + 1] = {
[NL80211_SAR_ATTR_SPECS] = NLA_POLICY_NESTED_ARRAY(sar_specs_policy),
};
+static const struct nla_policy
+nl80211_multiple_bssid_elems_policy[NL80211_MULTIPLE_BSSID_ELEMS_ATTR_MAX + 1] = {
+ [NL80211_MULTIPLE_BSSID_ELEMS_ATTR_COUNT] = { .type = NLA_U8 },
+ [NL80211_MULTIPLE_BSSID_ELEMS_ATTR_DATA] = { .type = NLA_NESTED },
+};
+
+static const struct nla_policy
+nl80211_multiple_bssid_policy[NL80211_MULTIPLE_BSSID_CONFIG_ATTR_MAX + 1] = {
+ [NL80211_MULTIPLE_BSSID_CONFIG_ATTR_PARENT] = { .type = NLA_U32 },
+ [NL80211_MULTIPLE_BSSID_CONFIG_ATTR_INDEX] = { .type = NLA_U8 },
+ [NL80211_MULTIPLE_BSSID_CONFIG_ATTR_COUNT] = { .type = NLA_U8 },
+ [NL80211_MULTIPLE_BSSID_CONFIG_ATTR_EMA] = { .type = NLA_FLAG },
+};
+
static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD },
[NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
@@ -753,6 +767,10 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT },
[NL80211_ATTR_SAR_SPEC] = NLA_POLICY_NESTED(sar_policy),
[NL80211_ATTR_DISABLE_HE] = { .type = NLA_FLAG },
+ [NL80211_ATTR_MULTIPLE_BSSID_CONFIG] =
+ NLA_POLICY_NESTED(nl80211_multiple_bssid_policy),
+ [NL80211_ATTR_MULTIPLE_BSSID_ELEMS] =
+ NLA_POLICY_NESTED(nl80211_multiple_bssid_elems_policy),
};
/* policy for the key attributes */
@@ -2192,6 +2210,49 @@ nl80211_put_sar_specs(struct cfg80211_registered_device *rdev,
return -ENOBUFS;
}
+static int
+nl80211_put_multiple_bssid_support(struct wiphy *wiphy, struct sk_buff *msg)
+{
+ struct nlattr *config = NULL, *elems = NULL;
+
+ if (!wiphy_ext_feature_isset(wiphy,
+ NL80211_EXT_FEATURE_MULTIPLE_BSSID_AP))
+ return 0;
+
+ if (wiphy->multiple_bssid.max_num_vaps) {
+ config = nla_nest_start(msg,
+ NL80211_ATTR_MULTIPLE_BSSID_CONFIG);
+ if (!config)
+ return -ENOSPC;
+
+ if (nla_put_u8(msg, NL80211_MULTIPLE_BSSID_CONFIG_ATTR_COUNT,
+ wiphy->multiple_bssid.max_num_vaps))
+ goto fail_config;
+
+ nla_nest_end(msg, config);
+ }
+
+ if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_EMA_AP) &&
+ wiphy->multiple_bssid.max_profile_periodicity) {
+ elems = nla_nest_start(msg, NL80211_ATTR_MULTIPLE_BSSID_ELEMS);
+ if (!elems)
+ goto fail_config;
+
+ if (nla_put_u8(msg, NL80211_MULTIPLE_BSSID_ELEMS_ATTR_COUNT,
+ wiphy->multiple_bssid.max_profile_periodicity))
+ goto fail_elems;
+
+ nla_nest_end(msg, elems);
+ }
+ return 0;
+
+fail_elems:
+ nla_nest_cancel(msg, elems);
+fail_config:
+ nla_nest_cancel(msg, config);
+ return -ENOBUFS;
+}
+
struct nl80211_dump_wiphy_state {
s64 filter_wiphy;
long start;
@@ -2774,6 +2835,9 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
if (nl80211_put_sar_specs(rdev, msg))
goto nla_put_failure;
+ if (nl80211_put_multiple_bssid_support(&rdev->wiphy, msg))
+ goto nla_put_failure;
+
/* done */
state->split_start = 0;
break;
@@ -4952,6 +5016,90 @@ static int validate_beacon_tx_rate(struct cfg80211_registered_device *rdev,
return 0;
}
+static int
+nl80211_parse_multiple_bssid_config(struct wiphy *wiphy,
+ struct nlattr *attrs,
+ struct cfg80211_ap_settings *params)
+{
+ struct nlattr *tb[NL80211_MULTIPLE_BSSID_CONFIG_ATTR_MAX + 1];
+ int ret;
+ struct cfg80211_multiple_bssid *config = ¶ms->multiple_bssid;
+
+ if (!wiphy_ext_feature_isset(wiphy,
+ NL80211_EXT_FEATURE_MULTIPLE_BSSID_AP))
+ return -EINVAL;
+
+ ret = nla_parse_nested(tb, NL80211_MULTIPLE_BSSID_CONFIG_ATTR_MAX, attrs, NULL,
+ NULL);
+ if (ret)
+ return ret;
+
+ config->ema = nla_get_flag(tb[NL80211_MULTIPLE_BSSID_CONFIG_ATTR_EMA]);
+ if (config->ema &&
+ (!wiphy_ext_feature_isset(wiphy,
+ NL80211_EXT_FEATURE_EMA_AP) ||
+ (wiphy->multiple_bssid.max_profile_periodicity &&
+ params->beacon.multiple_bssid->cnt >
+ wiphy->multiple_bssid.max_profile_periodicity)))
+ return -EINVAL;
+
+ if (!tb[NL80211_MULTIPLE_BSSID_CONFIG_ATTR_COUNT])
+ return -EINVAL;
+
+ config->count = nla_get_u8(tb[NL80211_MULTIPLE_BSSID_CONFIG_ATTR_COUNT]);
+ if (config->count < 1 ||
+ (wiphy->multiple_bssid.max_num_vaps &&
+ config->count > wiphy->multiple_bssid.max_num_vaps))
+ return -EINVAL;
+
+ if (tb[NL80211_MULTIPLE_BSSID_CONFIG_ATTR_PARENT])
+ config->parent = nla_get_u32(tb[NL80211_MULTIPLE_BSSID_CONFIG_ATTR_PARENT]);
+
+ if (tb[NL80211_MULTIPLE_BSSID_CONFIG_ATTR_INDEX])
+ config->index = nla_get_u8(tb[NL80211_MULTIPLE_BSSID_CONFIG_ATTR_INDEX]);
+
+ return 0;
+}
+
+static struct cfg80211_multiple_bssid_data *
+nl80211_parse_multiple_bssid_elems(struct wiphy *wiphy, struct nlattr *attrs)
+{
+ struct cfg80211_multiple_bssid_data *multiple_bssid;
+ struct nlattr *nl_ie;
+ struct nlattr *tb[NL80211_MULTIPLE_BSSID_ELEMS_ATTR_MAX + 1];
+ int rem_ie;
+ u8 i = 0, err, num_elems;
+
+ if (!wiphy_ext_feature_isset(wiphy,
+ NL80211_EXT_FEATURE_MULTIPLE_BSSID_AP))
+ return NULL;
+
+ err = nla_parse_nested(tb, NL80211_MULTIPLE_BSSID_ELEMS_ATTR_MAX,
+ attrs, NULL, NULL);
+ if (err)
+ return NULL;
+
+ if (!tb[NL80211_MULTIPLE_BSSID_ELEMS_ATTR_COUNT] ||
+ !tb[NL80211_MULTIPLE_BSSID_ELEMS_ATTR_DATA])
+ return NULL;
+
+ num_elems = nla_get_u8(tb[NL80211_MULTIPLE_BSSID_ELEMS_ATTR_COUNT]);
+ multiple_bssid = kzalloc(struct_size(multiple_bssid, elems, num_elems),
+ GFP_KERNEL);
+ if (!multiple_bssid)
+ return NULL;
+
+ multiple_bssid->cnt = num_elems;
+ nla_for_each_nested(nl_ie, tb[NL80211_MULTIPLE_BSSID_ELEMS_ATTR_DATA],
+ rem_ie) {
+ multiple_bssid->elems[i].data = nla_data(nl_ie);
+ multiple_bssid->elems[i].len = nla_len(nl_ie);
+ i++;
+ }
+
+ return multiple_bssid;
+}
+
static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
struct nlattr *attrs[],
struct cfg80211_beacon_data *bcn)
@@ -5032,6 +5180,14 @@ static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
bcn->ftm_responder = -1;
}
+ if (attrs[NL80211_ATTR_MULTIPLE_BSSID_ELEMS]) {
+ bcn->multiple_bssid = nl80211_parse_multiple_bssid_elems(
+ &rdev->wiphy,
+ attrs[NL80211_ATTR_MULTIPLE_BSSID_ELEMS]);
+ if (!bcn->multiple_bssid)
+ return -EINVAL;
+ }
+
return 0;
}
@@ -5317,7 +5473,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
err = nl80211_parse_beacon(rdev, info->attrs, ¶ms.beacon);
if (err)
- return err;
+ goto out;
params.beacon_interval =
nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
@@ -5327,7 +5483,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
err = cfg80211_validate_beacon_int(rdev, dev->ieee80211_ptr->iftype,
params.beacon_interval);
if (err)
- return err;
+ goto out;
/*
* In theory, some of these attributes should be required here
@@ -5340,8 +5496,10 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
params.ssid_len =
nla_len(info->attrs[NL80211_ATTR_SSID]);
- if (params.ssid_len == 0)
- return -EINVAL;
+ if (params.ssid_len == 0) {
+ err = -EINVAL;
+ goto out;
+ }
}
if (info->attrs[NL80211_ATTR_HIDDEN_SSID])
@@ -5354,57 +5512,74 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
params.auth_type = nla_get_u32(
info->attrs[NL80211_ATTR_AUTH_TYPE]);
if (!nl80211_valid_auth_type(rdev, params.auth_type,
- NL80211_CMD_START_AP))
- return -EINVAL;
+ NL80211_CMD_START_AP)) {
+ err = -EINVAL;
+ goto out;
+ }
} else
params.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
err = nl80211_crypto_settings(rdev, info, ¶ms.crypto,
NL80211_MAX_NR_CIPHER_SUITES);
if (err)
- return err;
+ goto out;
if (info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]) {
- if (!(rdev->wiphy.features & NL80211_FEATURE_INACTIVITY_TIMER))
- return -EOPNOTSUPP;
+ if (!(rdev->wiphy.features &
+ NL80211_FEATURE_INACTIVITY_TIMER)) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
params.inactivity_timeout = nla_get_u16(
info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]);
}
if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
- if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
- return -EINVAL;
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
+ err = -EINVAL;
+ goto out;
+ }
params.p2p_ctwindow =
nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
if (params.p2p_ctwindow != 0 &&
- !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
- return -EINVAL;
+ !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN)) {
+ err = -EINVAL;
+ goto out;
+ }
}
if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
u8 tmp;
- if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
- return -EINVAL;
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
+ err = -EINVAL;
+ goto out;
+ }
tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
params.p2p_opp_ps = tmp;
if (params.p2p_opp_ps != 0 &&
- !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
- return -EINVAL;
+ !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS)) {
+ err = -EINVAL;
+ goto out;
+ }
}
if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
err = nl80211_parse_chandef(rdev, info, ¶ms.chandef);
if (err)
- return err;
+ goto out;
} else if (wdev->preset_chandef.chan) {
params.chandef = wdev->preset_chandef;
- } else if (!nl80211_get_ap_channel(rdev, ¶ms))
- return -EINVAL;
+ } else if (!nl80211_get_ap_channel(rdev, ¶ms)) {
+ err = -EINVAL;
+ goto out;
+ }
if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, ¶ms.chandef,
- wdev->iftype))
- return -EINVAL;
+ wdev->iftype)) {
+ err = -EINVAL;
+ goto out;
+ }
if (info->attrs[NL80211_ATTR_TX_RATES]) {
err = nl80211_parse_tx_bitrate_mask(info, info->attrs,
@@ -5412,12 +5587,12 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
¶ms.beacon_rate,
dev, false);
if (err)
- return err;
+ goto out;
err = validate_beacon_tx_rate(rdev, params.chandef.chan->band,
¶ms.beacon_rate);
if (err)
- return err;
+ goto out;
}
if (info->attrs[NL80211_ATTR_SMPS_MODE]) {
@@ -5428,29 +5603,38 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
break;
case NL80211_SMPS_STATIC:
if (!(rdev->wiphy.features &
- NL80211_FEATURE_STATIC_SMPS))
- return -EINVAL;
+ NL80211_FEATURE_STATIC_SMPS)) {
+ err = -EINVAL;
+ goto out;
+ }
break;
case NL80211_SMPS_DYNAMIC:
if (!(rdev->wiphy.features &
- NL80211_FEATURE_DYNAMIC_SMPS))
- return -EINVAL;
+ NL80211_FEATURE_DYNAMIC_SMPS)) {
+ err = -EINVAL;
+ goto out;
+ }
break;
default:
- return -EINVAL;
+ err = -EINVAL;
+ goto out;
}
} else {
params.smps_mode = NL80211_SMPS_OFF;
}
params.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
- if (params.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ])
- return -EOPNOTSUPP;
+ if (params.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ]) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
if (info->attrs[NL80211_ATTR_ACL_POLICY]) {
params.acl = parse_acl_data(&rdev->wiphy, info);
- if (IS_ERR(params.acl))
- return PTR_ERR(params.acl);
+ if (IS_ERR(params.acl)) {
+ err = PTR_ERR(params.acl);
+ goto out;
+ }
}
params.twt_responder =
@@ -5485,7 +5669,16 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
rdev, info->attrs[NL80211_ATTR_UNSOL_BCAST_PROBE_RESP],
¶ms);
if (err)
- return err;
+ goto out;
+ }
+
+ if (info->attrs[NL80211_ATTR_MULTIPLE_BSSID_CONFIG]) {
+ err = nl80211_parse_multiple_bssid_config(
+ &rdev->wiphy,
+ info->attrs[NL80211_ATTR_MULTIPLE_BSSID_CONFIG],
+ ¶ms);
+ if (err)
+ goto out;
}
nl80211_calculate_ap_params(¶ms);
@@ -5508,8 +5701,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
wdev_unlock(wdev);
out:
- kfree(params.acl);
-
+ if (!IS_ERR(params.acl))
+ kfree(params.acl);
+ kfree(params.beacon.multiple_bssid);
return err;
}
@@ -5533,12 +5727,14 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
err = nl80211_parse_beacon(rdev, info->attrs, ¶ms);
if (err)
- return err;
+ goto out;
wdev_lock(wdev);
err = rdev_change_beacon(rdev, dev, ¶ms);
wdev_unlock(wdev);
+out:
+ kfree(params.multiple_bssid);
return err;
}
@@ -9218,12 +9414,14 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
err = nl80211_parse_beacon(rdev, info->attrs, ¶ms.beacon_after);
if (err)
- return err;
+ goto free;
csa_attrs = kcalloc(NL80211_ATTR_MAX + 1, sizeof(*csa_attrs),
GFP_KERNEL);
- if (!csa_attrs)
- return -ENOMEM;
+ if (!csa_attrs) {
+ err = -ENOMEM;
+ goto free;
+ }
err = nla_parse_nested_deprecated(csa_attrs, NL80211_ATTR_MAX,
info->attrs[NL80211_ATTR_CSA_IES],
@@ -9341,6 +9539,8 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
wdev_unlock(wdev);
free:
+ kfree(params.beacon_after.multiple_bssid);
+ kfree(params.beacon_csa.multiple_bssid);
kfree(csa_attrs);
return err;
}
--
2.25.0
next prev parent reply other threads:[~2021-03-10 18:27 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-10 18:26 [PATCH v9 0/4] Multiple BSSID support Aloka Dixit
2021-03-10 18:26 ` Aloka Dixit [this message]
2021-04-08 12:05 ` [PATCH v9 1/4] nl80211: add basic multiple bssid support Johannes Berg
2021-04-08 17:09 ` Aloka Dixit
2021-03-10 18:26 ` [PATCH v9 2/4] mac80211: add multiple bssid support to interface handling Aloka Dixit
2021-04-08 12:06 ` Johannes Berg
2021-04-16 21:35 ` Aloka Dixit
2021-04-19 11:28 ` Johannes Berg
2021-04-19 22:35 ` Aloka Dixit
2021-04-19 22:42 ` Aloka Dixit
2021-04-20 8:25 ` Johannes Berg
2021-03-10 18:26 ` [PATCH v9 3/4] mac80211: add multiple bssid/EMA support to beacon handling Aloka Dixit
2021-04-08 12:11 ` Johannes Berg
2021-04-08 17:16 ` Aloka Dixit
2021-03-10 18:26 ` [PATCH v9 4/4] mac80211: CSA on non-transmitting interfaces Aloka Dixit
2021-04-08 11:53 ` [PATCH v9 0/4] Multiple BSSID support Johannes Berg
2021-04-09 18:05 ` Aloka Dixit
2021-04-08 12:17 ` Johannes Berg
2021-04-09 18:31 ` Aloka Dixit
2021-04-09 19:28 ` Johannes Berg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210310182604.8858-2-alokad@codeaurora.org \
--to=alokad@codeaurora.org \
--cc=dan.carpenter@oracle.com \
--cc=johannes@sipsolutions.net \
--cc=john@phrozen.org \
--cc=linux-wireless@vger.kernel.org \
--cc=lkp@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.