/*
 *	Implements the IPX routing routines.
 *	Code moved from af_ipx.c.
 *
 *	Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2003
 *
 *	See net/ipx/ChangeLog.
 */

#include <linux/list.h>
#include <linux/route.h>
#include <linux/slab.h>
#include <linux/spinlock.h>

#include <net/ipx.h>
#include <net/sock.h>

LIST_HEAD(ipx_routes);
DEFINE_RWLOCK(ipx_routes_lock);

extern struct ipx_interface *ipx_internal_net;

extern struct ipx_interface *ipxitf_find_using_net(__be32 net);
extern int ipxitf_demux_socket(struct ipx_interface *intrfc,
			       struct sk_buff *skb, int copy);
extern int ipxitf_demux_socket(struct ipx_interface *intrfc,
			       struct sk_buff *skb, int copy);

struct ipx_route *ipxrtr_lookup(__be32 net)
{
	struct ipx_route *r;

	read_lock_bh(&ipx_routes_lock);
	list_for_each_entry(r, &ipx_routes, node)
		if (r->ir_net == net) {
			ipxrtr_hold(r);
			goto unlock;
		}
	r = NULL;
unlock:
	read_unlock_bh(&ipx_routes_lock);
	return r;
}

/*
 * Caller must hold a reference to intrfc
 */
int ipxrtr_add_route(__be32 network, struct ipx_interface *intrfc,
		     unsigned char *node)
{
	struct ipx_route *rt;
	int rc;

	/* Get a route structure; either existing or create */
	rt = ipxrtr_lookup(network);
	if (!rt) {
		rt = kmalloc(sizeof(*rt), GFP_ATOMIC);
		rc = -EAGAIN;
		if (!rt)
			goto out;

		atomic_set(&rt->refcnt, 1);
		ipxrtr_hold(rt);
		write_lock_bh(&ipx_routes_lock);
		list_add(&rt->node, &ipx_routes);
		write_unlock_bh(&ipx_routes_lock);
	} else {
		rc = -EEXIST;
		if (intrfc == ipx_internal_net)
			goto out_put;
	}

	rt->ir_net 	= network;
	rt->ir_intrfc 	= intrfc;
	if (!node) {
		memset(rt->ir_router_node, '\0', IPX_NODE_LEN);
		rt->ir_routed = 0;
	} else {
		memcpy(rt->ir_router_node, node, IPX_NODE_LEN);
		rt->ir_routed = 1;
	}

	rc = 0;
out_put:
	ipxrtr_put(rt);
out:
	return rc;
}

void ipxrtr_del_routes(struct ipx_interface *intrfc)
{
	struct ipx_route *r, *tmp;

	write_lock_bh(&ipx_routes_lock);
	list_for_each_entry_safe(r, tmp, &ipx_routes, node)
		if (r->ir_intrfc == intrfc) {
			list_del(&r->node);
			ipxrtr_put(r);
		}
	write_unlock_bh(&ipx_routes_lock);
}

static int ipxrtr_create(struct ipx_route_definition *rd)
{
	struct ipx_interface *intrfc;
	int rc = -ENETUNREACH;

	/* Find the appropriate interface */
	intrfc = ipxitf_find_using_net(rd->ipx_router_network);
	if (!intrfc)
		goto out;
	rc = ipxrtr_add_route(rd->ipx_network, intrfc, rd->ipx_router_node);
	ipxitf_put(intrfc);
out:
	return rc;
}

static int ipxrtr_delete(__be32 net)
{
	struct ipx_route *r, *tmp;
	int rc;

	write_lock_bh(&ipx_routes_lock);
	list_for_each_entry_safe(r, tmp, &ipx_routes, node)
		if (r->ir_net == net) {
			/* Directly connected; can't lose route */
			rc = -EPERM;
			if (!r->ir_routed)
				goto out;
			list_del(&r->node);
			ipxrtr_put(r);
			rc = 0;
			goto out;
		}
	rc = -ENOENT;
out:
	write_unlock_bh(&ipx_routes_lock);
	return rc;
}

/*
 * The skb has to be unshared, we'll end up calling ipxitf_send, that'll
 * modify the packet
 */
int ipxrtr_route_skb(struct sk_buff *skb)
{
	struct ipxhdr *ipx = ipx_hdr(skb);
	struct ipx_route *r = ipxrtr_lookup(IPX_SKB_CB(skb)->ipx_dest_net);

	if (!r) {	/* no known route */
		kfree_skb(skb);
		return 0;
	}

	ipxitf_hold(r->ir_intrfc);
	ipxitf_send(r->ir_intrfc, skb, r->ir_routed ?
			r->ir_router_node : ipx->ipx_dest.node);
	ipxitf_put(r->ir_intrfc);
	ipxrtr_put(r);

	return 0;
}

/*
 * Route an outgoing frame from a socket.
 */
