cfg.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074
  1. /*
  2. * mac80211 configuration hooks for cfg80211
  3. *
  4. * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net>
  5. *
  6. * This file is GPLv2 as found in COPYING.
  7. */
  8. #include <linux/ieee80211.h>
  9. #include <linux/nl80211.h>
  10. #include <linux/rtnetlink.h>
  11. #include <net/net_namespace.h>
  12. #include <linux/rcupdate.h>
  13. #include <net/cfg80211.h>
  14. #include "ieee80211_i.h"
  15. #include "cfg.h"
  16. #include "rate.h"
  17. #include "mesh.h"
  18. struct ieee80211_hw *wiphy_to_hw(struct wiphy *wiphy)
  19. {
  20. struct ieee80211_local *local = wiphy_priv(wiphy);
  21. return &local->hw;
  22. }
  23. EXPORT_SYMBOL(wiphy_to_hw);
  24. static bool nl80211_type_check(enum nl80211_iftype type)
  25. {
  26. switch (type) {
  27. case NL80211_IFTYPE_ADHOC:
  28. case NL80211_IFTYPE_STATION:
  29. case NL80211_IFTYPE_MONITOR:
  30. #ifdef CONFIG_MAC80211_MESH
  31. case NL80211_IFTYPE_MESH_POINT:
  32. #endif
  33. case NL80211_IFTYPE_WDS:
  34. return true;
  35. default:
  36. return false;
  37. }
  38. }
  39. static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
  40. enum nl80211_iftype type, u32 *flags,
  41. struct vif_params *params)
  42. {
  43. struct ieee80211_local *local = wiphy_priv(wiphy);
  44. struct net_device *dev;
  45. struct ieee80211_sub_if_data *sdata;
  46. int err;
  47. if (!nl80211_type_check(type))
  48. return -EINVAL;
  49. err = ieee80211_if_add(local, name, &dev, type, params);
  50. if (err || type != NL80211_IFTYPE_MONITOR || !flags)
  51. return err;
  52. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  53. sdata->u.mntr_flags = *flags;
  54. return 0;
  55. }
  56. static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex)
  57. {
  58. struct net_device *dev;
  59. struct ieee80211_sub_if_data *sdata;
  60. /* we're under RTNL */
  61. dev = __dev_get_by_index(&init_net, ifindex);
  62. if (!dev)
  63. return -ENODEV;
  64. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  65. ieee80211_if_remove(sdata);
  66. return 0;
  67. }
  68. static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
  69. enum nl80211_iftype type, u32 *flags,
  70. struct vif_params *params)
  71. {
  72. struct ieee80211_local *local = wiphy_priv(wiphy);
  73. struct net_device *dev;
  74. struct ieee80211_sub_if_data *sdata;
  75. int ret;
  76. /* we're under RTNL */
  77. dev = __dev_get_by_index(&init_net, ifindex);
  78. if (!dev)
  79. return -ENODEV;
  80. if (!nl80211_type_check(type))
  81. return -EINVAL;
  82. if (dev == local->mdev)
  83. return -EOPNOTSUPP;
  84. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  85. ret = ieee80211_if_change_type(sdata, type);
  86. if (ret)
  87. return ret;
  88. if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len)
  89. ieee80211_sdata_set_mesh_id(sdata,
  90. params->mesh_id_len,
  91. params->mesh_id);
  92. if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags)
  93. return 0;
  94. sdata->u.mntr_flags = *flags;
  95. return 0;
  96. }
  97. static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
  98. u8 key_idx, u8 *mac_addr,
  99. struct key_params *params)
  100. {
  101. struct ieee80211_local *local = wiphy_priv(wiphy);
  102. struct ieee80211_sub_if_data *sdata;
  103. struct sta_info *sta = NULL;
  104. enum ieee80211_key_alg alg;
  105. struct ieee80211_key *key;
  106. int err;
  107. if (dev == local->mdev)
  108. return -EOPNOTSUPP;
  109. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  110. switch (params->cipher) {
  111. case WLAN_CIPHER_SUITE_WEP40:
  112. case WLAN_CIPHER_SUITE_WEP104:
  113. alg = ALG_WEP;
  114. break;
  115. case WLAN_CIPHER_SUITE_TKIP:
  116. alg = ALG_TKIP;
  117. break;
  118. case WLAN_CIPHER_SUITE_CCMP:
  119. alg = ALG_CCMP;
  120. break;
  121. default:
  122. return -EINVAL;
  123. }
  124. key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key);
  125. if (!key)
  126. return -ENOMEM;
  127. rcu_read_lock();
  128. if (mac_addr) {
  129. sta = sta_info_get(sdata->local, mac_addr);
  130. if (!sta) {
  131. ieee80211_key_free(key);
  132. err = -ENOENT;
  133. goto out_unlock;
  134. }
  135. }
  136. ieee80211_key_link(key, sdata, sta);
  137. err = 0;
  138. out_unlock:
  139. rcu_read_unlock();
  140. return err;
  141. }
  142. static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
  143. u8 key_idx, u8 *mac_addr)
  144. {
  145. struct ieee80211_local *local = wiphy_priv(wiphy);
  146. struct ieee80211_sub_if_data *sdata;
  147. struct sta_info *sta;
  148. int ret;
  149. if (dev == local->mdev)
  150. return -EOPNOTSUPP;
  151. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  152. rcu_read_lock();
  153. if (mac_addr) {
  154. ret = -ENOENT;
  155. sta = sta_info_get(sdata->local, mac_addr);
  156. if (!sta)
  157. goto out_unlock;
  158. if (sta->key) {
  159. ieee80211_key_free(sta->key);
  160. WARN_ON(sta->key);
  161. ret = 0;
  162. }
  163. goto out_unlock;
  164. }
  165. if (!sdata->keys[key_idx]) {
  166. ret = -ENOENT;
  167. goto out_unlock;
  168. }
  169. ieee80211_key_free(sdata->keys[key_idx]);
  170. WARN_ON(sdata->keys[key_idx]);
  171. ret = 0;
  172. out_unlock:
  173. rcu_read_unlock();
  174. return ret;
  175. }
  176. static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
  177. u8 key_idx, u8 *mac_addr, void *cookie,
  178. void (*callback)(void *cookie,
  179. struct key_params *params))
  180. {
  181. struct ieee80211_local *local = wiphy_priv(wiphy);
  182. struct ieee80211_sub_if_data *sdata;
  183. struct sta_info *sta = NULL;
  184. u8 seq[6] = {0};
  185. struct key_params params;
  186. struct ieee80211_key *key;
  187. u32 iv32;
  188. u16 iv16;
  189. int err = -ENOENT;
  190. if (dev == local->mdev)
  191. return -EOPNOTSUPP;
  192. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  193. rcu_read_lock();
  194. if (mac_addr) {
  195. sta = sta_info_get(sdata->local, mac_addr);
  196. if (!sta)
  197. goto out;
  198. key = sta->key;
  199. } else
  200. key = sdata->keys[key_idx];
  201. if (!key)
  202. goto out;
  203. memset(&params, 0, sizeof(params));
  204. switch (key->conf.alg) {
  205. case ALG_TKIP:
  206. params.cipher = WLAN_CIPHER_SUITE_TKIP;
  207. iv32 = key->u.tkip.tx.iv32;
  208. iv16 = key->u.tkip.tx.iv16;
  209. if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE &&
  210. sdata->local->ops->get_tkip_seq)
  211. sdata->local->ops->get_tkip_seq(
  212. local_to_hw(sdata->local),
  213. key->conf.hw_key_idx,
  214. &iv32, &iv16);
  215. seq[0] = iv16 & 0xff;
  216. seq[1] = (iv16 >> 8) & 0xff;
  217. seq[2] = iv32 & 0xff;
  218. seq[3] = (iv32 >> 8) & 0xff;
  219. seq[4] = (iv32 >> 16) & 0xff;
  220. seq[5] = (iv32 >> 24) & 0xff;
  221. params.seq = seq;
  222. params.seq_len = 6;
  223. break;
  224. case ALG_CCMP:
  225. params.cipher = WLAN_CIPHER_SUITE_CCMP;
  226. seq[0] = key->u.ccmp.tx_pn[5];
  227. seq[1] = key->u.ccmp.tx_pn[4];
  228. seq[2] = key->u.ccmp.tx_pn[3];
  229. seq[3] = key->u.ccmp.tx_pn[2];
  230. seq[4] = key->u.ccmp.tx_pn[1];
  231. seq[5] = key->u.ccmp.tx_pn[0];
  232. params.seq = seq;
  233. params.seq_len = 6;
  234. break;
  235. case ALG_WEP:
  236. if (key->conf.keylen == 5)
  237. params.cipher = WLAN_CIPHER_SUITE_WEP40;
  238. else
  239. params.cipher = WLAN_CIPHER_SUITE_WEP104;
  240. break;
  241. }
  242. params.key = key->conf.key;
  243. params.key_len = key->conf.keylen;
  244. callback(cookie, &params);
  245. err = 0;
  246. out:
  247. rcu_read_unlock();
  248. return err;
  249. }
  250. static int ieee80211_config_default_key(struct wiphy *wiphy,
  251. struct net_device *dev,
  252. u8 key_idx)
  253. {
  254. struct ieee80211_local *local = wiphy_priv(wiphy);
  255. struct ieee80211_sub_if_data *sdata;
  256. if (dev == local->mdev)
  257. return -EOPNOTSUPP;
  258. rcu_read_lock();
  259. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  260. ieee80211_set_default_key(sdata, key_idx);
  261. rcu_read_unlock();
  262. return 0;
  263. }
  264. static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
  265. {
  266. struct ieee80211_sub_if_data *sdata = sta->sdata;
  267. sinfo->filled = STATION_INFO_INACTIVE_TIME |
  268. STATION_INFO_RX_BYTES |
  269. STATION_INFO_TX_BYTES;
  270. sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
  271. sinfo->rx_bytes = sta->rx_bytes;
  272. sinfo->tx_bytes = sta->tx_bytes;
  273. if (ieee80211_vif_is_mesh(&sdata->vif)) {
  274. #ifdef CONFIG_MAC80211_MESH
  275. sinfo->filled |= STATION_INFO_LLID |
  276. STATION_INFO_PLID |
  277. STATION_INFO_PLINK_STATE;
  278. sinfo->llid = le16_to_cpu(sta->llid);
  279. sinfo->plid = le16_to_cpu(sta->plid);
  280. sinfo->plink_state = sta->plink_state;
  281. #endif
  282. }
  283. }
  284. static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
  285. int idx, u8 *mac, struct station_info *sinfo)
  286. {
  287. struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
  288. struct sta_info *sta;
  289. int ret = -ENOENT;
  290. rcu_read_lock();
  291. sta = sta_info_get_by_idx(local, idx, dev);
  292. if (sta) {
  293. ret = 0;
  294. memcpy(mac, sta->sta.addr, ETH_ALEN);
  295. sta_set_sinfo(sta, sinfo);
  296. }
  297. rcu_read_unlock();
  298. return ret;
  299. }
  300. static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
  301. u8 *mac, struct station_info *sinfo)
  302. {
  303. struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
  304. struct sta_info *sta;
  305. int ret = -ENOENT;
  306. rcu_read_lock();
  307. /* XXX: verify sta->dev == dev */
  308. sta = sta_info_get(local, mac);
  309. if (sta) {
  310. ret = 0;
  311. sta_set_sinfo(sta, sinfo);
  312. }
  313. rcu_read_unlock();
  314. return ret;
  315. }
  316. /*
  317. * This handles both adding a beacon and setting new beacon info
  318. */
  319. static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
  320. struct beacon_parameters *params)
  321. {
  322. struct beacon_data *new, *old;
  323. int new_head_len, new_tail_len;
  324. int size;
  325. int err = -EINVAL;
  326. old = sdata->u.ap.beacon;
  327. /* head must not be zero-length */
  328. if (params->head && !params->head_len)
  329. return -EINVAL;
  330. /*
  331. * This is a kludge. beacon interval should really be part
  332. * of the beacon information.
  333. */
  334. if (params->interval) {
  335. sdata->local->hw.conf.beacon_int = params->interval;
  336. if (ieee80211_hw_config(sdata->local))
  337. return -EINVAL;
  338. /*
  339. * We updated some parameter so if below bails out
  340. * it's not an error.
  341. */
  342. err = 0;
  343. }
  344. /* Need to have a beacon head if we don't have one yet */
  345. if (!params->head && !old)
  346. return err;
  347. /* sorry, no way to start beaconing without dtim period */
  348. if (!params->dtim_period && !old)
  349. return err;
  350. /* new or old head? */
  351. if (params->head)
  352. new_head_len = params->head_len;
  353. else
  354. new_head_len = old->head_len;
  355. /* new or old tail? */
  356. if (params->tail || !old)
  357. /* params->tail_len will be zero for !params->tail */
  358. new_tail_len = params->tail_len;
  359. else
  360. new_tail_len = old->tail_len;
  361. size = sizeof(*new) + new_head_len + new_tail_len;
  362. new = kzalloc(size, GFP_KERNEL);
  363. if (!new)
  364. return -ENOMEM;
  365. /* start filling the new info now */
  366. /* new or old dtim period? */
  367. if (params->dtim_period)
  368. new->dtim_period = params->dtim_period;
  369. else
  370. new->dtim_period = old->dtim_period;
  371. /*
  372. * pointers go into the block we allocated,
  373. * memory is | beacon_data | head | tail |
  374. */
  375. new->head = ((u8 *) new) + sizeof(*new);
  376. new->tail = new->head + new_head_len;
  377. new->head_len = new_head_len;
  378. new->tail_len = new_tail_len;
  379. /* copy in head */
  380. if (params->head)
  381. memcpy(new->head, params->head, new_head_len);
  382. else
  383. memcpy(new->head, old->head, new_head_len);
  384. /* copy in optional tail */
  385. if (params->tail)
  386. memcpy(new->tail, params->tail, new_tail_len);
  387. else
  388. if (old)
  389. memcpy(new->tail, old->tail, new_tail_len);
  390. rcu_assign_pointer(sdata->u.ap.beacon, new);
  391. synchronize_rcu();
  392. kfree(old);
  393. return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
  394. }
  395. static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
  396. struct beacon_parameters *params)
  397. {
  398. struct ieee80211_local *local = wiphy_priv(wiphy);
  399. struct ieee80211_sub_if_data *sdata;
  400. struct beacon_data *old;
  401. if (dev == local->mdev)
  402. return -EOPNOTSUPP;
  403. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  404. if (sdata->vif.type != NL80211_IFTYPE_AP)
  405. return -EINVAL;
  406. old = sdata->u.ap.beacon;
  407. if (old)
  408. return -EALREADY;
  409. return ieee80211_config_beacon(sdata, params);
  410. }
  411. static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
  412. struct beacon_parameters *params)
  413. {
  414. struct ieee80211_local *local = wiphy_priv(wiphy);
  415. struct ieee80211_sub_if_data *sdata;
  416. struct beacon_data *old;
  417. if (dev == local->mdev)
  418. return -EOPNOTSUPP;
  419. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  420. if (sdata->vif.type != NL80211_IFTYPE_AP)
  421. return -EINVAL;
  422. old = sdata->u.ap.beacon;
  423. if (!old)
  424. return -ENOENT;
  425. return ieee80211_config_beacon(sdata, params);
  426. }
  427. static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
  428. {
  429. struct ieee80211_local *local = wiphy_priv(wiphy);
  430. struct ieee80211_sub_if_data *sdata;
  431. struct beacon_data *old;
  432. if (dev == local->mdev)
  433. return -EOPNOTSUPP;
  434. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  435. if (sdata->vif.type != NL80211_IFTYPE_AP)
  436. return -EINVAL;
  437. old = sdata->u.ap.beacon;
  438. if (!old)
  439. return -ENOENT;
  440. rcu_assign_pointer(sdata->u.ap.beacon, NULL);
  441. synchronize_rcu();
  442. kfree(old);
  443. return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
  444. }
  445. /* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
  446. struct iapp_layer2_update {
  447. u8 da[ETH_ALEN]; /* broadcast */
  448. u8 sa[ETH_ALEN]; /* STA addr */
  449. __be16 len; /* 6 */
  450. u8 dsap; /* 0 */
  451. u8 ssap; /* 0 */
  452. u8 control;
  453. u8 xid_info[3];
  454. } __attribute__ ((packed));
  455. static void ieee80211_send_layer2_update(struct sta_info *sta)
  456. {
  457. struct iapp_layer2_update *msg;
  458. struct sk_buff *skb;
  459. /* Send Level 2 Update Frame to update forwarding tables in layer 2
  460. * bridge devices */
  461. skb = dev_alloc_skb(sizeof(*msg));
  462. if (!skb)
  463. return;
  464. msg = (struct iapp_layer2_update *)skb_put(skb, sizeof(*msg));
  465. /* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID)
  466. * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */
  467. memset(msg->da, 0xff, ETH_ALEN);
  468. memcpy(msg->sa, sta->sta.addr, ETH_ALEN);
  469. msg->len = htons(6);
  470. msg->dsap = 0;
  471. msg->ssap = 0x01; /* NULL LSAP, CR Bit: Response */
  472. msg->control = 0xaf; /* XID response lsb.1111F101.
  473. * F=0 (no poll command; unsolicited frame) */
  474. msg->xid_info[0] = 0x81; /* XID format identifier */
  475. msg->xid_info[1] = 1; /* LLC types/classes: Type 1 LLC */
  476. msg->xid_info[2] = 0; /* XID sender's receive window size (RW) */
  477. skb->dev = sta->sdata->dev;
  478. skb->protocol = eth_type_trans(skb, sta->sdata->dev);
  479. memset(skb->cb, 0, sizeof(skb->cb));
  480. netif_rx(skb);
  481. }
  482. static void sta_apply_parameters(struct ieee80211_local *local,
  483. struct sta_info *sta,
  484. struct station_parameters *params)
  485. {
  486. u32 rates;
  487. int i, j;
  488. struct ieee80211_supported_band *sband;
  489. struct ieee80211_sub_if_data *sdata = sta->sdata;
  490. /*
  491. * FIXME: updating the flags is racy when this function is
  492. * called from ieee80211_change_station(), this will
  493. * be resolved in a future patch.
  494. */
  495. if (params->station_flags & STATION_FLAG_CHANGED) {
  496. spin_lock_bh(&sta->lock);
  497. sta->flags &= ~WLAN_STA_AUTHORIZED;
  498. if (params->station_flags & STATION_FLAG_AUTHORIZED)
  499. sta->flags |= WLAN_STA_AUTHORIZED;
  500. sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
  501. if (params->station_flags & STATION_FLAG_SHORT_PREAMBLE)
  502. sta->flags |= WLAN_STA_SHORT_PREAMBLE;
  503. sta->flags &= ~WLAN_STA_WME;
  504. if (params->station_flags & STATION_FLAG_WME)
  505. sta->flags |= WLAN_STA_WME;
  506. spin_unlock_bh(&sta->lock);
  507. }
  508. /*
  509. * FIXME: updating the following information is racy when this
  510. * function is called from ieee80211_change_station().
  511. * However, all this information should be static so
  512. * maybe we should just reject attemps to change it.
  513. */
  514. if (params->aid) {
  515. sta->sta.aid = params->aid;
  516. if (sta->sta.aid > IEEE80211_MAX_AID)
  517. sta->sta.aid = 0; /* XXX: should this be an error? */
  518. }
  519. if (params->listen_interval >= 0)
  520. sta->listen_interval = params->listen_interval;
  521. if (params->supported_rates) {
  522. rates = 0;
  523. sband = local->hw.wiphy->bands[local->oper_channel->band];
  524. for (i = 0; i < params->supported_rates_len; i++) {
  525. int rate = (params->supported_rates[i] & 0x7f) * 5;
  526. for (j = 0; j < sband->n_bitrates; j++) {
  527. if (sband->bitrates[j].bitrate == rate)
  528. rates |= BIT(j);
  529. }
  530. }
  531. sta->sta.supp_rates[local->oper_channel->band] = rates;
  532. }
  533. if (params->ht_capa) {
  534. ieee80211_ht_cap_ie_to_ht_info(params->ht_capa,
  535. &sta->ht_info);
  536. }
  537. if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) {
  538. switch (params->plink_action) {
  539. case PLINK_ACTION_OPEN:
  540. mesh_plink_open(sta);
  541. break;
  542. case PLINK_ACTION_BLOCK:
  543. mesh_plink_block(sta);
  544. break;
  545. }
  546. }
  547. }
  548. static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
  549. u8 *mac, struct station_parameters *params)
  550. {
  551. struct ieee80211_local *local = wiphy_priv(wiphy);
  552. struct sta_info *sta;
  553. struct ieee80211_sub_if_data *sdata;
  554. int err;
  555. if (dev == local->mdev || params->vlan == local->mdev)
  556. return -EOPNOTSUPP;
  557. /* Prevent a race with changing the rate control algorithm */
  558. if (!netif_running(dev))
  559. return -ENETDOWN;
  560. if (params->vlan) {
  561. sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
  562. if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
  563. sdata->vif.type != NL80211_IFTYPE_AP)
  564. return -EINVAL;
  565. } else
  566. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  567. if (compare_ether_addr(mac, dev->dev_addr) == 0)
  568. return -EINVAL;
  569. if (is_multicast_ether_addr(mac))
  570. return -EINVAL;
  571. sta = sta_info_alloc(sdata, mac, GFP_KERNEL);
  572. if (!sta)
  573. return -ENOMEM;
  574. sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;
  575. sta_apply_parameters(local, sta, params);
  576. rate_control_rate_init(sta, local);
  577. rcu_read_lock();
  578. err = sta_info_insert(sta);
  579. if (err) {
  580. /* STA has been freed */
  581. rcu_read_unlock();
  582. return err;
  583. }
  584. if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
  585. sdata->vif.type == NL80211_IFTYPE_AP)
  586. ieee80211_send_layer2_update(sta);
  587. rcu_read_unlock();
  588. return 0;
  589. }
  590. static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
  591. u8 *mac)
  592. {
  593. struct ieee80211_local *local = wiphy_priv(wiphy);
  594. struct ieee80211_sub_if_data *sdata;
  595. struct sta_info *sta;
  596. if (dev == local->mdev)
  597. return -EOPNOTSUPP;
  598. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  599. if (mac) {
  600. rcu_read_lock();
  601. /* XXX: get sta belonging to dev */
  602. sta = sta_info_get(local, mac);
  603. if (!sta) {
  604. rcu_read_unlock();
  605. return -ENOENT;
  606. }
  607. sta_info_unlink(&sta);
  608. rcu_read_unlock();
  609. sta_info_destroy(sta);
  610. } else
  611. sta_info_flush(local, sdata);
  612. return 0;
  613. }
  614. static int ieee80211_change_station(struct wiphy *wiphy,
  615. struct net_device *dev,
  616. u8 *mac,
  617. struct station_parameters *params)
  618. {
  619. struct ieee80211_local *local = wiphy_priv(wiphy);
  620. struct sta_info *sta;
  621. struct ieee80211_sub_if_data *vlansdata;
  622. if (dev == local->mdev || params->vlan == local->mdev)
  623. return -EOPNOTSUPP;
  624. rcu_read_lock();
  625. /* XXX: get sta belonging to dev */
  626. sta = sta_info_get(local, mac);
  627. if (!sta) {
  628. rcu_read_unlock();
  629. return -ENOENT;
  630. }
  631. if (params->vlan && params->vlan != sta->sdata->dev) {
  632. vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
  633. if (vlansdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
  634. vlansdata->vif.type != NL80211_IFTYPE_AP) {
  635. rcu_read_unlock();
  636. return -EINVAL;
  637. }
  638. sta->sdata = vlansdata;
  639. ieee80211_send_layer2_update(sta);
  640. }
  641. sta_apply_parameters(local, sta, params);
  642. rcu_read_unlock();
  643. return 0;
  644. }
  645. #ifdef CONFIG_MAC80211_MESH
  646. static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
  647. u8 *dst, u8 *next_hop)
  648. {
  649. struct ieee80211_local *local = wiphy_priv(wiphy);
  650. struct ieee80211_sub_if_data *sdata;
  651. struct mesh_path *mpath;
  652. struct sta_info *sta;
  653. int err;
  654. if (dev == local->mdev)
  655. return -EOPNOTSUPP;
  656. if (!netif_running(dev))
  657. return -ENETDOWN;
  658. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  659. if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
  660. return -ENOTSUPP;
  661. rcu_read_lock();
  662. sta = sta_info_get(local, next_hop);
  663. if (!sta) {
  664. rcu_read_unlock();
  665. return -ENOENT;
  666. }
  667. err = mesh_path_add(dst, sdata);
  668. if (err) {
  669. rcu_read_unlock();
  670. return err;
  671. }
  672. mpath = mesh_path_lookup(dst, sdata);
  673. if (!mpath) {
  674. rcu_read_unlock();
  675. return -ENXIO;
  676. }
  677. mesh_path_fix_nexthop(mpath, sta);
  678. rcu_read_unlock();
  679. return 0;
  680. }
  681. static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev,
  682. u8 *dst)
  683. {
  684. struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  685. if (dst)
  686. return mesh_path_del(dst, sdata);
  687. mesh_path_flush(sdata);
  688. return 0;
  689. }
  690. static int ieee80211_change_mpath(struct wiphy *wiphy,
  691. struct net_device *dev,
  692. u8 *dst, u8 *next_hop)
  693. {
  694. struct ieee80211_local *local = wiphy_priv(wiphy);
  695. struct ieee80211_sub_if_data *sdata;
  696. struct mesh_path *mpath;
  697. struct sta_info *sta;
  698. if (dev == local->mdev)
  699. return -EOPNOTSUPP;
  700. if (!netif_running(dev))
  701. return -ENETDOWN;
  702. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  703. if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
  704. return -ENOTSUPP;
  705. rcu_read_lock();
  706. sta = sta_info_get(local, next_hop);
  707. if (!sta) {
  708. rcu_read_unlock();
  709. return -ENOENT;
  710. }
  711. mpath = mesh_path_lookup(dst, sdata);
  712. if (!mpath) {
  713. rcu_read_unlock();
  714. return -ENOENT;
  715. }
  716. mesh_path_fix_nexthop(mpath, sta);
  717. rcu_read_unlock();
  718. return 0;
  719. }
  720. static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
  721. struct mpath_info *pinfo)
  722. {
  723. if (mpath->next_hop)
  724. memcpy(next_hop, mpath->next_hop->sta.addr, ETH_ALEN);
  725. else
  726. memset(next_hop, 0, ETH_ALEN);
  727. pinfo->filled = MPATH_INFO_FRAME_QLEN |
  728. MPATH_INFO_DSN |
  729. MPATH_INFO_METRIC |
  730. MPATH_INFO_EXPTIME |
  731. MPATH_INFO_DISCOVERY_TIMEOUT |
  732. MPATH_INFO_DISCOVERY_RETRIES |
  733. MPATH_INFO_FLAGS;
  734. pinfo->frame_qlen = mpath->frame_queue.qlen;
  735. pinfo->dsn = mpath->dsn;
  736. pinfo->metric = mpath->metric;
  737. if (time_before(jiffies, mpath->exp_time))
  738. pinfo->exptime = jiffies_to_msecs(mpath->exp_time - jiffies);
  739. pinfo->discovery_timeout =
  740. jiffies_to_msecs(mpath->discovery_timeout);
  741. pinfo->discovery_retries = mpath->discovery_retries;
  742. pinfo->flags = 0;
  743. if (mpath->flags & MESH_PATH_ACTIVE)
  744. pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE;
  745. if (mpath->flags & MESH_PATH_RESOLVING)
  746. pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
  747. if (mpath->flags & MESH_PATH_DSN_VALID)
  748. pinfo->flags |= NL80211_MPATH_FLAG_DSN_VALID;
  749. if (mpath->flags & MESH_PATH_FIXED)
  750. pinfo->flags |= NL80211_MPATH_FLAG_FIXED;
  751. if (mpath->flags & MESH_PATH_RESOLVING)
  752. pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
  753. pinfo->flags = mpath->flags;
  754. }
  755. static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev,
  756. u8 *dst, u8 *next_hop, struct mpath_info *pinfo)
  757. {
  758. struct ieee80211_local *local = wiphy_priv(wiphy);
  759. struct ieee80211_sub_if_data *sdata;
  760. struct mesh_path *mpath;
  761. if (dev == local->mdev)
  762. return -EOPNOTSUPP;
  763. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  764. if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
  765. return -ENOTSUPP;
  766. rcu_read_lock();
  767. mpath = mesh_path_lookup(dst, sdata);
  768. if (!mpath) {
  769. rcu_read_unlock();
  770. return -ENOENT;
  771. }
  772. memcpy(dst, mpath->dst, ETH_ALEN);
  773. mpath_set_pinfo(mpath, next_hop, pinfo);
  774. rcu_read_unlock();
  775. return 0;
  776. }
  777. static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
  778. int idx, u8 *dst, u8 *next_hop,
  779. struct mpath_info *pinfo)
  780. {
  781. struct ieee80211_local *local = wiphy_priv(wiphy);
  782. struct ieee80211_sub_if_data *sdata;
  783. struct mesh_path *mpath;
  784. if (dev == local->mdev)
  785. return -EOPNOTSUPP;
  786. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  787. if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
  788. return -ENOTSUPP;
  789. rcu_read_lock();
  790. mpath = mesh_path_lookup_by_idx(idx, sdata);
  791. if (!mpath) {
  792. rcu_read_unlock();
  793. return -ENOENT;
  794. }
  795. memcpy(dst, mpath->dst, ETH_ALEN);
  796. mpath_set_pinfo(mpath, next_hop, pinfo);
  797. rcu_read_unlock();
  798. return 0;
  799. }
  800. #endif
  801. static int ieee80211_change_bss(struct wiphy *wiphy,
  802. struct net_device *dev,
  803. struct bss_parameters *params)
  804. {
  805. struct ieee80211_local *local = wiphy_priv(wiphy);
  806. struct ieee80211_sub_if_data *sdata;
  807. u32 changed = 0;
  808. if (dev == local->mdev)
  809. return -EOPNOTSUPP;
  810. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  811. if (sdata->vif.type != NL80211_IFTYPE_AP)
  812. return -EINVAL;
  813. if (params->use_cts_prot >= 0) {
  814. sdata->bss_conf.use_cts_prot = params->use_cts_prot;
  815. changed |= BSS_CHANGED_ERP_CTS_PROT;
  816. }
  817. if (params->use_short_preamble >= 0) {
  818. sdata->bss_conf.use_short_preamble =
  819. params->use_short_preamble;
  820. changed |= BSS_CHANGED_ERP_PREAMBLE;
  821. }
  822. if (params->use_short_slot_time >= 0) {
  823. sdata->bss_conf.use_short_slot =
  824. params->use_short_slot_time;
  825. changed |= BSS_CHANGED_ERP_SLOT;
  826. }
  827. ieee80211_bss_info_change_notify(sdata, changed);
  828. return 0;
  829. }
  830. struct cfg80211_ops mac80211_config_ops = {
  831. .add_virtual_intf = ieee80211_add_iface,
  832. .del_virtual_intf = ieee80211_del_iface,
  833. .change_virtual_intf = ieee80211_change_iface,
  834. .add_key = ieee80211_add_key,
  835. .del_key = ieee80211_del_key,
  836. .get_key = ieee80211_get_key,
  837. .set_default_key = ieee80211_config_default_key,
  838. .add_beacon = ieee80211_add_beacon,
  839. .set_beacon = ieee80211_set_beacon,
  840. .del_beacon = ieee80211_del_beacon,
  841. .add_station = ieee80211_add_station,
  842. .del_station = ieee80211_del_station,
  843. .change_station = ieee80211_change_station,
  844. .get_station = ieee80211_get_station,
  845. .dump_station = ieee80211_dump_station,
  846. #ifdef CONFIG_MAC80211_MESH
  847. .add_mpath = ieee80211_add_mpath,
  848. .del_mpath = ieee80211_del_mpath,
  849. .change_mpath = ieee80211_change_mpath,
  850. .get_mpath = ieee80211_get_mpath,
  851. .dump_mpath = ieee80211_dump_mpath,
  852. #endif
  853. .change_bss = ieee80211_change_bss,
  854. };