/*
 * IPv6 Address Label subsystem
 * for the IPv6 "Default" Source Address Selection
 *
 * Copyright (C)2007 USAGI/WIDE Project
 */
/*
 * Author:
 * 	YOSHIFUJI Hideaki @ USAGI/WIDE Project <yoshfuji@linux-ipv6.org>
 */

#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/rcupdate.h>
#include <linux/in6.h>
#include <net/addrconf.h>
#include <linux/if_addrlabel.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>

#if 0
#define ADDRLABEL(x...) printk(x)
#else
#define ADDRLABEL(x...) do { ; } while(0)
#endif

/*
 * Policy Table
 */
struct ip6addrlbl_entry
{
	struct in6_addr prefix;
	int prefixlen;
	int ifindex;
	int addrtype;
	u32 label;
	struct hlist_node list;
	atomic_t refcnt;
	struct rcu_head rcu;
};

static struct ip6addrlbl_table
{
	struct hlist_head head;
	spinlock_t lock;
	u32 seq;
} ip6addrlbl_table;

/*
 * Default policy table (RFC3484 + extensions)
 *
 * prefix		addr_type	label
 * -------------------------------------------------------------------------
 * ::1/128		LOOPBACK	0
 * ::/0			N/A		1
 * 2002::/16		N/A		2
 * ::/96		COMPATv4	3
 * ::ffff:0:0/96	V4MAPPED	4
 * fc00::/7		N/A		5		ULA (RFC 4193)
 * 2001::/32		N/A		6		Teredo (RFC 4380)
 *
 * Note: 0xffffffff is used if we do not have any policies.
 */

#define IPV6_ADDR_LABEL_DEFAULT	0xffffffffUL

static const __initdata struct ip6addrlbl_init_table
{
	const struct in6_addr *prefix;
	int prefixlen;
	u32 label;
} ip6addrlbl_init_table[] = {
	{	/* ::/0 */
		.prefix = &in6addr_any,
		.label = 1,
	},{	/* fc00::/7 */
		.prefix = &(struct in6_addr){{{ 0xfc }}},
		.prefixlen = 7,
		.label = 5,
	},{	/* 2002::/16 */
		.prefix = &(struct in6_addr){{{ 0x20, 0x02 }}},
		.prefixlen = 16,
		.label = 2,
	},{	/* 2001::/32 */
		.prefix = &(struct in6_addr){{{ 0x20, 0x01 }}},
		.prefixlen = 32,
		.label = 6,
	},{	/* ::ffff:0:0 */
		.prefix = &(struct in6_addr){{{ [10] = 0xff, [11] = 0xff }}},
		.prefixlen = 96,
		.label = 4,
	},{	/* ::/96 */
		.prefix = &in6addr_any,
		.prefixlen = 96,
		.label = 3,
	},{	/* ::1/128 */
		.prefix = &in6addr_loopback,
		.prefixlen = 128,
		.label = 0,
	}
};

/* Object management */
static inline void ip6addrlbl_free(struct ip6addrlbl_entry *p)
{
	kfree(p);
}

static inline int ip6addrlbl_hold(struct ip6addrlbl_entry *p)
{
	return atomic_inc_not_zero(&p->refcnt);
}

static inline void ip6addrlbl_put(struct ip6addrlbl_entry *p)
{
	if (atomic_dec_and_test(&p->refcnt))
		ip6addrlbl_free(p);
}

static void ip6addrlbl_free_rcu(struct rcu_head *h)
{
	ip6addrlbl_free(container_of(h, struct ip6addrlbl_entry, rcu));
}

/* Find label */
static int __ip6addrlbl_match(struct ip6addrlbl_entry *p,
			      const struct in6_addr *addr,
			      int addrtype, int ifindex)
{
	if (p->ifindex && p->ifindex != ifindex)
		return 0;
	if (p->addrtype && p->addrtype != addrtype)
		return 0;
	if (!ipv6_prefix_equal(addr, &p->prefix, p->prefixlen))
		return 0;
	return 1;
}

static struct ip6addrlbl_entry *__ipv6_addr_label(const struct in6_addr *addr,
						  int type, int ifindex)
{
	struct hlist_node *pos;
	struct ip6addrlbl_entry *p;
	hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) {
		if (__ip6addrlbl_match(p, addr, type, ifindex))
			return p;
	}
	return NULL;
}

