/*
 * net/ipv6/fib6_rules.c	IPv6 Routing Policy Rules
 *
 * Copyright (C)2003-2006 Helsinki University of Technology
 * Copyright (C)2003-2006 USAGI/WIDE Project
 *
 *	This program is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU General Public License as
 *	published by the Free Software Foundation, version 2.
 *
 * Authors
 *	Thomas Graf		<tgraf@suug.ch>
 *	Ville Nuorvala		<vnuorval@tcs.hut.fi>
 */

#include <linux/config.h>
#include <linux/netdevice.h>

#include <net/fib_rules.h>
#include <net/ipv6.h>
#include <net/ip6_route.h>
#include <net/netlink.h>

struct fib6_rule
{
	struct fib_rule		common;
	struct rt6key		src;
	struct rt6key		dst;
#ifdef CONFIG_IPV6_ROUTE_FWMARK
	u32			fwmark;
	u32			fwmask;
#endif
	u8			tclass;
};

static struct fib_rules_ops fib6_rules_ops;

static struct fib6_rule main_rule = {
	.common = {
		.refcnt =	ATOMIC_INIT(2),
		.pref =		0x7FFE,
		.action =	FR_ACT_TO_TBL,
		.table =	RT6_TABLE_MAIN,
	},
};

static struct fib6_rule local_rule = {
	.common = {
		.refcnt =	ATOMIC_INIT(2),
		.pref =		0,
		.action =	FR_ACT_TO_TBL,
		.table =	RT6_TABLE_LOCAL,
		.flags =	FIB_RULE_PERMANENT,
	},
};

static LIST_HEAD(fib6_rules);

struct dst_entry *fib6_rule_lookup(struct flowi *fl, int flags,
				   pol_lookup_t lookup)
{
	struct fib_lookup_arg arg = {
		.lookup_ptr = lookup,
	};

	fib_rules_lookup(&fib6_rules_ops, fl, flags, &arg);
	if (arg.rule)
		fib_rule_put(arg.rule);

	if (arg.result)
		return (struct dst_entry *) arg.result;

	dst_hold(&ip6_null_entry.u.dst);
	return &ip6_null_entry.u.dst;
}

static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
			    int flags, struct fib_lookup_arg *arg)
{
	struct rt6_info *rt = NULL;
	struct fib6_table *table;
	pol_lookup_t lookup = arg->lookup_ptr;

	switch (rule->action) {
	case FR_ACT_TO_TBL:
		break;
	case FR_ACT_UNREACHABLE:
		rt = &ip6_null_entry;
		goto discard_pkt;
	default:
	case FR_ACT_BLACKHOLE:
		rt = &ip6_blk_hole_entry;
		goto discard_pkt;
	case FR_ACT_PROHIBIT:
		rt = &ip6_prohibit_entry;
		goto discard_pkt;
	}

	table = fib6_get_table(rule->table);
	if (table)
		rt = lookup(table, flp, flags);

	if (rt != &ip6_null_entry)
		goto out;
	dst_release(&rt->u.dst);
	rt = NULL;
	goto out;

discard_pkt:
	dst_hold(&rt->u.dst);
out:
	arg->result = rt;
	return rt == NULL ? -EAGAIN : 0;
}


static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
{
	struct fib6_rule *r = (struct fib6_rule *) rule;

	if (!ipv6_prefix_equal(&fl->fl6_dst, &r->dst.addr, r->dst.plen))
		return 0;

	if ((flags & RT6_LOOKUP_F_HAS_SADDR) &&
	    !ipv6_prefix_equal(&fl->fl6_src, &r->src.addr, r->src.plen))
		return 0;

	if (r->tclass && r->tclass != ((ntohl(fl->fl6_flowlabel) >> 20) & 0xff))
		return 0;

#ifdef CONFIG_IPV6_ROUTE_FWMARK
	if ((r->fwmark ^ fl->fl6_fwmark) & r->fwmask)
		return 0;
#endif

	return 1;
}

static struct nla_policy fib6_rule_policy[FRA_MAX+1] __read_mostly = {
	[FRA_IFNAME]	= { .type = NLA_STRING, .len = IFNAMSIZ - 1 },
	[FRA_PRIORITY]	= { .type = NLA_U32 },
	[FRA_SRC]	= { .len = sizeof(struct in6_addr) },
	[FRA_DST]	= { .len = sizeof(struct in6_addr) },
	[FRA_FWMARK]	= { .type = NLA_U32 },
	[FRA_FWMASK]	= { .type = NLA_U32 },
	[FRA_TABLE]	= { .type = NLA_U32 },
};

static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
			       struct nlmsghdr *nlh, struct fib_rule_hdr *frh,
			       struct nlattr **tb)
{
	int err = -EINVAL;
	struct fib6_rule *rule6 = (struct fib6_rule *) rule;

