History

cfg80211: support RNR for EMA AP

As per IEEE Std 802.11ax-2021, 11.1.3.8.3 Discovery of a nontransmitted BSSID profile, an EMA AP that transmits a Beacon frame carrying a partial list of nontransmitted BSSID profiles should include in the frame a Reduced Neighbor Report element carrying information for at least the nontransmitted BSSIDs that are not present in the Multiple BSSID element carried in that frame. Add new nested attribute NL80211_ATTR_EMA_RNR_ELEMS to support the above. Number of RNR elements must be more than or equal to the number of MBSSID elements. This attribute can be used only when EMA is enabled. Userspace is responsible for splitting the RNR into multiple elements such that each element excludes the non-transmitting profiles already included in the MBSSID element (%NL80211_ATTR_MBSSID_ELEMS) at the same index. Each EMA beacon will be generated by adding MBSSID and RNR elements at the same index. If the userspace provides more RNR elements than the number of MBSSID elements then these will be added in every EMA beacon.

Aloka Dixit committed 3 years ago

Commit dbbb27e1 parent f1024243 files · +104 −7Browse files

Unified · Split

3 files
  1. include/net/cfg80211.h +19 −0
  2. include/uapi/linux/nl80211.h +13 −0
  3. net/wireless/nl80211.c +72 −7
