/*
 * DECnet       An implementation of the DECnet protocol suite for the LINUX
 *              operating system.  DECnet is implemented using the  BSD Socket
 *              interface as the means of communication with the user level.
 *
 *              DECnet Routing Forwarding Information Base (Glue/Info List)
 *
 * Author:      Steve Whitehouse <SteveW@ACM.org>
 *
 *
 * Changes:
 *              Alexey Kuznetsov : SMP locking changes
 *              Steve Whitehouse : Rewrote it... Well to be more correct, I
 *                                 copied most of it from the ipv4 fib code.
 *              Steve Whitehouse : Updated it in style and fixed a few bugs
 *                                 which were fixed in the ipv4 code since
 *                                 this code was copied from it.
 *
 */
#include <linux/string.h>
#include <linux/net.h>
#include <linux/socket.h>
#include <linux/slab.h>
#include <linux/sockios.h>
#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/proc_fs.h>
#include <linux/netdevice.h>
#include <linux/timer.h>
#include <linux/spinlock.h>
#include <linux/atomic.h>
#include <linux/uaccess.h>
#include <net/neighbour.h>
#include <net/dst.h>
#include <net/flow.h>
#include <net/fib_rules.h>
#include <net/dn.h>
#include <net/dn_route.h>
#include <net/dn_fib.h>
#include <net/dn_neigh.h>
#include <net/dn_dev.h>
#include <net/nexthop.h>

#define RT_MIN_TABLE 1

#define for_fib_info() { struct dn_fib_info *fi;\
	for(fi = dn_fib_info_list; fi; fi = fi->fib_next)
#define endfor_fib_info() }

#define for_nexthops(fi) { int nhsel; const struct dn_fib_nh *nh;\
	for(nhsel = 0, nh = (fi)->fib_nh; nhsel < (fi)->fib_nhs; nh++, nhsel++)

#define change_nexthops(fi) { int nhsel; struct dn_fib_nh *nh;\
	for(nhsel = 0, nh = (struct dn_fib_nh *)((fi)->fib_nh); nhsel < (fi)->fib_nhs; nh++, nhsel++)

#define endfor_nexthops(fi) }

static DEFINE_SPINLOCK(dn_fib_multipath_lock);
static struct dn_fib_info *dn_fib_info_list;
static DEFINE_SPINLOCK(dn_fib_info_lock);

static struct
{
	int error;
	u8 scope;
} dn_fib_props[RTN_MAX+1] = {
	[RTN_UNSPEC] =      { .error = 0,       .scope = RT_SCOPE_NOWHERE },
	[RTN_UNICAST] =     { .error = 0,       .scope = RT_SCOPE_UNIVERSE },
	[RTN_LOCAL] =       { .error = 0,       .scope = RT_SCOPE_HOST },
	[RTN_BROADCAST] =   { .error = -EINVAL, .scope = RT_SCOPE_NOWHERE },
	[RTN_ANYCAST] =     { .error = -EINVAL, .scope = RT_SCOPE_NOWHERE },
	[RTN_MULTICAST] =   { .error = -EINVAL, .scope = RT_SCOPE_NOWHERE },
	[RTN_BLACKHOLE] =   { .error = -EINVAL, .scope = RT_SCOPE_UNIVERSE },
	[RTN_UNREACHABLE] = { .error = -EHOSTUNREACH, .scope = RT_SCOPE_UNIVERSE },
	[RTN_PROHIBIT] =    { .error = -EACCES, .scope = RT_SCOPE_UNIVERSE },
	[RTN_THROW] =       { .error = -EAGAIN, .scope = RT_SCOPE_UNIVERSE },
	[RTN_NAT] =         { .error = 0,       .scope = RT_SCOPE_NOWHERE },
	[RTN_XRESOLVE] =    { .error = -EINVAL, .scope = RT_SCOPE_NOWHERE },
};

static int dn_fib_sync_down(__le16 local, struct net_device *dev, int force);
static int dn_fib_sync_up(struct net_device *dev);