u32 ipv6_addr_label(const struct in6_addr *addr, int type, int ifindex)
{
	u32 label;
	struct ip6addrlbl_entry *p;

	type &= IPV6_ADDR_MAPPED | IPV6_ADDR_COMPATv4 | IPV6_ADDR_LOOPBACK;

	rcu_read_lock();
	p = __ipv6_addr_label(addr, type, ifindex);
	label = p ? p->label : IPV6_ADDR_LABEL_DEFAULT;
	rcu_read_unlock();

	ADDRLABEL(KERN_DEBUG "%s(addr=" NIP6_FMT ", type=%d, ifindex=%d) => %08x\n",
			__FUNCTION__,
			NIP6(*addr), type, ifindex,
			label);

	return label;
}

/* allocate one entry */
struct ip6addrlbl_entry *ip6addrlbl_alloc(const struct in6_addr *prefix,
					  int prefixlen, int ifindex,
					  u32 label)
{
	struct ip6addrlbl_entry *newp;
	int addrtype;

	ADDRLABEL(KERN_DEBUG "%s(prefix=" NIP6_FMT ", prefixlen=%d, ifindex=%d, label=%u)\n",
			__FUNCTION__,
			NIP6(*prefix), prefixlen,
			ifindex,
			(unsigned int)label);

	addrtype = ipv6_addr_type(prefix) & (IPV6_ADDR_MAPPED | IPV6_ADDR_COMPATv4 | IPV6_ADDR_LOOPBACK);

	switch (addrtype) {
	case IPV6_ADDR_MAPPED:
		if (prefixlen > 96)
			return ERR_PTR(-EINVAL);
		if (prefixlen < 96)
			addrtype = 0;
		break;
	case IPV6_ADDR_COMPATv4:
		if (prefixlen != 96)
			addrtype = 0;
		break;
	case IPV6_ADDR_LOOPBACK:
		if (prefixlen != 128)
			addrtype = 0;
		break;
	}

	newp = kmalloc(sizeof(*newp), GFP_KERNEL);
	if (!newp)
		return ERR_PTR(-ENOMEM);

	ipv6_addr_prefix(&newp->prefix, prefix, prefixlen);
	newp->prefixlen = prefixlen;
	newp->ifindex = ifindex;
	newp->addrtype = addrtype;
	newp->label = label;
	INIT_HLIST_NODE(&newp->list);
	atomic_set(&newp->refcnt, 1);
	return newp;
}

/* add a label */
int __ip6addrlbl_add(struct ip6addrlbl_entry *newp, int replace)
{
	int ret = 0;

	ADDRLABEL(KERN_DEBUG "%s(newp=%p, replace=%d)\n",
			__FUNCTION__,
			newp, replace);

	if (hlist_empty(&ip6addrlbl_table.head)) {
		hlist_add_head_rcu(&newp->list, &ip6addrlbl_table.head);
	} else {
		struct hlist_node *pos, *n;
		struct ip6addrlbl_entry *p = NULL;
		hlist_for_each_entry_safe(p, pos, n,
					  &ip6addrlbl_table.head, list) {
			if (p->prefixlen == newp->prefixlen &&
			    p->ifindex == newp->ifindex &&
			    ipv6_addr_equal(&p->prefix, &newp->prefix)) {
				if (!replace) {
					ret = -EEXIST;
					goto out;
				}
				hlist_replace_rcu(&p->list, &newp->list);
				ip6addrlbl_put(p);
				call_rcu(&p->rcu, ip6addrlbl_free_rcu);
				goto out;
			} else if ((p->prefixlen == newp->prefixlen && !p->ifindex) ||
				   (p->prefixlen < newp->prefixlen)) {
				hlist_add_before_rcu(&newp->list, &p->list);
				goto out;
			}
		}
		hlist_add_after_rcu(&p->list, &newp->list);
	}
out:
	if (!ret)
		ip6addrlbl_table.seq++;
	return ret;
}

/* add a label */
int ip6addrlbl_add(const struct in6_addr *prefix, int prefixlen,
		       int ifindex, u32 label, int replace)
{
	struct ip6addrlbl_entry *newp;
	int ret = 0;

	ADDRLABEL(KERN_DEBUG "%s(prefix=" NIP6_FMT ", prefixlen=%d, ifindex=%d, label=%u, replace=%d)\n",
			__FUNCTION__,
			NIP6(*prefix), prefixlen,
			ifindex,
			(unsigned int)label,
			replace);

	newp = ip6addrlbl_alloc(prefix, prefixlen, ifindex, label);
	if (IS_ERR(newp))
		return PTR_ERR(newp);
	spin_lock(&ip6addrlbl_table.lock);
	ret = __ip6addrlbl_add(newp, replace);
	spin_unlock(&ip6addrlbl_table.lock);
	if (ret)
		ip6addrlbl_free(newp);
	return ret;
}

