/*
 * 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 Neighbour Functions (Adjacency Database and 
 *                                                        On-Ethernet Cache)
 *
 * Author:      Steve Whitehouse <SteveW@ACM.org>
 *
 *
 * Changes:
 *     Steve Whitehouse     : Fixed router listing routine
 *     Steve Whitehouse     : Added error_report functions
 *     Steve Whitehouse     : Added default router detection
 *     Steve Whitehouse     : Hop counts in outgoing messages
 *     Steve Whitehouse     : Fixed src/dst in outgoing messages so
 *                            forwarding now stands a good chance of
 *                            working.
 *     Steve Whitehouse     : Fixed neighbour states (for now anyway).
 *     Steve Whitehouse     : Made error_report functions dummies. This
 *                            is not the right place to return skbs.
 *
 */

#include <linux/config.h>
#include <linux/net.h>
#include <linux/socket.h>
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/string.h>
#include <linux/netfilter_decnet.h>
#include <linux/spinlock.h>
#include <asm/atomic.h>
#include <net/neighbour.h>
#include <net/dst.h>
#include <net/dn.h>
#include <net/dn_dev.h>
#include <net/dn_neigh.h>
#include <net/dn_route.h>

static u32 dn_neigh_hash(const void *pkey, const struct net_device *dev);
static int dn_neigh_construct(struct neighbour *);
static void dn_long_error_report(struct neighbour *, struct sk_buff *);
static void dn_short_error_report(struct neighbour *, struct sk_buff *);
static int dn_long_output(struct sk_buff *);
static int dn_short_output(struct sk_buff *);
static int dn_phase3_output(struct sk_buff *);


/*
 * For talking to broadcast devices: Ethernet & PPP
 */
static struct neigh_ops dn_long_ops = {
	family:			AF_DECnet,
	error_report:		dn_long_error_report,
	output:			dn_long_output,
	connected_output:	dn_long_output,
	hh_output:		dev_queue_xmit,
	queue_xmit:		dev_queue_xmit,
};

/*
 * For talking to pointopoint and multidrop devices: DDCMP and X.25
 */
static struct neigh_ops dn_short_ops = {
	family:			AF_DECnet,
	error_report:		dn_short_error_report,
	output:			dn_short_output,
	connected_output:	dn_short_output,
	hh_output:		dev_queue_xmit,
	queue_xmit:		dev_queue_xmit,
};

/*
 * For talking to DECnet phase III nodes
 */
static struct neigh_ops dn_phase3_ops = {
	family:			AF_DECnet,
	error_report:		dn_short_error_report, /* Can use short version here */
	output:			dn_phase3_output,
	connected_output:	dn_phase3_output,
	hh_output:		dev_queue_xmit,
	queue_xmit:		dev_queue_xmit
};

struct neigh_table dn_neigh_table = {
	family:				PF_DECnet,
	entry_size:			sizeof(struct dn_neigh),
	key_len:			sizeof(dn_address),
	hash:				dn_neigh_hash,
	constructor:			dn_neigh_construct,
	id:				"dn_neigh_cache",
	parms:	{
		tbl:			&dn_neigh_table,
		entries:		0,
		base_reachable_time:	30 * HZ,
		retrans_time:		1 * HZ,
		gc_staletime:		60 * HZ,
		reachable_time:		30 * HZ,
		delay_probe_time:	5 * HZ,
		queue_len:		3,
		ucast_probes:		0,
		app_probes:		0,
		mcast_probes:		0,
		anycast_delay:		0,
		proxy_delay:		0,
		proxy_qlen:		0,
		locktime:		1 * HZ,
	},
	gc_interval:			30 * HZ,
	gc_thresh1:			128,
	gc_thresh2:			512,
	gc_thresh3:			1024,
};

static u32 dn_neigh_hash(const void *pkey, const struct net_device *dev)
{
	u32 hash_val;

	hash_val = *(dn_address *)pkey;
	hash_val ^= (hash_val >> 10);
	hash_val ^= (hash_val >> 3);

	return hash_val & NEIGH_HASHMASK;
}

