aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c435
1 files changed, 334 insertions, 101 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 206465dc0cab..3b508eaf2d07 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -70,6 +70,94 @@ static int get_rdev_dev_by_ifindex(struct net *netns, struct nlattr **attrs,
70 return 0; 70 return 0;
71} 71}
72 72
73static struct cfg80211_registered_device *
74__cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
75{
76 struct cfg80211_registered_device *rdev = NULL, *tmp;
77 struct net_device *netdev;
78
79 assert_cfg80211_lock();
80
81 if (!attrs[NL80211_ATTR_WIPHY] &&
82 !attrs[NL80211_ATTR_IFINDEX])
83 return ERR_PTR(-EINVAL);
84
85 if (attrs[NL80211_ATTR_WIPHY])
86 rdev = cfg80211_rdev_by_wiphy_idx(
87 nla_get_u32(attrs[NL80211_ATTR_WIPHY]));
88
89 if (attrs[NL80211_ATTR_IFINDEX]) {
90 int ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
91 netdev = dev_get_by_index(netns, ifindex);
92 if (netdev) {
93 if (netdev->ieee80211_ptr)
94 tmp = wiphy_to_dev(
95 netdev->ieee80211_ptr->wiphy);
96 else
97 tmp = NULL;
98
99 dev_put(netdev);
100
101 /* not wireless device -- return error */
102 if (!tmp)
103 return ERR_PTR(-EINVAL);
104
105 /* mismatch -- return error */
106 if (rdev && tmp != rdev)
107 return ERR_PTR(-EINVAL);
108
109 rdev = tmp;
110 }
111 }
112
113 if (!rdev)
114 return ERR_PTR(-ENODEV);
115
116 if (netns != wiphy_net(&rdev->wiphy))
117 return ERR_PTR(-ENODEV);
118
119 return rdev;
120}
121
122/*
123 * This function returns a pointer to the driver
124 * that the genl_info item that is passed refers to.
125 * If successful, it returns non-NULL and also locks
126 * the driver's mutex!
127 *
128 * This means that you need to call cfg80211_unlock_rdev()
129 * before being allowed to acquire &cfg80211_mutex!
130 *
131 * This is necessary because we need to lock the global
132 * mutex to get an item off the list safely, and then
133 * we lock the rdev mutex so it doesn't go away under us.
134 *
135 * We don't want to keep cfg80211_mutex locked
136 * for all the time in order to allow requests on
137 * other interfaces to go through at the same time.
138 *
139 * The result of this can be a PTR_ERR and hence must
140 * be checked with IS_ERR() for errors.
141 */
142static struct cfg80211_registered_device *
143cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info)
144{
145 struct cfg80211_registered_device *rdev;
146
147 mutex_lock(&cfg80211_mutex);
148 rdev = __cfg80211_rdev_from_attrs(netns, info->attrs);
149
150 /* if it is not an error we grab the lock on
151 * it to assure it won't be going away while
152 * we operate on it */
153 if (!IS_ERR(rdev))
154 mutex_lock(&rdev->mtx);
155
156 mutex_unlock(&cfg80211_mutex);
157
158 return rdev;
159}
160
73/* policy for the attributes */ 161/* policy for the attributes */
74static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { 162static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
75 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 }, 163 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
@@ -115,7 +203,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
115 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 }, 203 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
116 [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ }, 204 [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
117 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY, 205 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
118 .len = IEEE80211_MAX_MESH_ID_LEN }, 206 .len = IEEE80211_MAX_MESH_ID_LEN },
119 [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 }, 207 [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 },
120 208
121 [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 }, 209 [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 },
@@ -250,8 +338,9 @@ nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
250 338
251static const struct nla_policy 339static const struct nla_policy
252nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = { 340nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
253 [NL80211_ATTR_SCHED_SCAN_MATCH_SSID] = { .type = NLA_BINARY, 341 [NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
254 .len = IEEE80211_MAX_SSID_LEN }, 342 .len = IEEE80211_MAX_SSID_LEN },
343 [NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
255}; 344};
256 345
257/* ifidx get helper */ 346/* ifidx get helper */
@@ -921,7 +1010,12 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
921 if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS)) 1010 if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS))
922 goto nla_put_failure; 1011 goto nla_put_failure;
923 } 1012 }
924 CMD(set_channel, SET_CHANNEL); 1013 if (dev->ops->set_monitor_channel || dev->ops->start_ap ||
1014 dev->ops->join_mesh) {
1015 i++;
1016 if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL))
1017 goto nla_put_failure;
1018 }
925 CMD(set_wds_peer, SET_WDS_PEER); 1019 CMD(set_wds_peer, SET_WDS_PEER);
926 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) { 1020 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) {
927 CMD(tdls_mgmt, TDLS_MGMT); 1021 CMD(tdls_mgmt, TDLS_MGMT);
@@ -1162,18 +1256,22 @@ static int parse_txq_params(struct nlattr *tb[],
1162static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev) 1256static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
1163{ 1257{
1164 /* 1258 /*
1165 * You can only set the channel explicitly for AP, mesh 1259 * You can only set the channel explicitly for WDS interfaces,
1166 * and WDS type interfaces; all others have their channel 1260 * all others have their channel managed via their respective
1167 * managed via their respective "establish a connection" 1261 * "establish a connection" command (connect, join, ...)
1168 * command (connect, join, ...) 1262 *
1263 * For AP/GO and mesh mode, the channel can be set with the
1264 * channel userspace API, but is only stored and passed to the
1265 * low-level driver when the AP starts or the mesh is joined.
1266 * This is for backward compatibility, userspace can also give
1267 * the channel in the start-ap or join-mesh commands instead.
1169 * 1268 *
1170 * Monitors are special as they are normally slaved to 1269 * Monitors are special as they are normally slaved to
1171 * whatever else is going on, so they behave as though 1270 * whatever else is going on, so they have their own special
1172 * you tried setting the wiphy channel itself. 1271 * operation to set the monitor channel if possible.
1173 */ 1272 */
1174 return !wdev || 1273 return !wdev ||
1175 wdev->iftype == NL80211_IFTYPE_AP || 1274 wdev->iftype == NL80211_IFTYPE_AP ||
1176 wdev->iftype == NL80211_IFTYPE_WDS ||
1177 wdev->iftype == NL80211_IFTYPE_MESH_POINT || 1275 wdev->iftype == NL80211_IFTYPE_MESH_POINT ||
1178 wdev->iftype == NL80211_IFTYPE_MONITOR || 1276 wdev->iftype == NL80211_IFTYPE_MONITOR ||
1179 wdev->iftype == NL80211_IFTYPE_P2P_GO; 1277 wdev->iftype == NL80211_IFTYPE_P2P_GO;
@@ -1204,9 +1302,14 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
1204 struct wireless_dev *wdev, 1302 struct wireless_dev *wdev,
1205 struct genl_info *info) 1303 struct genl_info *info)
1206{ 1304{
1305 struct ieee80211_channel *channel;
1207 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; 1306 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
1208 u32 freq; 1307 u32 freq;
1209 int result; 1308 int result;
1309 enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR;
1310
1311 if (wdev)
1312 iftype = wdev->iftype;
1210 1313
1211 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ]) 1314 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
1212 return -EINVAL; 1315 return -EINVAL;
@@ -1221,12 +1324,32 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
1221 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); 1324 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
1222 1325
1223 mutex_lock(&rdev->devlist_mtx); 1326 mutex_lock(&rdev->devlist_mtx);
1224 if (wdev) { 1327 switch (iftype) {
1225 wdev_lock(wdev); 1328 case NL80211_IFTYPE_AP:
1226 result = cfg80211_set_freq(rdev, wdev, freq, channel_type); 1329 case NL80211_IFTYPE_P2P_GO:
1227 wdev_unlock(wdev); 1330 if (wdev->beacon_interval) {
1228 } else { 1331 result = -EBUSY;
1229 result = cfg80211_set_freq(rdev, NULL, freq, channel_type); 1332 break;
1333 }
1334 channel = rdev_freq_to_chan(rdev, freq, channel_type);
1335 if (!channel || !cfg80211_can_beacon_sec_chan(&rdev->wiphy,
1336 channel,
1337 channel_type)) {
1338 result = -EINVAL;
1339 break;
1340 }
1341 wdev->preset_chan = channel;
1342 wdev->preset_chantype = channel_type;
1343 result = 0;
1344 break;
1345 case NL80211_IFTYPE_MESH_POINT:
1346 result = cfg80211_set_mesh_freq(rdev, wdev, freq, channel_type);
1347 break;
1348 case NL80211_IFTYPE_MONITOR:
1349 result = cfg80211_set_monitor_channel(rdev, freq, channel_type);
1350 break;
1351 default:
1352 result = -EINVAL;
1230 } 1353 }
1231 mutex_unlock(&rdev->devlist_mtx); 1354 mutex_unlock(&rdev->devlist_mtx);
1232 1355
@@ -1300,7 +1423,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1300 } 1423 }
1301 1424
1302 if (!netdev) { 1425 if (!netdev) {
1303 rdev = __cfg80211_rdev_from_info(info); 1426 rdev = __cfg80211_rdev_from_attrs(genl_info_net(info),
1427 info->attrs);
1304 if (IS_ERR(rdev)) { 1428 if (IS_ERR(rdev)) {
1305 mutex_unlock(&cfg80211_mutex); 1429 mutex_unlock(&cfg80211_mutex);
1306 return PTR_ERR(rdev); 1430 return PTR_ERR(rdev);
@@ -1310,8 +1434,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1310 result = 0; 1434 result = 0;
1311 1435
1312 mutex_lock(&rdev->mtx); 1436 mutex_lock(&rdev->mtx);
1313 } else if (netif_running(netdev) && 1437 } else if (nl80211_can_set_dev_channel(netdev->ieee80211_ptr))
1314 nl80211_can_set_dev_channel(netdev->ieee80211_ptr))
1315 wdev = netdev->ieee80211_ptr; 1438 wdev = netdev->ieee80211_ptr;
1316 else 1439 else
1317 wdev = NULL; 1440 wdev = NULL;
@@ -2213,6 +2336,33 @@ static int nl80211_parse_beacon(struct genl_info *info,
2213 return 0; 2336 return 0;
2214} 2337}
2215 2338
2339static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
2340 struct cfg80211_ap_settings *params)
2341{
2342 struct wireless_dev *wdev;
2343 bool ret = false;
2344
2345 mutex_lock(&rdev->devlist_mtx);
2346
2347 list_for_each_entry(wdev, &rdev->netdev_list, list) {
2348 if (wdev->iftype != NL80211_IFTYPE_AP &&
2349 wdev->iftype != NL80211_IFTYPE_P2P_GO)
2350 continue;
2351
2352 if (!wdev->preset_chan)
2353 continue;
2354
2355 params->channel = wdev->preset_chan;
2356 params->channel_type = wdev->preset_chantype;
2357 ret = true;
2358 break;
2359 }
2360
2361 mutex_unlock(&rdev->devlist_mtx);
2362
2363 return ret;
2364}
2365
2216static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) 2366static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
2217{ 2367{
2218 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 2368 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2299,9 +2449,35 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
2299 info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]); 2449 info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]);
2300 } 2450 }
2301 2451
2452 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
2453 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
2454
2455 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] &&
2456 !nl80211_valid_channel_type(info, &channel_type))
2457 return -EINVAL;
2458
2459 params.channel = rdev_freq_to_chan(rdev,
2460 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
2461 channel_type);
2462 if (!params.channel)
2463 return -EINVAL;
2464 params.channel_type = channel_type;
2465 } else if (wdev->preset_chan) {
2466 params.channel = wdev->preset_chan;
2467 params.channel_type = wdev->preset_chantype;
2468 } else if (!nl80211_get_ap_channel(rdev, &params))
2469 return -EINVAL;
2470
2471 if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, params.channel,
2472 params.channel_type))
2473 return -EINVAL;
2474
2302 err = rdev->ops->start_ap(&rdev->wiphy, dev, &params); 2475 err = rdev->ops->start_ap(&rdev->wiphy, dev, &params);
2303 if (!err) 2476 if (!err) {
2477 wdev->preset_chan = params.channel;
2478 wdev->preset_chantype = params.channel_type;
2304 wdev->beacon_interval = params.beacon_interval; 2479 wdev->beacon_interval = params.beacon_interval;
2480 }
2305 return err; 2481 return err;
2306} 2482}
2307 2483
@@ -3413,7 +3589,13 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
3413 nla_put_u32(msg, NL80211_MESHCONF_RSSI_THRESHOLD, 3589 nla_put_u32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
3414 cur_params.rssi_threshold) || 3590 cur_params.rssi_threshold) ||
3415 nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE, 3591 nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE,
3416 cur_params.ht_opmode)) 3592 cur_params.ht_opmode) ||
3593 nla_put_u32(msg, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
3594 cur_params.dot11MeshHWMPactivePathToRootTimeout) ||
3595 nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
3596 cur_params.dot11MeshHWMProotInterval) ||
3597 nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
3598 cur_params.dot11MeshHWMPconfirmationInterval))
3417 goto nla_put_failure; 3599 goto nla_put_failure;
3418 nla_nest_end(msg, pinfoattr); 3600 nla_nest_end(msg, pinfoattr);
3419 genlmsg_end(msg, hdr); 3601 genlmsg_end(msg, hdr);
@@ -3436,7 +3618,6 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
3436 [NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 }, 3618 [NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 },
3437 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 }, 3619 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 },
3438 [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] = { .type = NLA_U32 }, 3620 [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] = { .type = NLA_U32 },
3439
3440 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 }, 3621 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
3441 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 }, 3622 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
3442 [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 }, 3623 [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 },
@@ -3448,8 +3629,11 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
3448 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 }, 3629 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 },
3449 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 }, 3630 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 },
3450 [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 }, 3631 [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 },
3451 [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32}, 3632 [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32 },
3452 [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16}, 3633 [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 },
3634 [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 },
3635 [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] = { .type = NLA_U16 },
3636 [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] = { .type = NLA_U16 },
3453}; 3637};
3454 3638
3455static const struct nla_policy 3639static const struct nla_policy
@@ -3459,7 +3643,7 @@ static const struct nla_policy
3459 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 }, 3643 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
3460 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG }, 3644 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
3461 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY, 3645 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY,
3462 .len = IEEE80211_MAX_DATA_LEN }, 3646 .len = IEEE80211_MAX_DATA_LEN },
3463 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG }, 3647 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
3464}; 3648};
3465 3649
@@ -3492,63 +3676,82 @@ do {\
3492 3676
3493 /* Fill in the params struct */ 3677 /* Fill in the params struct */
3494 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, 3678 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout,
3495 mask, NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16); 3679 mask, NL80211_MESHCONF_RETRY_TIMEOUT,
3680 nla_get_u16);
3496 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, 3681 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout,
3497 mask, NL80211_MESHCONF_CONFIRM_TIMEOUT, nla_get_u16); 3682 mask, NL80211_MESHCONF_CONFIRM_TIMEOUT,
3683 nla_get_u16);
3498 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout, 3684 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout,
3499 mask, NL80211_MESHCONF_HOLDING_TIMEOUT, nla_get_u16); 3685 mask, NL80211_MESHCONF_HOLDING_TIMEOUT,
3686 nla_get_u16);
3500 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks, 3687 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks,
3501 mask, NL80211_MESHCONF_MAX_PEER_LINKS, nla_get_u16); 3688 mask, NL80211_MESHCONF_MAX_PEER_LINKS,
3689 nla_get_u16);
3502 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries, 3690 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries,
3503 mask, NL80211_MESHCONF_MAX_RETRIES, nla_get_u8); 3691 mask, NL80211_MESHCONF_MAX_RETRIES,
3692 nla_get_u8);
3504 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL, 3693 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL,
3505 mask, NL80211_MESHCONF_TTL, nla_get_u8); 3694 mask, NL80211_MESHCONF_TTL, nla_get_u8);
3506 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl, 3695 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl,
3507 mask, NL80211_MESHCONF_ELEMENT_TTL, nla_get_u8); 3696 mask, NL80211_MESHCONF_ELEMENT_TTL,
3697 nla_get_u8);
3508 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, 3698 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks,
3509 mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS, nla_get_u8); 3699 mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
3510 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor, 3700 nla_get_u8);
3511 mask, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, 3701 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor, mask,
3512 nla_get_u32); 3702 NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
3703 nla_get_u32);
3513 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, 3704 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries,
3514 mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, 3705 mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
3515 nla_get_u8); 3706 nla_get_u8);
3516 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time, 3707 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time,
3517 mask, NL80211_MESHCONF_PATH_REFRESH_TIME, nla_get_u32); 3708 mask, NL80211_MESHCONF_PATH_REFRESH_TIME,
3709 nla_get_u32);
3518 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout, 3710 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout,
3519 mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, 3711 mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
3520 nla_get_u16); 3712 nla_get_u16);
3521 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout, 3713 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout, mask,
3522 mask, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, 3714 NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
3523 nla_get_u32); 3715 nla_get_u32);
3524 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval, 3716 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval,
3525 mask, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, 3717 mask, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
3526 nla_get_u16); 3718 nla_get_u16);
3527 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval, 3719 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval,
3528 mask, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, 3720 mask, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
3529 nla_get_u16); 3721 nla_get_u16);
3530 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
3531 dot11MeshHWMPnetDiameterTraversalTime,
3532 mask, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
3533 nla_get_u16);
3534 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
3535 dot11MeshHWMPRootMode, mask,
3536 NL80211_MESHCONF_HWMP_ROOTMODE,
3537 nla_get_u8);
3538 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, 3722 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
3539 dot11MeshHWMPRannInterval, mask, 3723 dot11MeshHWMPnetDiameterTraversalTime, mask,
3540 NL80211_MESHCONF_HWMP_RANN_INTERVAL, 3724 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
3541 nla_get_u16); 3725 nla_get_u16);
3726 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, mask,
3727 NL80211_MESHCONF_HWMP_ROOTMODE, nla_get_u8);
3728 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, mask,
3729 NL80211_MESHCONF_HWMP_RANN_INTERVAL,
3730 nla_get_u16);
3542 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, 3731 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
3543 dot11MeshGateAnnouncementProtocol, mask, 3732 dot11MeshGateAnnouncementProtocol, mask,
3544 NL80211_MESHCONF_GATE_ANNOUNCEMENTS, 3733 NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
3545 nla_get_u8); 3734 nla_get_u8);
3546 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, 3735 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding,
3547 mask, NL80211_MESHCONF_FORWARDING, nla_get_u8); 3736 mask, NL80211_MESHCONF_FORWARDING,
3737 nla_get_u8);
3548 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, 3738 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold,
3549 mask, NL80211_MESHCONF_RSSI_THRESHOLD, nla_get_u32); 3739 mask, NL80211_MESHCONF_RSSI_THRESHOLD,
3740 nla_get_u32);
3550 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, ht_opmode, 3741 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, ht_opmode,
3551 mask, NL80211_MESHCONF_HT_OPMODE, nla_get_u16); 3742 mask, NL80211_MESHCONF_HT_OPMODE,
3743 nla_get_u16);
3744 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathToRootTimeout,
3745 mask,
3746 NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
3747 nla_get_u32);
3748 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval,
3749 mask, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
3750 nla_get_u16);
3751 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
3752 dot11MeshHWMPconfirmationInterval, mask,
3753 NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
3754 nla_get_u16);
3552 if (mask_out) 3755 if (mask_out)
3553 *mask_out = mask; 3756 *mask_out = mask;
3554 3757
@@ -4185,12 +4388,12 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
4185 nla_for_each_nested(attr, 4388 nla_for_each_nested(attr,
4186 info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH], 4389 info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
4187 tmp) { 4390 tmp) {
4188 struct nlattr *ssid; 4391 struct nlattr *ssid, *rssi;
4189 4392
4190 nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX, 4393 nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
4191 nla_data(attr), nla_len(attr), 4394 nla_data(attr), nla_len(attr),
4192 nl80211_match_policy); 4395 nl80211_match_policy);
4193 ssid = tb[NL80211_ATTR_SCHED_SCAN_MATCH_SSID]; 4396 ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
4194 if (ssid) { 4397 if (ssid) {
4195 if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) { 4398 if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
4196 err = -EINVAL; 4399 err = -EINVAL;
@@ -4201,6 +4404,12 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
4201 request->match_sets[i].ssid.ssid_len = 4404 request->match_sets[i].ssid.ssid_len =
4202 nla_len(ssid); 4405 nla_len(ssid);
4203 } 4406 }
4407 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
4408 if (rssi)
4409 request->rssi_thold = nla_get_u32(rssi);
4410 else
4411 request->rssi_thold =
4412 NL80211_SCAN_RSSI_THOLD_OFF;
4204 i++; 4413 i++;
4205 } 4414 }
4206 } 4415 }
@@ -5058,21 +5267,18 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
5058 nl80211_policy); 5267 nl80211_policy);
5059 if (err) 5268 if (err)
5060 return err; 5269 return err;
5061 if (nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]) {
5062 phy_idx = nla_get_u32(
5063 nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]);
5064 } else {
5065 struct net_device *netdev;
5066 5270
5067 err = get_rdev_dev_by_ifindex(sock_net(skb->sk), 5271 mutex_lock(&cfg80211_mutex);
5068 nl80211_fam.attrbuf, 5272 rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk),
5069 &rdev, &netdev); 5273 nl80211_fam.attrbuf);
5070 if (err) 5274 if (IS_ERR(rdev)) {
5071 return err; 5275 mutex_unlock(&cfg80211_mutex);
5072 dev_put(netdev); 5276 return PTR_ERR(rdev);
5073 phy_idx = rdev->wiphy_idx;
5074 cfg80211_unlock_rdev(rdev);
5075 } 5277 }
5278 phy_idx = rdev->wiphy_idx;
5279 rdev = NULL;
5280 mutex_unlock(&cfg80211_mutex);
5281
5076 if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]) 5282 if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA])
5077 cb->args[1] = 5283 cb->args[1] =
5078 (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]; 5284 (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA];
@@ -5489,18 +5695,18 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
5489 5695
5490 duration = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]); 5696 duration = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
5491 5697
5698 if (!rdev->ops->remain_on_channel ||
5699 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL))
5700 return -EOPNOTSUPP;
5701
5492 /* 5702 /*
5493 * We should be on that channel for at least one jiffie, 5703 * We should be on that channel for at least a minimum amount of
5494 * and more than 5 seconds seems excessive. 5704 * time (10ms) but no longer than the driver supports.
5495 */ 5705 */
5496 if (!duration || !msecs_to_jiffies(duration) || 5706 if (duration < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
5497 duration > rdev->wiphy.max_remain_on_channel_duration) 5707 duration > rdev->wiphy.max_remain_on_channel_duration)
5498 return -EINVAL; 5708 return -EINVAL;
5499 5709
5500 if (!rdev->ops->remain_on_channel ||
5501 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL))
5502 return -EOPNOTSUPP;
5503
5504 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] && 5710 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] &&
5505 !nl80211_valid_channel_type(info, &channel_type)) 5711 !nl80211_valid_channel_type(info, &channel_type))
5506 return -EINVAL; 5712 return -EINVAL;
@@ -5771,6 +5977,15 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
5771 if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX)) 5977 if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
5772 return -EINVAL; 5978 return -EINVAL;
5773 wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]); 5979 wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
5980
5981 /*
5982 * We should wait on the channel for at least a minimum amount
5983 * of time (10ms) but no longer than the driver supports.
5984 */
5985 if (wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
5986 wait > rdev->wiphy.max_remain_on_channel_duration)
5987 return -EINVAL;
5988
5774 } 5989 }
5775 5990
5776 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { 5991 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
@@ -6032,6 +6247,24 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
6032 return err; 6247 return err;
6033 } 6248 }
6034 6249
6250 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
6251 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
6252
6253 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] &&
6254 !nl80211_valid_channel_type(info, &channel_type))
6255 return -EINVAL;
6256
6257 setup.channel = rdev_freq_to_chan(rdev,
6258 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
6259 channel_type);
6260 if (!setup.channel)
6261 return -EINVAL;
6262 setup.channel_type = channel_type;
6263 } else {
6264 /* cfg80211_join_mesh() will sort it out */
6265 setup.channel = NULL;
6266 }
6267
6035 return cfg80211_join_mesh(rdev, dev, &setup, &cfg); 6268 return cfg80211_join_mesh(rdev, dev, &setup, &cfg);
6036} 6269}
6037 6270
@@ -6428,7 +6661,7 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
6428 rtnl_lock(); 6661 rtnl_lock();
6429 6662
6430 if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) { 6663 if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) {
6431 rdev = cfg80211_get_dev_from_info(info); 6664 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
6432 if (IS_ERR(rdev)) { 6665 if (IS_ERR(rdev)) {
6433 if (rtnl) 6666 if (rtnl)
6434 rtnl_unlock(); 6667 rtnl_unlock();
@@ -7127,7 +7360,7 @@ void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
7127{ 7360{
7128 struct sk_buff *msg; 7361 struct sk_buff *msg;
7129 7362
7130 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 7363 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7131 if (!msg) 7364 if (!msg)
7132 return; 7365 return;
7133 7366
@@ -7203,7 +7436,7 @@ void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
7203{ 7436{
7204 struct sk_buff *msg; 7437 struct sk_buff *msg;
7205 7438
7206 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 7439 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7207 if (!msg) 7440 if (!msg)
7208 return; 7441 return;
7209 7442
@@ -7419,7 +7652,7 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
7419 struct sk_buff *msg; 7652 struct sk_buff *msg;
7420 void *hdr; 7653 void *hdr;
7421 7654
7422 msg = nlmsg_new(NLMSG_GOODSIZE, gfp); 7655 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
7423 if (!msg) 7656 if (!msg)
7424 return; 7657 return;
7425 7658
@@ -7459,7 +7692,7 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
7459 struct sk_buff *msg; 7692 struct sk_buff *msg;
7460 void *hdr; 7693 void *hdr;
7461 7694
7462 msg = nlmsg_new(NLMSG_GOODSIZE, gfp); 7695 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
7463 if (!msg) 7696 if (!msg)
7464 return; 7697 return;
7465 7698
@@ -7497,7 +7730,7 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
7497 struct sk_buff *msg; 7730 struct sk_buff *msg;
7498 void *hdr; 7731 void *hdr;
7499 7732
7500 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 7733 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7501 if (!msg) 7734 if (!msg)
7502 return; 7735 return;
7503 7736
@@ -7759,7 +7992,7 @@ void nl80211_send_sta_event(struct cfg80211_registered_device *rdev,
7759{ 7992{
7760 struct sk_buff *msg; 7993 struct sk_buff *msg;
7761 7994
7762 msg = nlmsg_new(NLMSG_GOODSIZE, gfp); 7995 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
7763 if (!msg) 7996 if (!msg)
7764 return; 7997 return;
7765 7998
@@ -7780,7 +8013,7 @@ void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev,
7780 struct sk_buff *msg; 8013 struct sk_buff *msg;
7781 void *hdr; 8014 void *hdr;
7782 8015
7783 msg = nlmsg_new(NLMSG_GOODSIZE, gfp); 8016 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
7784 if (!msg) 8017 if (!msg)
7785 return; 8018 return;
7786 8019
@@ -7943,7 +8176,7 @@ nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev,
7943 struct nlattr *pinfoattr; 8176 struct nlattr *pinfoattr;
7944 void *hdr; 8177 void *hdr;
7945 8178
7946 msg = nlmsg_new(NLMSG_GOODSIZE, gfp); 8179 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
7947 if (!msg) 8180 if (!msg)
7948 return; 8181 return;
7949 8182
@@ -7986,7 +8219,7 @@ void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
7986 struct nlattr *rekey_attr; 8219 struct nlattr *rekey_attr;
7987 void *hdr; 8220 void *hdr;
7988 8221
7989 msg = nlmsg_new(NLMSG_GOODSIZE, gfp); 8222 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
7990 if (!msg) 8223 if (!msg)
7991 return; 8224 return;
7992 8225
@@ -8030,7 +8263,7 @@ void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
8030 struct nlattr *attr; 8263 struct nlattr *attr;
8031 void *hdr; 8264 void *hdr;
8032 8265
8033 msg = nlmsg_new(NLMSG_GOODSIZE, gfp); 8266 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
8034 if (!msg) 8267 if (!msg)
8035 return; 8268 return;
8036 8269
@@ -8074,7 +8307,7 @@ void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
8074 struct sk_buff *msg; 8307 struct sk_buff *msg;
8075 void *hdr; 8308 void *hdr;
8076 8309
8077 msg = nlmsg_new(NLMSG_GOODSIZE, gfp); 8310 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
8078 if (!msg) 8311 if (!msg)
8079 return; 8312 return;
8080 8313
@@ -8109,7 +8342,7 @@ nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
8109 struct nlattr *pinfoattr; 8342 struct nlattr *pinfoattr;
8110 void *hdr; 8343 void *hdr;
8111 8344
8112 msg = nlmsg_new(NLMSG_GOODSIZE, gfp); 8345 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
8113 if (!msg) 8346 if (!msg)
8114 return; 8347 return;
8115 8348
@@ -8153,7 +8386,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
8153 void *hdr; 8386 void *hdr;
8154 int err; 8387 int err;
8155 8388
8156 msg = nlmsg_new(NLMSG_GOODSIZE, gfp); 8389 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
8157 if (!msg) 8390 if (!msg)
8158 return; 8391 return;
8159 8392