@@ -1286,11 +1286,14 @@ struct cfg80211_crypto_settings {
* struct cfg80211_mbssid_config - AP settings for multi bssid
*
* @tx_wdev: pointer to the transmitted interface in the MBSSID set
+ * @tx_link_id: link ID of the transmitted interface if it is part of an MLD.
+ * If transmitted interface is not part of an MLD, link ID is set to -1.
* @index: index of this AP in the multi bssid group.
* @ema: set to true if the beacons should be sent out in EMA mode.
*/
struct cfg80211_mbssid_config {
struct wireless_dev *tx_wdev;
+ int tx_link_id;
u8 index;
bool ema;
};
@@ -7987,6 +7987,12 @@ enum nl80211_sar_specs_attrs {
* Setting this flag is permitted only if the driver advertises EMA support
* by setting wiphy->ema_max_profile_periodicity to non-zero.
*
+ * @NL80211_MBSSID_CONFIG_ATTR_TX_LINK_ID: Parameter for a non-transmitted
+ * profile which provides the link ID (u8) of the transmitted profile when
+ * the latter is part of an MLD. This is a mandatory parameter for a
+ * non-transmitted profile. If transmitted profile is not part of an MLD,
+ * link_id will be set to -1.
+ *
* @__NL80211_MBSSID_CONFIG_ATTR_LAST: Internal
* @NL80211_MBSSID_CONFIG_ATTR_MAX: highest attribute
*/
@@ -7998,6 +8004,7 @@ enum nl80211_mbssid_config_attributes {
NL80211_MBSSID_CONFIG_ATTR_INDEX,
NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX,
NL80211_MBSSID_CONFIG_ATTR_EMA,
+ NL80211_MBSSID_CONFIG_ATTR_TX_LINK_ID,
/* keep last */
__NL80211_MBSSID_CONFIG_ATTR_LAST,
@@ -454,6 +454,8 @@ nl80211_mbssid_config_policy[NL80211_MBSSID_CONFIG_ATTR_MAX + 1] = {
[NL80211_MBSSID_CONFIG_ATTR_INDEX] = { .type = NLA_U8 },
[NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX] = { .type = NLA_U32 },
[NL80211_MBSSID_CONFIG_ATTR_EMA] = { .type = NLA_FLAG },
+ [NL80211_MBSSID_CONFIG_ATTR_TX_LINK_ID] =
+ NLA_POLICY_MAX(NLA_U8, IEEE80211_MLD_MAX_NUM_LINKS),
};
static const struct nla_policy
@@ -5477,6 +5479,7 @@ static int nl80211_parse_mbssid_config(struct wiphy *wiphy,
u8 num_elems)
{
struct nlattr *tb[NL80211_MBSSID_CONFIG_ATTR_MAX + 1];
+ int err;
if (!wiphy->mbssid_max_interfaces)
return -EOPNOTSUPP;
@@ -5509,18 +5512,14 @@ static int nl80211_parse_mbssid_config(struct wiphy *wiphy,
return -EINVAL;
if (tx_ifindex != dev->ifindex) {
- struct net_device *tx_netdev =
- dev_get_by_index(wiphy_net(wiphy), tx_ifindex);
-
- if (!tx_netdev || !tx_netdev->ieee80211_ptr ||
- tx_netdev->ieee80211_ptr->wiphy != wiphy ||
- tx_netdev->ieee80211_ptr->iftype !=
- NL80211_IFTYPE_AP) {
- dev_put(tx_netdev);
- return -EINVAL;
+ config->tx_wdev =
+ dev_get_by_index(wiphy_net(wiphy), tx_ifindex)->ieee80211_ptr;
+ if (!config->tx_wdev ||
+ config->tx_wdev->wiphy != wiphy ||
+ config->tx_wdev->iftype != NL80211_IFTYPE_AP) {
+ err = -EINVAL;
+ goto out;
}
-
- config->tx_wdev = tx_netdev->ieee80211_ptr;
} else {
config->tx_wdev = dev->ieee80211_ptr;
}
@@ -5530,7 +5529,29 @@ static int nl80211_parse_mbssid_config(struct wiphy *wiphy,
return -EINVAL;
}
+ config->tx_link_id = 0;
+ if (config->tx_wdev->valid_links) {
+ if (!tb[NL80211_MBSSID_CONFIG_ATTR_TX_LINK_ID])
+ goto out;
+
+ config->tx_link_id =
+ nla_get_u8(tb[NL80211_MBSSID_CONFIG_ATTR_TX_LINK_ID]);
+ if (!(config->tx_wdev->valid_links & BIT(config->tx_link_id))) {
+ err = -ENOLINK;
+ goto out;
+ }
+ } else if (tb[NL80211_MBSSID_CONFIG_ATTR_TX_LINK_ID]) {
+ goto out;
+ }
+
return 0;
+
+out:
+ if (config->tx_wdev && config->tx_wdev->netdev &&
+ config->tx_wdev->netdev != dev)
+ dev_put(config->tx_wdev->netdev);
+
+ return err;
}
static struct cfg80211_mbssid_elems *