static int dn_neigh_construct(struct neighbour *neigh)
{
	struct net_device *dev = neigh->dev;
	struct dn_neigh *dn = (struct dn_neigh *)neigh;
	struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr;

	if (dn_db == NULL)
		return -EINVAL;

	if (dn_db->neigh_parms)
		neigh->parms = dn_db->neigh_parms;

	if (dn_db->use_long)
		neigh->ops = &dn_long_ops;
	else
		neigh->ops = &dn_short_ops;

	if (dn->flags & DN_NDFLAG_P3)
		neigh->ops = &dn_phase3_ops;

	neigh->nud_state = NUD_NOARP;
	neigh->output = neigh->ops->connected_output;

	if ((dev->type == ARPHRD_IPGRE) || (dev->flags & IFF_POINTOPOINT))
		memcpy(neigh->ha, dev->broadcast, dev->addr_len);
	else if ((dev->type == ARPHRD_ETHER) || (dev->type == ARPHRD_LOOPBACK))
		dn_dn2eth(neigh->ha, dn->addr);
	else {
		if (net_ratelimit())
			printk(KERN_DEBUG "Trying to create neigh for hw %d\n",  dev->type);
		return -EINVAL;
	}

	dn->blksize = 230;

	return 0;
}

static void dn_long_error_report(struct neighbour *neigh, struct sk_buff *skb)
{
	printk(KERN_DEBUG "dn_long_error_report: called\n");
	kfree_skb(skb);
}


static void dn_short_error_report(struct neighbour *neigh, struct sk_buff *skb)
{
	printk(KERN_DEBUG "dn_short_error_report: called\n");
	kfree_skb(skb);
}

static int dn_neigh_output_packet(struct sk_buff *skb)
{
	struct dst_entry *dst = skb->dst;
	struct neighbour *neigh = dst->neighbour;
	struct net_device *dev = neigh->dev;

	if (!dev->hard_header || dev->hard_header(skb, dev, ntohs(skb->protocol), neigh->ha, NULL, skb->len) >= 0)
		return neigh->ops->queue_xmit(skb);

	if (net_ratelimit())
		printk(KERN_DEBUG "dn_neigh_output_packet: oops, can't send packet\n");

	kfree_skb(skb);
	return -EINVAL;
}

static int dn_long_output(struct sk_buff *skb)
{
	struct dst_entry *dst = skb->dst;
	struct neighbour *neigh = dst->neighbour;
	struct net_device *dev = neigh->dev;
	int headroom = dev->hard_header_len + sizeof(struct dn_long_packet) + 3;
	unsigned char *data;
	struct dn_long_packet *lp;
	struct dn_skb_cb *cb = DN_SKB_CB(skb);


	if (skb_headroom(skb) < headroom) {
		struct sk_buff *skb2 = skb_realloc_headroom(skb, headroom);
		if (skb2 == NULL) {
			if (net_ratelimit())
				printk(KERN_CRIT "dn_long_output: no memory\n");
			kfree_skb(skb);
			return -ENOBUFS;
		}
		kfree_skb(skb);
		skb = skb2;
		if (net_ratelimit())
			printk(KERN_INFO "dn_long_output: Increasing headroom\n");
	}

	data = skb_push(skb, sizeof(struct dn_long_packet) + 3);
	lp = (struct dn_long_packet *)(data+3);

	*((unsigned short *)data) = dn_htons(skb->len - 2);
	*(data + 2) = 1 | DN_RT_F_PF; /* Padding */

	lp->msgflg   = DN_RT_PKT_LONG|(cb->rt_flags&(DN_RT_F_IE|DN_RT_F_RQR|DN_RT_F_RTS));
	lp->d_area   = lp->d_subarea = 0;
	dn_dn2eth(lp->d_id, dn_ntohs(cb->dst));
	lp->s_area   = lp->s_subarea = 0;
	dn_dn2eth(lp->s_id, dn_ntohs(cb->src));
	lp->nl2      = 0;
	lp->visit_ct = cb->hops & 0x3f;
	lp->s_class  = 0;
	lp->pt       = 0;

	skb->nh.raw = skb->data;

	return NF_HOOK(PF_DECnet, NF_DN_POST_ROUTING, skb, NULL, neigh->dev, dn_neigh_output_packet);
}