void dn_fib_free_info(struct dn_fib_info *fi)
{
	if (fi->fib_dead == 0) {
		printk(KERN_DEBUG "DECnet: BUG! Attempt to free alive dn_fib_info\n");
		return;
	}

	change_nexthops(fi) {
		if (nh->nh_dev)
			dev_put(nh->nh_dev);
		nh->nh_dev = NULL;
	} endfor_nexthops(fi);
	kfree(fi);
}

void dn_fib_release_info(struct dn_fib_info *fi)
{
	spin_lock(&dn_fib_info_lock);
	if (fi && --fi->fib_treeref == 0) {
		if (fi->fib_next)
			fi->fib_next->fib_prev = fi->fib_prev;
		if (fi->fib_prev)
			fi->fib_prev->fib_next = fi->fib_next;
		if (fi == dn_fib_info_list)
			dn_fib_info_list = fi->fib_next;
		fi->fib_dead = 1;
		dn_fib_info_put(fi);
	}
	spin_unlock(&dn_fib_info_lock);
}

static inline int dn_fib_nh_comp(const struct dn_fib_info *fi, const struct dn_fib_info *ofi)
{
	const struct dn_fib_nh *onh = ofi->fib_nh;

	for_nexthops(fi) {
		if (nh->nh_oif != onh->nh_oif ||
			nh->nh_gw != onh->nh_gw ||
			nh->nh_scope != onh->nh_scope ||
			nh->nh_weight != onh->nh_weight ||
			((nh->nh_flags^onh->nh_flags)&~RTNH_F_DEAD))
				return -1;
		onh++;
	} endfor_nexthops(fi);
	return 0;
}

static inline struct dn_fib_info *dn_fib_find_info(const struct dn_fib_info *nfi)
{
	for_fib_info() {
		if (fi->fib_nhs != nfi->fib_nhs)
			continue;
		if (nfi->fib_protocol == fi->fib_protocol &&
			nfi->fib_prefsrc == fi->fib_prefsrc &&
			nfi->fib_priority == fi->fib_priority &&
			memcmp(nfi->fib_metrics, fi->fib_metrics, sizeof(fi->fib_metrics)) == 0 &&
			((nfi->fib_flags^fi->fib_flags)&~RTNH_F_DEAD) == 0 &&
			(nfi->fib_nhs == 0 || dn_fib_nh_comp(fi, nfi) == 0))
				return fi;
	} endfor_fib_info();
	return NULL;
}

static int dn_fib_count_nhs(const struct nlattr *attr)
{
	struct rtnexthop *nhp = nla_data(attr);
	int nhs = 0, nhlen = nla_len(attr);

	while (rtnh_ok(nhp, nhlen)) {
		nhs++;
		nhp = rtnh_next(nhp, &nhlen);
	}

	/* leftover implies invalid nexthop configuration, discard it */
	return nhlen > 0 ? 0 : nhs;
}

static int dn_fib_get_nhs(struct dn_fib_info *fi, const struct nlattr *attr,
			  const struct rtmsg *r)
{
	struct rtnexthop *nhp = nla_data(attr);
	int nhlen = nla_len(attr);

	change_nexthops(fi) {
		int attrlen;

		if (!rtnh_ok(nhp, nhlen))
			return -EINVAL;

		nh->nh_flags  = (r->rtm_flags&~0xFF) | nhp->rtnh_flags;
		nh->nh_oif    = nhp->rtnh_ifindex;
		nh->nh_weight = nhp->rtnh_hops + 1;

		attrlen = rtnh_attrlen(nhp);
		if (attrlen > 0) {
			struct nlattr *gw_attr;

			gw_attr = nla_find((struct nlattr *) (nhp + 1), attrlen, RTA_GATEWAY);
			nh->nh_gw = gw_attr ? nla_get_le16(gw_attr) : 0;
		}

		nhp = rtnh_next(nhp, &nhlen);
	} endfor_nexthops(fi);

	return 0;
}