	if (frh->src_len > 128 || frh->dst_len > 128 ||
	    (frh->tos & ~IPV6_FLOWINFO_MASK))
		goto errout;

	if (rule->action == FR_ACT_TO_TBL) {
		if (rule->table == RT6_TABLE_UNSPEC)
			goto errout;

		if (fib6_new_table(rule->table) == NULL) {
			err = -ENOBUFS;
			goto errout;
		}
	}

	if (tb[FRA_SRC])
		nla_memcpy(&rule6->src.addr, tb[FRA_SRC],
			   sizeof(struct in6_addr));

	if (tb[FRA_DST])
		nla_memcpy(&rule6->dst.addr, tb[FRA_DST],
			   sizeof(struct in6_addr));

#ifdef CONFIG_IPV6_ROUTE_FWMARK
	if (tb[FRA_FWMARK]) {
		rule6->fwmark = nla_get_u32(tb[FRA_FWMARK]);
		if (rule6->fwmark) {
			/*
			 * if the mark value is non-zero,
			 * all bits are compared by default
			 * unless a mask is explicitly specified.
			 */
			rule6->fwmask = 0xFFFFFFFF;
		}
	}

	if (tb[FRA_FWMASK])
		rule6->fwmask = nla_get_u32(tb[FRA_FWMASK]);
#endif

	rule6->src.plen = frh->src_len;
	rule6->dst.plen = frh->dst_len;
	rule6->tclass = frh->tos;

	err = 0;
errout:
	return err;
}

static int fib6_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
			     struct nlattr **tb)
{
	struct fib6_rule *rule6 = (struct fib6_rule *) rule;

	if (frh->src_len && (rule6->src.plen != frh->src_len))
		return 0;

	if (frh->dst_len && (rule6->dst.plen != frh->dst_len))
		return 0;

	if (frh->tos && (rule6->tclass != frh->tos))
		return 0;

	if (tb[FRA_SRC] &&
	    nla_memcmp(tb[FRA_SRC], &rule6->src.addr, sizeof(struct in6_addr)))
		return 0;

	if (tb[FRA_DST] &&
	    nla_memcmp(tb[FRA_DST], &rule6->dst.addr, sizeof(struct in6_addr)))
		return 0;

#ifdef CONFIG_IPV6_ROUTE_FWMARK
	if (tb[FRA_FWMARK] && (rule6->fwmark != nla_get_u32(tb[FRA_FWMARK])))
		return 0;

	if (tb[FRA_FWMASK] && (rule6->fwmask != nla_get_u32(tb[FRA_FWMASK])))
		return 0;
#endif

	return 1;
}

static int fib6_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
			  struct nlmsghdr *nlh, struct fib_rule_hdr *frh)
{
	struct fib6_rule *rule6 = (struct fib6_rule *) rule;

	frh->family = AF_INET6;
	frh->dst_len = rule6->dst.plen;
	frh->src_len = rule6->src.plen;
	frh->tos = rule6->tclass;

	if (rule6->dst.plen)
		NLA_PUT(skb, FRA_DST, sizeof(struct in6_addr),
			&rule6->dst.addr);

	if (rule6->src.plen)
		NLA_PUT(skb, FRA_SRC, sizeof(struct in6_addr),
			&rule6->src.addr);

#ifdef CONFIG_IPV6_ROUTE_FWMARK
	if (rule6->fwmark)
		NLA_PUT_U32(skb, FRA_FWMARK, rule6->fwmark);

	if (rule6->fwmask || rule6->fwmark)
		NLA_PUT_U32(skb, FRA_FWMASK, rule6->fwmask);
#endif

	return 0;

nla_put_failure:
	return -ENOBUFS;
}

int fib6_rules_dump(struct sk_buff *skb, struct netlink_callback *cb)
{
	return fib_rules_dump(skb, cb, AF_INET6);
}

static u32 fib6_rule_default_pref(void)
{
	return 0x3FFF;
}

static struct fib_rules_ops fib6_rules_ops = {
	.family			= AF_INET6,
	.rule_size		= sizeof(struct fib6_rule),
	.action			= fib6_rule_action,
	.match			= fib6_rule_match,
	.configure		= fib6_rule_configure,
	.compare		= fib6_rule_compare,
	.fill			= fib6_rule_fill,
	.default_pref		= fib6_rule_default_pref,
	.nlgroup		= RTNLGRP_IPV6_RULE,
	.policy			= fib6_rule_policy,
	.rules_list		= &fib6_rules,
	.owner			= THIS_MODULE,
};

void __init fib6_rules_init(void)
{
	list_add_tail(&local_rule.common.list, &fib6_rules);
	list_add_tail(&main_rule.common.list, &fib6_rules);

	fib_rules_register(&fib6_rules_ops);
}

void fib6_rules_cleanup(void)
{
	fib_rules_unregister(&fib6_rules_ops);
}