include/net/cfg80211.h+19−0
@@ -1178,6 +1178,23 @@ struct cfg80211_mbssid_elems { · 1177 unmodified lines
11781178 } elem[];
11791179 };
11801180
1181+/**
1182+ * struct cfg80211_rnr_elems - Reduced neighbor report (RNR) elements
1183+ *
1184+ * @cnt: Number of elements in array %elems.
1185+ *
1186+ * @elem: Array of RNR element(s) to be added into Beacon frames.
1187+ * @elem.data: Data for RNR elements.
1188+ * @elem.len: Length of data.
1189+ */
1190+struct cfg80211_rnr_elems {
1191+ u8 cnt;
1192+ struct {
1193+ const u8 *data;
1194+ size_t len;
1195+ } elem[];
1196+};
1197+
11811198 /**
11821199 * struct cfg80211_beacon_data - beacon data
11831200 * @link_id: the link ID for the AP MLD link sending this beacon
@@ -1198,6 +1215,7 @@ struct cfg80211_mbssid_elems { · 14 unmodified lines
11981215 * @probe_resp_len: length of probe response template (@probe_resp)
11991216 * @probe_resp: probe response template (AP mode only)
12001217 * @mbssid_ies: multiple BSSID elements
1218+ * @rnr_ies: reduced neighbor report elements
12011219 * @ftm_responder: enable FTM responder functionality; -1 for no change
12021220 * (which also implies no change in LCI/civic location data)
12031221 * @lci: Measurement Report element content, starting with Measurement Token
@@ -1221,6 +1239,7 @@ struct cfg80211_beacon_data { · 17 unmodified lines
12211239 const u8 *lci;
12221240 const u8 *civicloc;
12231241 struct cfg80211_mbssid_elems *mbssid_ies;
1242+ struct cfg80211_rnr_elems *rnr_ies;
12241243 s8 ftm_responder;
12251244
12261245 size_t head_len, tail_len;
include/uapi/linux/nl80211.h+13−0
@@ -2794,6 +2794,17 @@ enum nl80211_commands { · 2793 unmodified lines
27942794 * @NL80211_ATTR_HW_TIMESTAMP_ENABLED: Indicates whether HW timestamping should
27952795 * be enabled or not (flag attribute).
27962796 *
2797+ * @NL80211_ATTR_EMA_RNR_ELEMS: Optional nested attribute for
2798+ * reduced neighbor report (RNR) elements. This attribute can be used
2799+ * only when NL80211_MBSSID_CONFIG_ATTR_EMA is enabled.
2800+ * Userspace is responsible for splitting the RNR into multiple
2801+ * elements such that each element excludes the non-transmitting
2802+ * profiles already included in the MBSSID element
2803+ * (%NL80211_ATTR_MBSSID_ELEMS) at the same index. Each EMA beacon
2804+ * will be generated by adding MBSSID and RNR elements at the same
2805+ * index. If the userspace includes more RNR elements than number of
2806+ * MBSSID elements then these will be added in every EMA beacon.
2807+ *
27972808 * @NUM_NL80211_ATTR: total number of nl80211_attrs available
27982809 * @NL80211_ATTR_MAX: highest attribute number currently defined
27992810 * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3328,6 +3339,8 @@ enum nl80211_attrs { · 528 unmodified lines
33283339 NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS,
33293340 NL80211_ATTR_HW_TIMESTAMP_ENABLED,
33303341
3342+ NL80211_ATTR_EMA_RNR_ELEMS,
3343+
33313344 /* add attributes here, update the policy in nl80211.c */
33323345
33333346 __NL80211_ATTR_AFTER_LAST,
net/wireless/nl80211.c+72−7
@@ -809,6 +809,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { · 808 unmodified lines
809809
810810 [NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS] = { .type = NLA_U16 },
811811 [NL80211_ATTR_HW_TIMESTAMP_ENABLED] = { .type = NLA_FLAG },
812+ [NL80211_ATTR_EMA_RNR_ELEMS] = { .type = NLA_NESTED },
812813 };
813814
814815 /* policy for the key attributes */
@@ -5425,6 +5426,38 @@ nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs) · 4610 unmodified lines
54255426 return elems;
54265427 }
54275428
5429+static struct cfg80211_rnr_elems *
5430+nl80211_parse_rnr_elems(struct wiphy *wiphy, struct nlattr *attrs,
5431+ struct netlink_ext_ack *extack)
5432+{
5433+ struct nlattr *nl_elems;
5434+ struct cfg80211_rnr_elems *elems;
5435+ int rem_elems;
5436+ u8 i = 0, num_elems = 0;
5437+
5438+ nla_for_each_nested(nl_elems, attrs, rem_elems) {
5439+ int ret;
5440+
5441+ ret = validate_ie_attr(nl_elems, extack);
5442+ if (ret)
5443+ return ERR_PTR(ret);
5444+
5445+ num_elems++;
5446+ }
5447+
5448+ elems = kzalloc(struct_size(elems, elem, num_elems), GFP_KERNEL);
5449+ if (!elems)
5450+ return ERR_PTR(-ENOMEM);
5451+
5452+ nla_for_each_nested(nl_elems, attrs, rem_elems) {
5453+ elems->elem[i].data = nla_data(nl_elems);
5454+ elems->elem[i].len = nla_len(nl_elems);
5455+ i++;
5456+ }
5457+ elems->cnt = num_elems;
5458+ return elems;
5459+}
5460+
54285461 static int nl80211_parse_he_bss_color(struct nlattr *attrs,
54295462 struct cfg80211_he_bss_color *he_bss_color)
54305463 {
@@ -5451,7 +5484,8 @@ static int nl80211_parse_he_bss_color(struct nlattr *attrs, · 20 unmodified lines
54515484
54525485 static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
54535486 struct nlattr *attrs[],
5454− struct cfg80211_beacon_data *bcn)
5487+ struct cfg80211_beacon_data *bcn,
5488+ struct netlink_ext_ack *extack)
54555489 {
54565490 bool haveinfo = false;
54575491 int err;
@@ -5548,6 +5582,21 @@ static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev, · 90 unmodified lines
55485582 return PTR_ERR(mbssid);
55495583
55505584 bcn->mbssid_ies = mbssid;
5585+
5586+ if (bcn->mbssid_ies && attrs[NL80211_ATTR_EMA_RNR_ELEMS]) {
5587+ struct cfg80211_rnr_elems *rnr =
5588+ nl80211_parse_rnr_elems(&rdev->wiphy,
5589+ attrs[NL80211_ATTR_EMA_RNR_ELEMS],
5590+ extack);
5591+
5592+ if (IS_ERR(rnr))
5593+ return PTR_ERR(rnr);
5594+
5595+ if (rnr && rnr->cnt < bcn->mbssid_ies->cnt)
5596+ return -EINVAL;
5597+
5598+ bcn->rnr_ies = rnr;
5599+ }
55515600 }
55525601
55535602 return 0;
@@ -5866,7 +5915,8 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) · 312 unmodified lines
58665915 if (!params)
58675916 return -ENOMEM;
58685917
5869− err = nl80211_parse_beacon(rdev, info->attrs, &params->beacon);
5918+ err = nl80211_parse_beacon(rdev, info->attrs, &params->beacon,
5919+ info->extack);
58705920 if (err)
58715921 goto out;
58725922
@@ -6096,6 +6146,11 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) · 223 unmodified lines
60966146 goto out_unlock;
60976147 }
60986148
6149+ if (!params->mbssid_config.ema && params->beacon.rnr_ies) {
6150+ err = -EINVAL;
6151+ goto out_unlock;
6152+ }
6153+
60996154 err = nl80211_calculate_ap_params(params);
61006155 if (err)
61016156 goto out_unlock;
@@ -6137,6 +6192,7 @@ out: · 35 unmodified lines
61376192 params->mbssid_config.tx_wdev->netdev &&
61386193 params->mbssid_config.tx_wdev->netdev != dev)
61396194 dev_put(params->mbssid_config.tx_wdev->netdev);
6195+ kfree(params->beacon.rnr_ies);
61406196 kfree(params);
61416197
61426198 return err;
@@ -6161,7 +6217,7 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info) · 18 unmodified lines
61616217 if (!wdev->links[link_id].ap.beacon_interval)
61626218 return -EINVAL;
61636219
6164− err = nl80211_parse_beacon(rdev, info->attrs, &params);
6220+ err = nl80211_parse_beacon(rdev, info->attrs, &params, info->extack);
61656221 if (err)
61666222 goto out;
61676223
@@ -6171,6 +6227,7 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info) · 3 unmodified lines
61716227
61726228 out:
61736229 kfree(params.mbssid_ies);
6230+ kfree(params.rnr_ies);
61746231 return err;
61756232 }
61766233
@@ -10030,7 +10087,8 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) · 3853 unmodified lines
1003010087 if (!need_new_beacon)
1003110088 goto skip_beacons;
1003210089
10033− err = nl80211_parse_beacon(rdev, info->attrs, &params.beacon_after);
10090+ err = nl80211_parse_beacon(rdev, info->attrs, &params.beacon_after,
10091+ info->extack);
1003410092 if (err)
1003510093 goto free;
1003610094
@@ -10047,7 +10105,8 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) · 10 unmodified lines
1004710105 if (err)
1004810106 goto free;
1004910107
10050− err = nl80211_parse_beacon(rdev, csa_attrs, &params.beacon_csa);
10108+ err = nl80211_parse_beacon(rdev, csa_attrs, &params.beacon_csa,
10109+ info->extack);
1005110110 if (err)
1005210111 goto free;
1005310112
@@ -10167,6 +10226,8 @@ skip_beacons: · 113 unmodified lines
1016710226 free:
1016810227 kfree(params.beacon_after.mbssid_ies);
1016910228 kfree(params.beacon_csa.mbssid_ies);
10229+ kfree(params.beacon_after.rnr_ies);
10230+ kfree(params.beacon_csa.rnr_ies);
1017010231 kfree(csa_attrs);
1017110232 return err;
1017210233 }
@@ -15882,7 +15943,8 @@ static int nl80211_color_change(struct sk_buff *skb, struct genl_info *info) · 5709 unmodified lines
1588215943 params.count = nla_get_u8(info->attrs[NL80211_ATTR_COLOR_CHANGE_COUNT]);
1588315944 params.color = nla_get_u8(info->attrs[NL80211_ATTR_COLOR_CHANGE_COLOR]);
1588415945
15885− err = nl80211_parse_beacon(rdev, info->attrs, &params.beacon_next);
15946+ err = nl80211_parse_beacon(rdev, info->attrs, &params.beacon_next,
15947+ info->extack);
1588615948 if (err)
1588715949 return err;
1588815950
@@ -15896,7 +15958,8 @@ static int nl80211_color_change(struct sk_buff *skb, struct genl_info *info) · 7 unmodified lines
1589615958 if (err)
1589715959 goto out;
1589815960
15899− err = nl80211_parse_beacon(rdev, tb, &params.beacon_color_change);
15961+ err = nl80211_parse_beacon(rdev, tb, &params.beacon_color_change,
15962+ info->extack);
1590015963 if (err)
1590115964 goto out;
1590215965
@@ -15952,6 +16015,8 @@ static int nl80211_color_change(struct sk_buff *skb, struct genl_info *info) · 49 unmodified lines
1595216015 out:
1595316016 kfree(params.beacon_next.mbssid_ies);
1595416017 kfree(params.beacon_color_change.mbssid_ies);
16018+ kfree(params.beacon_next.rnr_ies);
16019+ kfree(params.beacon_color_change.rnr_ies);
1595516020 kfree(tb);
1595616021 return err;
1595716022 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t