static int dn_fib_check_nh(const struct rtmsg *r, struct dn_fib_info *fi, struct dn_fib_nh *nh)
{
	int err;

	if (nh->nh_gw) {
		struct flowidn fld;
		struct dn_fib_res res;

		if (nh->nh_flags&RTNH_F_ONLINK) {
			struct net_device *dev;

			if (r->rtm_scope >= RT_SCOPE_LINK)
				return -EINVAL;
			if (dnet_addr_type(nh->nh_gw) != RTN_UNICAST)
				return -EINVAL;
			if ((dev = __dev_get_by_index(&init_net, nh->nh_oif)) == NULL)
				return -ENODEV;
			if (!(dev->flags&IFF_UP))
				return -ENETDOWN;
			nh->nh_dev = dev;
			dev_hold(dev);
			nh->nh_scope = RT_SCOPE_LINK;
			return 0;
		}

		memset(&fld, 0, sizeof(fld));
		fld.daddr = nh->nh_gw;
		fld.flowidn_oif = nh->nh_oif;
		fld.flowidn_scope = r->rtm_scope + 1;

		if (fld.flowidn_scope < RT_SCOPE_LINK)
			fld.flowidn_scope = RT_SCOPE_LINK;

		if ((err = dn_fib_lookup(&fld, &res)) != 0)
			return err;

		err = -EINVAL;
		if (res.type != RTN_UNICAST && res.type != RTN_LOCAL)
			goto out;
		nh->nh_scope = res.scope;
		nh->nh_oif = DN_FIB_RES_OIF(res);
		nh->nh_dev = DN_FIB_RES_DEV(res);
		if (nh->nh_dev == NULL)
			goto out;
		dev_hold(nh->nh_dev);
		err = -ENETDOWN;
		if (!(nh->nh_dev->flags & IFF_UP))
			goto out;
		err = 0;
out:
		dn_fib_res_put(&res);
		return err;
	} else {
		struct net_device *dev;

		if (nh->nh_flags&(RTNH_F_PERVASIVE|RTNH_F_ONLINK))
			return -EINVAL;

		dev = __dev_get_by_index(&init_net, nh->nh_oif);
		if (dev == NULL || dev->dn_ptr == NULL)
			return -ENODEV;
		if (!(dev->flags&IFF_UP))
			return -ENETDOWN;
		nh->nh_dev = dev;
		dev_hold(nh->nh_dev);
		nh->nh_scope = RT_SCOPE_HOST;
	}

	return 0;
}


