/*
 * Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
 * Copyright (c) 2012-2013 Pablo Neira Ayuso <pablo@netfilter.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * Development of this code funded by Astaro AG (http://www.astaro.com/)
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/ipv6.h>
#include <linux/netfilter_ipv6.h>
#include <net/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables_ipv6.h>

static unsigned int nft_do_chain_ipv6(void *priv,
				      struct sk_buff *skb,
				      const struct nf_hook_state *state)
{
	struct nft_pktinfo pkt;

	/* malformed packet, drop it */
	if (nft_set_pktinfo_ipv6(&pkt, skb, state) < 0)
		return NF_DROP;

	return nft_do_chain(&pkt, priv);
}

static unsigned int nft_ipv6_output(void *priv,
				    struct sk_buff *skb,
				    const struct nf_hook_state *state)
{
	if (unlikely(skb->len < sizeof(struct ipv6hdr))) {
		if (net_ratelimit())
			pr_info("nf_tables_ipv6: ignoring short SOCK_RAW "
				"packet\n");
		return NF_ACCEPT;
	}

	return nft_do_chain_ipv6(priv, skb, state);
}

struct nft_af_info nft_af_ipv6 __read_mostly = {
	.family		= NFPROTO_IPV6,
	.nhooks		= NF_INET_NUMHOOKS,
	.owner		= THIS_MODULE,
	.nops		= 1,
	.hooks		= {
		[NF_INET_LOCAL_IN]	= nft_do_chain_ipv6,
		[NF_INET_LOCAL_OUT]	= nft_ipv6_output,
		[NF_INET_FORWARD]	= nft_do_chain_ipv6,
		[NF_INET_PRE_ROUTING]	= nft_do_chain_ipv6,
		[NF_INET_POST_ROUTING]	= nft_do_chain_ipv6,
	},
};
EXPORT_SYMBOL_GPL(nft_af_ipv6);

static int nf_tables_ipv6_init_net(struct net *net)
{
	net->nft.ipv6 = kmalloc(sizeof(struct nft_af_info), GFP_KERNEL);
	if (net->nft.ipv6 == NULL)
		return -ENOMEM;

	memcpy(net->nft.ipv6, &nft_af_ipv6, sizeof(nft_af_ipv6));

	if (nft_register_afinfo(net, net->nft.ipv6) < 0)
		goto err;

	return 0;
err:
	kfree(net->nft.ipv6);
	return -ENOMEM;
}

static void nf_tables_ipv6_exit_net(struct net *net)
{
	nft_unregister_afinfo(net, net->nft.ipv6);
	kfree(net->nft.ipv6);
}

static struct pernet_operations nf_tables_ipv6_net_ops = {
	.init	= nf_tables_ipv6_init_net,
	.exit	= nf_tables_ipv6_exit_net,
};

static const struct nf_chain_type filter_ipv6 = {
	.name		= "filter",
	.type		= NFT_CHAIN_T_DEFAULT,
	.family		= NFPROTO_IPV6,
	.owner		= THIS_MODULE,
	.hook_mask	= (1 << NF_INET_LOCAL_IN) |
			  (1 << NF_INET_LOCAL_OUT) |
			  (1 << NF_INET_FORWARD) |
			  (1 << NF_INET_PRE_ROUTING) |
			  (1 << NF_INET_POST_ROUTING),
};

static int __init nf_tables_ipv6_init(void)
{
	int ret;

	nft_register_chain_type(&filter_ipv6);
	ret = register_pernet_subsys(&nf_tables_ipv6_net_ops);
	if (ret < 0)
		nft_unregister_chain_type(&filter_ipv6);

	return ret;
}

static void __exit nf_tables_ipv6_exit(void)
{
	unregister_pernet_subsys(&nf_tables_ipv6_net_ops);
	nft_unregister_chain_type(&filter_ipv6);
}

module_init(nf_tables_ipv6_init);
module_exit(nf_tables_ipv6_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
MODULE_ALIAS_NFT_FAMILY(AF_INET6);
