ibss.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  1. /*
  2. * Some IBSS support code for cfg80211.
  3. *
  4. * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
  5. */
  6. #include <linux/etherdevice.h>
  7. #include <linux/if_arp.h>
  8. #include <linux/slab.h>
  9. #include <linux/export.h>
  10. #include <net/cfg80211.h>
  11. #include "wext-compat.h"
  12. #include "nl80211.h"
  13. #include "rdev-ops.h"
  14. void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
  15. struct ieee80211_channel *channel)
  16. {
  17. struct wireless_dev *wdev = dev->ieee80211_ptr;
  18. struct cfg80211_bss *bss;
  19. #ifdef CONFIG_CFG80211_WEXT
  20. union iwreq_data wrqu;
  21. #endif
  22. if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
  23. return;
  24. if (!wdev->ssid_len)
  25. return;
  26. bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, NULL, 0,
  27. WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
  28. if (WARN_ON(!bss))
  29. return;
  30. if (wdev->current_bss) {
  31. cfg80211_unhold_bss(wdev->current_bss);
  32. cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
  33. }
  34. cfg80211_hold_bss(bss_from_pub(bss));
  35. wdev->current_bss = bss_from_pub(bss);
  36. cfg80211_upload_connect_keys(wdev);
  37. nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid,
  38. GFP_KERNEL);
  39. #ifdef CONFIG_CFG80211_WEXT
  40. memset(&wrqu, 0, sizeof(wrqu));
  41. memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
  42. wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
  43. #endif
  44. }
  45. void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
  46. struct ieee80211_channel *channel, gfp_t gfp)
  47. {
  48. struct wireless_dev *wdev = dev->ieee80211_ptr;
  49. struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
  50. struct cfg80211_event *ev;
  51. unsigned long flags;
  52. trace_cfg80211_ibss_joined(dev, bssid, channel);
  53. if (WARN_ON(!channel))
  54. return;
  55. ev = kzalloc(sizeof(*ev), gfp);
  56. if (!ev)
  57. return;
  58. ev->type = EVENT_IBSS_JOINED;
  59. memcpy(ev->ij.bssid, bssid, ETH_ALEN);
  60. ev->ij.channel = channel;
  61. spin_lock_irqsave(&wdev->event_lock, flags);
  62. list_add_tail(&ev->list, &wdev->event_list);
  63. spin_unlock_irqrestore(&wdev->event_lock, flags);
  64. queue_work(cfg80211_wq, &rdev->event_work);
  65. }
  66. EXPORT_SYMBOL(cfg80211_ibss_joined);
  67. static int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
  68. struct net_device *dev,
  69. struct cfg80211_ibss_params *params,
  70. struct cfg80211_cached_keys *connkeys)
  71. {
  72. struct wireless_dev *wdev = dev->ieee80211_ptr;
  73. struct ieee80211_channel *check_chan;
  74. u8 radar_detect_width = 0;
  75. int err;
  76. ASSERT_WDEV_LOCK(wdev);
  77. if (wdev->ssid_len)
  78. return -EALREADY;
  79. if (!params->basic_rates) {
  80. /*
  81. * If no rates were explicitly configured,
  82. * use the mandatory rate set for 11b or
  83. * 11a for maximum compatibility.
  84. */
  85. struct ieee80211_supported_band *sband =
  86. rdev->wiphy.bands[params->chandef.chan->band];
  87. int j;
  88. u32 flag = params->chandef.chan->band == IEEE80211_BAND_5GHZ ?
  89. IEEE80211_RATE_MANDATORY_A :
  90. IEEE80211_RATE_MANDATORY_B;
  91. for (j = 0; j < sband->n_bitrates; j++) {
  92. if (sband->bitrates[j].flags & flag)
  93. params->basic_rates |= BIT(j);
  94. }
  95. }
  96. if (WARN_ON(wdev->connect_keys))
  97. kfree(wdev->connect_keys);
  98. wdev->connect_keys = connkeys;
  99. wdev->ibss_fixed = params->channel_fixed;
  100. wdev->ibss_dfs_possible = params->userspace_handles_dfs;
  101. wdev->chandef = params->chandef;
  102. #ifdef CONFIG_CFG80211_WEXT
  103. wdev->wext.ibss.chandef = params->chandef;
  104. #endif
  105. check_chan = params->chandef.chan;
  106. if (params->userspace_handles_dfs) {
  107. /* Check for radar even if the current channel is not
  108. * a radar channel - it might decide to change to DFS
  109. * channel later.
  110. */
  111. radar_detect_width = BIT(params->chandef.width);
  112. }
  113. err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
  114. check_chan,
  115. (params->channel_fixed &&
  116. !radar_detect_width)
  117. ? CHAN_MODE_SHARED
  118. : CHAN_MODE_EXCLUSIVE,
  119. radar_detect_width);
  120. if (err) {
  121. wdev->connect_keys = NULL;
  122. return err;
  123. }
  124. err = rdev_join_ibss(rdev, dev, params);
  125. if (err) {
  126. wdev->connect_keys = NULL;
  127. return err;
  128. }
  129. memcpy(wdev->ssid, params->ssid, params->ssid_len);
  130. wdev->ssid_len = params->ssid_len;
  131. return 0;
  132. }
  133. int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
  134. struct net_device *dev,
  135. struct cfg80211_ibss_params *params,
  136. struct cfg80211_cached_keys *connkeys)
  137. {
  138. struct wireless_dev *wdev = dev->ieee80211_ptr;
  139. int err;
  140. ASSERT_RTNL();
  141. wdev_lock(wdev);
  142. err = __cfg80211_join_ibss(rdev, dev, params, connkeys);
  143. wdev_unlock(wdev);
  144. return err;
  145. }
  146. static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext)
  147. {
  148. struct wireless_dev *wdev = dev->ieee80211_ptr;
  149. struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
  150. int i;
  151. ASSERT_WDEV_LOCK(wdev);
  152. kfree(wdev->connect_keys);
  153. wdev->connect_keys = NULL;
  154. rdev_set_qos_map(rdev, dev, NULL);
  155. /*
  156. * Delete all the keys ... pairwise keys can't really
  157. * exist any more anyway, but default keys might.
  158. */
  159. if (rdev->ops->del_key)
  160. for (i = 0; i < 6; i++)
  161. rdev_del_key(rdev, dev, i, false, NULL);
  162. if (wdev->current_bss) {
  163. cfg80211_unhold_bss(wdev->current_bss);
  164. cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
  165. }
  166. wdev->current_bss = NULL;
  167. wdev->ssid_len = 0;
  168. memset(&wdev->chandef, 0, sizeof(wdev->chandef));
  169. #ifdef CONFIG_CFG80211_WEXT
  170. if (!nowext)
  171. wdev->wext.ibss.ssid_len = 0;
  172. #endif
  173. }
  174. void cfg80211_clear_ibss(struct net_device *dev, bool nowext)
  175. {
  176. struct wireless_dev *wdev = dev->ieee80211_ptr;
  177. wdev_lock(wdev);
  178. __cfg80211_clear_ibss(dev, nowext);
  179. wdev_unlock(wdev);
  180. }
  181. int __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
  182. struct net_device *dev, bool nowext)
  183. {
  184. struct wireless_dev *wdev = dev->ieee80211_ptr;
  185. int err;
  186. ASSERT_WDEV_LOCK(wdev);
  187. if (!wdev->ssid_len)
  188. return -ENOLINK;
  189. err = rdev_leave_ibss(rdev, dev);
  190. if (err)
  191. return err;
  192. __cfg80211_clear_ibss(dev, nowext);
  193. return 0;
  194. }
  195. int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
  196. struct net_device *dev, bool nowext)
  197. {
  198. struct wireless_dev *wdev = dev->ieee80211_ptr;
  199. int err;
  200. wdev_lock(wdev);
  201. err = __cfg80211_leave_ibss(rdev, dev, nowext);
  202. wdev_unlock(wdev);
  203. return err;
  204. }
  205. #ifdef CONFIG_CFG80211_WEXT
  206. int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
  207. struct wireless_dev *wdev)
  208. {
  209. struct cfg80211_cached_keys *ck = NULL;
  210. enum ieee80211_band band;
  211. int i, err;
  212. ASSERT_WDEV_LOCK(wdev);
  213. if (!wdev->wext.ibss.beacon_interval)
  214. wdev->wext.ibss.beacon_interval = 100;
  215. /* try to find an IBSS channel if none requested ... */
  216. if (!wdev->wext.ibss.chandef.chan) {
  217. struct ieee80211_channel *new_chan = NULL;
  218. for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
  219. struct ieee80211_supported_band *sband;
  220. struct ieee80211_channel *chan;
  221. sband = rdev->wiphy.bands[band];
  222. if (!sband)
  223. continue;
  224. for (i = 0; i < sband->n_channels; i++) {
  225. chan = &sband->channels[i];
  226. if (chan->flags & IEEE80211_CHAN_NO_IR)
  227. continue;
  228. if (chan->flags & IEEE80211_CHAN_DISABLED)
  229. continue;
  230. new_chan = chan;
  231. break;
  232. }
  233. if (new_chan)
  234. break;
  235. }
  236. if (!new_chan)
  237. return -EINVAL;
  238. cfg80211_chandef_create(&wdev->wext.ibss.chandef, new_chan,
  239. NL80211_CHAN_NO_HT);
  240. }
  241. /* don't join -- SSID is not there */
  242. if (!wdev->wext.ibss.ssid_len)
  243. return 0;
  244. if (!netif_running(wdev->netdev))
  245. return 0;
  246. if (wdev->wext.keys) {
  247. wdev->wext.keys->def = wdev->wext.default_key;
  248. wdev->wext.keys->defmgmt = wdev->wext.default_mgmt_key;
  249. }
  250. wdev->wext.ibss.privacy = wdev->wext.default_key != -1;
  251. if (wdev->wext.keys) {
  252. ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL);
  253. if (!ck)
  254. return -ENOMEM;
  255. for (i = 0; i < 6; i++)
  256. ck->params[i].key = ck->data[i];
  257. }
  258. err = __cfg80211_join_ibss(rdev, wdev->netdev,
  259. &wdev->wext.ibss, ck);
  260. if (err)
  261. kfree(ck);
  262. return err;
  263. }
  264. int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
  265. struct iw_request_info *info,
  266. struct iw_freq *wextfreq, char *extra)
  267. {
  268. struct wireless_dev *wdev = dev->ieee80211_ptr;
  269. struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
  270. struct ieee80211_channel *chan = NULL;
  271. int err, freq;
  272. /* call only for ibss! */
  273. if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
  274. return -EINVAL;
  275. if (!rdev->ops->join_ibss)
  276. return -EOPNOTSUPP;
  277. freq = cfg80211_wext_freq(wdev->wiphy, wextfreq);
  278. if (freq < 0)
  279. return freq;
  280. if (freq) {
  281. chan = ieee80211_get_channel(wdev->wiphy, freq);
  282. if (!chan)
  283. return -EINVAL;
  284. if (chan->flags & IEEE80211_CHAN_NO_IR ||
  285. chan->flags & IEEE80211_CHAN_DISABLED)
  286. return -EINVAL;
  287. }
  288. if (wdev->wext.ibss.chandef.chan == chan)
  289. return 0;
  290. wdev_lock(wdev);
  291. err = 0;
  292. if (wdev->ssid_len)
  293. err = __cfg80211_leave_ibss(rdev, dev, true);
  294. wdev_unlock(wdev);
  295. if (err)
  296. return err;
  297. if (chan) {
  298. cfg80211_chandef_create(&wdev->wext.ibss.chandef, chan,
  299. NL80211_CHAN_NO_HT);
  300. wdev->wext.ibss.channel_fixed = true;
  301. } else {
  302. /* cfg80211_ibss_wext_join will pick one if needed */
  303. wdev->wext.ibss.channel_fixed = false;
  304. }
  305. wdev_lock(wdev);
  306. err = cfg80211_ibss_wext_join(rdev, wdev);
  307. wdev_unlock(wdev);
  308. return err;
  309. }
  310. int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
  311. struct iw_request_info *info,
  312. struct iw_freq *freq, char *extra)
  313. {
  314. struct wireless_dev *wdev = dev->ieee80211_ptr;
  315. struct ieee80211_channel *chan = NULL;
  316. /* call only for ibss! */
  317. if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
  318. return -EINVAL;
  319. wdev_lock(wdev);
  320. if (wdev->current_bss)
  321. chan = wdev->current_bss->pub.channel;
  322. else if (wdev->wext.ibss.chandef.chan)
  323. chan = wdev->wext.ibss.chandef.chan;
  324. wdev_unlock(wdev);
  325. if (chan) {
  326. freq->m = chan->center_freq;
  327. freq->e = 6;
  328. return 0;
  329. }
  330. /* no channel if not joining */
  331. return -EINVAL;
  332. }
  333. int cfg80211_ibss_wext_siwessid(struct net_device *dev,
  334. struct iw_request_info *info,
  335. struct iw_point *data, char *ssid)
  336. {
  337. struct wireless_dev *wdev = dev->ieee80211_ptr;
  338. struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
  339. size_t len = data->length;
  340. int err;
  341. /* call only for ibss! */
  342. if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
  343. return -EINVAL;
  344. if (!rdev->ops->join_ibss)
  345. return -EOPNOTSUPP;
  346. wdev_lock(wdev);
  347. err = 0;
  348. if (wdev->ssid_len)
  349. err = __cfg80211_leave_ibss(rdev, dev, true);
  350. wdev_unlock(wdev);
  351. if (err)
  352. return err;
  353. /* iwconfig uses nul termination in SSID.. */
  354. if (len > 0 && ssid[len - 1] == '\0')
  355. len--;
  356. wdev->wext.ibss.ssid = wdev->ssid;
  357. memcpy(wdev->wext.ibss.ssid, ssid, len);
  358. wdev->wext.ibss.ssid_len = len;
  359. wdev_lock(wdev);
  360. err = cfg80211_ibss_wext_join(rdev, wdev);
  361. wdev_unlock(wdev);
  362. return err;
  363. }
  364. int cfg80211_ibss_wext_giwessid(struct net_device *dev,
  365. struct iw_request_info *info,
  366. struct iw_point *data, char *ssid)
  367. {
  368. struct wireless_dev *wdev = dev->ieee80211_ptr;
  369. /* call only for ibss! */
  370. if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
  371. return -EINVAL;
  372. data->flags = 0;
  373. wdev_lock(wdev);
  374. if (wdev->ssid_len) {
  375. data->flags = 1;
  376. data->length = wdev->ssid_len;
  377. memcpy(ssid, wdev->ssid, data->length);
  378. } else if (wdev->wext.ibss.ssid && wdev->wext.ibss.ssid_len) {
  379. data->flags = 1;
  380. data->length = wdev->wext.ibss.ssid_len;
  381. memcpy(ssid, wdev->wext.ibss.ssid, data->length);
  382. }
  383. wdev_unlock(wdev);
  384. return 0;
  385. }
  386. int cfg80211_ibss_wext_siwap(struct net_device *dev,
  387. struct iw_request_info *info,
  388. struct sockaddr *ap_addr, char *extra)
  389. {
  390. struct wireless_dev *wdev = dev->ieee80211_ptr;
  391. struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
  392. u8 *bssid = ap_addr->sa_data;
  393. int err;
  394. /* call only for ibss! */
  395. if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
  396. return -EINVAL;
  397. if (!rdev->ops->join_ibss)
  398. return -EOPNOTSUPP;
  399. if (ap_addr->sa_family != ARPHRD_ETHER)
  400. return -EINVAL;
  401. /* automatic mode */
  402. if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid))
  403. bssid = NULL;
  404. /* both automatic */
  405. if (!bssid && !wdev->wext.ibss.bssid)
  406. return 0;
  407. /* fixed already - and no change */
  408. if (wdev->wext.ibss.bssid && bssid &&
  409. ether_addr_equal(bssid, wdev->wext.ibss.bssid))
  410. return 0;
  411. wdev_lock(wdev);
  412. err = 0;
  413. if (wdev->ssid_len)
  414. err = __cfg80211_leave_ibss(rdev, dev, true);
  415. wdev_unlock(wdev);
  416. if (err)
  417. return err;
  418. if (bssid) {
  419. memcpy(wdev->wext.bssid, bssid, ETH_ALEN);
  420. wdev->wext.ibss.bssid = wdev->wext.bssid;
  421. } else
  422. wdev->wext.ibss.bssid = NULL;
  423. wdev_lock(wdev);
  424. err = cfg80211_ibss_wext_join(rdev, wdev);
  425. wdev_unlock(wdev);
  426. return err;
  427. }
  428. int cfg80211_ibss_wext_giwap(struct net_device *dev,
  429. struct iw_request_info *info,
  430. struct sockaddr *ap_addr, char *extra)
  431. {
  432. struct wireless_dev *wdev = dev->ieee80211_ptr;
  433. /* call only for ibss! */
  434. if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
  435. return -EINVAL;
  436. ap_addr->sa_family = ARPHRD_ETHER;
  437. wdev_lock(wdev);
  438. if (wdev->current_bss)
  439. memcpy(ap_addr->sa_data, wdev->current_bss->pub.bssid, ETH_ALEN);
  440. else if (wdev->wext.ibss.bssid)
  441. memcpy(ap_addr->sa_data, wdev->wext.ibss.bssid, ETH_ALEN);
  442. else
  443. memset(ap_addr->sa_data, 0, ETH_ALEN);
  444. wdev_unlock(wdev);
  445. return 0;
  446. }
  447. #endif