static int dn_short_output(struct sk_buff *skb)
{
	struct dst_entry *dst = skb->dst;
	struct neighbour *neigh = dst->neighbour;
	struct net_device *dev = neigh->dev;
	int headroom = dev->hard_header_len + sizeof(struct dn_short_packet) + 2;
	struct dn_short_packet *sp;
	unsigned char *data;
	struct dn_skb_cb *cb = DN_SKB_CB(skb);


        if (skb_headroom(skb) < headroom) {
                struct sk_buff *skb2 = skb_realloc_headroom(skb, headroom);
                if (skb2 == NULL) {
			if (net_ratelimit())
                        	printk(KERN_CRIT "dn_short_output: no memory\n");
                        kfree_skb(skb);
                        return -ENOBUFS;
                }
                kfree_skb(skb);
                skb = skb2;
		if (net_ratelimit())
                	printk(KERN_INFO "dn_short_output: Increasing headroom\n");
        }

	data = skb_push(skb, sizeof(struct dn_short_packet) + 2);
	*((unsigned short *)data) = dn_htons(skb->len - 2);
	sp = (struct dn_short_packet *)(data+2);

	sp->msgflg     = DN_RT_PKT_SHORT|(cb->rt_flags&(DN_RT_F_RQR|DN_RT_F_RTS));
	sp->dstnode    = cb->dst;
	sp->srcnode    = cb->src;
	sp->forward    = cb->hops & 0x3f;

	skb->nh.raw = skb->data;

	return NF_HOOK(PF_DECnet, NF_DN_POST_ROUTING, skb, NULL, neigh->dev, dn_neigh_output_packet);
}

/*
 * Phase 3 output is the same is short output, execpt that
 * it clears the area bits before transmission.
 */
static int dn_phase3_output(struct sk_buff *skb)
{
	struct dst_entry *dst = skb->dst;
	struct neighbour *neigh = dst->neighbour;
	struct net_device *dev = neigh->dev;
	int headroom = dev->hard_header_len + sizeof(struct dn_short_packet) + 2;
	struct dn_short_packet *sp;
	unsigned char *data;
	struct dn_skb_cb *cb = DN_SKB_CB(skb);

	if (skb_headroom(skb) < headroom) {
		struct sk_buff *skb2 = skb_realloc_headroom(skb, headroom);
		if (skb2 == NULL) {
			if (net_ratelimit())
				printk(KERN_CRIT "dn_phase3_output: no memory\n");
			kfree_skb(skb);
			return -ENOBUFS;
		}
		kfree_skb(skb);
		skb = skb2;
		if (net_ratelimit())
			printk(KERN_INFO "dn_phase3_output: Increasing headroom\n");
	}

	data = skb_push(skb, sizeof(struct dn_short_packet) + 2);
	((unsigned short *)data) = dn_htons(skb->len - 2);
	sp = (struct dn_short_packet *)(data + 2);

	sp->msgflg   = DN_RT_PKT_SHORT|(cb->rt_flags&(DN_RT_F_RQR|DN_RT_F_RTS));
	sp->dstnode  = cb->dst & dn_htons(0x03ff);
	sp->srcnode  = cb->src & dn_htons(0x03ff);
	sp->forward  = cb->hops & 0x3f;

	skb->nh.raw = skb->data;

	return NF_HOOK(PF_DECnet, NF_DN_POST_ROUTING, skb, NULL, neigh->dev, dn_neigh_output_packet);
}

/*
 * Unfortunately, the neighbour code uses the device in its hash
 * function, so we don't get any advantage from it. This function
 * basically does a neigh_lookup(), but without comparing the device
 * field. This is required for the On-Ethernet cache
 */
