/*
 * Copyright (c) 2008-2010 Patrick McHardy <kaber@trash.net>
 * Copyright (c) 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/module.h>
#include <linux/init.h>
#include <linux/netfilter_arp.h>
#include <net/netfilter/nf_tables.h>

static struct nft_af_info nft_af_arp __read_mostly = {
	.family		= NFPROTO_ARP,
	.nhooks		= NF_ARP_NUMHOOKS,
	.owner		= THIS_MODULE,
};

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

	memcpy(net->nft.arp, &nft_af_arp, sizeof(nft_af_arp));

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

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

static void nf_tables_arp_exit_net(struct net *net)
{
	nft_unregister_afinfo(net->nft.arp);
	kfree(net->nft.arp);
}

static struct pernet_operations nf_tables_arp_net_ops = {
	.init   = nf_tables_arp_init_net,
	.exit   = nf_tables_arp_exit_net,
};

static unsigned int
nft_do_chain_arp(const struct nf_hook_ops *ops,
		  struct sk_buff *skb,
		  const struct net_device *in,
		  const struct net_device *out,
		  int (*okfn)(struct sk_buff *))
{
	struct nft_pktinfo pkt;

	nft_set_pktinfo(&pkt, ops, skb, in, out);

	return nft_do_chain_pktinfo(&pkt, ops);
}

static struct nf_chain_type filter_arp = {
	.family		= NFPROTO_ARP,
	.name		= "filter",
	.type		= NFT_CHAIN_T_DEFAULT,
	.hook_mask	= (1 << NF_ARP_IN) |
			  (1 << NF_ARP_OUT) |
			  (1 << NF_ARP_FORWARD),
	.fn		= {
		[NF_ARP_IN]		= nft_do_chain_arp,
		[NF_ARP_OUT]		= nft_do_chain_arp,
		[NF_ARP_FORWARD]	= nft_do_chain_arp,
	},
};

static int __init nf_tables_arp_init(void)
{
	int ret;

	nft_register_chain_type(&filter_arp);
	ret = register_pernet_subsys(&nf_tables_arp_net_ops);
	if (ret < 0)
		nft_unregister_chain_type(&filter_arp);

	return ret;
}

static void __exit nf_tables_arp_exit(void)
{
	unregister_pernet_subsys(&nf_tables_arp_net_ops);
	nft_unregister_chain_type(&filter_arp);
}

module_init(nf_tables_arp_init);
module_exit(nf_tables_arp_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
MODULE_ALIAS_NFT_FAMILY(3); /* NFPROTO_ARP */
