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

dn_dev.c (32828B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * DECnet       An implementation of the DECnet protocol suite for the LINUX
      4 *              operating system.  DECnet is implemented using the  BSD Socket
      5 *              interface as the means of communication with the user level.
      6 *
      7 *              DECnet Device Layer
      8 *
      9 * Authors:     Steve Whitehouse <SteveW@ACM.org>
     10 *              Eduardo Marcelo Serrat <emserrat@geocities.com>
     11 *
     12 * Changes:
     13 *          Steve Whitehouse : Devices now see incoming frames so they
     14 *                             can mark on who it came from.
     15 *          Steve Whitehouse : Fixed bug in creating neighbours. Each neighbour
     16 *                             can now have a device specific setup func.
     17 *          Steve Whitehouse : Added /proc/sys/net/decnet/conf/<dev>/
     18 *          Steve Whitehouse : Fixed bug which sometimes killed timer
     19 *          Steve Whitehouse : Multiple ifaddr support
     20 *          Steve Whitehouse : SIOCGIFCONF is now a compile time option
     21 *          Steve Whitehouse : /proc/sys/net/decnet/conf/<sys>/forwarding
     22 *          Steve Whitehouse : Removed timer1 - it's a user space issue now
     23 *         Patrick Caulfield : Fixed router hello message format
     24 *          Steve Whitehouse : Got rid of constant sizes for blksize for
     25 *                             devices. All mtu based now.
     26 */
     27
     28#include <linux/capability.h>
     29#include <linux/module.h>
     30#include <linux/moduleparam.h>
     31#include <linux/init.h>
     32#include <linux/net.h>
     33#include <linux/netdevice.h>
     34#include <linux/proc_fs.h>
     35#include <linux/seq_file.h>
     36#include <linux/timer.h>
     37#include <linux/string.h>
     38#include <linux/if_addr.h>
     39#include <linux/if_arp.h>
     40#include <linux/if_ether.h>
     41#include <linux/skbuff.h>
     42#include <linux/sysctl.h>
     43#include <linux/notifier.h>
     44#include <linux/slab.h>
     45#include <linux/jiffies.h>
     46#include <linux/uaccess.h>
     47#include <net/net_namespace.h>
     48#include <net/neighbour.h>
     49#include <net/dst.h>
     50#include <net/flow.h>
     51#include <net/fib_rules.h>
     52#include <net/netlink.h>
     53#include <net/dn.h>
     54#include <net/dn_dev.h>
     55#include <net/dn_route.h>
     56#include <net/dn_neigh.h>
     57#include <net/dn_fib.h>
     58
     59#define DN_IFREQ_SIZE (offsetof(struct ifreq, ifr_ifru) + sizeof(struct sockaddr_dn))
     60
     61static char dn_rt_all_end_mcast[ETH_ALEN] = {0xAB,0x00,0x00,0x04,0x00,0x00};
     62static char dn_rt_all_rt_mcast[ETH_ALEN]  = {0xAB,0x00,0x00,0x03,0x00,0x00};
     63static char dn_hiord[ETH_ALEN]            = {0xAA,0x00,0x04,0x00,0x00,0x00};
     64static unsigned char dn_eco_version[3]    = {0x02,0x00,0x00};
     65
     66extern struct neigh_table dn_neigh_table;
     67
     68/*
     69 * decnet_address is kept in network order.
     70 */
     71__le16 decnet_address = 0;
     72
     73static DEFINE_SPINLOCK(dndev_lock);
     74static struct net_device *decnet_default_device;
     75static BLOCKING_NOTIFIER_HEAD(dnaddr_chain);
     76
     77static struct dn_dev *dn_dev_create(struct net_device *dev, int *err);
     78static void dn_dev_delete(struct net_device *dev);
     79static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa);
     80
     81static int dn_eth_up(struct net_device *);
     82static void dn_eth_down(struct net_device *);
     83static void dn_send_brd_hello(struct net_device *dev, struct dn_ifaddr *ifa);
     84static void dn_send_ptp_hello(struct net_device *dev, struct dn_ifaddr *ifa);
     85
     86static struct dn_dev_parms dn_dev_list[] =  {
     87{
     88	.type =		ARPHRD_ETHER, /* Ethernet */
     89	.mode =		DN_DEV_BCAST,
     90	.state =	DN_DEV_S_RU,
     91	.t2 =		1,
     92	.t3 =		10,
     93	.name =		"ethernet",
     94	.up =		dn_eth_up,
     95	.down = 	dn_eth_down,
     96	.timer3 =	dn_send_brd_hello,
     97},
     98{
     99	.type =		ARPHRD_IPGRE, /* DECnet tunneled over GRE in IP */
    100	.mode =		DN_DEV_BCAST,
    101	.state =	DN_DEV_S_RU,
    102	.t2 =		1,
    103	.t3 =		10,
    104	.name =		"ipgre",
    105	.timer3 =	dn_send_brd_hello,
    106},
    107#if 0
    108{
    109	.type =		ARPHRD_X25, /* Bog standard X.25 */
    110	.mode =		DN_DEV_UCAST,
    111	.state =	DN_DEV_S_DS,
    112	.t2 =		1,
    113	.t3 =		120,
    114	.name =		"x25",
    115	.timer3 =	dn_send_ptp_hello,
    116},
    117#endif
    118#if 0
    119{
    120	.type =		ARPHRD_PPP, /* DECnet over PPP */
    121	.mode =		DN_DEV_BCAST,
    122	.state =	DN_DEV_S_RU,
    123	.t2 =		1,
    124	.t3 =		10,
    125	.name =		"ppp",
    126	.timer3 =	dn_send_brd_hello,
    127},
    128#endif
    129{
    130	.type =		ARPHRD_DDCMP, /* DECnet over DDCMP */
    131	.mode =		DN_DEV_UCAST,
    132	.state =	DN_DEV_S_DS,
    133	.t2 =		1,
    134	.t3 =		120,
    135	.name =		"ddcmp",
    136	.timer3 =	dn_send_ptp_hello,
    137},
    138{
    139	.type =		ARPHRD_LOOPBACK, /* Loopback interface - always last */
    140	.mode =		DN_DEV_BCAST,
    141	.state =	DN_DEV_S_RU,
    142	.t2 =		1,
    143	.t3 =		10,
    144	.name =		"loopback",
    145	.timer3 =	dn_send_brd_hello,
    146}
    147};
    148
    149#define DN_DEV_LIST_SIZE ARRAY_SIZE(dn_dev_list)
    150
    151#define DN_DEV_PARMS_OFFSET(x) offsetof(struct dn_dev_parms, x)
    152
    153#ifdef CONFIG_SYSCTL
    154
    155static int min_t2[] = { 1 };
    156static int max_t2[] = { 60 }; /* No max specified, but this seems sensible */
    157static int min_t3[] = { 1 };
    158static int max_t3[] = { 8191 }; /* Must fit in 16 bits when multiplied by BCT3MULT or T3MULT */
    159
    160static int min_priority[1];
    161static int max_priority[] = { 127 }; /* From DECnet spec */
    162
    163static int dn_forwarding_proc(struct ctl_table *, int, void *, size_t *,
    164		loff_t *);
    165static struct dn_dev_sysctl_table {
    166	struct ctl_table_header *sysctl_header;
    167	struct ctl_table dn_dev_vars[5];
    168} dn_dev_sysctl = {
    169	NULL,
    170	{
    171	{
    172		.procname = "forwarding",
    173		.data = (void *)DN_DEV_PARMS_OFFSET(forwarding),
    174		.maxlen = sizeof(int),
    175		.mode = 0644,
    176		.proc_handler = dn_forwarding_proc,
    177	},
    178	{
    179		.procname = "priority",
    180		.data = (void *)DN_DEV_PARMS_OFFSET(priority),
    181		.maxlen = sizeof(int),
    182		.mode = 0644,
    183		.proc_handler = proc_dointvec_minmax,
    184		.extra1 = &min_priority,
    185		.extra2 = &max_priority
    186	},
    187	{
    188		.procname = "t2",
    189		.data = (void *)DN_DEV_PARMS_OFFSET(t2),
    190		.maxlen = sizeof(int),
    191		.mode = 0644,
    192		.proc_handler = proc_dointvec_minmax,
    193		.extra1 = &min_t2,
    194		.extra2 = &max_t2
    195	},
    196	{
    197		.procname = "t3",
    198		.data = (void *)DN_DEV_PARMS_OFFSET(t3),
    199		.maxlen = sizeof(int),
    200		.mode = 0644,
    201		.proc_handler = proc_dointvec_minmax,
    202		.extra1 = &min_t3,
    203		.extra2 = &max_t3
    204	},
    205	{ }
    206	},
    207};
    208
    209static void dn_dev_sysctl_register(struct net_device *dev, struct dn_dev_parms *parms)
    210{
    211	struct dn_dev_sysctl_table *t;
    212	int i;
    213
    214	char path[sizeof("net/decnet/conf/") + IFNAMSIZ];
    215
    216	t = kmemdup(&dn_dev_sysctl, sizeof(*t), GFP_KERNEL);
    217	if (t == NULL)
    218		return;
    219
    220	for(i = 0; i < ARRAY_SIZE(t->dn_dev_vars) - 1; i++) {
    221		long offset = (long)t->dn_dev_vars[i].data;
    222		t->dn_dev_vars[i].data = ((char *)parms) + offset;
    223	}
    224
    225	snprintf(path, sizeof(path), "net/decnet/conf/%s",
    226		dev? dev->name : parms->name);
    227
    228	t->dn_dev_vars[0].extra1 = (void *)dev;
    229
    230	t->sysctl_header = register_net_sysctl(&init_net, path, t->dn_dev_vars);
    231	if (t->sysctl_header == NULL)
    232		kfree(t);
    233	else
    234		parms->sysctl = t;
    235}
    236
    237static void dn_dev_sysctl_unregister(struct dn_dev_parms *parms)
    238{
    239	if (parms->sysctl) {
    240		struct dn_dev_sysctl_table *t = parms->sysctl;
    241		parms->sysctl = NULL;
    242		unregister_net_sysctl_table(t->sysctl_header);
    243		kfree(t);
    244	}
    245}
    246
    247static int dn_forwarding_proc(struct ctl_table *table, int write,
    248		void *buffer, size_t *lenp, loff_t *ppos)
    249{
    250#ifdef CONFIG_DECNET_ROUTER
    251	struct net_device *dev = table->extra1;
    252	struct dn_dev *dn_db;
    253	int err;
    254	int tmp, old;
    255
    256	if (table->extra1 == NULL)
    257		return -EINVAL;
    258
    259	dn_db = rcu_dereference_raw(dev->dn_ptr);
    260	old = dn_db->parms.forwarding;
    261
    262	err = proc_dointvec(table, write, buffer, lenp, ppos);
    263
    264	if ((err >= 0) && write) {
    265		if (dn_db->parms.forwarding < 0)
    266			dn_db->parms.forwarding = 0;
    267		if (dn_db->parms.forwarding > 2)
    268			dn_db->parms.forwarding = 2;
    269		/*
    270		 * What an ugly hack this is... its works, just. It
    271		 * would be nice if sysctl/proc were just that little
    272		 * bit more flexible so I don't have to write a special
    273		 * routine, or suffer hacks like this - SJW
    274		 */
    275		tmp = dn_db->parms.forwarding;
    276		dn_db->parms.forwarding = old;
    277		if (dn_db->parms.down)
    278			dn_db->parms.down(dev);
    279		dn_db->parms.forwarding = tmp;
    280		if (dn_db->parms.up)
    281			dn_db->parms.up(dev);
    282	}
    283
    284	return err;
    285#else
    286	return -EINVAL;
    287#endif
    288}
    289
    290#else /* CONFIG_SYSCTL */
    291static void dn_dev_sysctl_unregister(struct dn_dev_parms *parms)
    292{
    293}
    294static void dn_dev_sysctl_register(struct net_device *dev, struct dn_dev_parms *parms)
    295{
    296}
    297
    298#endif /* CONFIG_SYSCTL */
    299
    300static inline __u16 mtu2blksize(struct net_device *dev)
    301{
    302	u32 blksize = dev->mtu;
    303	if (blksize > 0xffff)
    304		blksize = 0xffff;
    305
    306	if (dev->type == ARPHRD_ETHER ||
    307	    dev->type == ARPHRD_PPP ||
    308	    dev->type == ARPHRD_IPGRE ||
    309	    dev->type == ARPHRD_LOOPBACK)
    310		blksize -= 2;
    311
    312	return (__u16)blksize;
    313}
    314
    315static struct dn_ifaddr *dn_dev_alloc_ifa(void)
    316{
    317	struct dn_ifaddr *ifa;
    318
    319	ifa = kzalloc(sizeof(*ifa), GFP_KERNEL);
    320
    321	return ifa;
    322}
    323
    324static void dn_dev_free_ifa(struct dn_ifaddr *ifa)
    325{
    326	kfree_rcu(ifa, rcu);
    327}
    328
    329static void dn_dev_del_ifa(struct dn_dev *dn_db, struct dn_ifaddr __rcu **ifap, int destroy)
    330{
    331	struct dn_ifaddr *ifa1 = rtnl_dereference(*ifap);
    332	unsigned char mac_addr[6];
    333	struct net_device *dev = dn_db->dev;
    334
    335	ASSERT_RTNL();
    336
    337	*ifap = ifa1->ifa_next;
    338
    339	if (dn_db->dev->type == ARPHRD_ETHER) {
    340		if (ifa1->ifa_local != dn_eth2dn(dev->dev_addr)) {
    341			dn_dn2eth(mac_addr, ifa1->ifa_local);
    342			dev_mc_del(dev, mac_addr);
    343		}
    344	}
    345
    346	dn_ifaddr_notify(RTM_DELADDR, ifa1);
    347	blocking_notifier_call_chain(&dnaddr_chain, NETDEV_DOWN, ifa1);
    348	if (destroy) {
    349		dn_dev_free_ifa(ifa1);
    350
    351		if (dn_db->ifa_list == NULL)
    352			dn_dev_delete(dn_db->dev);
    353	}
    354}
    355
    356static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa)
    357{
    358	struct net_device *dev = dn_db->dev;
    359	struct dn_ifaddr *ifa1;
    360	unsigned char mac_addr[6];
    361
    362	ASSERT_RTNL();
    363
    364	/* Check for duplicates */
    365	for (ifa1 = rtnl_dereference(dn_db->ifa_list);
    366	     ifa1 != NULL;
    367	     ifa1 = rtnl_dereference(ifa1->ifa_next)) {
    368		if (ifa1->ifa_local == ifa->ifa_local)
    369			return -EEXIST;
    370	}
    371
    372	if (dev->type == ARPHRD_ETHER) {
    373		if (ifa->ifa_local != dn_eth2dn(dev->dev_addr)) {
    374			dn_dn2eth(mac_addr, ifa->ifa_local);
    375			dev_mc_add(dev, mac_addr);
    376		}
    377	}
    378
    379	ifa->ifa_next = dn_db->ifa_list;
    380	rcu_assign_pointer(dn_db->ifa_list, ifa);
    381
    382	dn_ifaddr_notify(RTM_NEWADDR, ifa);
    383	blocking_notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa);
    384
    385	return 0;
    386}
    387
    388static int dn_dev_set_ifa(struct net_device *dev, struct dn_ifaddr *ifa)
    389{
    390	struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr);
    391	int rv;
    392
    393	if (dn_db == NULL) {
    394		int err;
    395		dn_db = dn_dev_create(dev, &err);
    396		if (dn_db == NULL)
    397			return err;
    398	}
    399
    400	ifa->ifa_dev = dn_db;
    401
    402	if (dev->flags & IFF_LOOPBACK)
    403		ifa->ifa_scope = RT_SCOPE_HOST;
    404
    405	rv = dn_dev_insert_ifa(dn_db, ifa);
    406	if (rv)
    407		dn_dev_free_ifa(ifa);
    408	return rv;
    409}
    410
    411
    412int dn_dev_ioctl(unsigned int cmd, void __user *arg)
    413{
    414	char buffer[DN_IFREQ_SIZE];
    415	struct ifreq *ifr = (struct ifreq *)buffer;
    416	struct sockaddr_dn *sdn = (struct sockaddr_dn *)&ifr->ifr_addr;
    417	struct dn_dev *dn_db;
    418	struct net_device *dev;
    419	struct dn_ifaddr *ifa = NULL;
    420	struct dn_ifaddr __rcu **ifap = NULL;
    421	int ret = 0;
    422
    423	if (copy_from_user(ifr, arg, DN_IFREQ_SIZE))
    424		return -EFAULT;
    425	ifr->ifr_name[IFNAMSIZ-1] = 0;
    426
    427	dev_load(&init_net, ifr->ifr_name);
    428
    429	switch (cmd) {
    430	case SIOCGIFADDR:
    431		break;
    432	case SIOCSIFADDR:
    433		if (!capable(CAP_NET_ADMIN))
    434			return -EACCES;
    435		if (sdn->sdn_family != AF_DECnet)
    436			return -EINVAL;
    437		break;
    438	default:
    439		return -EINVAL;
    440	}
    441
    442	rtnl_lock();
    443
    444	if ((dev = __dev_get_by_name(&init_net, ifr->ifr_name)) == NULL) {
    445		ret = -ENODEV;
    446		goto done;
    447	}
    448
    449	if ((dn_db = rtnl_dereference(dev->dn_ptr)) != NULL) {
    450		for (ifap = &dn_db->ifa_list;
    451		     (ifa = rtnl_dereference(*ifap)) != NULL;
    452		     ifap = &ifa->ifa_next)
    453			if (strcmp(ifr->ifr_name, ifa->ifa_label) == 0)
    454				break;
    455	}
    456
    457	if (ifa == NULL && cmd != SIOCSIFADDR) {
    458		ret = -EADDRNOTAVAIL;
    459		goto done;
    460	}
    461
    462	switch (cmd) {
    463	case SIOCGIFADDR:
    464		*((__le16 *)sdn->sdn_nodeaddr) = ifa->ifa_local;
    465		if (copy_to_user(arg, ifr, DN_IFREQ_SIZE))
    466			ret = -EFAULT;
    467		break;
    468
    469	case SIOCSIFADDR:
    470		if (!ifa) {
    471			if ((ifa = dn_dev_alloc_ifa()) == NULL) {
    472				ret = -ENOBUFS;
    473				break;
    474			}
    475			memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
    476		} else {
    477			if (ifa->ifa_local == dn_saddr2dn(sdn))
    478				break;
    479			dn_dev_del_ifa(dn_db, ifap, 0);
    480		}
    481
    482		ifa->ifa_local = ifa->ifa_address = dn_saddr2dn(sdn);
    483
    484		ret = dn_dev_set_ifa(dev, ifa);
    485	}
    486done:
    487	rtnl_unlock();
    488
    489	return ret;
    490}
    491
    492struct net_device *dn_dev_get_default(void)
    493{
    494	struct net_device *dev;
    495
    496	spin_lock(&dndev_lock);
    497	dev = decnet_default_device;
    498	if (dev) {
    499		if (dev->dn_ptr)
    500			dev_hold(dev);
    501		else
    502			dev = NULL;
    503	}
    504	spin_unlock(&dndev_lock);
    505
    506	return dev;
    507}
    508
    509int dn_dev_set_default(struct net_device *dev, int force)
    510{
    511	struct net_device *old = NULL;
    512	int rv = -EBUSY;
    513	if (!dev->dn_ptr)
    514		return -ENODEV;
    515
    516	spin_lock(&dndev_lock);
    517	if (force || decnet_default_device == NULL) {
    518		old = decnet_default_device;
    519		decnet_default_device = dev;
    520		rv = 0;
    521	}
    522	spin_unlock(&dndev_lock);
    523
    524	dev_put(old);
    525	return rv;
    526}
    527
    528static void dn_dev_check_default(struct net_device *dev)
    529{
    530	spin_lock(&dndev_lock);
    531	if (dev == decnet_default_device) {
    532		decnet_default_device = NULL;
    533	} else {
    534		dev = NULL;
    535	}
    536	spin_unlock(&dndev_lock);
    537
    538	dev_put(dev);
    539}
    540
    541/*
    542 * Called with RTNL
    543 */
    544static struct dn_dev *dn_dev_by_index(int ifindex)
    545{
    546	struct net_device *dev;
    547	struct dn_dev *dn_dev = NULL;
    548
    549	dev = __dev_get_by_index(&init_net, ifindex);
    550	if (dev)
    551		dn_dev = rtnl_dereference(dev->dn_ptr);
    552
    553	return dn_dev;
    554}
    555
    556static const struct nla_policy dn_ifa_policy[IFA_MAX+1] = {
    557	[IFA_ADDRESS]		= { .type = NLA_U16 },
    558	[IFA_LOCAL]		= { .type = NLA_U16 },
    559	[IFA_LABEL]		= { .type = NLA_STRING,
    560				    .len = IFNAMSIZ - 1 },
    561	[IFA_FLAGS]		= { .type = NLA_U32 },
    562};
    563
    564static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh,
    565			 struct netlink_ext_ack *extack)
    566{
    567	struct net *net = sock_net(skb->sk);
    568	struct nlattr *tb[IFA_MAX+1];
    569	struct dn_dev *dn_db;
    570	struct ifaddrmsg *ifm;
    571	struct dn_ifaddr *ifa;
    572	struct dn_ifaddr __rcu **ifap;
    573	int err = -EINVAL;
    574
    575	if (!netlink_capable(skb, CAP_NET_ADMIN))
    576		return -EPERM;
    577
    578	if (!net_eq(net, &init_net))
    579		goto errout;
    580
    581	err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFA_MAX,
    582				     dn_ifa_policy, extack);
    583	if (err < 0)
    584		goto errout;
    585
    586	err = -ENODEV;
    587	ifm = nlmsg_data(nlh);
    588	if ((dn_db = dn_dev_by_index(ifm->ifa_index)) == NULL)
    589		goto errout;
    590
    591	err = -EADDRNOTAVAIL;
    592	for (ifap = &dn_db->ifa_list;
    593	     (ifa = rtnl_dereference(*ifap)) != NULL;
    594	     ifap = &ifa->ifa_next) {
    595		if (tb[IFA_LOCAL] &&
    596		    nla_memcmp(tb[IFA_LOCAL], &ifa->ifa_local, 2))
    597			continue;
    598
    599		if (tb[IFA_LABEL] && nla_strcmp(tb[IFA_LABEL], ifa->ifa_label))
    600			continue;
    601
    602		dn_dev_del_ifa(dn_db, ifap, 1);
    603		return 0;
    604	}
    605
    606errout:
    607	return err;
    608}
    609
    610static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
    611			 struct netlink_ext_ack *extack)
    612{
    613	struct net *net = sock_net(skb->sk);
    614	struct nlattr *tb[IFA_MAX+1];
    615	struct net_device *dev;
    616	struct dn_dev *dn_db;
    617	struct ifaddrmsg *ifm;
    618	struct dn_ifaddr *ifa;
    619	int err;
    620
    621	if (!netlink_capable(skb, CAP_NET_ADMIN))
    622		return -EPERM;
    623
    624	if (!net_eq(net, &init_net))
    625		return -EINVAL;
    626
    627	err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFA_MAX,
    628				     dn_ifa_policy, extack);
    629	if (err < 0)
    630		return err;
    631
    632	if (tb[IFA_LOCAL] == NULL)
    633		return -EINVAL;
    634
    635	ifm = nlmsg_data(nlh);
    636	if ((dev = __dev_get_by_index(&init_net, ifm->ifa_index)) == NULL)
    637		return -ENODEV;
    638
    639	if ((dn_db = rtnl_dereference(dev->dn_ptr)) == NULL) {
    640		dn_db = dn_dev_create(dev, &err);
    641		if (!dn_db)
    642			return err;
    643	}
    644
    645	if ((ifa = dn_dev_alloc_ifa()) == NULL)
    646		return -ENOBUFS;
    647
    648	if (tb[IFA_ADDRESS] == NULL)
    649		tb[IFA_ADDRESS] = tb[IFA_LOCAL];
    650
    651	ifa->ifa_local = nla_get_le16(tb[IFA_LOCAL]);
    652	ifa->ifa_address = nla_get_le16(tb[IFA_ADDRESS]);
    653	ifa->ifa_flags = tb[IFA_FLAGS] ? nla_get_u32(tb[IFA_FLAGS]) :
    654					 ifm->ifa_flags;
    655	ifa->ifa_scope = ifm->ifa_scope;
    656	ifa->ifa_dev = dn_db;
    657
    658	if (tb[IFA_LABEL])
    659		nla_strscpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
    660	else
    661		memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
    662
    663	err = dn_dev_insert_ifa(dn_db, ifa);
    664	if (err)
    665		dn_dev_free_ifa(ifa);
    666
    667	return err;
    668}
    669
    670static inline size_t dn_ifaddr_nlmsg_size(void)
    671{
    672	return NLMSG_ALIGN(sizeof(struct ifaddrmsg))
    673	       + nla_total_size(IFNAMSIZ) /* IFA_LABEL */
    674	       + nla_total_size(2) /* IFA_ADDRESS */
    675	       + nla_total_size(2) /* IFA_LOCAL */
    676	       + nla_total_size(4); /* IFA_FLAGS */
    677}
    678
    679static int dn_nl_fill_ifaddr(struct sk_buff *skb, struct dn_ifaddr *ifa,
    680			     u32 portid, u32 seq, int event, unsigned int flags)
    681{
    682	struct ifaddrmsg *ifm;
    683	struct nlmsghdr *nlh;
    684	u32 ifa_flags = ifa->ifa_flags | IFA_F_PERMANENT;
    685
    686	nlh = nlmsg_put(skb, portid, seq, event, sizeof(*ifm), flags);
    687	if (nlh == NULL)
    688		return -EMSGSIZE;
    689
    690	ifm = nlmsg_data(nlh);
    691	ifm->ifa_family = AF_DECnet;
    692	ifm->ifa_prefixlen = 16;
    693	ifm->ifa_flags = ifa_flags;
    694	ifm->ifa_scope = ifa->ifa_scope;
    695	ifm->ifa_index = ifa->ifa_dev->dev->ifindex;
    696
    697	if ((ifa->ifa_address &&
    698	     nla_put_le16(skb, IFA_ADDRESS, ifa->ifa_address)) ||
    699	    (ifa->ifa_local &&
    700	     nla_put_le16(skb, IFA_LOCAL, ifa->ifa_local)) ||
    701	    (ifa->ifa_label[0] &&
    702	     nla_put_string(skb, IFA_LABEL, ifa->ifa_label)) ||
    703	     nla_put_u32(skb, IFA_FLAGS, ifa_flags))
    704		goto nla_put_failure;
    705	nlmsg_end(skb, nlh);
    706	return 0;
    707
    708nla_put_failure:
    709	nlmsg_cancel(skb, nlh);
    710	return -EMSGSIZE;
    711}
    712
    713static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa)
    714{
    715	struct sk_buff *skb;
    716	int err = -ENOBUFS;
    717
    718	skb = alloc_skb(dn_ifaddr_nlmsg_size(), GFP_KERNEL);
    719	if (skb == NULL)
    720		goto errout;
    721
    722	err = dn_nl_fill_ifaddr(skb, ifa, 0, 0, event, 0);
    723	if (err < 0) {
    724		/* -EMSGSIZE implies BUG in dn_ifaddr_nlmsg_size() */
    725		WARN_ON(err == -EMSGSIZE);
    726		kfree_skb(skb);
    727		goto errout;
    728	}
    729	rtnl_notify(skb, &init_net, 0, RTNLGRP_DECnet_IFADDR, NULL, GFP_KERNEL);
    730	return;
    731errout:
    732	if (err < 0)
    733		rtnl_set_sk_err(&init_net, RTNLGRP_DECnet_IFADDR, err);
    734}
    735
    736static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
    737{
    738	struct net *net = sock_net(skb->sk);
    739	int idx, dn_idx = 0, skip_ndevs, skip_naddr;
    740	struct net_device *dev;
    741	struct dn_dev *dn_db;
    742	struct dn_ifaddr *ifa;
    743
    744	if (!net_eq(net, &init_net))
    745		return 0;
    746
    747	skip_ndevs = cb->args[0];
    748	skip_naddr = cb->args[1];
    749
    750	idx = 0;
    751	rcu_read_lock();
    752	for_each_netdev_rcu(&init_net, dev) {
    753		if (idx < skip_ndevs)
    754			goto cont;
    755		else if (idx > skip_ndevs) {
    756			/* Only skip over addresses for first dev dumped
    757			 * in this iteration (idx == skip_ndevs) */
    758			skip_naddr = 0;
    759		}
    760
    761		if ((dn_db = rcu_dereference(dev->dn_ptr)) == NULL)
    762			goto cont;
    763
    764		for (ifa = rcu_dereference(dn_db->ifa_list), dn_idx = 0; ifa;
    765		     ifa = rcu_dereference(ifa->ifa_next), dn_idx++) {
    766			if (dn_idx < skip_naddr)
    767				continue;
    768
    769			if (dn_nl_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).portid,
    770					      cb->nlh->nlmsg_seq, RTM_NEWADDR,
    771					      NLM_F_MULTI) < 0)
    772				goto done;
    773		}
    774cont:
    775		idx++;
    776	}
    777done:
    778	rcu_read_unlock();
    779	cb->args[0] = idx;
    780	cb->args[1] = dn_idx;
    781
    782	return skb->len;
    783}
    784
    785static int dn_dev_get_first(struct net_device *dev, __le16 *addr)
    786{
    787	struct dn_dev *dn_db;
    788	struct dn_ifaddr *ifa;
    789	int rv = -ENODEV;
    790
    791	rcu_read_lock();
    792	dn_db = rcu_dereference(dev->dn_ptr);
    793	if (dn_db == NULL)
    794		goto out;
    795
    796	ifa = rcu_dereference(dn_db->ifa_list);
    797	if (ifa != NULL) {
    798		*addr = ifa->ifa_local;
    799		rv = 0;
    800	}
    801out:
    802	rcu_read_unlock();
    803	return rv;
    804}
    805
    806/*
    807 * Find a default address to bind to.
    808 *
    809 * This is one of those areas where the initial VMS concepts don't really
    810 * map onto the Linux concepts, and since we introduced multiple addresses
    811 * per interface we have to cope with slightly odd ways of finding out what
    812 * "our address" really is. Mostly it's not a problem; for this we just guess
    813 * a sensible default. Eventually the routing code will take care of all the
    814 * nasties for us I hope.
    815 */
    816int dn_dev_bind_default(__le16 *addr)
    817{
    818	struct net_device *dev;
    819	int rv;
    820	dev = dn_dev_get_default();
    821last_chance:
    822	if (dev) {
    823		rv = dn_dev_get_first(dev, addr);
    824		dev_put(dev);
    825		if (rv == 0 || dev == init_net.loopback_dev)
    826			return rv;
    827	}
    828	dev = init_net.loopback_dev;
    829	dev_hold(dev);
    830	goto last_chance;
    831}
    832
    833static void dn_send_endnode_hello(struct net_device *dev, struct dn_ifaddr *ifa)
    834{
    835	struct endnode_hello_message *msg;
    836	struct sk_buff *skb = NULL;
    837	__le16 *pktlen;
    838	struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
    839
    840	if ((skb = dn_alloc_skb(NULL, sizeof(*msg), GFP_ATOMIC)) == NULL)
    841		return;
    842
    843	skb->dev = dev;
    844
    845	msg = skb_put(skb, sizeof(*msg));
    846
    847	msg->msgflg  = 0x0D;
    848	memcpy(msg->tiver, dn_eco_version, 3);
    849	dn_dn2eth(msg->id, ifa->ifa_local);
    850	msg->iinfo   = DN_RT_INFO_ENDN;
    851	msg->blksize = cpu_to_le16(mtu2blksize(dev));
    852	msg->area    = 0x00;
    853	memset(msg->seed, 0, 8);
    854	memcpy(msg->neighbor, dn_hiord, ETH_ALEN);
    855
    856	if (dn_db->router) {
    857		struct dn_neigh *dn = container_of(dn_db->router, struct dn_neigh, n);
    858		dn_dn2eth(msg->neighbor, dn->addr);
    859	}
    860
    861	msg->timer   = cpu_to_le16((unsigned short)dn_db->parms.t3);
    862	msg->mpd     = 0x00;
    863	msg->datalen = 0x02;
    864	memset(msg->data, 0xAA, 2);
    865
    866	pktlen = skb_push(skb, 2);
    867	*pktlen = cpu_to_le16(skb->len - 2);
    868
    869	skb_reset_network_header(skb);
    870
    871	dn_rt_finish_output(skb, dn_rt_all_rt_mcast, msg->id);
    872}
    873
    874
    875#define DRDELAY (5 * HZ)
    876
    877static int dn_am_i_a_router(struct dn_neigh *dn, struct dn_dev *dn_db, struct dn_ifaddr *ifa)
    878{
    879	/* First check time since device went up */
    880	if (time_before(jiffies, dn_db->uptime + DRDELAY))
    881		return 0;
    882
    883	/* If there is no router, then yes... */
    884	if (!dn_db->router)
    885		return 1;
    886
    887	/* otherwise only if we have a higher priority or.. */
    888	if (dn->priority < dn_db->parms.priority)
    889		return 1;
    890
    891	/* if we have equal priority and a higher node number */
    892	if (dn->priority != dn_db->parms.priority)
    893		return 0;
    894
    895	if (le16_to_cpu(dn->addr) < le16_to_cpu(ifa->ifa_local))
    896		return 1;
    897
    898	return 0;
    899}
    900
    901static void dn_send_router_hello(struct net_device *dev, struct dn_ifaddr *ifa)
    902{
    903	int n;
    904	struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
    905	struct dn_neigh *dn = container_of(dn_db->router, struct dn_neigh, n);
    906	struct sk_buff *skb;
    907	size_t size;
    908	unsigned char *ptr;
    909	unsigned char *i1, *i2;
    910	__le16 *pktlen;
    911	char *src;
    912
    913	if (mtu2blksize(dev) < (26 + 7))
    914		return;
    915
    916	n = mtu2blksize(dev) - 26;
    917	n /= 7;
    918
    919	if (n > 32)
    920		n = 32;
    921
    922	size = 2 + 26 + 7 * n;
    923
    924	if ((skb = dn_alloc_skb(NULL, size, GFP_ATOMIC)) == NULL)
    925		return;
    926
    927	skb->dev = dev;
    928	ptr = skb_put(skb, size);
    929
    930	*ptr++ = DN_RT_PKT_CNTL | DN_RT_PKT_ERTH;
    931	*ptr++ = 2; /* ECO */
    932	*ptr++ = 0;
    933	*ptr++ = 0;
    934	dn_dn2eth(ptr, ifa->ifa_local);
    935	src = ptr;
    936	ptr += ETH_ALEN;
    937	*ptr++ = dn_db->parms.forwarding == 1 ?
    938			DN_RT_INFO_L1RT : DN_RT_INFO_L2RT;
    939	*((__le16 *)ptr) = cpu_to_le16(mtu2blksize(dev));
    940	ptr += 2;
    941	*ptr++ = dn_db->parms.priority; /* Priority */
    942	*ptr++ = 0; /* Area: Reserved */
    943	*((__le16 *)ptr) = cpu_to_le16((unsigned short)dn_db->parms.t3);
    944	ptr += 2;
    945	*ptr++ = 0; /* MPD: Reserved */
    946	i1 = ptr++;
    947	memset(ptr, 0, 7); /* Name: Reserved */
    948	ptr += 7;
    949	i2 = ptr++;
    950
    951	n = dn_neigh_elist(dev, ptr, n);
    952
    953	*i2 = 7 * n;
    954	*i1 = 8 + *i2;
    955
    956	skb_trim(skb, (27 + *i2));
    957
    958	pktlen = skb_push(skb, 2);
    959	*pktlen = cpu_to_le16(skb->len - 2);
    960
    961	skb_reset_network_header(skb);
    962
    963	if (dn_am_i_a_router(dn, dn_db, ifa)) {
    964		struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
    965		if (skb2) {
    966			dn_rt_finish_output(skb2, dn_rt_all_end_mcast, src);
    967		}
    968	}
    969
    970	dn_rt_finish_output(skb, dn_rt_all_rt_mcast, src);
    971}
    972
    973static void dn_send_brd_hello(struct net_device *dev, struct dn_ifaddr *ifa)
    974{
    975	struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
    976
    977	if (dn_db->parms.forwarding == 0)
    978		dn_send_endnode_hello(dev, ifa);
    979	else
    980		dn_send_router_hello(dev, ifa);
    981}
    982
    983static void dn_send_ptp_hello(struct net_device *dev, struct dn_ifaddr *ifa)
    984{
    985	int tdlen = 16;
    986	int size = dev->hard_header_len + 2 + 4 + tdlen;
    987	struct sk_buff *skb = dn_alloc_skb(NULL, size, GFP_ATOMIC);
    988	int i;
    989	unsigned char *ptr;
    990	char src[ETH_ALEN];
    991
    992	if (skb == NULL)
    993		return ;
    994
    995	skb->dev = dev;
    996	skb_push(skb, dev->hard_header_len);
    997	ptr = skb_put(skb, 2 + 4 + tdlen);
    998
    999	*ptr++ = DN_RT_PKT_HELO;
   1000	*((__le16 *)ptr) = ifa->ifa_local;
   1001	ptr += 2;
   1002	*ptr++ = tdlen;
   1003
   1004	for(i = 0; i < tdlen; i++)
   1005		*ptr++ = 0252;
   1006
   1007	dn_dn2eth(src, ifa->ifa_local);
   1008	dn_rt_finish_output(skb, dn_rt_all_rt_mcast, src);
   1009}
   1010
   1011static int dn_eth_up(struct net_device *dev)
   1012{
   1013	struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
   1014
   1015	if (dn_db->parms.forwarding == 0)
   1016		dev_mc_add(dev, dn_rt_all_end_mcast);
   1017	else
   1018		dev_mc_add(dev, dn_rt_all_rt_mcast);
   1019
   1020	dn_db->use_long = 1;
   1021
   1022	return 0;
   1023}
   1024
   1025static void dn_eth_down(struct net_device *dev)
   1026{
   1027	struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
   1028
   1029	if (dn_db->parms.forwarding == 0)
   1030		dev_mc_del(dev, dn_rt_all_end_mcast);
   1031	else
   1032		dev_mc_del(dev, dn_rt_all_rt_mcast);
   1033}
   1034
   1035static void dn_dev_set_timer(struct net_device *dev);
   1036
   1037static void dn_dev_timer_func(struct timer_list *t)
   1038{
   1039	struct dn_dev *dn_db = from_timer(dn_db, t, timer);
   1040	struct net_device *dev;
   1041	struct dn_ifaddr *ifa;
   1042
   1043	rcu_read_lock();
   1044	dev = dn_db->dev;
   1045	if (dn_db->t3 <= dn_db->parms.t2) {
   1046		if (dn_db->parms.timer3) {
   1047			for (ifa = rcu_dereference(dn_db->ifa_list);
   1048			     ifa;
   1049			     ifa = rcu_dereference(ifa->ifa_next)) {
   1050				if (!(ifa->ifa_flags & IFA_F_SECONDARY))
   1051					dn_db->parms.timer3(dev, ifa);
   1052			}
   1053		}
   1054		dn_db->t3 = dn_db->parms.t3;
   1055	} else {
   1056		dn_db->t3 -= dn_db->parms.t2;
   1057	}
   1058	rcu_read_unlock();
   1059	dn_dev_set_timer(dev);
   1060}
   1061
   1062static void dn_dev_set_timer(struct net_device *dev)
   1063{
   1064	struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
   1065
   1066	if (dn_db->parms.t2 > dn_db->parms.t3)
   1067		dn_db->parms.t2 = dn_db->parms.t3;
   1068
   1069	dn_db->timer.expires = jiffies + (dn_db->parms.t2 * HZ);
   1070
   1071	add_timer(&dn_db->timer);
   1072}
   1073
   1074static struct dn_dev *dn_dev_create(struct net_device *dev, int *err)
   1075{
   1076	int i;
   1077	struct dn_dev_parms *p = dn_dev_list;
   1078	struct dn_dev *dn_db;
   1079
   1080	for(i = 0; i < DN_DEV_LIST_SIZE; i++, p++) {
   1081		if (p->type == dev->type)
   1082			break;
   1083	}
   1084
   1085	*err = -ENODEV;
   1086	if (i == DN_DEV_LIST_SIZE)
   1087		return NULL;
   1088
   1089	*err = -ENOBUFS;
   1090	if ((dn_db = kzalloc(sizeof(struct dn_dev), GFP_ATOMIC)) == NULL)
   1091		return NULL;
   1092
   1093	memcpy(&dn_db->parms, p, sizeof(struct dn_dev_parms));
   1094
   1095	rcu_assign_pointer(dev->dn_ptr, dn_db);
   1096	dn_db->dev = dev;
   1097	timer_setup(&dn_db->timer, dn_dev_timer_func, 0);
   1098
   1099	dn_db->uptime = jiffies;
   1100
   1101	dn_db->neigh_parms = neigh_parms_alloc(dev, &dn_neigh_table);
   1102	if (!dn_db->neigh_parms) {
   1103		RCU_INIT_POINTER(dev->dn_ptr, NULL);
   1104		kfree(dn_db);
   1105		return NULL;
   1106	}
   1107
   1108	if (dn_db->parms.up) {
   1109		if (dn_db->parms.up(dev) < 0) {
   1110			neigh_parms_release(&dn_neigh_table, dn_db->neigh_parms);
   1111			dev->dn_ptr = NULL;
   1112			kfree(dn_db);
   1113			return NULL;
   1114		}
   1115	}
   1116
   1117	dn_dev_sysctl_register(dev, &dn_db->parms);
   1118
   1119	dn_dev_set_timer(dev);
   1120
   1121	*err = 0;
   1122	return dn_db;
   1123}
   1124
   1125
   1126/*
   1127 * This processes a device up event. We only start up
   1128 * the loopback device & ethernet devices with correct
   1129 * MAC addresses automatically. Others must be started
   1130 * specifically.
   1131 *
   1132 * FIXME: How should we configure the loopback address ? If we could dispense
   1133 * with using decnet_address here and for autobind, it will be one less thing
   1134 * for users to worry about setting up.
   1135 */
   1136
   1137void dn_dev_up(struct net_device *dev)
   1138{
   1139	struct dn_ifaddr *ifa;
   1140	__le16 addr = decnet_address;
   1141	int maybe_default = 0;
   1142	struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr);
   1143
   1144	if ((dev->type != ARPHRD_ETHER) && (dev->type != ARPHRD_LOOPBACK))
   1145		return;
   1146
   1147	/*
   1148	 * Need to ensure that loopback device has a dn_db attached to it
   1149	 * to allow creation of neighbours against it, even though it might
   1150	 * not have a local address of its own. Might as well do the same for
   1151	 * all autoconfigured interfaces.
   1152	 */
   1153	if (dn_db == NULL) {
   1154		int err;
   1155		dn_db = dn_dev_create(dev, &err);
   1156		if (dn_db == NULL)
   1157			return;
   1158	}
   1159
   1160	if (dev->type == ARPHRD_ETHER) {
   1161		if (memcmp(dev->dev_addr, dn_hiord, 4) != 0)
   1162			return;
   1163		addr = dn_eth2dn(dev->dev_addr);
   1164		maybe_default = 1;
   1165	}
   1166
   1167	if (addr == 0)
   1168		return;
   1169
   1170	if ((ifa = dn_dev_alloc_ifa()) == NULL)
   1171		return;
   1172
   1173	ifa->ifa_local = ifa->ifa_address = addr;
   1174	ifa->ifa_flags = 0;
   1175	ifa->ifa_scope = RT_SCOPE_UNIVERSE;
   1176	strcpy(ifa->ifa_label, dev->name);
   1177
   1178	dn_dev_set_ifa(dev, ifa);
   1179
   1180	/*
   1181	 * Automagically set the default device to the first automatically
   1182	 * configured ethernet card in the system.
   1183	 */
   1184	if (maybe_default) {
   1185		dev_hold(dev);
   1186		if (dn_dev_set_default(dev, 0))
   1187			dev_put(dev);
   1188	}
   1189}
   1190
   1191static void dn_dev_delete(struct net_device *dev)
   1192{
   1193	struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr);
   1194
   1195	if (dn_db == NULL)
   1196		return;
   1197
   1198	del_timer_sync(&dn_db->timer);
   1199	dn_dev_sysctl_unregister(&dn_db->parms);
   1200	dn_dev_check_default(dev);
   1201	neigh_ifdown(&dn_neigh_table, dev);
   1202
   1203	if (dn_db->parms.down)
   1204		dn_db->parms.down(dev);
   1205
   1206	dev->dn_ptr = NULL;
   1207
   1208	neigh_parms_release(&dn_neigh_table, dn_db->neigh_parms);
   1209	neigh_ifdown(&dn_neigh_table, dev);
   1210
   1211	if (dn_db->router)
   1212		neigh_release(dn_db->router);
   1213	if (dn_db->peer)
   1214		neigh_release(dn_db->peer);
   1215
   1216	kfree(dn_db);
   1217}
   1218
   1219void dn_dev_down(struct net_device *dev)
   1220{
   1221	struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr);
   1222	struct dn_ifaddr *ifa;
   1223
   1224	if (dn_db == NULL)
   1225		return;
   1226
   1227	while ((ifa = rtnl_dereference(dn_db->ifa_list)) != NULL) {
   1228		dn_dev_del_ifa(dn_db, &dn_db->ifa_list, 0);
   1229		dn_dev_free_ifa(ifa);
   1230	}
   1231
   1232	dn_dev_delete(dev);
   1233}
   1234
   1235void dn_dev_init_pkt(struct sk_buff *skb)
   1236{
   1237}
   1238
   1239void dn_dev_veri_pkt(struct sk_buff *skb)
   1240{
   1241}
   1242
   1243void dn_dev_hello(struct sk_buff *skb)
   1244{
   1245}
   1246
   1247void dn_dev_devices_off(void)
   1248{
   1249	struct net_device *dev;
   1250
   1251	rtnl_lock();
   1252	for_each_netdev(&init_net, dev)
   1253		dn_dev_down(dev);
   1254	rtnl_unlock();
   1255
   1256}
   1257
   1258void dn_dev_devices_on(void)
   1259{
   1260	struct net_device *dev;
   1261
   1262	rtnl_lock();
   1263	for_each_netdev(&init_net, dev) {
   1264		if (dev->flags & IFF_UP)
   1265			dn_dev_up(dev);
   1266	}
   1267	rtnl_unlock();
   1268}
   1269
   1270int register_dnaddr_notifier(struct notifier_block *nb)
   1271{
   1272	return blocking_notifier_chain_register(&dnaddr_chain, nb);
   1273}
   1274
   1275int unregister_dnaddr_notifier(struct notifier_block *nb)
   1276{
   1277	return blocking_notifier_chain_unregister(&dnaddr_chain, nb);
   1278}
   1279
   1280#ifdef CONFIG_PROC_FS
   1281static inline int is_dn_dev(struct net_device *dev)
   1282{
   1283	return dev->dn_ptr != NULL;
   1284}
   1285
   1286static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos)
   1287	__acquires(RCU)
   1288{
   1289	int i;
   1290	struct net_device *dev;
   1291
   1292	rcu_read_lock();
   1293
   1294	if (*pos == 0)
   1295		return SEQ_START_TOKEN;
   1296
   1297	i = 1;
   1298	for_each_netdev_rcu(&init_net, dev) {
   1299		if (!is_dn_dev(dev))
   1300			continue;
   1301
   1302		if (i++ == *pos)
   1303			return dev;
   1304	}
   1305
   1306	return NULL;
   1307}
   1308
   1309static void *dn_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
   1310{
   1311	struct net_device *dev;
   1312
   1313	++*pos;
   1314
   1315	dev = v;
   1316	if (v == SEQ_START_TOKEN)
   1317		dev = net_device_entry(&init_net.dev_base_head);
   1318
   1319	for_each_netdev_continue_rcu(&init_net, dev) {
   1320		if (!is_dn_dev(dev))
   1321			continue;
   1322
   1323		return dev;
   1324	}
   1325
   1326	return NULL;
   1327}
   1328
   1329static void dn_dev_seq_stop(struct seq_file *seq, void *v)
   1330	__releases(RCU)
   1331{
   1332	rcu_read_unlock();
   1333}
   1334
   1335static char *dn_type2asc(char type)
   1336{
   1337	switch (type) {
   1338	case DN_DEV_BCAST:
   1339		return "B";
   1340	case DN_DEV_UCAST:
   1341		return "U";
   1342	case DN_DEV_MPOINT:
   1343		return "M";
   1344	}
   1345
   1346	return "?";
   1347}
   1348
   1349static int dn_dev_seq_show(struct seq_file *seq, void *v)
   1350{
   1351	if (v == SEQ_START_TOKEN)
   1352		seq_puts(seq, "Name     Flags T1   Timer1 T3   Timer3 BlkSize Pri State DevType    Router Peer\n");
   1353	else {
   1354		struct net_device *dev = v;
   1355		char peer_buf[DN_ASCBUF_LEN];
   1356		char router_buf[DN_ASCBUF_LEN];
   1357		struct dn_dev *dn_db = rcu_dereference(dev->dn_ptr);
   1358
   1359		seq_printf(seq, "%-8s %1s     %04u %04u   %04lu %04lu"
   1360				"   %04hu    %03d %02x    %-10s %-7s %-7s\n",
   1361				dev->name,
   1362				dn_type2asc(dn_db->parms.mode),
   1363				0, 0,
   1364				dn_db->t3, dn_db->parms.t3,
   1365				mtu2blksize(dev),
   1366				dn_db->parms.priority,
   1367				dn_db->parms.state, dn_db->parms.name,
   1368				dn_db->router ? dn_addr2asc(le16_to_cpu(*(__le16 *)dn_db->router->primary_key), router_buf) : "",
   1369				dn_db->peer ? dn_addr2asc(le16_to_cpu(*(__le16 *)dn_db->peer->primary_key), peer_buf) : "");
   1370	}
   1371	return 0;
   1372}
   1373
   1374static const struct seq_operations dn_dev_seq_ops = {
   1375	.start	= dn_dev_seq_start,
   1376	.next	= dn_dev_seq_next,
   1377	.stop	= dn_dev_seq_stop,
   1378	.show	= dn_dev_seq_show,
   1379};
   1380#endif /* CONFIG_PROC_FS */
   1381
   1382static int addr[2];
   1383module_param_array(addr, int, NULL, 0444);
   1384MODULE_PARM_DESC(addr, "The DECnet address of this machine: area,node");
   1385
   1386void __init dn_dev_init(void)
   1387{
   1388	if (addr[0] > 63 || addr[0] < 0) {
   1389		printk(KERN_ERR "DECnet: Area must be between 0 and 63");
   1390		return;
   1391	}
   1392
   1393	if (addr[1] > 1023 || addr[1] < 0) {
   1394		printk(KERN_ERR "DECnet: Node must be between 0 and 1023");
   1395		return;
   1396	}
   1397
   1398	decnet_address = cpu_to_le16((addr[0] << 10) | addr[1]);
   1399
   1400	dn_dev_devices_on();
   1401
   1402	rtnl_register_module(THIS_MODULE, PF_DECnet, RTM_NEWADDR,
   1403			     dn_nl_newaddr, NULL, 0);
   1404	rtnl_register_module(THIS_MODULE, PF_DECnet, RTM_DELADDR,
   1405			     dn_nl_deladdr, NULL, 0);
   1406	rtnl_register_module(THIS_MODULE, PF_DECnet, RTM_GETADDR,
   1407			     NULL, dn_nl_dump_ifaddr, 0);
   1408
   1409	proc_create_seq("decnet_dev", 0444, init_net.proc_net, &dn_dev_seq_ops);
   1410
   1411#ifdef CONFIG_SYSCTL
   1412	{
   1413		int i;
   1414		for(i = 0; i < DN_DEV_LIST_SIZE; i++)
   1415			dn_dev_sysctl_register(NULL, &dn_dev_list[i]);
   1416	}
   1417#endif /* CONFIG_SYSCTL */
   1418}
   1419
   1420void __exit dn_dev_cleanup(void)
   1421{
   1422#ifdef CONFIG_SYSCTL
   1423	{
   1424		int i;
   1425		for(i = 0; i < DN_DEV_LIST_SIZE; i++)
   1426			dn_dev_sysctl_unregister(&dn_dev_list[i]);
   1427	}
   1428#endif /* CONFIG_SYSCTL */
   1429
   1430	remove_proc_entry("decnet_dev", init_net.proc_net);
   1431
   1432	dn_dev_devices_off();
   1433}