struct neighbour *dn_neigh_lookup(struct neigh_table *tbl, void *ptr)
{
	struct neighbour *neigh;
	u32 hash_val;

	hash_val = tbl->hash(ptr, NULL);

	read_lock_bh(&tbl->lock);
	for(neigh = tbl->hash_buckets[hash_val]; neigh != NULL; neigh = neigh->next) {
		if (memcmp(neigh->primary_key, ptr, tbl->key_len) == 0) {
			atomic_inc(&neigh->refcnt);
			read_unlock_bh(&tbl->lock);
			return neigh;
		}
	}
	read_unlock_bh(&tbl->lock);

	return NULL;
}


/*
 * Any traffic on a pointopoint link causes the timer to be reset
 * for the entry in the neighbour table.
 */
void dn_neigh_pointopoint_notify(struct sk_buff *skb)
{
	return;
}

/*
 * Pointopoint link receives a hello message
 */
void dn_neigh_pointopoint_hello(struct sk_buff *skb)
{
	kfree_skb(skb);
}

/*
 * Ethernet router hello message received
 */
int dn_neigh_router_hello(struct sk_buff *skb)
{
	struct rtnode_hello_message *msg = (struct rtnode_hello_message *)skb->data;

	struct neighbour *neigh;
	struct dn_neigh *dn;
	struct dn_dev *dn_db;
	dn_address src;

	src = dn_htons(dn_eth2dn(msg->id));

	neigh = __neigh_lookup(&dn_neigh_table, &src, skb->dev, 1);

	dn = (struct dn_neigh *)neigh;

	if (neigh) {
		write_lock(&neigh->lock);

		neigh->used = jiffies;
		dn_db = (struct dn_dev *)neigh->dev->dn_ptr;

		if (!(neigh->nud_state & NUD_PERMANENT)) {
			neigh->updated = jiffies;

			if (neigh->dev->type == ARPHRD_ETHER)
				memcpy(neigh->ha, &skb->mac.ethernet->h_source, ETH_ALEN);

			dn->blksize  = dn_ntohs(msg->blksize);
			dn->priority = msg->priority;

			dn->flags &= ~DN_NDFLAG_P3;

			switch(msg->iinfo & DN_RT_INFO_TYPE) {
				case DN_RT_INFO_L1RT:
					dn->flags &=~DN_NDFLAG_R2;
					dn->flags |= DN_NDFLAG_R1;
					break;
				case DN_RT_INFO_L2RT:
					dn->flags |= DN_NDFLAG_R2;
			}
		}

		if (!dn_db->router) {
			dn_db->router = neigh_clone(neigh);
		} else {
			if (msg->priority > ((struct dn_neigh *)dn_db->router)->priority)
				neigh_release(xchg(&dn_db->router, neigh_clone(neigh)));
		}
		write_unlock(&neigh->lock);
		neigh_release(neigh);
	}

	kfree_skb(skb);
	return 0;
}

/*
 * Endnode hello message received
 */
int dn_neigh_endnode_hello(struct sk_buff *skb)
{
	struct endnode_hello_message *msg = (struct endnode_hello_message *)skb->data;
	struct neighbour *neigh;
	struct dn_neigh *dn;
	dn_address src;

	src = dn_htons(dn_eth2dn(msg->id));

	neigh = __neigh_lookup(&dn_neigh_table, &src, skb->dev, 1);

	dn = (struct dn_neigh *)neigh;

	if (neigh) {
		write_lock(&neigh->lock);

		neigh->used = jiffies;

		if (!(neigh->nud_state & NUD_PERMANENT)) {
			neigh->updated = jiffies;

			if (neigh->dev->type == ARPHRD_ETHER)
				memcpy(neigh->ha, &skb->mac.ethernet->h_source, ETH_ALEN);
			dn->flags   &= ~(DN_NDFLAG_R1 | DN_NDFLAG_R2);
			dn->blksize  = dn_ntohs(msg->blksize);
			dn->priority = 0;
		}

		write_unlock(&neigh->lock);
		neigh_release(neigh);
	}

	kfree_skb(skb);
	return 0;
}