struct dn_fib_info *dn_fib_create_info(const struct rtmsg *r, struct nlattr *attrs[],
				       const struct nlmsghdr *nlh, int *errp)
{
	int err;
	struct dn_fib_info *fi = NULL;
	struct dn_fib_info *ofi;
	int nhs = 1;

	if (r->rtm_type > RTN_MAX)
		goto err_inval;

	if (dn_fib_props[r->rtm_type].scope > r->rtm_scope)
		goto err_inval;

	if (attrs[RTA_MULTIPATH] &&
	    (nhs = dn_fib_count_nhs(attrs[RTA_MULTIPATH])) == 0)
		goto err_inval;

	fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct dn_fib_nh), GFP_KERNEL);
	err = -ENOBUFS;
	if (fi == NULL)
		goto failure;

	fi->fib_protocol = r->rtm_protocol;
	fi->fib_nhs = nhs;
	fi->fib_flags = r->rtm_flags;

	if (attrs[RTA_PRIORITY])
		fi->fib_priority = nla_get_u32(attrs[RTA_PRIORITY]);

	if (attrs[RTA_METRICS]) {
		struct nlattr *attr;
		int rem;

		nla_for_each_nested(attr, attrs[RTA_METRICS], rem) {
			int type = nla_type(attr);

			if (type) {
				if (type > RTAX_MAX || type == RTAX_CC_ALGO ||
				    nla_len(attr) < 4)
					goto err_inval;

				fi->fib_metrics[type-1] = nla_get_u32(attr);
			}
		}
	}

	if (attrs[RTA_PREFSRC])
		fi->fib_prefsrc = nla_get_le16(attrs[RTA_PREFSRC]);

	if (attrs[RTA_MULTIPATH]) {
		if ((err = dn_fib_get_nhs(fi, attrs[RTA_MULTIPATH], r)) != 0)
			goto failure;

		if (attrs[RTA_OIF] &&
		    fi->fib_nh->nh_oif != nla_get_u32(attrs[RTA_OIF]))
			goto err_inval;

		if (attrs[RTA_GATEWAY] &&
		    fi->fib_nh->nh_gw != nla_get_le16(attrs[RTA_GATEWAY]))
			goto err_inval;
	} else {
		struct dn_fib_nh *nh = fi->fib_nh;

		if (attrs[RTA_OIF])
			nh->nh_oif = nla_get_u32(attrs[RTA_OIF]);

		if (attrs[RTA_GATEWAY])
			nh->nh_gw = nla_get_le16(attrs[RTA_GATEWAY]);

		nh->nh_flags = r->rtm_flags;
		nh->nh_weight = 1;
	}

	if (r->rtm_type == RTN_NAT) {
		if (!attrs[RTA_GATEWAY] || nhs != 1 || attrs[RTA_OIF])
			goto err_inval;

		fi->fib_nh->nh_gw = nla_get_le16(attrs[RTA_GATEWAY]);
		goto link_it;
	}

	if (dn_fib_props[r->rtm_type].error) {
		if (attrs[RTA_GATEWAY] || attrs[RTA_OIF] || attrs[RTA_MULTIPATH])
			goto err_inval;

		goto link_it;
	}

	if (r->rtm_scope > RT_SCOPE_HOST)
		goto err_inval;

	if (r->rtm_scope == RT_SCOPE_HOST) {
		struct dn_fib_nh *nh = fi->fib_nh;

		/* Local address is added */
		if (nhs != 1 || nh->nh_gw)
			goto err_inval;
		nh->nh_scope = RT_SCOPE_NOWHERE;
		nh->nh_dev = dev_get_by_index(&init_net, fi->fib_nh->nh_oif);
		err = -ENODEV;
		if (nh->nh_dev == NULL)
			goto failure;
	} else {
		change_nexthops(fi) {
			if ((err = dn_fib_check_nh(r, fi, nh)) != 0)
				goto failure;
		} endfor_nexthops(fi)
	}

	if (fi->fib_prefsrc) {
		if (r->rtm_type != RTN_LOCAL || !attrs[RTA_DST] ||
		    fi->fib_prefsrc != nla_get_le16(attrs[RTA_DST]))
			if (dnet_addr_type(fi->fib_prefsrc) != RTN_LOCAL)
				goto err_inval;
	}

link_it:
	if ((ofi = dn_fib_find_info(fi)) != NULL) {
		fi->fib_dead = 1;
		dn_fib_free_info(fi);
		ofi->fib_treeref++;
		return ofi;
	}

	fi->fib_treeref++;
	atomic_inc(&fi->fib_clntref);
	spin_lock(&dn_fib_info_lock);
	fi->fib_next = dn_fib_info_list;
	fi->fib_prev = NULL;
	if (dn_fib_info_list)
		dn_fib_info_list->fib_prev = fi;
	dn_fib_info_list = fi;
	spin_unlock(&dn_fib_info_lock);
	return fi;

err_inval:
	err = -EINVAL;

failure:
	*errp = err;
	if (fi) {
		fi->fib_dead = 1;
		dn_fib_free_info(fi);
	}

	return NULL;
}

