| @@ -809,6 +809,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { · 808 unmodified lines |
| 809 | | 809 | |
| 810 | [NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS] = { .type = NLA_U16 }, | 810 | [NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS] = { .type = NLA_U16 }, |
| 811 | [NL80211_ATTR_HW_TIMESTAMP_ENABLED] = { .type = NLA_FLAG }, | 811 | [NL80211_ATTR_HW_TIMESTAMP_ENABLED] = { .type = NLA_FLAG }, |
| | 812 | [NL80211_ATTR_EMA_RNR_ELEMS] = { .type = NLA_NESTED }, |
| 812 | }; | 813 | }; |
| 813 | | 814 | |
| 814 | /* policy for the key attributes */ | 815 | /* policy for the key attributes */ |
| @@ -5425,6 +5426,38 @@ nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs) · 4610 unmodified lines |
| 5425 | return elems; | 5426 | return elems; |
| 5426 | } | 5427 | } |
| 5427 | | 5428 | |
| | 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 | |
| 5428 | static int nl80211_parse_he_bss_color(struct nlattr *attrs, | 5461 | static int nl80211_parse_he_bss_color(struct nlattr *attrs, |
| 5429 | struct cfg80211_he_bss_color *he_bss_color) | 5462 | struct cfg80211_he_bss_color *he_bss_color) |
| 5430 | { | 5463 | { |
| @@ -5451,7 +5484,8 @@ static int nl80211_parse_he_bss_color(struct nlattr *attrs, · 20 unmodified lines |
| 5451 | | 5484 | |
| 5452 | static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev, | 5485 | static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev, |
| 5453 | struct nlattr *attrs[], | 5486 | struct nlattr *attrs[], |
| 5454 | struct cfg80211_beacon_data *bcn) | 5487 | struct cfg80211_beacon_data *bcn, |
| | 5488 | struct netlink_ext_ack *extack) |
| 5455 | { | 5489 | { |
| 5456 | bool haveinfo = false; | 5490 | bool haveinfo = false; |
| 5457 | int err; | 5491 | int err; |
| @@ -5548,6 +5582,21 @@ static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev, · 90 unmodified lines |
| 5548 | return PTR_ERR(mbssid); | 5582 | return PTR_ERR(mbssid); |
| 5549 | | 5583 | |
| 5550 | bcn->mbssid_ies = mbssid; | 5584 | 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 | } |
| 5551 | } | 5600 | } |
| 5552 | | 5601 | |
| 5553 | return 0; | 5602 | return 0; |
| @@ -5866,7 +5915,8 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) · 312 unmodified lines |
| 5866 | if (!params) | 5915 | if (!params) |
| 5867 | return -ENOMEM; | 5916 | return -ENOMEM; |
| 5868 | | 5917 | |
| 5869 | err = nl80211_parse_beacon(rdev, info->attrs, ¶ms->beacon); | 5918 | err = nl80211_parse_beacon(rdev, info->attrs, ¶ms->beacon, |
| | 5919 | info->extack); |
| 5870 | if (err) | 5920 | if (err) |
| 5871 | goto out; | 5921 | goto out; |
| 5872 | | 5922 | |
| @@ -6096,6 +6146,11 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) · 223 unmodified lines |
| 6096 | goto out_unlock; | 6146 | goto out_unlock; |
| 6097 | } | 6147 | } |
| 6098 | | 6148 | |
| | 6149 | if (!params->mbssid_config.ema && params->beacon.rnr_ies) { |
| | 6150 | err = -EINVAL; |
| | 6151 | goto out_unlock; |
| | 6152 | } |
| | 6153 | |
| 6099 | err = nl80211_calculate_ap_params(params); | 6154 | err = nl80211_calculate_ap_params(params); |
| 6100 | if (err) | 6155 | if (err) |
| 6101 | goto out_unlock; | 6156 | goto out_unlock; |
| @@ -6137,6 +6192,7 @@ out: · 35 unmodified lines |
| 6137 | params->mbssid_config.tx_wdev->netdev && | 6192 | params->mbssid_config.tx_wdev->netdev && |
| 6138 | params->mbssid_config.tx_wdev->netdev != dev) | 6193 | params->mbssid_config.tx_wdev->netdev != dev) |
| 6139 | dev_put(params->mbssid_config.tx_wdev->netdev); | 6194 | dev_put(params->mbssid_config.tx_wdev->netdev); |
| | 6195 | kfree(params->beacon.rnr_ies); |
| 6140 | kfree(params); | 6196 | kfree(params); |
| 6141 | | 6197 | |
| 6142 | return err; | 6198 | return err; |
| @@ -6161,7 +6217,7 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info) · 18 unmodified lines |
| 6161 | if (!wdev->links[link_id].ap.beacon_interval) | 6217 | if (!wdev->links[link_id].ap.beacon_interval) |
| 6162 | return -EINVAL; | 6218 | return -EINVAL; |
| 6163 | | 6219 | |
| 6164 | err = nl80211_parse_beacon(rdev, info->attrs, ¶ms); | 6220 | err = nl80211_parse_beacon(rdev, info->attrs, ¶ms, info->extack); |
| 6165 | if (err) | 6221 | if (err) |
| 6166 | goto out; | 6222 | goto out; |
| 6167 | | 6223 | |
| @@ -6171,6 +6227,7 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info) · 3 unmodified lines |
| 6171 | | 6227 | |
| 6172 | out: | 6228 | out: |
| 6173 | kfree(params.mbssid_ies); | 6229 | kfree(params.mbssid_ies); |
| | 6230 | kfree(params.rnr_ies); |
| 6174 | return err; | 6231 | return err; |
| 6175 | } | 6232 | } |
| 6176 | | 6233 | |
| @@ -10030,7 +10087,8 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) · 3853 unmodified lines |
| 10030 | if (!need_new_beacon) | 10087 | if (!need_new_beacon) |
| 10031 | goto skip_beacons; | 10088 | goto skip_beacons; |
| 10032 | | 10089 | |
| 10033 | err = nl80211_parse_beacon(rdev, info->attrs, ¶ms.beacon_after); | 10090 | err = nl80211_parse_beacon(rdev, info->attrs, ¶ms.beacon_after, |
| | 10091 | info->extack); |
| 10034 | if (err) | 10092 | if (err) |
| 10035 | goto free; | 10093 | goto free; |
| 10036 | | 10094 | |
| @@ -10047,7 +10105,8 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) · 10 unmodified lines |
| 10047 | if (err) | 10105 | if (err) |
| 10048 | goto free; | 10106 | goto free; |
| 10049 | | 10107 | |
| 10050 | err = nl80211_parse_beacon(rdev, csa_attrs, ¶ms.beacon_csa); | 10108 | err = nl80211_parse_beacon(rdev, csa_attrs, ¶ms.beacon_csa, |
| | 10109 | info->extack); |
| 10051 | if (err) | 10110 | if (err) |
| 10052 | goto free; | 10111 | goto free; |
| 10053 | | 10112 | |
| @@ -10167,6 +10226,8 @@ skip_beacons: · 113 unmodified lines |
| 10167 | free: | 10226 | free: |
| 10168 | kfree(params.beacon_after.mbssid_ies); | 10227 | kfree(params.beacon_after.mbssid_ies); |
| 10169 | kfree(params.beacon_csa.mbssid_ies); | 10228 | kfree(params.beacon_csa.mbssid_ies); |
| | 10229 | kfree(params.beacon_after.rnr_ies); |
| | 10230 | kfree(params.beacon_csa.rnr_ies); |
| 10170 | kfree(csa_attrs); | 10231 | kfree(csa_attrs); |
| 10171 | return err; | 10232 | return err; |
| 10172 | } | 10233 | } |
| @@ -15882,7 +15943,8 @@ static int nl80211_color_change(struct sk_buff *skb, struct genl_info *info) · 5709 unmodified lines |
| 15882 | params.count = nla_get_u8(info->attrs[NL80211_ATTR_COLOR_CHANGE_COUNT]); | 15943 | params.count = nla_get_u8(info->attrs[NL80211_ATTR_COLOR_CHANGE_COUNT]); |
| 15883 | params.color = nla_get_u8(info->attrs[NL80211_ATTR_COLOR_CHANGE_COLOR]); | 15944 | params.color = nla_get_u8(info->attrs[NL80211_ATTR_COLOR_CHANGE_COLOR]); |
| 15884 | | 15945 | |
| 15885 | err = nl80211_parse_beacon(rdev, info->attrs, ¶ms.beacon_next); | 15946 | err = nl80211_parse_beacon(rdev, info->attrs, ¶ms.beacon_next, |
| | 15947 | info->extack); |
| 15886 | if (err) | 15948 | if (err) |
| 15887 | return err; | 15949 | return err; |
| 15888 | | 15950 | |
| @@ -15896,7 +15958,8 @@ static int nl80211_color_change(struct sk_buff *skb, struct genl_info *info) · 7 unmodified lines |
| 15896 | if (err) | 15958 | if (err) |
| 15897 | goto out; | 15959 | goto out; |
| 15898 | | 15960 | |
| 15899 | err = nl80211_parse_beacon(rdev, tb, ¶ms.beacon_color_change); | 15961 | err = nl80211_parse_beacon(rdev, tb, ¶ms.beacon_color_change, |
| | 15962 | info->extack); |
| 15900 | if (err) | 15963 | if (err) |
| 15901 | goto out; | 15964 | goto out; |
| 15902 | | 15965 | |
| @@ -15952,6 +16015,8 @@ static int nl80211_color_change(struct sk_buff *skb, struct genl_info *info) · 49 unmodified lines |
| 15952 | out: | 16015 | out: |
| 15953 | kfree(params.beacon_next.mbssid_ies); | 16016 | kfree(params.beacon_next.mbssid_ies); |
| 15954 | kfree(params.beacon_color_change.mbssid_ies); | 16017 | kfree(params.beacon_color_change.mbssid_ies); |
| | 16018 | kfree(params.beacon_next.rnr_ies); |
| | 16019 | kfree(params.beacon_color_change.rnr_ies); |
| 15955 | kfree(tb); | 16020 | kfree(tb); |
| 15956 | return err; | 16021 | return err; |
| 15957 | } | 16022 | } |