cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

core.c (4083B)


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