If a device has self-managed regulatory, insist on returning the wiphy specific regdomain if a wiphy-idx is specified. The global regdomain is meaningless for such devices. Also add an attribute for self-managed devices, so usermode can distinguish them as such.
Unified · Split
| @@ -261,6 +261,9 @@ · 260 unmodified lines | ||
| 261 | 261 | * the regulatory core to help with compliance. A dump version of this API |
| 262 | 262 | * is now available which will returns the global regdomain as well as |
| 263 | 263 | * all private regdomains of present wiphys (for those that have it). |
| 264 | + * If a wiphy is self-managed (%NL80211_ATTR_WIPHY_SELF_MANAGED_REG), then | |
| 265 | + * its private regdomain is the only valid one for it. The regulatory | |
| 266 | + * core is not used to help with compliance in this case. | |
| 264 | 267 | * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command |
| 265 | 268 | * after being queried by the kernel. CRDA replies by sending a regulatory |
| 266 | 269 | * domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our |
| @@ -1702,6 +1705,11 @@ enum nl80211_commands { · 1435 unmodified lines | ||
| 1702 | 1705 | * |
| 1703 | 1706 | * @NL80211_ATTR_MAC_MASK: MAC address mask |
| 1704 | 1707 | * |
| 1708 | + * @NL80211_ATTR_WIPHY_SELF_MANAGED_REG: flag attribute indicating this device | |
| 1709 | + * is self-managing its regulatory information and any regulatory domain | |
| 1710 | + * obtained from it is coming from the device's wiphy and not the global | |
| 1711 | + * cfg80211 regdomain. | |
| 1712 | + * | |
| 1705 | 1713 | * @NUM_NL80211_ATTR: total number of nl80211_attrs available |
| 1706 | 1714 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
| 1707 | 1715 | * @__NL80211_ATTR_AFTER_LAST: internal use |
| @@ -2059,6 +2067,8 @@ enum nl80211_attrs { · 351 unmodified lines | ||
| 2059 | 2067 | |
| 2060 | 2068 | NL80211_ATTR_MAC_MASK, |
| 2061 | 2069 | |
| 2070 | + NL80211_ATTR_WIPHY_SELF_MANAGED_REG, | |
| 2071 | + | |
| 2062 | 2072 | /* add attributes here, update the policy in nl80211.c */ |
| 2063 | 2073 | |
| 2064 | 2074 | __NL80211_ATTR_AFTER_LAST, |
| @@ -396,6 +396,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { · 395 unmodified lines | ||
| 396 | 396 | [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 }, |
| 397 | 397 | [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 }, |
| 398 | 398 | [NL80211_ATTR_MAC_MASK] = { .len = ETH_ALEN }, |
| 399 | + [NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG }, | |
| 399 | 400 | }; |
| 400 | 401 | |
| 401 | 402 | /* policy for the key attributes */ |
| @@ -1701,6 +1702,10 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev, · 1299 unmodified lines | ||
| 1701 | 1702 | rdev->wiphy.max_num_csa_counters)) |
| 1702 | 1703 | goto nla_put_failure; |
| 1703 | 1704 | |
| 1705 | + if (rdev->wiphy.regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED && | |
| 1706 | + nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG)) | |
| 1707 | + goto nla_put_failure; | |
| 1708 | + | |
| 1704 | 1709 | /* done */ |
| 1705 | 1710 | state->split_start = 0; |
| 1706 | 1711 | break; |
| @@ -5406,6 +5411,8 @@ static int nl80211_get_reg_do(struct sk_buff *skb, struct genl_info *info) · 3699 unmodified lines | ||
| 5406 | 5411 | goto put_failure; |
| 5407 | 5412 | |
| 5408 | 5413 | if (info->attrs[NL80211_ATTR_WIPHY]) { |
| 5414 | + bool self_managed; | |
| 5415 | + | |
| 5409 | 5416 | rdev = cfg80211_get_dev_from_info(genl_info_net(info), info); |
| 5410 | 5417 | if (IS_ERR(rdev)) { |
| 5411 | 5418 | nlmsg_free(msg); |
| @@ -5413,8 +5420,16 @@ static int nl80211_get_reg_do(struct sk_buff *skb, struct genl_info *info) · 1 unmodified line | ||
| 5413 | 5420 | } |
| 5414 | 5421 | |
| 5415 | 5422 | wiphy = &rdev->wiphy; |
| 5423 | + self_managed = wiphy->regulatory_flags & | |
| 5424 | + REGULATORY_WIPHY_SELF_MANAGED; | |
| 5416 | 5425 | regdom = get_wiphy_regdom(wiphy); |
| 5417 | 5426 | |
| 5427 | + /* a self-managed-reg device must have a private regdom */ | |
| 5428 | + if (WARN_ON(!regdom && self_managed)) { | |
| 5429 | + nlmsg_free(msg); | |
| 5430 | + return -EINVAL; | |
| 5431 | + } | |
| 5432 | + | |
| 5418 | 5433 | if (regdom && |
| 5419 | 5434 | nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy))) |
| 5420 | 5435 | goto nla_put_failure; |
| @@ -5471,6 +5486,10 @@ static int nl80211_send_regdom(struct sk_buff *msg, struct netlink_callback *cb, · 50 unmodified lines | ||
| 5471 | 5486 | nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy))) |
| 5472 | 5487 | goto nla_put_failure; |
| 5473 | 5488 | |
| 5489 | + if (wiphy && wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED && | |
| 5490 | + nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG)) | |
| 5491 | + goto nla_put_failure; | |
| 5492 | + | |
| 5474 | 5493 | return genlmsg_end(msg, hdr); |
| 5475 | 5494 | |
| 5476 | 5495 | nla_put_failure: |
| @@ -11076,6 +11095,11 @@ static bool nl80211_reg_change_event_fill(struct sk_buff *msg, · 5599 unmodified lines | ||
| 11076 | 11095 | if (wiphy && |
| 11077 | 11096 | nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx)) |
| 11078 | 11097 | goto nla_put_failure; |
| 11098 | + | |
| 11099 | + if (wiphy && | |
| 11100 | + wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED && | |
| 11101 | + nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG)) | |
| 11102 | + goto nla_put_failure; | |
| 11079 | 11103 | } |
| 11080 | 11104 | |
| 11081 | 11105 | return true; |