root/net/6lowpan/core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. lowpan_register_netdevice
  2. lowpan_register_netdev
  3. lowpan_unregister_netdevice
  4. lowpan_unregister_netdev
  5. addrconf_ifid_802154_6lowpan
  6. lowpan_event
  7. lowpan_module_init
  8. lowpan_module_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *
   4  * Authors:
   5  * (C) 2015 Pengutronix, Alexander Aring <aar@pengutronix.de>
   6  */
   7 
   8 #include <linux/module.h>
   9 
  10 #include <net/6lowpan.h>
  11 #include <net/addrconf.h>
  12 
  13 #include "6lowpan_i.h"
  14 
  15 int lowpan_register_netdevice(struct net_device *dev,
  16                               enum lowpan_lltypes lltype)
  17 {
  18         int i, ret;
  19 
  20         switch (lltype) {
  21         case LOWPAN_LLTYPE_IEEE802154:
  22                 dev->addr_len = EUI64_ADDR_LEN;
  23                 break;
  24 
  25         case LOWPAN_LLTYPE_BTLE:
  26                 dev->addr_len = ETH_ALEN;
  27                 break;
  28         }
  29 
  30         dev->type = ARPHRD_6LOWPAN;
  31         dev->mtu = IPV6_MIN_MTU;
  32 
  33         lowpan_dev(dev)->lltype = lltype;
  34 
  35         spin_lock_init(&lowpan_dev(dev)->ctx.lock);
  36         for (i = 0; i < LOWPAN_IPHC_CTX_TABLE_SIZE; i++)
  37                 lowpan_dev(dev)->ctx.table[i].id = i;
  38 
  39         dev->ndisc_ops = &lowpan_ndisc_ops;
  40 
  41         ret = register_netdevice(dev);
  42         if (ret < 0)
  43                 return ret;
  44 
  45         lowpan_dev_debugfs_init(dev);
  46 
  47         return ret;
  48 }
  49 EXPORT_SYMBOL(lowpan_register_netdevice);
  50 
  51 int lowpan_register_netdev(struct net_device *dev,
  52                            enum lowpan_lltypes lltype)
  53 {
  54         int ret;
  55 
  56         rtnl_lock();
  57         ret = lowpan_register_netdevice(dev, lltype);
  58         rtnl_unlock();
  59         return ret;
  60 }
  61 EXPORT_SYMBOL(lowpan_register_netdev);
  62 
  63 void lowpan_unregister_netdevice(struct net_device *dev)
  64 {
  65         unregister_netdevice(dev);
  66         lowpan_dev_debugfs_exit(dev);
  67 }
  68 EXPORT_SYMBOL(lowpan_unregister_netdevice);
  69 
  70 void lowpan_unregister_netdev(struct net_device *dev)
  71 {
  72         rtnl_lock();
  73         lowpan_unregister_netdevice(dev);
  74         rtnl_unlock();
  75 }
  76 EXPORT_SYMBOL(lowpan_unregister_netdev);
  77 
  78 int addrconf_ifid_802154_6lowpan(u8 *eui, struct net_device *dev)
  79 {
  80         struct wpan_dev *wpan_dev = lowpan_802154_dev(dev)->wdev->ieee802154_ptr;
  81 
  82         /* Set short_addr autoconfiguration if short_addr is present only */
  83         if (!lowpan_802154_is_valid_src_short_addr(wpan_dev->short_addr))
  84                 return -1;
  85 
  86         /* For either address format, all zero addresses MUST NOT be used */
  87         if (wpan_dev->pan_id == cpu_to_le16(0x0000) &&
  88             wpan_dev->short_addr == cpu_to_le16(0x0000))
  89                 return -1;
  90 
  91         /* Alternatively, if no PAN ID is known, 16 zero bits may be used */
  92         if (wpan_dev->pan_id == cpu_to_le16(IEEE802154_PAN_ID_BROADCAST))
  93                 memset(eui, 0, 2);
  94         else
  95                 ieee802154_le16_to_be16(eui, &wpan_dev->pan_id);
  96 
  97         /* The "Universal/Local" (U/L) bit shall be set to zero */
  98         eui[0] &= ~2;
  99         eui[2] = 0;
 100         eui[3] = 0xFF;
 101         eui[4] = 0xFE;
 102         eui[5] = 0;
 103         ieee802154_le16_to_be16(&eui[6], &wpan_dev->short_addr);
 104         return 0;
 105 }
 106 
 107 static int lowpan_event(struct notifier_block *unused,
 108                         unsigned long event, void *ptr)
 109 {
 110         struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 111         struct inet6_dev *idev;
 112         struct in6_addr addr;
 113         int i;
 114 
 115         if (dev->type != ARPHRD_6LOWPAN)
 116                 return NOTIFY_DONE;
 117 
 118         idev = __in6_dev_get(dev);
 119         if (!idev)
 120                 return NOTIFY_DONE;
 121 
 122         switch (event) {
 123         case NETDEV_UP:
 124         case NETDEV_CHANGE:
 125                 /* (802.15.4 6LoWPAN short address slaac handling */
 126                 if (lowpan_is_ll(dev, LOWPAN_LLTYPE_IEEE802154) &&
 127                     addrconf_ifid_802154_6lowpan(addr.s6_addr + 8, dev) == 0) {
 128                         __ipv6_addr_set_half(&addr.s6_addr32[0],
 129                                              htonl(0xFE800000), 0);
 130                         addrconf_add_linklocal(idev, &addr, 0);
 131                 }
 132                 break;
 133         case NETDEV_DOWN:
 134                 for (i = 0; i < LOWPAN_IPHC_CTX_TABLE_SIZE; i++)
 135                         clear_bit(LOWPAN_IPHC_CTX_FLAG_ACTIVE,
 136                                   &lowpan_dev(dev)->ctx.table[i].flags);
 137                 break;
 138         default:
 139                 return NOTIFY_DONE;
 140         }
 141 
 142         return NOTIFY_OK;
 143 }
 144 
 145 static struct notifier_block lowpan_notifier = {
 146         .notifier_call = lowpan_event,
 147 };
 148 
 149 static int __init lowpan_module_init(void)
 150 {
 151         int ret;
 152 
 153         lowpan_debugfs_init();
 154 
 155         ret = register_netdevice_notifier(&lowpan_notifier);
 156         if (ret < 0) {
 157                 lowpan_debugfs_exit();
 158                 return ret;
 159         }
 160 
 161         request_module_nowait("nhc_dest");
 162         request_module_nowait("nhc_fragment");
 163         request_module_nowait("nhc_hop");
 164         request_module_nowait("nhc_ipv6");
 165         request_module_nowait("nhc_mobility");
 166         request_module_nowait("nhc_routing");
 167         request_module_nowait("nhc_udp");
 168 
 169         return 0;
 170 }
 171 
 172 static void __exit lowpan_module_exit(void)
 173 {
 174         lowpan_debugfs_exit();
 175         unregister_netdevice_notifier(&lowpan_notifier);
 176 }
 177 
 178 module_init(lowpan_module_init);
 179 module_exit(lowpan_module_exit);
 180 
 181 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */