aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-06-29 12:42:14 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-06-29 12:42:14 -0400
commit8732baafc3f19e69df683c3f0f36c13cec746fb9 (patch)
tree9059d0fe8f2a49425edab88ea8e7d5337e13e66c /net/wireless
parent7a9bc9b81a5bc6e44ebc80ef781332e4385083f2 (diff)
parent42fb0b0278e6b9a44bee8adec051de5f43e10b2b (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts: drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/core.c63
-rw-r--r--net/wireless/core.h26
-rw-r--r--net/wireless/mesh.c6
-rw-r--r--net/wireless/nl80211.c282
4 files changed, 222 insertions, 155 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index a87d43552974..907f62c80e28 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -96,69 +96,6 @@ struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx)
96 return &rdev->wiphy; 96 return &rdev->wiphy;
97} 97}
98 98
99/* requires cfg80211_mutex to be held! */
100struct cfg80211_registered_device *
101__cfg80211_rdev_from_info(struct genl_info *info)
102{
103 int ifindex;
104 struct cfg80211_registered_device *bywiphyidx = NULL, *byifidx = NULL;
105 struct net_device *dev;
106 int err = -EINVAL;
107
108 assert_cfg80211_lock();
109
110 if (info->attrs[NL80211_ATTR_WIPHY]) {
111 bywiphyidx = cfg80211_rdev_by_wiphy_idx(
112 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY]));
113 err = -ENODEV;
114 }
115
116 if (info->attrs[NL80211_ATTR_IFINDEX]) {
117 ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
118 dev = dev_get_by_index(genl_info_net(info), ifindex);
119 if (dev) {
120 if (dev->ieee80211_ptr)
121 byifidx =
122 wiphy_to_dev(dev->ieee80211_ptr->wiphy);
123 dev_put(dev);
124 }
125 err = -ENODEV;
126 }
127
128 if (bywiphyidx && byifidx) {
129 if (bywiphyidx != byifidx)
130 return ERR_PTR(-EINVAL);
131 else
132 return bywiphyidx; /* == byifidx */
133 }
134 if (bywiphyidx)
135 return bywiphyidx;
136
137 if (byifidx)
138 return byifidx;
139
140 return ERR_PTR(err);
141}
142
143struct cfg80211_registered_device *
144cfg80211_get_dev_from_info(struct genl_info *info)
145{
146 struct cfg80211_registered_device *rdev;
147
148 mutex_lock(&cfg80211_mutex);
149 rdev = __cfg80211_rdev_from_info(info);
150
151 /* if it is not an error we grab the lock on
152 * it to assure it won't be going away while
153 * we operate on it */
154 if (!IS_ERR(rdev))
155 mutex_lock(&rdev->mtx);
156
157 mutex_unlock(&cfg80211_mutex);
158
159 return rdev;
160}
161
162struct cfg80211_registered_device * 99struct cfg80211_registered_device *
163cfg80211_get_dev_from_ifindex(struct net *net, int ifindex) 100cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)
164{ 101{
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 9348a47562a4..609a579255ac 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -159,32 +159,6 @@ static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss)
159struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx); 159struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx);
160int get_wiphy_idx(struct wiphy *wiphy); 160int get_wiphy_idx(struct wiphy *wiphy);
161 161
162struct cfg80211_registered_device *
163__cfg80211_rdev_from_info(struct genl_info *info);
164
165/*
166 * This function returns a pointer to the driver
167 * that the genl_info item that is passed refers to.
168 * If successful, it returns non-NULL and also locks
169 * the driver's mutex!
170 *
171 * This means that you need to call cfg80211_unlock_rdev()
172 * before being allowed to acquire &cfg80211_mutex!
173 *
174 * This is necessary because we need to lock the global
175 * mutex to get an item off the list safely, and then
176 * we lock the rdev mutex so it doesn't go away under us.
177 *
178 * We don't want to keep cfg80211_mutex locked
179 * for all the time in order to allow requests on
180 * other interfaces to go through at the same time.
181 *
182 * The result of this can be a PTR_ERR and hence must
183 * be checked with IS_ERR() for errors.
184 */
185extern struct cfg80211_registered_device *
186cfg80211_get_dev_from_info(struct genl_info *info);
187
188/* requires cfg80211_rdev_mutex to be held! */ 162/* requires cfg80211_rdev_mutex to be held! */
189struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx); 163struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx);
190 164
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index b44c736bf9cf..3b73b07486cf 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -14,6 +14,9 @@
14 14
15#define MESH_PATH_TIMEOUT 5000 15#define MESH_PATH_TIMEOUT 5000
16#define MESH_RANN_INTERVAL 5000 16#define MESH_RANN_INTERVAL 5000
17#define MESH_PATH_TO_ROOT_TIMEOUT 6000
18#define MESH_ROOT_INTERVAL 5000
19#define MESH_ROOT_CONFIRMATION_INTERVAL 2000
17 20
18/* 21/*
19 * Minimum interval between two consecutive PREQs originated by the same 22 * Minimum interval between two consecutive PREQs originated by the same
@@ -62,6 +65,9 @@ const struct mesh_config default_mesh_config = {
62 .dot11MeshForwarding = true, 65 .dot11MeshForwarding = true,
63 .rssi_threshold = MESH_RSSI_THRESHOLD, 66 .rssi_threshold = MESH_RSSI_THRESHOLD,
64 .ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED, 67 .ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED,
68 .dot11MeshHWMPactivePathToRootTimeout = MESH_PATH_TO_ROOT_TIMEOUT,
69 .dot11MeshHWMProotInterval = MESH_ROOT_INTERVAL,
70 .dot11MeshHWMPconfirmationInterval = MESH_ROOT_CONFIRMATION_INTERVAL,
65}; 71};
66 72
67const struct mesh_setup default_mesh_setup = { 73const struct mesh_setup default_mesh_setup = {
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index cbdc0fd67a14..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 */
@@ -1334,7 +1423,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1334 } 1423 }
1335 1424
1336 if (!netdev) { 1425 if (!netdev) {
1337 rdev = __cfg80211_rdev_from_info(info); 1426 rdev = __cfg80211_rdev_from_attrs(genl_info_net(info),
1427 info->attrs);
1338 if (IS_ERR(rdev)) { 1428 if (IS_ERR(rdev)) {
1339 mutex_unlock(&cfg80211_mutex); 1429 mutex_unlock(&cfg80211_mutex);
1340 return PTR_ERR(rdev); 1430 return PTR_ERR(rdev);
@@ -2246,6 +2336,33 @@ static int nl80211_parse_beacon(struct genl_info *info,
2246 return 0; 2336 return 0;
2247} 2337}
2248 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
2249static 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)
2250{ 2367{
2251 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 2368 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2348,7 +2465,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
2348 } else if (wdev->preset_chan) { 2465 } else if (wdev->preset_chan) {
2349 params.channel = wdev->preset_chan; 2466 params.channel = wdev->preset_chan;
2350 params.channel_type = wdev->preset_chantype; 2467 params.channel_type = wdev->preset_chantype;
2351 } else 2468 } else if (!nl80211_get_ap_channel(rdev, &params))
2352 return -EINVAL; 2469 return -EINVAL;
2353 2470
2354 if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, params.channel, 2471 if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, params.channel,
@@ -2356,8 +2473,11 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
2356 return -EINVAL; 2473 return -EINVAL;
2357 2474
2358 err = rdev->ops->start_ap(&rdev->wiphy, dev, &params); 2475 err = rdev->ops->start_ap(&rdev->wiphy, dev, &params);
2359 if (!err) 2476 if (!err) {
2477 wdev->preset_chan = params.channel;
2478 wdev->preset_chantype = params.channel_type;
2360 wdev->beacon_interval = params.beacon_interval; 2479 wdev->beacon_interval = params.beacon_interval;
2480 }
2361 return err; 2481 return err;
2362} 2482}
2363 2483
@@ -3469,7 +3589,13 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
3469 nla_put_u32(msg, NL80211_MESHCONF_RSSI_THRESHOLD, 3589 nla_put_u32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
3470 cur_params.rssi_threshold) || 3590 cur_params.rssi_threshold) ||
3471 nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE, 3591 nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE,
3472 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))
3473 goto nla_put_failure; 3599 goto nla_put_failure;
3474 nla_nest_end(msg, pinfoattr); 3600 nla_nest_end(msg, pinfoattr);
3475 genlmsg_end(msg, hdr); 3601 genlmsg_end(msg, hdr);
@@ -3492,7 +3618,6 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
3492 [NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 }, 3618 [NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 },
3493 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 }, 3619 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 },
3494 [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] = { .type = NLA_U32 }, 3620 [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] = { .type = NLA_U32 },
3495
3496 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 }, 3621 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
3497 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 }, 3622 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
3498 [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 }, 3623 [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 },
@@ -3504,8 +3629,11 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
3504 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 }, 3629 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 },
3505 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 }, 3630 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 },
3506 [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 }, 3631 [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 },
3507 [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32}, 3632 [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32 },
3508 [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 },
3509}; 3637};
3510 3638
3511static const struct nla_policy 3639static const struct nla_policy
@@ -3515,7 +3643,7 @@ static const struct nla_policy
3515 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 }, 3643 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
3516 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG }, 3644 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
3517 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY, 3645 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY,
3518 .len = IEEE80211_MAX_DATA_LEN }, 3646 .len = IEEE80211_MAX_DATA_LEN },
3519 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG }, 3647 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
3520}; 3648};
3521 3649
@@ -3548,63 +3676,82 @@ do {\
3548 3676
3549 /* Fill in the params struct */ 3677 /* Fill in the params struct */
3550 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, 3678 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout,
3551 mask, NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16); 3679 mask, NL80211_MESHCONF_RETRY_TIMEOUT,
3680 nla_get_u16);
3552 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, 3681 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout,
3553 mask, NL80211_MESHCONF_CONFIRM_TIMEOUT, nla_get_u16); 3682 mask, NL80211_MESHCONF_CONFIRM_TIMEOUT,
3683 nla_get_u16);
3554 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout, 3684 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout,
3555 mask, NL80211_MESHCONF_HOLDING_TIMEOUT, nla_get_u16); 3685 mask, NL80211_MESHCONF_HOLDING_TIMEOUT,
3686 nla_get_u16);
3556 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks, 3687 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks,
3557 mask, NL80211_MESHCONF_MAX_PEER_LINKS, nla_get_u16); 3688 mask, NL80211_MESHCONF_MAX_PEER_LINKS,
3689 nla_get_u16);
3558 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries, 3690 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries,
3559 mask, NL80211_MESHCONF_MAX_RETRIES, nla_get_u8); 3691 mask, NL80211_MESHCONF_MAX_RETRIES,
3692 nla_get_u8);
3560 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL, 3693 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL,
3561 mask, NL80211_MESHCONF_TTL, nla_get_u8); 3694 mask, NL80211_MESHCONF_TTL, nla_get_u8);
3562 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl, 3695 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl,
3563 mask, NL80211_MESHCONF_ELEMENT_TTL, nla_get_u8); 3696 mask, NL80211_MESHCONF_ELEMENT_TTL,
3697 nla_get_u8);
3564 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, 3698 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks,
3565 mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS, nla_get_u8); 3699 mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
3566 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor, 3700 nla_get_u8);
3567 mask, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, 3701 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor, mask,
3568 nla_get_u32); 3702 NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
3703 nla_get_u32);
3569 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, 3704 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries,
3570 mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, 3705 mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
3571 nla_get_u8); 3706 nla_get_u8);
3572 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time, 3707 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time,
3573 mask, NL80211_MESHCONF_PATH_REFRESH_TIME, nla_get_u32); 3708 mask, NL80211_MESHCONF_PATH_REFRESH_TIME,
3709 nla_get_u32);
3574 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout, 3710 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout,
3575 mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, 3711 mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
3576 nla_get_u16); 3712 nla_get_u16);
3577 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout, 3713 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout, mask,
3578 mask, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, 3714 NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
3579 nla_get_u32); 3715 nla_get_u32);
3580 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval, 3716 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval,
3581 mask, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, 3717 mask, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
3582 nla_get_u16); 3718 nla_get_u16);
3583 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval, 3719 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval,
3584 mask, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, 3720 mask, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
3585 nla_get_u16); 3721 nla_get_u16);
3586 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
3587 dot11MeshHWMPnetDiameterTraversalTime,
3588 mask, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
3589 nla_get_u16);
3590 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, 3722 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
3591 dot11MeshHWMPRootMode, mask, 3723 dot11MeshHWMPnetDiameterTraversalTime, mask,
3592 NL80211_MESHCONF_HWMP_ROOTMODE, 3724 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
3593 nla_get_u8); 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);
3594 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, 3731 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
3595 dot11MeshHWMPRannInterval, mask, 3732 dot11MeshGateAnnouncementProtocol, mask,
3596 NL80211_MESHCONF_HWMP_RANN_INTERVAL, 3733 NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
3597 nla_get_u16); 3734 nla_get_u8);
3598 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
3599 dot11MeshGateAnnouncementProtocol, mask,
3600 NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
3601 nla_get_u8);
3602 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, 3735 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding,
3603 mask, NL80211_MESHCONF_FORWARDING, nla_get_u8); 3736 mask, NL80211_MESHCONF_FORWARDING,
3737 nla_get_u8);
3604 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, 3738 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold,
3605 mask, NL80211_MESHCONF_RSSI_THRESHOLD, nla_get_u32); 3739 mask, NL80211_MESHCONF_RSSI_THRESHOLD,
3740 nla_get_u32);
3606 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, ht_opmode, 3741 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, ht_opmode,
3607 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);
3608 if (mask_out) 3755 if (mask_out)
3609 *mask_out = mask; 3756 *mask_out = mask;
3610 3757
@@ -4241,12 +4388,12 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
4241 nla_for_each_nested(attr, 4388 nla_for_each_nested(attr,
4242 info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH], 4389 info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
4243 tmp) { 4390 tmp) {
4244 struct nlattr *ssid; 4391 struct nlattr *ssid, *rssi;
4245 4392
4246 nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX, 4393 nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
4247 nla_data(attr), nla_len(attr), 4394 nla_data(attr), nla_len(attr),
4248 nl80211_match_policy); 4395 nl80211_match_policy);
4249 ssid = tb[NL80211_ATTR_SCHED_SCAN_MATCH_SSID]; 4396 ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
4250 if (ssid) { 4397 if (ssid) {
4251 if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) { 4398 if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
4252 err = -EINVAL; 4399 err = -EINVAL;
@@ -4257,6 +4404,12 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
4257 request->match_sets[i].ssid.ssid_len = 4404 request->match_sets[i].ssid.ssid_len =
4258 nla_len(ssid); 4405 nla_len(ssid);
4259 } 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;
4260 i++; 4413 i++;
4261 } 4414 }
4262 } 4415 }
@@ -5114,21 +5267,18 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
5114 nl80211_policy); 5267 nl80211_policy);
5115 if (err) 5268 if (err)
5116 return err; 5269 return err;
5117 if (nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]) {
5118 phy_idx = nla_get_u32(
5119 nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]);
5120 } else {
5121 struct net_device *netdev;
5122 5270
5123 err = get_rdev_dev_by_ifindex(sock_net(skb->sk), 5271 mutex_lock(&cfg80211_mutex);
5124 nl80211_fam.attrbuf, 5272 rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk),
5125 &rdev, &netdev); 5273 nl80211_fam.attrbuf);
5126 if (err) 5274 if (IS_ERR(rdev)) {
5127 return err; 5275 mutex_unlock(&cfg80211_mutex);
5128 dev_put(netdev); 5276 return PTR_ERR(rdev);
5129 phy_idx = rdev->wiphy_idx;
5130 cfg80211_unlock_rdev(rdev);
5131 } 5277 }
5278 phy_idx = rdev->wiphy_idx;
5279 rdev = NULL;
5280 mutex_unlock(&cfg80211_mutex);
5281
5132 if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]) 5282 if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA])
5133 cb->args[1] = 5283 cb->args[1] =
5134 (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]; 5284 (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA];
@@ -6511,7 +6661,7 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
6511 rtnl_lock(); 6661 rtnl_lock();
6512 6662
6513 if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) { 6663 if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) {
6514 rdev = cfg80211_get_dev_from_info(info); 6664 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
6515 if (IS_ERR(rdev)) { 6665 if (IS_ERR(rdev)) {
6516 if (rtnl) 6666 if (rtnl)
6517 rtnl_unlock(); 6667 rtnl_unlock();