int dn_fib_semantic_match(int type, struct dn_fib_info *fi, const struct flowidn *fld, struct dn_fib_res *res)
{
	int err = dn_fib_props[type].error;

	if (err == 0) {
		if (fi->fib_flags & RTNH_F_DEAD)
			return 1;

		res->fi = fi;

		switch (type) {
		case RTN_NAT:
			DN_FIB_RES_RESET(*res);
			atomic_inc(&fi->fib_clntref);
			return 0;
		case RTN_UNICAST:
		case RTN_LOCAL:
			for_nexthops(fi) {
				if (nh->nh_flags & RTNH_F_DEAD)
					continue;
				if (!fld->flowidn_oif ||
				    fld->flowidn_oif == nh->nh_oif)
					break;
			}
			if (nhsel < fi->fib_nhs) {
				res->nh_sel = nhsel;
				atomic_inc(&fi->fib_clntref);
				return 0;
			}
			endfor_nexthops(fi);
			res->fi = NULL;
			return 1;
		default:
			net_err_ratelimited("DECnet: impossible routing event : dn_fib_semantic_match type=%d\n",
					    type);
			res->fi = NULL;
			return -EINVAL;
		}
	}
	return err;
}

void dn_fib_select_multipath(const struct flowidn *fld, struct dn_fib_res *res)
{
	struct dn_fib_info *fi = res->fi;
	int w;

	spin_lock_bh(&dn_fib_multipath_lock);
	if (fi->fib_power <= 0) {
		int power = 0;
		change_nexthops(fi) {
			if (!(nh->nh_flags&RTNH_F_DEAD)) {
				power += nh->nh_weight;
				nh->nh_power = nh->nh_weight;
			}
		} endfor_nexthops(fi);
		fi->fib_power = power;
		if (power < 0) {
			spin_unlock_bh(&dn_fib_multipath_lock);
			res->nh_sel = 0;
			return;
		}
	}

	w = jiffies % fi->fib_power;

	change_nexthops(fi) {
		if (!(nh->nh_flags&RTNH_F_DEAD) && nh->nh_power) {
			if ((w -= nh->nh_power) <= 0) {
				nh->nh_power--;
				fi->fib_power--;
				res->nh_sel = nhsel;
				spin_unlock_bh(&dn_fib_multipath_lock);
				return;
			}
		}
	} endfor_nexthops(fi);
	res->nh_sel = 0;
	spin_unlock_bh(&dn_fib_multipath_lock);
}

static inline u32 rtm_get_table(struct nlattr *attrs[], u8 table)
{
	if (attrs[RTA_TABLE])
		table = nla_get_u32(attrs[RTA_TABLE]);

	return table;
}

static int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh)
{
	struct net *net = sock_net(skb->sk);
	struct dn_fib_table *tb;
	struct rtmsg *r = nlmsg_data(nlh);
	struct nlattr *attrs[RTA_MAX+1];
	int err;

	if (!netlink_capable(skb, CAP_NET_ADMIN))
		return -EPERM;

	if (!net_eq(net, &init_net))
		return -EINVAL;

	err = nlmsg_parse(nlh, sizeof(*r), attrs, RTA_MAX, rtm_dn_policy);
	if (err < 0)
		return err;

	tb = dn_fib_get_table(rtm_get_table(attrs, r->rtm_table), 0);
	if (!tb)
		return -ESRCH;

	return tb->delete(tb, r, attrs, nlh, &NETLINK_CB(skb));
}

static int dn_fib_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh)
{
	struct net *net = sock_net(skb->sk);
	struct dn_fib_table *tb;
	struct rtmsg *r = nlmsg_data(nlh);
	struct nlattr *attrs[RTA_MAX+1];
	int err;

	if (!netlink_capable(skb, CAP_NET_ADMIN))
		return -EPERM;

	if (!net_eq(net, &init_net))
		return -EINVAL;

	err = nlmsg_parse(nlh, sizeof(*r), attrs, RTA_MAX, rtm_dn_policy);
	if (err < 0)
		return err;

	tb = dn_fib_get_table(rtm_get_table(attrs, r->rtm_table), 1);
	if (!tb)
		return -ENOBUFS;

	return tb->insert(tb, r, attrs, nlh, &NETLINK_CB(skb));
}

