wpan.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. /*
  2. * Copyright 2007-2012 Siemens AG
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2
  6. * as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License along
  14. * with this program; if not, write to the Free Software Foundation, Inc.,
  15. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  16. *
  17. * Written by:
  18. * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
  19. * Sergey Lapin <slapin@ossfans.org>
  20. * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
  21. * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
  22. */
  23. #include <linux/netdevice.h>
  24. #include <linux/module.h>
  25. #include <linux/if_arp.h>
  26. #include <net/rtnetlink.h>
  27. #include <linux/nl802154.h>
  28. #include <net/af_ieee802154.h>
  29. #include <net/mac802154.h>
  30. #include <net/ieee802154_netdev.h>
  31. #include <net/ieee802154.h>
  32. #include <net/wpan-phy.h>
  33. #include "mac802154.h"
  34. static int mac802154_wpan_update_llsec(struct net_device *dev)
  35. {
  36. struct mac802154_sub_if_data *priv = netdev_priv(dev);
  37. struct ieee802154_mlme_ops *ops = ieee802154_mlme_ops(dev);
  38. int rc = 0;
  39. if (ops->llsec) {
  40. struct ieee802154_llsec_params params;
  41. int changed = 0;
  42. params.pan_id = priv->pan_id;
  43. changed |= IEEE802154_LLSEC_PARAM_PAN_ID;
  44. params.hwaddr = priv->extended_addr;
  45. changed |= IEEE802154_LLSEC_PARAM_HWADDR;
  46. rc = ops->llsec->set_params(dev, &params, changed);
  47. }
  48. return rc;
  49. }
  50. static int
  51. mac802154_wpan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
  52. {
  53. struct mac802154_sub_if_data *priv = netdev_priv(dev);
  54. struct sockaddr_ieee802154 *sa =
  55. (struct sockaddr_ieee802154 *)&ifr->ifr_addr;
  56. int err = -ENOIOCTLCMD;
  57. spin_lock_bh(&priv->mib_lock);
  58. switch (cmd) {
  59. case SIOCGIFADDR:
  60. {
  61. u16 pan_id, short_addr;
  62. pan_id = le16_to_cpu(priv->pan_id);
  63. short_addr = le16_to_cpu(priv->short_addr);
  64. if (pan_id == IEEE802154_PANID_BROADCAST ||
  65. short_addr == IEEE802154_ADDR_BROADCAST) {
  66. err = -EADDRNOTAVAIL;
  67. break;
  68. }
  69. sa->family = AF_IEEE802154;
  70. sa->addr.addr_type = IEEE802154_ADDR_SHORT;
  71. sa->addr.pan_id = pan_id;
  72. sa->addr.short_addr = short_addr;
  73. err = 0;
  74. break;
  75. }
  76. case SIOCSIFADDR:
  77. dev_warn(&dev->dev,
  78. "Using DEBUGing ioctl SIOCSIFADDR isn't recommened!\n");
  79. if (sa->family != AF_IEEE802154 ||
  80. sa->addr.addr_type != IEEE802154_ADDR_SHORT ||
  81. sa->addr.pan_id == IEEE802154_PANID_BROADCAST ||
  82. sa->addr.short_addr == IEEE802154_ADDR_BROADCAST ||
  83. sa->addr.short_addr == IEEE802154_ADDR_UNDEF) {
  84. err = -EINVAL;
  85. break;
  86. }
  87. priv->pan_id = cpu_to_le16(sa->addr.pan_id);
  88. priv->short_addr = cpu_to_le16(sa->addr.short_addr);
  89. err = mac802154_wpan_update_llsec(dev);
  90. break;
  91. }
  92. spin_unlock_bh(&priv->mib_lock);
  93. return err;
  94. }
  95. static int mac802154_wpan_mac_addr(struct net_device *dev, void *p)
  96. {
  97. struct sockaddr *addr = p;
  98. if (netif_running(dev))
  99. return -EBUSY;
  100. /* FIXME: validate addr */
  101. memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
  102. mac802154_dev_set_ieee_addr(dev);
  103. return mac802154_wpan_update_llsec(dev);
  104. }
  105. int mac802154_set_mac_params(struct net_device *dev,
  106. const struct ieee802154_mac_params *params)
  107. {
  108. struct mac802154_sub_if_data *priv = netdev_priv(dev);
  109. mutex_lock(&priv->hw->slaves_mtx);
  110. priv->mac_params = *params;
  111. mutex_unlock(&priv->hw->slaves_mtx);
  112. return 0;
  113. }
  114. void mac802154_get_mac_params(struct net_device *dev,
  115. struct ieee802154_mac_params *params)
  116. {
  117. struct mac802154_sub_if_data *priv = netdev_priv(dev);
  118. mutex_lock(&priv->hw->slaves_mtx);
  119. *params = priv->mac_params;
  120. mutex_unlock(&priv->hw->slaves_mtx);
  121. }
  122. static int mac802154_wpan_open(struct net_device *dev)
  123. {
  124. int rc;
  125. struct mac802154_sub_if_data *priv = netdev_priv(dev);
  126. struct wpan_phy *phy = priv->hw->phy;
  127. rc = mac802154_slave_open(dev);
  128. if (rc < 0)
  129. return rc;
  130. mutex_lock(&phy->pib_lock);
  131. if (phy->set_txpower) {
  132. rc = phy->set_txpower(phy, priv->mac_params.transmit_power);
  133. if (rc < 0)
  134. goto out;
  135. }
  136. if (phy->set_lbt) {
  137. rc = phy->set_lbt(phy, priv->mac_params.lbt);
  138. if (rc < 0)
  139. goto out;
  140. }
  141. if (phy->set_cca_mode) {
  142. rc = phy->set_cca_mode(phy, priv->mac_params.cca_mode);
  143. if (rc < 0)
  144. goto out;
  145. }
  146. if (phy->set_cca_ed_level) {
  147. rc = phy->set_cca_ed_level(phy, priv->mac_params.cca_ed_level);
  148. if (rc < 0)
  149. goto out;
  150. }
  151. if (phy->set_csma_params) {
  152. rc = phy->set_csma_params(phy, priv->mac_params.min_be,
  153. priv->mac_params.max_be,
  154. priv->mac_params.csma_retries);
  155. if (rc < 0)
  156. goto out;
  157. }
  158. if (phy->set_frame_retries) {
  159. rc = phy->set_frame_retries(phy,
  160. priv->mac_params.frame_retries);
  161. if (rc < 0)
  162. goto out;
  163. }
  164. mutex_unlock(&phy->pib_lock);
  165. return 0;
  166. out:
  167. mutex_unlock(&phy->pib_lock);
  168. return rc;
  169. }
  170. static int mac802154_set_header_security(struct mac802154_sub_if_data *priv,
  171. struct ieee802154_hdr *hdr,
  172. const struct ieee802154_mac_cb *cb)
  173. {
  174. struct ieee802154_llsec_params params;
  175. u8 level;
  176. mac802154_llsec_get_params(&priv->sec, &params);
  177. if (!params.enabled && cb->secen_override && cb->secen)
  178. return -EINVAL;
  179. if (!params.enabled ||
  180. (cb->secen_override && !cb->secen) ||
  181. !params.out_level)
  182. return 0;
  183. if (cb->seclevel_override && !cb->seclevel)
  184. return -EINVAL;
  185. level = cb->seclevel_override ? cb->seclevel : params.out_level;
  186. hdr->fc.security_enabled = 1;
  187. hdr->sec.level = level;
  188. hdr->sec.key_id_mode = params.out_key.mode;
  189. if (params.out_key.mode == IEEE802154_SCF_KEY_SHORT_INDEX)
  190. hdr->sec.short_src = params.out_key.short_source;
  191. else if (params.out_key.mode == IEEE802154_SCF_KEY_HW_INDEX)
  192. hdr->sec.extended_src = params.out_key.extended_source;
  193. hdr->sec.key_id = params.out_key.id;
  194. return 0;
  195. }
  196. static int mac802154_header_create(struct sk_buff *skb,
  197. struct net_device *dev,
  198. unsigned short type,
  199. const void *daddr,
  200. const void *saddr,
  201. unsigned len)
  202. {
  203. struct ieee802154_hdr hdr;
  204. struct mac802154_sub_if_data *priv = netdev_priv(dev);
  205. struct ieee802154_mac_cb *cb = mac_cb(skb);
  206. int hlen;
  207. if (!daddr)
  208. return -EINVAL;
  209. memset(&hdr.fc, 0, sizeof(hdr.fc));
  210. hdr.fc.type = cb->type;
  211. hdr.fc.security_enabled = cb->secen;
  212. hdr.fc.ack_request = cb->ackreq;
  213. hdr.seq = ieee802154_mlme_ops(dev)->get_dsn(dev);
  214. if (mac802154_set_header_security(priv, &hdr, cb) < 0)
  215. return -EINVAL;
  216. if (!saddr) {
  217. spin_lock_bh(&priv->mib_lock);
  218. if (priv->short_addr == cpu_to_le16(IEEE802154_ADDR_BROADCAST) ||
  219. priv->short_addr == cpu_to_le16(IEEE802154_ADDR_UNDEF) ||
  220. priv->pan_id == cpu_to_le16(IEEE802154_PANID_BROADCAST)) {
  221. hdr.source.mode = IEEE802154_ADDR_LONG;
  222. hdr.source.extended_addr = priv->extended_addr;
  223. } else {
  224. hdr.source.mode = IEEE802154_ADDR_SHORT;
  225. hdr.source.short_addr = priv->short_addr;
  226. }
  227. hdr.source.pan_id = priv->pan_id;
  228. spin_unlock_bh(&priv->mib_lock);
  229. } else {
  230. hdr.source = *(const struct ieee802154_addr *)saddr;
  231. }
  232. hdr.dest = *(const struct ieee802154_addr *)daddr;
  233. hlen = ieee802154_hdr_push(skb, &hdr);
  234. if (hlen < 0)
  235. return -EINVAL;
  236. skb_reset_mac_header(skb);
  237. skb->mac_len = hlen;
  238. if (len > ieee802154_max_payload(&hdr))
  239. return -EMSGSIZE;
  240. return hlen;
  241. }
  242. static int
  243. mac802154_header_parse(const struct sk_buff *skb, unsigned char *haddr)
  244. {
  245. struct ieee802154_hdr hdr;
  246. struct ieee802154_addr *addr = (struct ieee802154_addr *)haddr;
  247. if (ieee802154_hdr_peek_addrs(skb, &hdr) < 0) {
  248. pr_debug("malformed packet\n");
  249. return 0;
  250. }
  251. *addr = hdr.source;
  252. return sizeof(*addr);
  253. }
  254. static netdev_tx_t
  255. mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev)
  256. {
  257. struct mac802154_sub_if_data *priv;
  258. u8 chan, page;
  259. int rc;
  260. priv = netdev_priv(dev);
  261. spin_lock_bh(&priv->mib_lock);
  262. chan = priv->chan;
  263. page = priv->page;
  264. spin_unlock_bh(&priv->mib_lock);
  265. if (chan == MAC802154_CHAN_NONE ||
  266. page >= WPAN_NUM_PAGES ||
  267. chan >= WPAN_NUM_CHANNELS) {
  268. kfree_skb(skb);
  269. return NETDEV_TX_OK;
  270. }
  271. rc = mac802154_llsec_encrypt(&priv->sec, skb);
  272. if (rc) {
  273. pr_warn("encryption failed: %i\n", rc);
  274. kfree_skb(skb);
  275. return NETDEV_TX_OK;
  276. }
  277. skb->skb_iif = dev->ifindex;
  278. dev->stats.tx_packets++;
  279. dev->stats.tx_bytes += skb->len;
  280. return mac802154_tx(priv->hw, skb, page, chan);
  281. }
  282. static struct header_ops mac802154_header_ops = {
  283. .create = mac802154_header_create,
  284. .parse = mac802154_header_parse,
  285. };
  286. static const struct net_device_ops mac802154_wpan_ops = {
  287. .ndo_open = mac802154_wpan_open,
  288. .ndo_stop = mac802154_slave_close,
  289. .ndo_start_xmit = mac802154_wpan_xmit,
  290. .ndo_do_ioctl = mac802154_wpan_ioctl,
  291. .ndo_set_mac_address = mac802154_wpan_mac_addr,
  292. };
  293. static void mac802154_wpan_free(struct net_device *dev)
  294. {
  295. struct mac802154_sub_if_data *priv = netdev_priv(dev);
  296. mac802154_llsec_destroy(&priv->sec);
  297. free_netdev(dev);
  298. }
  299. void mac802154_wpan_setup(struct net_device *dev)
  300. {
  301. struct mac802154_sub_if_data *priv;
  302. dev->addr_len = IEEE802154_ADDR_LEN;
  303. memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN);
  304. dev->hard_header_len = MAC802154_FRAME_HARD_HEADER_LEN;
  305. dev->header_ops = &mac802154_header_ops;
  306. dev->needed_tailroom = 2 + 16; /* FCS + MIC */
  307. dev->mtu = IEEE802154_MTU;
  308. dev->tx_queue_len = 300;
  309. dev->type = ARPHRD_IEEE802154;
  310. dev->flags = IFF_NOARP | IFF_BROADCAST;
  311. dev->watchdog_timeo = 0;
  312. dev->destructor = mac802154_wpan_free;
  313. dev->netdev_ops = &mac802154_wpan_ops;
  314. dev->ml_priv = &mac802154_mlme_wpan;
  315. priv = netdev_priv(dev);
  316. priv->type = IEEE802154_DEV_WPAN;
  317. priv->chan = MAC802154_CHAN_NONE;
  318. priv->page = 0;
  319. spin_lock_init(&priv->mib_lock);
  320. mutex_init(&priv->sec_mtx);
  321. get_random_bytes(&priv->bsn, 1);
  322. get_random_bytes(&priv->dsn, 1);
  323. /* defaults per 802.15.4-2011 */
  324. priv->mac_params.min_be = 3;
  325. priv->mac_params.max_be = 5;
  326. priv->mac_params.csma_retries = 4;
  327. priv->mac_params.frame_retries = -1; /* for compatibility, actual default is 3 */
  328. priv->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST);
  329. priv->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
  330. mac802154_llsec_init(&priv->sec);
  331. }
  332. static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb)
  333. {
  334. return netif_rx_ni(skb);
  335. }
  336. static int
  337. mac802154_subif_frame(struct mac802154_sub_if_data *sdata, struct sk_buff *skb,
  338. const struct ieee802154_hdr *hdr)
  339. {
  340. __le16 span, sshort;
  341. int rc;
  342. pr_debug("getting packet via slave interface %s\n", sdata->dev->name);
  343. spin_lock_bh(&sdata->mib_lock);
  344. span = sdata->pan_id;
  345. sshort = sdata->short_addr;
  346. switch (mac_cb(skb)->dest.mode) {
  347. case IEEE802154_ADDR_NONE:
  348. if (mac_cb(skb)->dest.mode != IEEE802154_ADDR_NONE)
  349. /* FIXME: check if we are PAN coordinator */
  350. skb->pkt_type = PACKET_OTHERHOST;
  351. else
  352. /* ACK comes with both addresses empty */
  353. skb->pkt_type = PACKET_HOST;
  354. break;
  355. case IEEE802154_ADDR_LONG:
  356. if (mac_cb(skb)->dest.pan_id != span &&
  357. mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST))
  358. skb->pkt_type = PACKET_OTHERHOST;
  359. else if (mac_cb(skb)->dest.extended_addr == sdata->extended_addr)
  360. skb->pkt_type = PACKET_HOST;
  361. else
  362. skb->pkt_type = PACKET_OTHERHOST;
  363. break;
  364. case IEEE802154_ADDR_SHORT:
  365. if (mac_cb(skb)->dest.pan_id != span &&
  366. mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST))
  367. skb->pkt_type = PACKET_OTHERHOST;
  368. else if (mac_cb(skb)->dest.short_addr == sshort)
  369. skb->pkt_type = PACKET_HOST;
  370. else if (mac_cb(skb)->dest.short_addr ==
  371. cpu_to_le16(IEEE802154_ADDR_BROADCAST))
  372. skb->pkt_type = PACKET_BROADCAST;
  373. else
  374. skb->pkt_type = PACKET_OTHERHOST;
  375. break;
  376. default:
  377. break;
  378. }
  379. spin_unlock_bh(&sdata->mib_lock);
  380. skb->dev = sdata->dev;
  381. rc = mac802154_llsec_decrypt(&sdata->sec, skb);
  382. if (rc) {
  383. pr_debug("decryption failed: %i\n", rc);
  384. kfree_skb(skb);
  385. return NET_RX_DROP;
  386. }
  387. sdata->dev->stats.rx_packets++;
  388. sdata->dev->stats.rx_bytes += skb->len;
  389. switch (mac_cb(skb)->type) {
  390. case IEEE802154_FC_TYPE_DATA:
  391. return mac802154_process_data(sdata->dev, skb);
  392. default:
  393. pr_warn("ieee802154: bad frame received (type = %d)\n",
  394. mac_cb(skb)->type);
  395. kfree_skb(skb);
  396. return NET_RX_DROP;
  397. }
  398. }
  399. static void mac802154_print_addr(const char *name,
  400. const struct ieee802154_addr *addr)
  401. {
  402. if (addr->mode == IEEE802154_ADDR_NONE)
  403. pr_debug("%s not present\n", name);
  404. pr_debug("%s PAN ID: %04x\n", name, le16_to_cpu(addr->pan_id));
  405. if (addr->mode == IEEE802154_ADDR_SHORT) {
  406. pr_debug("%s is short: %04x\n", name,
  407. le16_to_cpu(addr->short_addr));
  408. } else {
  409. u64 hw = swab64((__force u64) addr->extended_addr);
  410. pr_debug("%s is hardware: %8phC\n", name, &hw);
  411. }
  412. }
  413. static int mac802154_parse_frame_start(struct sk_buff *skb,
  414. struct ieee802154_hdr *hdr)
  415. {
  416. int hlen;
  417. struct ieee802154_mac_cb *cb = mac_cb_init(skb);
  418. hlen = ieee802154_hdr_pull(skb, hdr);
  419. if (hlen < 0)
  420. return -EINVAL;
  421. skb->mac_len = hlen;
  422. pr_debug("fc: %04x dsn: %02x\n", le16_to_cpup((__le16 *)&hdr->fc),
  423. hdr->seq);
  424. cb->type = hdr->fc.type;
  425. cb->ackreq = hdr->fc.ack_request;
  426. cb->secen = hdr->fc.security_enabled;
  427. mac802154_print_addr("destination", &hdr->dest);
  428. mac802154_print_addr("source", &hdr->source);
  429. cb->source = hdr->source;
  430. cb->dest = hdr->dest;
  431. if (hdr->fc.security_enabled) {
  432. u64 key;
  433. pr_debug("seclevel %i\n", hdr->sec.level);
  434. switch (hdr->sec.key_id_mode) {
  435. case IEEE802154_SCF_KEY_IMPLICIT:
  436. pr_debug("implicit key\n");
  437. break;
  438. case IEEE802154_SCF_KEY_INDEX:
  439. pr_debug("key %02x\n", hdr->sec.key_id);
  440. break;
  441. case IEEE802154_SCF_KEY_SHORT_INDEX:
  442. pr_debug("key %04x:%04x %02x\n",
  443. le32_to_cpu(hdr->sec.short_src) >> 16,
  444. le32_to_cpu(hdr->sec.short_src) & 0xffff,
  445. hdr->sec.key_id);
  446. break;
  447. case IEEE802154_SCF_KEY_HW_INDEX:
  448. key = swab64((__force u64) hdr->sec.extended_src);
  449. pr_debug("key source %8phC %02x\n", &key,
  450. hdr->sec.key_id);
  451. break;
  452. }
  453. }
  454. return 0;
  455. }
  456. void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb)
  457. {
  458. int ret;
  459. struct mac802154_sub_if_data *sdata;
  460. struct ieee802154_hdr hdr;
  461. ret = mac802154_parse_frame_start(skb, &hdr);
  462. if (ret) {
  463. pr_debug("got invalid frame\n");
  464. return;
  465. }
  466. rcu_read_lock();
  467. list_for_each_entry_rcu(sdata, &priv->slaves, list) {
  468. if (sdata->type != IEEE802154_DEV_WPAN ||
  469. !netif_running(sdata->dev))
  470. continue;
  471. mac802154_subif_frame(sdata, skb, &hdr);
  472. skb = NULL;
  473. break;
  474. }
  475. rcu_read_unlock();
  476. if (skb)
  477. kfree_skb(skb);
  478. }