/* remove a label */
int __ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen,
			  int ifindex)
{
	struct ip6addrlbl_entry *p = NULL;
	struct hlist_node *pos, *n;
	int ret = -ESRCH;

	ADDRLABEL(KERN_DEBUG "%s(prefix=" NIP6_FMT ", prefixlen=%d, ifindex=%d)\n",
			__FUNCTION__,
			NIP6(*prefix), prefixlen,
			ifindex);

	hlist_for_each_entry_safe(p, pos, n, &ip6addrlbl_table.head, list) {
		if (p->prefixlen == prefixlen &&
		    p->ifindex == ifindex &&
		    ipv6_addr_equal(&p->prefix, prefix)) {
			hlist_del_rcu(&p->list);
			ip6addrlbl_put(p);
			call_rcu(&p->rcu, ip6addrlbl_free_rcu);
			ret = 0;
			break;
		}
	}
	return ret;
}

int ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen,
		       int ifindex)
{
	struct in6_addr prefix_buf;
	int ret;

	ADDRLABEL(KERN_DEBUG "%s(prefix=" NIP6_FMT ", prefixlen=%d, ifindex=%d)\n",
			__FUNCTION__,
			NIP6(*prefix), prefixlen,
			ifindex);

	ipv6_addr_prefix(&prefix_buf, prefix, prefixlen);
	spin_lock(&ip6addrlbl_table.lock);
	ret = __ip6addrlbl_del(&prefix_buf, prefixlen, ifindex);
	spin_unlock(&ip6addrlbl_table.lock);
	return ret;
}

/* add default label */
static __init int ip6addrlbl_init(void)
{
	int err = 0;
	int i;

	ADDRLABEL(KERN_DEBUG "%s()\n", __FUNCTION__);

	for (i = 0; i < ARRAY_SIZE(ip6addrlbl_init_table); i++) {
		int ret = ip6addrlbl_add(ip6addrlbl_init_table[i].prefix,
					 ip6addrlbl_init_table[i].prefixlen,
					 0,
					 ip6addrlbl_init_table[i].label, 0);
		/* XXX: should we free all rules when we catch an error? */
		if (ret && (!err || err != -ENOMEM))
			err = ret;
	}
	return err;
}

int __init ipv6_addr_label_init(void)
{
	spin_lock_init(&ip6addrlbl_table.lock);

	return ip6addrlbl_init();
}

static const struct nla_policy ifal_policy[IFAL_MAX+1] = {
	[IFAL_ADDRESS]		= { .len = sizeof(struct in6_addr), },
	[IFAL_LABEL]		= { .len = sizeof(u32), },
};

static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh,
			     void *arg)
{
	struct net *net = skb->sk->sk_net;
	struct ifaddrlblmsg *ifal;
	struct nlattr *tb[IFAL_MAX+1];
	struct in6_addr *pfx;
	u32 label;
	int err = 0;

	if (net != &init_net)
		return 0;

	err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy);
	if (err < 0)
		return err;

	ifal = nlmsg_data(nlh);

	if (ifal->ifal_family != AF_INET6 ||
	    ifal->ifal_prefixlen > 128)
		return -EINVAL;

	if (ifal->ifal_index &&
	    !__dev_get_by_index(&init_net, ifal->ifal_index))
		return -EINVAL;

	if (!tb[IFAL_ADDRESS])
		return -EINVAL;

	pfx = nla_data(tb[IFAL_ADDRESS]);
	if (!pfx)
		return -EINVAL;

	if (!tb[IFAL_LABEL])
		return -EINVAL;
	label = nla_get_u32(tb[IFAL_LABEL]);
	if (label == IPV6_ADDR_LABEL_DEFAULT)
		return -EINVAL;

	switch(nlh->nlmsg_type) {
	case RTM_NEWADDRLABEL:
		err = ip6addrlbl_add(pfx, ifal->ifal_prefixlen,
				     ifal->ifal_index, label,
				     nlh->nlmsg_flags & NLM_F_REPLACE);
		break;
	case RTM_DELADDRLABEL:
		err = ip6addrlbl_del(pfx, ifal->ifal_prefixlen,
				     ifal->ifal_index);
		break;
	default:
		err = -EOPNOTSUPP;
	}
	return err;
}

