iface.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  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. * Written by:
  14. * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
  15. * Sergey Lapin <slapin@ossfans.org>
  16. * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
  17. * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
  18. */
  19. #include <linux/netdevice.h>
  20. #include <linux/module.h>
  21. #include <linux/if_arp.h>
  22. #include <linux/ieee802154.h>
  23. #include <net/rtnetlink.h>
  24. #include <linux/nl802154.h>
  25. #include <net/af_ieee802154.h>
  26. #include <net/mac802154.h>
  27. #include <net/ieee802154_netdev.h>
  28. #include <net/cfg802154.h>
  29. #include "ieee802154_i.h"
  30. #include "driver-ops.h"
  31. static int mac802154_wpan_update_llsec(struct net_device *dev)
  32. {
  33. struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
  34. struct ieee802154_mlme_ops *ops = ieee802154_mlme_ops(dev);
  35. int rc = 0;
  36. if (ops->llsec) {
  37. struct ieee802154_llsec_params params;
  38. int changed = 0;
  39. params.pan_id = sdata->pan_id;
  40. changed |= IEEE802154_LLSEC_PARAM_PAN_ID;
  41. params.hwaddr = sdata->extended_addr;
  42. changed |= IEEE802154_LLSEC_PARAM_HWADDR;
  43. rc = ops->llsec->set_params(dev, &params, changed);
  44. }
  45. return rc;
  46. }
  47. static int
  48. mac802154_wpan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
  49. {
  50. struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
  51. struct sockaddr_ieee802154 *sa =
  52. (struct sockaddr_ieee802154 *)&ifr->ifr_addr;
  53. int err = -ENOIOCTLCMD;
  54. spin_lock_bh(&sdata->mib_lock);
  55. switch (cmd) {
  56. case SIOCGIFADDR:
  57. {
  58. u16 pan_id, short_addr;
  59. pan_id = le16_to_cpu(sdata->pan_id);
  60. short_addr = le16_to_cpu(sdata->short_addr);
  61. if (pan_id == IEEE802154_PANID_BROADCAST ||
  62. short_addr == IEEE802154_ADDR_BROADCAST) {
  63. err = -EADDRNOTAVAIL;
  64. break;
  65. }
  66. sa->family = AF_IEEE802154;
  67. sa->addr.addr_type = IEEE802154_ADDR_SHORT;
  68. sa->addr.pan_id = pan_id;
  69. sa->addr.short_addr = short_addr;
  70. err = 0;
  71. break;
  72. }
  73. case SIOCSIFADDR:
  74. dev_warn(&dev->dev,
  75. "Using DEBUGing ioctl SIOCSIFADDR isn't recommended!\n");
  76. if (sa->family != AF_IEEE802154 ||
  77. sa->addr.addr_type != IEEE802154_ADDR_SHORT ||
  78. sa->addr.pan_id == IEEE802154_PANID_BROADCAST ||
  79. sa->addr.short_addr == IEEE802154_ADDR_BROADCAST ||
  80. sa->addr.short_addr == IEEE802154_ADDR_UNDEF) {
  81. err = -EINVAL;
  82. break;
  83. }
  84. sdata->pan_id = cpu_to_le16(sa->addr.pan_id);
  85. sdata->short_addr = cpu_to_le16(sa->addr.short_addr);
  86. err = mac802154_wpan_update_llsec(dev);
  87. break;
  88. }
  89. spin_unlock_bh(&sdata->mib_lock);
  90. return err;
  91. }
  92. static int mac802154_wpan_mac_addr(struct net_device *dev, void *p)
  93. {
  94. struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
  95. struct sockaddr *addr = p;
  96. __le64 extended_addr;
  97. if (netif_running(dev))
  98. return -EBUSY;
  99. extended_addr = ieee802154_netdev_to_extended_addr(addr->sa_data);
  100. if (!ieee802154_is_valid_extended_addr(extended_addr))
  101. return -EINVAL;
  102. memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
  103. sdata->extended_addr = extended_addr;
  104. return mac802154_wpan_update_llsec(dev);
  105. }
  106. static int mac802154_slave_open(struct net_device *dev)
  107. {
  108. struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
  109. struct ieee802154_sub_if_data *subif;
  110. struct ieee802154_local *local = sdata->local;
  111. int res = 0;
  112. ASSERT_RTNL();
  113. if (sdata->type == IEEE802154_DEV_WPAN) {
  114. mutex_lock(&sdata->local->iflist_mtx);
  115. list_for_each_entry(subif, &sdata->local->interfaces, list) {
  116. if (subif != sdata && subif->type == sdata->type &&
  117. ieee802154_sdata_running(subif)) {
  118. mutex_unlock(&sdata->local->iflist_mtx);
  119. return -EBUSY;
  120. }
  121. }
  122. mutex_unlock(&sdata->local->iflist_mtx);
  123. }
  124. set_bit(SDATA_STATE_RUNNING, &sdata->state);
  125. if (!local->open_count) {
  126. res = drv_start(local);
  127. WARN_ON(res);
  128. if (res)
  129. goto err;
  130. }
  131. local->open_count++;
  132. netif_start_queue(dev);
  133. return 0;
  134. err:
  135. /* might already be clear but that doesn't matter */
  136. clear_bit(SDATA_STATE_RUNNING, &sdata->state);
  137. return res;
  138. }
  139. static int mac802154_wpan_open(struct net_device *dev)
  140. {
  141. int rc;
  142. struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
  143. struct ieee802154_local *local = sdata->local;
  144. struct wpan_phy *phy = sdata->local->phy;
  145. rc = mac802154_slave_open(dev);
  146. if (rc < 0)
  147. return rc;
  148. mutex_lock(&phy->pib_lock);
  149. if (local->hw.flags & IEEE802154_HW_PROMISCUOUS) {
  150. rc = drv_set_promiscuous_mode(local, sdata->promisuous_mode);
  151. if (rc < 0)
  152. goto out;
  153. }
  154. if (local->hw.flags & IEEE802154_HW_AFILT) {
  155. rc = drv_set_pan_id(local, sdata->pan_id);
  156. if (rc < 0)
  157. goto out;
  158. rc = drv_set_extended_addr(local, sdata->extended_addr);
  159. if (rc < 0)
  160. goto out;
  161. rc = drv_set_short_addr(local, sdata->short_addr);
  162. if (rc < 0)
  163. goto out;
  164. }
  165. if (local->hw.flags & IEEE802154_HW_LBT) {
  166. rc = drv_set_lbt_mode(local, sdata->mac_params.lbt);
  167. if (rc < 0)
  168. goto out;
  169. }
  170. if (local->hw.flags & IEEE802154_HW_CSMA_PARAMS) {
  171. rc = drv_set_csma_params(local, sdata->mac_params.min_be,
  172. sdata->mac_params.max_be,
  173. sdata->mac_params.csma_retries);
  174. if (rc < 0)
  175. goto out;
  176. }
  177. if (local->hw.flags & IEEE802154_HW_FRAME_RETRIES) {
  178. rc = drv_set_max_frame_retries(local,
  179. sdata->mac_params.frame_retries);
  180. if (rc < 0)
  181. goto out;
  182. }
  183. mutex_unlock(&phy->pib_lock);
  184. return 0;
  185. out:
  186. mutex_unlock(&phy->pib_lock);
  187. return rc;
  188. }
  189. static int mac802154_slave_close(struct net_device *dev)
  190. {
  191. struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
  192. struct ieee802154_local *local = sdata->local;
  193. ASSERT_RTNL();
  194. netif_stop_queue(dev);
  195. local->open_count--;
  196. clear_bit(SDATA_STATE_RUNNING, &sdata->state);
  197. if (!local->open_count)
  198. drv_stop(local);
  199. return 0;
  200. }
  201. static int mac802154_set_header_security(struct ieee802154_sub_if_data *sdata,
  202. struct ieee802154_hdr *hdr,
  203. const struct ieee802154_mac_cb *cb)
  204. {
  205. struct ieee802154_llsec_params params;
  206. u8 level;
  207. mac802154_llsec_get_params(&sdata->sec, &params);
  208. if (!params.enabled && cb->secen_override && cb->secen)
  209. return -EINVAL;
  210. if (!params.enabled ||
  211. (cb->secen_override && !cb->secen) ||
  212. !params.out_level)
  213. return 0;
  214. if (cb->seclevel_override && !cb->seclevel)
  215. return -EINVAL;
  216. level = cb->seclevel_override ? cb->seclevel : params.out_level;
  217. hdr->fc.security_enabled = 1;
  218. hdr->sec.level = level;
  219. hdr->sec.key_id_mode = params.out_key.mode;
  220. if (params.out_key.mode == IEEE802154_SCF_KEY_SHORT_INDEX)
  221. hdr->sec.short_src = params.out_key.short_source;
  222. else if (params.out_key.mode == IEEE802154_SCF_KEY_HW_INDEX)
  223. hdr->sec.extended_src = params.out_key.extended_source;
  224. hdr->sec.key_id = params.out_key.id;
  225. return 0;
  226. }
  227. static int mac802154_header_create(struct sk_buff *skb,
  228. struct net_device *dev,
  229. unsigned short type,
  230. const void *daddr,
  231. const void *saddr,
  232. unsigned len)
  233. {
  234. struct ieee802154_hdr hdr;
  235. struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
  236. struct ieee802154_mac_cb *cb = mac_cb(skb);
  237. int hlen;
  238. if (!daddr)
  239. return -EINVAL;
  240. memset(&hdr.fc, 0, sizeof(hdr.fc));
  241. hdr.fc.type = cb->type;
  242. hdr.fc.security_enabled = cb->secen;
  243. hdr.fc.ack_request = cb->ackreq;
  244. hdr.seq = ieee802154_mlme_ops(dev)->get_dsn(dev);
  245. if (mac802154_set_header_security(sdata, &hdr, cb) < 0)
  246. return -EINVAL;
  247. if (!saddr) {
  248. spin_lock_bh(&sdata->mib_lock);
  249. if (sdata->short_addr == cpu_to_le16(IEEE802154_ADDR_BROADCAST) ||
  250. sdata->short_addr == cpu_to_le16(IEEE802154_ADDR_UNDEF) ||
  251. sdata->pan_id == cpu_to_le16(IEEE802154_PANID_BROADCAST)) {
  252. hdr.source.mode = IEEE802154_ADDR_LONG;
  253. hdr.source.extended_addr = sdata->extended_addr;
  254. } else {
  255. hdr.source.mode = IEEE802154_ADDR_SHORT;
  256. hdr.source.short_addr = sdata->short_addr;
  257. }
  258. hdr.source.pan_id = sdata->pan_id;
  259. spin_unlock_bh(&sdata->mib_lock);
  260. } else {
  261. hdr.source = *(const struct ieee802154_addr *)saddr;
  262. }
  263. hdr.dest = *(const struct ieee802154_addr *)daddr;
  264. hlen = ieee802154_hdr_push(skb, &hdr);
  265. if (hlen < 0)
  266. return -EINVAL;
  267. skb_reset_mac_header(skb);
  268. skb->mac_len = hlen;
  269. if (len > ieee802154_max_payload(&hdr))
  270. return -EMSGSIZE;
  271. return hlen;
  272. }
  273. static int
  274. mac802154_header_parse(const struct sk_buff *skb, unsigned char *haddr)
  275. {
  276. struct ieee802154_hdr hdr;
  277. struct ieee802154_addr *addr = (struct ieee802154_addr *)haddr;
  278. if (ieee802154_hdr_peek_addrs(skb, &hdr) < 0) {
  279. pr_debug("malformed packet\n");
  280. return 0;
  281. }
  282. *addr = hdr.source;
  283. return sizeof(*addr);
  284. }
  285. static struct header_ops mac802154_header_ops = {
  286. .create = mac802154_header_create,
  287. .parse = mac802154_header_parse,
  288. };
  289. static const struct net_device_ops mac802154_wpan_ops = {
  290. .ndo_open = mac802154_wpan_open,
  291. .ndo_stop = mac802154_slave_close,
  292. .ndo_start_xmit = ieee802154_subif_start_xmit,
  293. .ndo_do_ioctl = mac802154_wpan_ioctl,
  294. .ndo_set_mac_address = mac802154_wpan_mac_addr,
  295. };
  296. static const struct net_device_ops mac802154_monitor_ops = {
  297. .ndo_open = mac802154_wpan_open,
  298. .ndo_stop = mac802154_slave_close,
  299. .ndo_start_xmit = ieee802154_monitor_start_xmit,
  300. };
  301. static void mac802154_wpan_free(struct net_device *dev)
  302. {
  303. struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
  304. mac802154_llsec_destroy(&sdata->sec);
  305. free_netdev(dev);
  306. }
  307. void mac802154_wpan_setup(struct net_device *dev)
  308. {
  309. struct ieee802154_sub_if_data *sdata;
  310. dev->addr_len = IEEE802154_ADDR_LEN;
  311. memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN);
  312. dev->hard_header_len = MAC802154_FRAME_HARD_HEADER_LEN;
  313. dev->header_ops = &mac802154_header_ops;
  314. dev->needed_tailroom = 2 + 16; /* FCS + MIC */
  315. dev->mtu = IEEE802154_MTU;
  316. dev->tx_queue_len = 300;
  317. dev->type = ARPHRD_IEEE802154;
  318. dev->flags = IFF_NOARP | IFF_BROADCAST;
  319. dev->destructor = mac802154_wpan_free;
  320. dev->netdev_ops = &mac802154_wpan_ops;
  321. dev->ml_priv = &mac802154_mlme_wpan;
  322. sdata = IEEE802154_DEV_TO_SUB_IF(dev);
  323. sdata->type = IEEE802154_DEV_WPAN;
  324. spin_lock_init(&sdata->mib_lock);
  325. mutex_init(&sdata->sec_mtx);
  326. get_random_bytes(&sdata->bsn, 1);
  327. get_random_bytes(&sdata->dsn, 1);
  328. /* defaults per 802.15.4-2011 */
  329. sdata->mac_params.min_be = 3;
  330. sdata->mac_params.max_be = 5;
  331. sdata->mac_params.csma_retries = 4;
  332. /* for compatibility, actual default is 3 */
  333. sdata->mac_params.frame_retries = -1;
  334. sdata->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST);
  335. sdata->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
  336. sdata->promisuous_mode = false;
  337. mac802154_llsec_init(&sdata->sec);
  338. }
  339. void mac802154_monitor_setup(struct net_device *dev)
  340. {
  341. struct ieee802154_sub_if_data *sdata;
  342. dev->needed_tailroom = 2; /* room for FCS */
  343. dev->mtu = IEEE802154_MTU;
  344. dev->tx_queue_len = 10;
  345. dev->type = ARPHRD_IEEE802154_MONITOR;
  346. dev->flags = IFF_NOARP | IFF_BROADCAST;
  347. dev->destructor = free_netdev;
  348. dev->netdev_ops = &mac802154_monitor_ops;
  349. dev->ml_priv = &mac802154_mlme_reduced;
  350. sdata = IEEE802154_DEV_TO_SUB_IF(dev);
  351. sdata->type = IEEE802154_DEV_MONITOR;
  352. sdata->promisuous_mode = true;
  353. }