cfg.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  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 "ieee80211_rate.h"
  17. static enum ieee80211_if_types
  18. nl80211_type_to_mac80211_type(enum nl80211_iftype type)
  19. {
  20. switch (type) {
  21. case NL80211_IFTYPE_UNSPECIFIED:
  22. return IEEE80211_IF_TYPE_STA;
  23. case NL80211_IFTYPE_ADHOC:
  24. return IEEE80211_IF_TYPE_IBSS;
  25. case NL80211_IFTYPE_STATION:
  26. return IEEE80211_IF_TYPE_STA;
  27. case NL80211_IFTYPE_MONITOR:
  28. return IEEE80211_IF_TYPE_MNTR;
  29. default:
  30. return IEEE80211_IF_TYPE_INVALID;
  31. }
  32. }
  33. static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
  34. enum nl80211_iftype type)
  35. {
  36. struct ieee80211_local *local = wiphy_priv(wiphy);
  37. enum ieee80211_if_types itype;
  38. if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED))
  39. return -ENODEV;
  40. itype = nl80211_type_to_mac80211_type(type);
  41. if (itype == IEEE80211_IF_TYPE_INVALID)
  42. return -EINVAL;
  43. return ieee80211_if_add(local->mdev, name, NULL, itype);
  44. }
  45. static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex)
  46. {
  47. struct ieee80211_local *local = wiphy_priv(wiphy);
  48. struct net_device *dev;
  49. char *name;
  50. if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED))
  51. return -ENODEV;
  52. /* we're under RTNL */
  53. dev = __dev_get_by_index(&init_net, ifindex);
  54. if (!dev)
  55. return 0;
  56. name = dev->name;
  57. return ieee80211_if_remove(local->mdev, name, -1);
  58. }
  59. static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
  60. enum nl80211_iftype type)
  61. {
  62. struct ieee80211_local *local = wiphy_priv(wiphy);
  63. struct net_device *dev;
  64. enum ieee80211_if_types itype;
  65. struct ieee80211_sub_if_data *sdata;
  66. if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED))
  67. return -ENODEV;
  68. /* we're under RTNL */
  69. dev = __dev_get_by_index(&init_net, ifindex);
  70. if (!dev)
  71. return -ENODEV;
  72. if (netif_running(dev))
  73. return -EBUSY;
  74. itype = nl80211_type_to_mac80211_type(type);
  75. if (itype == IEEE80211_IF_TYPE_INVALID)
  76. return -EINVAL;
  77. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  78. if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN)
  79. return -EOPNOTSUPP;
  80. ieee80211_if_reinit(dev);
  81. ieee80211_if_set_type(dev, itype);
  82. return 0;
  83. }
  84. static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
  85. u8 key_idx, u8 *mac_addr,
  86. struct key_params *params)
  87. {
  88. struct ieee80211_sub_if_data *sdata;
  89. struct sta_info *sta = NULL;
  90. enum ieee80211_key_alg alg;
  91. int ret;
  92. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  93. switch (params->cipher) {
  94. case WLAN_CIPHER_SUITE_WEP40:
  95. case WLAN_CIPHER_SUITE_WEP104:
  96. alg = ALG_WEP;
  97. break;
  98. case WLAN_CIPHER_SUITE_TKIP:
  99. alg = ALG_TKIP;
  100. break;
  101. case WLAN_CIPHER_SUITE_CCMP:
  102. alg = ALG_CCMP;
  103. break;
  104. default:
  105. return -EINVAL;
  106. }
  107. if (mac_addr) {
  108. sta = sta_info_get(sdata->local, mac_addr);
  109. if (!sta)
  110. return -ENOENT;
  111. }
  112. ret = 0;
  113. if (!ieee80211_key_alloc(sdata, sta, alg, key_idx,
  114. params->key_len, params->key))
  115. ret = -ENOMEM;
  116. if (sta)
  117. sta_info_put(sta);
  118. return ret;
  119. }
  120. static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
  121. u8 key_idx, u8 *mac_addr)
  122. {
  123. struct ieee80211_sub_if_data *sdata;
  124. struct sta_info *sta;
  125. int ret;
  126. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  127. if (mac_addr) {
  128. sta = sta_info_get(sdata->local, mac_addr);
  129. if (!sta)
  130. return -ENOENT;
  131. ret = 0;
  132. if (sta->key)
  133. ieee80211_key_free(sta->key);
  134. else
  135. ret = -ENOENT;
  136. sta_info_put(sta);
  137. return ret;
  138. }
  139. if (!sdata->keys[key_idx])
  140. return -ENOENT;
  141. ieee80211_key_free(sdata->keys[key_idx]);
  142. return 0;
  143. }
  144. static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
  145. u8 key_idx, u8 *mac_addr, void *cookie,
  146. void (*callback)(void *cookie,
  147. struct key_params *params))
  148. {
  149. struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  150. struct sta_info *sta = NULL;
  151. u8 seq[6] = {0};
  152. struct key_params params;
  153. struct ieee80211_key *key;
  154. u32 iv32;
  155. u16 iv16;
  156. int err = -ENOENT;
  157. if (mac_addr) {
  158. sta = sta_info_get(sdata->local, mac_addr);
  159. if (!sta)
  160. goto out;
  161. key = sta->key;
  162. } else
  163. key = sdata->keys[key_idx];
  164. if (!key)
  165. goto out;
  166. memset(&params, 0, sizeof(params));
  167. switch (key->conf.alg) {
  168. case ALG_TKIP:
  169. params.cipher = WLAN_CIPHER_SUITE_TKIP;
  170. iv32 = key->u.tkip.iv32;
  171. iv16 = key->u.tkip.iv16;
  172. if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE &&
  173. sdata->local->ops->get_tkip_seq)
  174. sdata->local->ops->get_tkip_seq(
  175. local_to_hw(sdata->local),
  176. key->conf.hw_key_idx,
  177. &iv32, &iv16);
  178. seq[0] = iv16 & 0xff;
  179. seq[1] = (iv16 >> 8) & 0xff;
  180. seq[2] = iv32 & 0xff;
  181. seq[3] = (iv32 >> 8) & 0xff;
  182. seq[4] = (iv32 >> 16) & 0xff;
  183. seq[5] = (iv32 >> 24) & 0xff;
  184. params.seq = seq;
  185. params.seq_len = 6;
  186. break;
  187. case ALG_CCMP:
  188. params.cipher = WLAN_CIPHER_SUITE_CCMP;
  189. seq[0] = key->u.ccmp.tx_pn[5];
  190. seq[1] = key->u.ccmp.tx_pn[4];
  191. seq[2] = key->u.ccmp.tx_pn[3];
  192. seq[3] = key->u.ccmp.tx_pn[2];
  193. seq[4] = key->u.ccmp.tx_pn[1];
  194. seq[5] = key->u.ccmp.tx_pn[0];
  195. params.seq = seq;
  196. params.seq_len = 6;
  197. break;
  198. case ALG_WEP:
  199. if (key->conf.keylen == 5)
  200. params.cipher = WLAN_CIPHER_SUITE_WEP40;
  201. else
  202. params.cipher = WLAN_CIPHER_SUITE_WEP104;
  203. break;
  204. }
  205. params.key = key->conf.key;
  206. params.key_len = key->conf.keylen;
  207. callback(cookie, &params);
  208. err = 0;
  209. out:
  210. if (sta)
  211. sta_info_put(sta);
  212. return err;
  213. }
  214. static int ieee80211_config_default_key(struct wiphy *wiphy,
  215. struct net_device *dev,
  216. u8 key_idx)
  217. {
  218. struct ieee80211_sub_if_data *sdata;
  219. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  220. ieee80211_set_default_key(sdata, key_idx);
  221. return 0;
  222. }
  223. static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
  224. u8 *mac, struct station_stats *stats)
  225. {
  226. struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
  227. struct sta_info *sta;
  228. sta = sta_info_get(local, mac);
  229. if (!sta)
  230. return -ENOENT;
  231. /* XXX: verify sta->dev == dev */
  232. stats->filled = STATION_STAT_INACTIVE_TIME |
  233. STATION_STAT_RX_BYTES |
  234. STATION_STAT_TX_BYTES;
  235. stats->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
  236. stats->rx_bytes = sta->rx_bytes;
  237. stats->tx_bytes = sta->tx_bytes;
  238. sta_info_put(sta);
  239. return 0;
  240. }
  241. /*
  242. * This handles both adding a beacon and setting new beacon info
  243. */
  244. static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
  245. struct beacon_parameters *params)
  246. {
  247. struct beacon_data *new, *old;
  248. int new_head_len, new_tail_len;
  249. int size;
  250. int err = -EINVAL;
  251. old = sdata->u.ap.beacon;
  252. /* head must not be zero-length */
  253. if (params->head && !params->head_len)
  254. return -EINVAL;
  255. /*
  256. * This is a kludge. beacon interval should really be part
  257. * of the beacon information.
  258. */
  259. if (params->interval) {
  260. sdata->local->hw.conf.beacon_int = params->interval;
  261. if (ieee80211_hw_config(sdata->local))
  262. return -EINVAL;
  263. /*
  264. * We updated some parameter so if below bails out
  265. * it's not an error.
  266. */
  267. err = 0;
  268. }
  269. /* Need to have a beacon head if we don't have one yet */
  270. if (!params->head && !old)
  271. return err;
  272. /* sorry, no way to start beaconing without dtim period */
  273. if (!params->dtim_period && !old)
  274. return err;
  275. /* new or old head? */
  276. if (params->head)
  277. new_head_len = params->head_len;
  278. else
  279. new_head_len = old->head_len;
  280. /* new or old tail? */
  281. if (params->tail || !old)
  282. /* params->tail_len will be zero for !params->tail */
  283. new_tail_len = params->tail_len;
  284. else
  285. new_tail_len = old->tail_len;
  286. size = sizeof(*new) + new_head_len + new_tail_len;
  287. new = kzalloc(size, GFP_KERNEL);
  288. if (!new)
  289. return -ENOMEM;
  290. /* start filling the new info now */
  291. /* new or old dtim period? */
  292. if (params->dtim_period)
  293. new->dtim_period = params->dtim_period;
  294. else
  295. new->dtim_period = old->dtim_period;
  296. /*
  297. * pointers go into the block we allocated,
  298. * memory is | beacon_data | head | tail |
  299. */
  300. new->head = ((u8 *) new) + sizeof(*new);
  301. new->tail = new->head + new_head_len;
  302. new->head_len = new_head_len;
  303. new->tail_len = new_tail_len;
  304. /* copy in head */
  305. if (params->head)
  306. memcpy(new->head, params->head, new_head_len);
  307. else
  308. memcpy(new->head, old->head, new_head_len);
  309. /* copy in optional tail */
  310. if (params->tail)
  311. memcpy(new->tail, params->tail, new_tail_len);
  312. else
  313. if (old)
  314. memcpy(new->tail, old->tail, new_tail_len);
  315. rcu_assign_pointer(sdata->u.ap.beacon, new);
  316. synchronize_rcu();
  317. kfree(old);
  318. return ieee80211_if_config_beacon(sdata->dev);
  319. }
  320. static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
  321. struct beacon_parameters *params)
  322. {
  323. struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  324. struct beacon_data *old;
  325. if (sdata->vif.type != IEEE80211_IF_TYPE_AP)
  326. return -EINVAL;
  327. old = sdata->u.ap.beacon;
  328. if (old)
  329. return -EALREADY;
  330. return ieee80211_config_beacon(sdata, params);
  331. }
  332. static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
  333. struct beacon_parameters *params)
  334. {
  335. struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  336. struct beacon_data *old;
  337. if (sdata->vif.type != IEEE80211_IF_TYPE_AP)
  338. return -EINVAL;
  339. old = sdata->u.ap.beacon;
  340. if (!old)
  341. return -ENOENT;
  342. return ieee80211_config_beacon(sdata, params);
  343. }
  344. static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
  345. {
  346. struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  347. struct beacon_data *old;
  348. if (sdata->vif.type != IEEE80211_IF_TYPE_AP)
  349. return -EINVAL;
  350. old = sdata->u.ap.beacon;
  351. if (!old)
  352. return -ENOENT;
  353. rcu_assign_pointer(sdata->u.ap.beacon, NULL);
  354. synchronize_rcu();
  355. kfree(old);
  356. return ieee80211_if_config_beacon(dev);
  357. }
  358. /* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
  359. struct iapp_layer2_update {
  360. u8 da[ETH_ALEN]; /* broadcast */
  361. u8 sa[ETH_ALEN]; /* STA addr */
  362. __be16 len; /* 6 */
  363. u8 dsap; /* 0 */
  364. u8 ssap; /* 0 */
  365. u8 control;
  366. u8 xid_info[3];
  367. } __attribute__ ((packed));
  368. static void ieee80211_send_layer2_update(struct sta_info *sta)
  369. {
  370. struct iapp_layer2_update *msg;
  371. struct sk_buff *skb;
  372. /* Send Level 2 Update Frame to update forwarding tables in layer 2
  373. * bridge devices */
  374. skb = dev_alloc_skb(sizeof(*msg));
  375. if (!skb)
  376. return;
  377. msg = (struct iapp_layer2_update *)skb_put(skb, sizeof(*msg));
  378. /* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID)
  379. * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */
  380. memset(msg->da, 0xff, ETH_ALEN);
  381. memcpy(msg->sa, sta->addr, ETH_ALEN);
  382. msg->len = htons(6);
  383. msg->dsap = 0;
  384. msg->ssap = 0x01; /* NULL LSAP, CR Bit: Response */
  385. msg->control = 0xaf; /* XID response lsb.1111F101.
  386. * F=0 (no poll command; unsolicited frame) */
  387. msg->xid_info[0] = 0x81; /* XID format identifier */
  388. msg->xid_info[1] = 1; /* LLC types/classes: Type 1 LLC */
  389. msg->xid_info[2] = 0; /* XID sender's receive window size (RW) */
  390. skb->dev = sta->dev;
  391. skb->protocol = eth_type_trans(skb, sta->dev);
  392. memset(skb->cb, 0, sizeof(skb->cb));
  393. netif_rx(skb);
  394. }
  395. static void sta_apply_parameters(struct ieee80211_local *local,
  396. struct sta_info *sta,
  397. struct station_parameters *params)
  398. {
  399. u32 rates;
  400. int i, j;
  401. struct ieee80211_hw_mode *mode;
  402. if (params->station_flags & STATION_FLAG_CHANGED) {
  403. sta->flags &= ~WLAN_STA_AUTHORIZED;
  404. if (params->station_flags & STATION_FLAG_AUTHORIZED)
  405. sta->flags |= WLAN_STA_AUTHORIZED;
  406. sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
  407. if (params->station_flags & STATION_FLAG_SHORT_PREAMBLE)
  408. sta->flags |= WLAN_STA_SHORT_PREAMBLE;
  409. sta->flags &= ~WLAN_STA_WME;
  410. if (params->station_flags & STATION_FLAG_WME)
  411. sta->flags |= WLAN_STA_WME;
  412. }
  413. if (params->aid) {
  414. sta->aid = params->aid;
  415. if (sta->aid > IEEE80211_MAX_AID)
  416. sta->aid = 0; /* XXX: should this be an error? */
  417. }
  418. if (params->listen_interval >= 0)
  419. sta->listen_interval = params->listen_interval;
  420. if (params->supported_rates) {
  421. rates = 0;
  422. mode = local->oper_hw_mode;
  423. for (i = 0; i < params->supported_rates_len; i++) {
  424. int rate = (params->supported_rates[i] & 0x7f) * 5;
  425. for (j = 0; j < mode->num_rates; j++) {
  426. if (mode->rates[j].rate == rate)
  427. rates |= BIT(j);
  428. }
  429. }
  430. sta->supp_rates = rates;
  431. }
  432. }
  433. static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
  434. u8 *mac, struct station_parameters *params)
  435. {
  436. struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
  437. struct sta_info *sta;
  438. struct ieee80211_sub_if_data *sdata;
  439. /* Prevent a race with changing the rate control algorithm */
  440. if (!netif_running(dev))
  441. return -ENETDOWN;
  442. /* XXX: get sta belonging to dev */
  443. sta = sta_info_get(local, mac);
  444. if (sta) {
  445. sta_info_put(sta);
  446. return -EEXIST;
  447. }
  448. if (params->vlan) {
  449. sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
  450. if (sdata->vif.type != IEEE80211_IF_TYPE_VLAN ||
  451. sdata->vif.type != IEEE80211_IF_TYPE_AP)
  452. return -EINVAL;
  453. } else
  454. sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  455. sta = sta_info_add(local, dev, mac, GFP_KERNEL);
  456. if (!sta)
  457. return -ENOMEM;
  458. sta->dev = sdata->dev;
  459. if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN ||
  460. sdata->vif.type == IEEE80211_IF_TYPE_AP)
  461. ieee80211_send_layer2_update(sta);
  462. sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;
  463. sta_apply_parameters(local, sta, params);
  464. rate_control_rate_init(sta, local);
  465. sta_info_put(sta);
  466. return 0;
  467. }
  468. static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
  469. u8 *mac)
  470. {
  471. struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
  472. struct sta_info *sta;
  473. if (mac) {
  474. /* XXX: get sta belonging to dev */
  475. sta = sta_info_get(local, mac);
  476. if (!sta)
  477. return -ENOENT;
  478. sta_info_free(sta);
  479. sta_info_put(sta);
  480. } else
  481. sta_info_flush(local, dev);
  482. return 0;
  483. }
  484. static int ieee80211_change_station(struct wiphy *wiphy,
  485. struct net_device *dev,
  486. u8 *mac,
  487. struct station_parameters *params)
  488. {
  489. struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
  490. struct sta_info *sta;
  491. struct ieee80211_sub_if_data *vlansdata;
  492. /* XXX: get sta belonging to dev */
  493. sta = sta_info_get(local, mac);
  494. if (!sta)
  495. return -ENOENT;
  496. if (params->vlan && params->vlan != sta->dev) {
  497. vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
  498. if (vlansdata->vif.type != IEEE80211_IF_TYPE_VLAN ||
  499. vlansdata->vif.type != IEEE80211_IF_TYPE_AP)
  500. return -EINVAL;
  501. sta->dev = params->vlan;
  502. ieee80211_send_layer2_update(sta);
  503. }
  504. sta_apply_parameters(local, sta, params);
  505. sta_info_put(sta);
  506. return 0;
  507. }
  508. struct cfg80211_ops mac80211_config_ops = {
  509. .add_virtual_intf = ieee80211_add_iface,
  510. .del_virtual_intf = ieee80211_del_iface,
  511. .change_virtual_intf = ieee80211_change_iface,
  512. .add_key = ieee80211_add_key,
  513. .del_key = ieee80211_del_key,
  514. .get_key = ieee80211_get_key,
  515. .set_default_key = ieee80211_config_default_key,
  516. .add_beacon = ieee80211_add_beacon,
  517. .set_beacon = ieee80211_set_beacon,
  518. .del_beacon = ieee80211_del_beacon,
  519. .add_station = ieee80211_add_station,
  520. .del_station = ieee80211_del_station,
  521. .change_station = ieee80211_change_station,
  522. .get_station = ieee80211_get_station,
  523. };