wifi: cfg80211: Support association to AP MLD with disabled links
authorIlan Peer <ilan.peer@intel.com>
Thu, 8 Jun 2023 13:36:10 +0000 (16:36 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 14 Jun 2023 10:21:17 +0000 (12:21 +0200)
An AP part of an AP MLD might be temporarily disabled, and might be
enabled later. Such a link should be included in the association
exchange, but should not be used until enabled.

Extend the NL80211_CMD_ASSOCIATE to also indicate disabled links.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230608163202.c4c61ee4c4a5.I784ef4a0d619fc9120514b5615458fbef3b3684a@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/cfg80211.h
include/uapi/linux/nl80211.h
net/wireless/nl80211.c

index 5d04e7e..388f2a3 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
  * Copyright 2013-2014 Intel Mobile Communications GmbH
  * Copyright 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2021 Intel Corporation
+ * Copyright (C) 2018-2021, 2023 Intel Corporation
  */
 
 #include <linux/ethtool.h>
@@ -2882,11 +2882,14 @@ struct cfg80211_auth_request {
  *     if this is %NULL for a link, that link is not requested
  * @elems: extra elements for the per-STA profile for this link
  * @elems_len: length of the elements
+ * @disabled: If set this link should be included during association etc. but it
+ *     should not be used until enabled by the AP MLD.
  */
 struct cfg80211_assoc_link {
        struct cfg80211_bss *bss;
        const u8 *elems;
        size_t elems_len;
+       bool disabled;
 };
 
 /**
index 435c4ac..03939bd 100644 (file)
@@ -11,7 +11,7 @@
  * Copyright 2008 Jouni Malinen <jouni.malinen@atheros.com>
  * Copyright 2008 Colin McCabe <colin@cozybit.com>
  * Copyright 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2022 Intel Corporation
+ * Copyright (C) 2018-2023 Intel Corporation
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -2805,6 +2805,9 @@ enum nl80211_commands {
  *     index. If the userspace includes more RNR elements than number of
  *     MBSSID elements then these will be added in every EMA beacon.
  *
+ * @NL80211_ATTR_MLO_LINK_DISABLED: Flag attribute indicating that the link is
+ *     disabled.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3341,6 +3344,8 @@ enum nl80211_attrs {
 
        NL80211_ATTR_EMA_RNR_ELEMS,
 
+       NL80211_ATTR_MLO_LINK_DISABLED,
+
        /* add attributes here, update the policy in nl80211.c */
 
        __NL80211_ATTR_AFTER_LAST,
index f962765..ec7d467 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
  * Copyright 2013-2014  Intel Mobile Communications GmbH
  * Copyright 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2022 Intel Corporation
+ * Copyright (C) 2018-2023 Intel Corporation
  */
 
 #include <linux/if.h>
@@ -816,6 +816,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
        [NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS] = { .type = NLA_U16 },
        [NL80211_ATTR_HW_TIMESTAMP_ENABLED] = { .type = NLA_FLAG },
        [NL80211_ATTR_EMA_RNR_ELEMS] = { .type = NLA_NESTED },
+       [NL80211_ATTR_MLO_LINK_DISABLED] = { .type = NLA_FLAG },
 };
 
 /* policy for the key attributes */
@@ -11138,6 +11139,9 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
                                        goto free;
                                }
                        }
+
+                       req.links[link_id].disabled =
+                               nla_get_flag(attrs[NL80211_ATTR_MLO_LINK_DISABLED]);
                }
 
                if (!req.links[req.link_id].bss) {
@@ -11152,6 +11156,13 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
                        goto free;
                }
 
+               if (req.links[req.link_id].disabled) {
+                       GENL_SET_ERR_MSG(info,
+                                        "cannot have assoc link disabled");
+                       err = -EINVAL;
+                       goto free;
+               }
+
                kfree(attrs);
                attrs = NULL;
        } else {