#ifdef CONFIG_DECNET_ROUTER
static char *dn_find_slot(char *base, int max, int priority)
{
	int i;
	unsigned char *min = NULL;

	base += 6; /* skip first id */

	for(i = 0; i < max; i++) {
		if (!min || (*base < *min))
			min = base;
		base += 7; /* find next priority */
	}

	if (!min)
		return NULL;

	return (*min < priority) ? (min - 6) : NULL;
}

int dn_neigh_elist(struct net_device *dev, unsigned char *ptr, int n)
{
	int t = 0;
	int i;
	struct neighbour *neigh;
	struct dn_neigh *dn;
	struct neigh_table *tbl = &dn_neigh_table;
	unsigned char *rs = ptr;
	struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr;

	read_lock_bh(&tbl->lock);

	for(i = 0; i < NEIGH_HASHMASK; i++) {
		for(neigh = tbl->hash_buckets[i]; neigh != NULL; neigh = neigh->next) {
			if (neigh->dev != dev)
				continue;
			dn = (struct dn_neigh *)neigh;
			if (!(dn->flags & (DN_NDFLAG_R1|DN_NDFLAG_R2)))
				continue;
			if (dn_db->parms.forwarding == 1 && (dn->flags & DN_NDFLAG_R2))
				continue;
			if (t == n)
				rs = dn_find_slot(ptr, n, dn->priority);
			else
				t++;
			if (rs == NULL)
				continue;
			dn_dn2eth(rs, dn->addr);
			rs += 6;
			*rs = neigh->nud_state & NUD_CONNECTED ? 0x80 : 0x0;
			*rs |= dn->priority;
			rs++;
		}
	}

	read_unlock_bh(&tbl->lock);

	return t;
}
#endif /* CONFIG_DECNET_ROUTER */



#ifdef CONFIG_PROC_FS
static int dn_neigh_get_info(char *buffer, char **start, off_t offset, int length)
{
        int len     = 0;
        off_t pos   = 0;
        off_t begin = 0;
	struct neighbour *n;
	int i;
	char buf[DN_ASCBUF_LEN];

	len += sprintf(buffer + len, "Addr    Flags State Use Blksize Dev\n");

	for(i=0;i <= NEIGH_HASHMASK; i++) {
		read_lock_bh(&dn_neigh_table.lock);
		n = dn_neigh_table.hash_buckets[i];
		for(; n != NULL; n = n->next) {
			struct dn_neigh *dn = (struct dn_neigh *)n;

			read_lock(&n->lock);
			len += sprintf(buffer+len, "%-7s %s%s%s   %02x    %02d  %07ld %-8s\n",
					dn_addr2asc(dn_ntohs(dn->addr), buf),
					(dn->flags&DN_NDFLAG_R1) ? "1" : "-",
					(dn->flags&DN_NDFLAG_R2) ? "2" : "-",
					(dn->flags&DN_NDFLAG_P3) ? "3" : "-",
					dn->n.nud_state,
					atomic_read(&dn->n.refcnt),
					dn->blksize,
					(dn->n.dev) ? dn->n.dev->name : "?");
			read_unlock(&n->lock);

			pos = begin + len;

                	if (pos < offset) {
                        	len = 0;
                        	begin = pos;
                	}

                	if (pos > offset + length) {
				read_unlock_bh(&dn_neigh_table.lock);
                       		goto done;
			}
		}
		read_unlock_bh(&dn_neigh_table.lock);
	}

done:

        *start = buffer + (offset - begin);
        len   -= offset - begin;

        if (len > length) len = length;

        return len;
}

#endif

void __init dn_neigh_init(void)
{
	neigh_table_init(&dn_neigh_table);

#ifdef CONFIG_PROC_FS
	proc_net_create("decnet_neigh",0,dn_neigh_get_info);
#endif /* CONFIG_PROC_FS */
}

void __exit dn_neigh_cleanup(void)
{
	proc_net_remove("decnet_neigh");
	neigh_table_clear(&dn_neigh_table);
}