static void fib_magic(int cmd, int type, __le16 dst, int dst_len, struct dn_ifaddr *ifa)
{
	struct dn_fib_table *tb;
	struct {
		struct nlmsghdr nlh;
		struct rtmsg rtm;
	} req;
	struct {
		struct nlattr hdr;
		__le16 dst;
	} dst_attr = {
		.dst = dst,
	};
	struct {
		struct nlattr hdr;
		__le16 prefsrc;
	} prefsrc_attr = {
		.prefsrc = ifa->ifa_local,
	};
	struct {
		struct nlattr hdr;
		u32 oif;
	} oif_attr = {
		.oif = ifa->ifa_dev->dev->ifindex,
	};
	struct nlattr *attrs[RTA_MAX+1] = {
		[RTA_DST] = (struct nlattr *) &dst_attr,
		[RTA_PREFSRC] = (struct nlattr * ) &prefsrc_attr,
		[RTA_OIF] = (struct nlattr *) &oif_attr,
	};

	memset(&req.rtm, 0, sizeof(req.rtm));

	if (type == RTN_UNICAST)
		tb = dn_fib_get_table(RT_MIN_TABLE, 1);
	else
		tb = dn_fib_get_table(RT_TABLE_LOCAL, 1);

	if (tb == NULL)
		return;

	req.nlh.nlmsg_len = sizeof(req);
	req.nlh.nlmsg_type = cmd;
	req.nlh.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_APPEND;
	req.nlh.nlmsg_pid = 0;
	req.nlh.nlmsg_seq = 0;

	req.rtm.rtm_dst_len = dst_len;
	req.rtm.rtm_table = tb->n;
	req.rtm.rtm_protocol = RTPROT_KERNEL;
	req.rtm.rtm_scope = (type != RTN_LOCAL ? RT_SCOPE_LINK : RT_SCOPE_HOST);
	req.rtm.rtm_type = type;

	if (cmd == RTM_NEWROUTE)
		tb->insert(tb, &req.rtm, attrs, &req.nlh, NULL);
	else
		tb->delete(tb, &req.rtm, attrs, &req.nlh, NULL);
}

static void dn_fib_add_ifaddr(struct dn_ifaddr *ifa)
{

	fib_magic(RTM_NEWROUTE, RTN_LOCAL, ifa->ifa_local, 16, ifa);

#if 0
	if (!(dev->flags&IFF_UP))
		return;
	/* In the future, we will want to add default routes here */

#endif
}

static void dn_fib_del_ifaddr(struct dn_ifaddr *ifa)
{
	int found_it = 0;
	struct net_device *dev;
	struct dn_dev *dn_db;
	struct dn_ifaddr *ifa2;

	ASSERT_RTNL();

	/* Scan device list */
	rcu_read_lock();
	for_each_netdev_rcu(&init_net, dev) {
		dn_db = rcu_dereference(dev->dn_ptr);
		if (dn_db == NULL)
			continue;
		for (ifa2 = rcu_dereference(dn_db->ifa_list);
		     ifa2 != NULL;
		     ifa2 = rcu_dereference(ifa2->ifa_next)) {
			if (ifa2->ifa_local == ifa->ifa_local) {
				found_it = 1;
				break;
			}
		}
	}
	rcu_read_unlock();

	if (found_it == 0) {
		fib_magic(RTM_DELROUTE, RTN_LOCAL, ifa->ifa_local, 16, ifa);

		if (dnet_addr_type(ifa->ifa_local) != RTN_LOCAL) {
			if (dn_fib_sync_down(ifa->ifa_local, NULL, 0))
				dn_fib_flush();
		}
	}
}

static void dn_fib_disable_addr(struct net_device *dev, int force)
{
	if (dn_fib_sync_down(0, dev, force))
		dn_fib_flush();
	dn_rt_cache_flush(0);
	neigh_ifdown(&dn_neigh_table, dev);
}