static inline void ip6addrlbl_putmsg(struct nlmsghdr *nlh,
				     int prefixlen, int ifindex, u32 lseq)
{
	struct ifaddrlblmsg *ifal = nlmsg_data(nlh);
	ifal->ifal_family = AF_INET6;
	ifal->ifal_prefixlen = prefixlen;
	ifal->ifal_flags = 0;
	ifal->ifal_index = ifindex;
	ifal->ifal_seq = lseq;
};

static int ip6addrlbl_fill(struct sk_buff *skb,
			   struct ip6addrlbl_entry *p,
			   u32 lseq,
			   u32 pid, u32 seq, int event,
			   unsigned int flags)
{
	struct nlmsghdr *nlh = nlmsg_put(skb, pid, seq, event,
					 sizeof(struct ifaddrlblmsg), flags);
	if (!nlh)
		return -EMSGSIZE;

	ip6addrlbl_putmsg(nlh, p->prefixlen, p->ifindex, lseq);

	if (nla_put(skb, IFAL_ADDRESS, 16, &p->prefix) < 0 ||
	    nla_put_u32(skb, IFAL_LABEL, p->label) < 0) {
		nlmsg_cancel(skb, nlh);
		return -EMSGSIZE;
	}

	return nlmsg_end(skb, nlh);
}

static int ip6addrlbl_dump(struct sk_buff *skb, struct netlink_callback *cb)
{
	struct net *net = skb->sk->sk_net;
	struct ip6addrlbl_entry *p;
	struct hlist_node *pos;
	int idx = 0, s_idx = cb->args[0];
	int err;

	if (net != &init_net)
		return 0;

	rcu_read_lock();
	hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) {
		if (idx >= s_idx) {
			if ((err = ip6addrlbl_fill(skb, p,
						   ip6addrlbl_table.seq,
						   NETLINK_CB(cb->skb).pid,
						   cb->nlh->nlmsg_seq,
						   RTM_NEWADDRLABEL,
						   NLM_F_MULTI)) <= 0)
				break;
		}
		idx++;
	}
	rcu_read_unlock();
	cb->args[0] = idx;
	return skb->len;
}

static inline int ip6addrlbl_msgsize(void)
{
	return (NLMSG_ALIGN(sizeof(struct ifaddrlblmsg))
		+ nla_total_size(16)	/* IFAL_ADDRESS */
		+ nla_total_size(4)	/* IFAL_LABEL */
	);
}

static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
			  void *arg)
{
	struct net *net = in_skb->sk->sk_net;
	struct ifaddrlblmsg *ifal;
	struct nlattr *tb[IFAL_MAX+1];
	struct in6_addr *addr;
	u32 lseq;
	int err = 0;
	struct ip6addrlbl_entry *p;
	struct sk_buff *skb;

	if (net != &init_net)
		return 0;

	err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy);
	if (err < 0)
		return err;

	ifal = nlmsg_data(nlh);

	if (ifal->ifal_family != AF_INET6 ||
	    ifal->ifal_prefixlen != 128)
		return -EINVAL;

	if (ifal->ifal_index &&
	    !__dev_get_by_index(&init_net, ifal->ifal_index))
		return -EINVAL;

	if (!tb[IFAL_ADDRESS])
		return -EINVAL;

	addr = nla_data(tb[IFAL_ADDRESS]);
	if (!addr)
		return -EINVAL;

	rcu_read_lock();
	p = __ipv6_addr_label(addr, ipv6_addr_type(addr), ifal->ifal_index);
	if (p && ip6addrlbl_hold(p))
		p = NULL;
	lseq = ip6addrlbl_table.seq;
	rcu_read_unlock();

	if (!p) {
		err = -ESRCH;
		goto out;
	}

	if (!(skb = nlmsg_new(ip6addrlbl_msgsize(), GFP_KERNEL))) {
		ip6addrlbl_put(p);
		return -ENOBUFS;
	}

	err = ip6addrlbl_fill(skb, p, lseq,
			      NETLINK_CB(in_skb).pid, nlh->nlmsg_seq,
			      RTM_NEWADDRLABEL, 0);

	ip6addrlbl_put(p);

	if (err < 0) {
		WARN_ON(err == -EMSGSIZE);
		kfree_skb(skb);
		goto out;
	}

	err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid);
out:
	return err;
}

void __init ipv6_addr_label_rtnl_register(void)
{
	__rtnl_register(PF_INET6, RTM_NEWADDRLABEL, ip6addrlbl_newdel, NULL);
	__rtnl_register(PF_INET6, RTM_DELADDRLABEL, ip6addrlbl_newdel, NULL);
	__rtnl_register(PF_INET6, RTM_GETADDRLABEL, ip6addrlbl_get, ip6addrlbl_dump);
}

