diff options
author | John W. Linville <linville@tuxdriver.com> | 2012-06-29 12:42:14 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-06-29 12:42:14 -0400 |
commit | 8732baafc3f19e69df683c3f0f36c13cec746fb9 (patch) | |
tree | 9059d0fe8f2a49425edab88ea8e7d5337e13e66c /net/wireless | |
parent | 7a9bc9b81a5bc6e44ebc80ef781332e4385083f2 (diff) | |
parent | 42fb0b0278e6b9a44bee8adec051de5f43e10b2b (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.c | 63 | ||||
-rw-r--r-- | net/wireless/core.h | 26 | ||||
-rw-r--r-- | net/wireless/mesh.c | 6 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 282 |
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! */ | ||
100 | struct 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 | |||
143 | struct cfg80211_registered_device * | ||
144 | cfg80211_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 | |||
162 | struct cfg80211_registered_device * | 99 | struct cfg80211_registered_device * |
163 | cfg80211_get_dev_from_ifindex(struct net *net, int ifindex) | 100 | cfg80211_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) | |||
159 | struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx); | 159 | struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx); |
160 | int get_wiphy_idx(struct wiphy *wiphy); | 160 | int get_wiphy_idx(struct wiphy *wiphy); |
161 | 161 | ||
162 | struct 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 | */ | ||
185 | extern struct cfg80211_registered_device * | ||
186 | cfg80211_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! */ |
189 | struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx); | 163 | struct 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 | ||
67 | const struct mesh_setup default_mesh_setup = { | 73 | const 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 | ||
73 | static 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 | */ | ||
142 | static struct cfg80211_registered_device * | ||
143 | cfg80211_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 */ |
74 | static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | 162 | static 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 | ||
251 | static const struct nla_policy | 339 | static const struct nla_policy |
252 | nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = { | 340 | nl80211_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 | ||
2339 | static 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 | |||
2249 | static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) | 2366 | static 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, ¶ms)) |
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, ¶ms); | 2475 | err = rdev->ops->start_ap(&rdev->wiphy, dev, ¶ms); |
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 | ||
3511 | static const struct nla_policy | 3639 | static 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(); |