static int dn_fib_dnaddr_event(struct notifier_block *this, unsigned long event, void *ptr)
{
	struct dn_ifaddr *ifa = (struct dn_ifaddr *)ptr;

	switch (event) {
	case NETDEV_UP:
		dn_fib_add_ifaddr(ifa);
		dn_fib_sync_up(ifa->ifa_dev->dev);
		dn_rt_cache_flush(-1);
		break;
	case NETDEV_DOWN:
		dn_fib_del_ifaddr(ifa);
		if (ifa->ifa_dev && ifa->ifa_dev->ifa_list == NULL) {
			dn_fib_disable_addr(ifa->ifa_dev->dev, 1);
		} else {
			dn_rt_cache_flush(-1);
		}
		break;
	}
	return NOTIFY_DONE;
}

static int dn_fib_sync_down(__le16 local, struct net_device *dev, int force)
{
	int ret = 0;
	int scope = RT_SCOPE_NOWHERE;

	if (force)
		scope = -1;

	for_fib_info() {
		/*
		 * This makes no sense for DECnet.... we will almost
		 * certainly have more than one local address the same
		 * over all our interfaces. It needs thinking about
		 * some more.
		 */
		if (local && fi->fib_prefsrc == local) {
			fi->fib_flags |= RTNH_F_DEAD;
			ret++;
		} else if (dev && fi->fib_nhs) {
			int dead = 0;

			change_nexthops(fi) {
				if (nh->nh_flags&RTNH_F_DEAD)
					dead++;
				else if (nh->nh_dev == dev &&
						nh->nh_scope != scope) {
					spin_lock_bh(&dn_fib_multipath_lock);
					nh->nh_flags |= RTNH_F_DEAD;
					fi->fib_power -= nh->nh_power;
					nh->nh_power = 0;
					spin_unlock_bh(&dn_fib_multipath_lock);
					dead++;
				}
			} endfor_nexthops(fi)
			if (dead == fi->fib_nhs) {
				fi->fib_flags |= RTNH_F_DEAD;
				ret++;
			}
		}
	} endfor_fib_info();
	return ret;
}


static int dn_fib_sync_up(struct net_device *dev)
{
	int ret = 0;

	if (!(dev->flags&IFF_UP))
		return 0;

	for_fib_info() {
		int alive = 0;

		change_nexthops(fi) {
			if (!(nh->nh_flags&RTNH_F_DEAD)) {
				alive++;
				continue;
			}
			if (nh->nh_dev == NULL || !(nh->nh_dev->flags&IFF_UP))
				continue;
			if (nh->nh_dev != dev || dev->dn_ptr == NULL)
				continue;
			alive++;
			spin_lock_bh(&dn_fib_multipath_lock);
			nh->nh_power = 0;
			nh->nh_flags &= ~RTNH_F_DEAD;
			spin_unlock_bh(&dn_fib_multipath_lock);
		} endfor_nexthops(fi);

		if (alive > 0) {
			fi->fib_flags &= ~RTNH_F_DEAD;
			ret++;
		}
	} endfor_fib_info();
	return ret;
}

static struct notifier_block dn_fib_dnaddr_notifier = {
	.notifier_call = dn_fib_dnaddr_event,
};

void __exit dn_fib_cleanup(void)
{
	dn_fib_table_cleanup();
	dn_fib_rules_cleanup();

	unregister_dnaddr_notifier(&dn_fib_dnaddr_notifier);
}


void __init dn_fib_init(void)
{
	dn_fib_table_init();
	dn_fib_rules_init();

	register_dnaddr_notifier(&dn_fib_dnaddr_notifier);

	rtnl_register(PF_DECnet, RTM_NEWROUTE, dn_fib_rtm_newroute, NULL, NULL);
	rtnl_register(PF_DECnet, RTM_DELROUTE, dn_fib_rtm_delroute, NULL, NULL);
}