int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx,
			struct iovec *iov, size_t len, int noblock)
{
	struct sk_buff *skb;
	struct ipx_sock *ipxs = ipx_sk(sk);
	struct ipx_interface *intrfc;
	struct ipxhdr *ipx;
	size_t size;
	int ipx_offset;
	struct ipx_route *rt = NULL;
	int rc;

	/* Find the appropriate interface on which to send packet */
	if (!usipx->sipx_network && ipx_primary_net) {
		usipx->sipx_network = ipx_primary_net->if_netnum;
		intrfc = ipx_primary_net;
	} else {
		rt = ipxrtr_lookup(usipx->sipx_network);
		rc = -ENETUNREACH;
		if (!rt)
			goto out;
		intrfc = rt->ir_intrfc;
	}

	ipxitf_hold(intrfc);
	ipx_offset = intrfc->if_ipx_offset;
	size = sizeof(struct ipxhdr) + len + ipx_offset;

	skb = sock_alloc_send_skb(sk, size, noblock, &rc);
	if (!skb)
		goto out_put;

	skb_reserve(skb, ipx_offset);
	skb->sk = sk;

	/* Fill in IPX header */
	skb_reset_network_header(skb);
	skb_reset_transport_header(skb);
	skb_put(skb, sizeof(struct ipxhdr));
	ipx = ipx_hdr(skb);
	ipx->ipx_pktsize = htons(len + sizeof(struct ipxhdr));
	IPX_SKB_CB(skb)->ipx_tctrl = 0;
	ipx->ipx_type 	 = usipx->sipx_type;

	IPX_SKB_CB(skb)->last_hop.index = -1;
#ifdef CONFIG_IPX_INTERN
	IPX_SKB_CB(skb)->ipx_source_net = ipxs->intrfc->if_netnum;
	memcpy(ipx->ipx_source.node, ipxs->node, IPX_NODE_LEN);
#else
	rc = ntohs(ipxs->port);
	if (rc == 0x453 || rc == 0x452) {
		/* RIP/SAP special handling for mars_nwe */
		IPX_SKB_CB(skb)->ipx_source_net = intrfc->if_netnum;
		memcpy(ipx->ipx_source.node, intrfc->if_node, IPX_NODE_LEN);
	} else {
		IPX_SKB_CB(skb)->ipx_source_net = ipxs->intrfc->if_netnum;
		memcpy(ipx->ipx_source.node, ipxs->intrfc->if_node,
			IPX_NODE_LEN);
	}
#endif	/* CONFIG_IPX_INTERN */
	ipx->ipx_source.sock		= ipxs->port;
	IPX_SKB_CB(skb)->ipx_dest_net	= usipx->sipx_network;
	memcpy(ipx->ipx_dest.node, usipx->sipx_node, IPX_NODE_LEN);
	ipx->ipx_dest.sock		= usipx->sipx_port;

	rc = memcpy_fromiovec(skb_put(skb, len), iov, len);
	if (rc) {
		kfree_skb(skb);
		goto out_put;
	}

	/* Apply checksum. Not allowed on 802.3 links. */
	if (sk->sk_no_check_tx ||
	    intrfc->if_dlink_type == htons(IPX_FRAME_8023))
		ipx->ipx_checksum = htons(0xFFFF);
	else
		ipx->ipx_checksum = ipx_cksum(ipx, len + sizeof(struct ipxhdr));

	rc = ipxitf_send(intrfc, skb, (rt && rt->ir_routed) ?
			 rt->ir_router_node : ipx->ipx_dest.node);
out_put:
	ipxitf_put(intrfc);
	if (rt)
		ipxrtr_put(rt);
out:
	return rc;
}

/*
 * We use a normal struct rtentry for route handling
 */
int ipxrtr_ioctl(unsigned int cmd, void __user *arg)
{
	struct rtentry rt;	/* Use these to behave like 'other' stacks */
	struct sockaddr_ipx *sg, *st;
	int rc = -EFAULT;

	if (copy_from_user(&rt, arg, sizeof(rt)))
		goto out;

	sg = (struct sockaddr_ipx *)&rt.rt_gateway;
	st = (struct sockaddr_ipx *)&rt.rt_dst;

	rc = -EINVAL;
	if (!(rt.rt_flags & RTF_GATEWAY) || /* Direct routes are fixed */
	    sg->sipx_family != AF_IPX ||
	    st->sipx_family != AF_IPX)
		goto out;

	switch (cmd) {
	case SIOCDELRT:
		rc = ipxrtr_delete(st->sipx_network);
		break;
	case SIOCADDRT: {
		struct ipx_route_definition f;
		f.ipx_network		= st->sipx_network;
		f.ipx_router_network	= sg->sipx_network;
		memcpy(f.ipx_router_node, sg->sipx_node, IPX_NODE_LEN);
		rc = ipxrtr_create(&f);
		break;
	}
	}

out:
	return rc;
}
