1/* 2 * Copyright (c) 2008-2010 Patrick McHardy <kaber@trash.net> 3 * Copyright (c) 2013 Pablo Neira Ayuso <pablo@netfilter.org> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Development of this code funded by Astaro AG (http://www.astaro.com/) 10 */ 11 12#include <linux/module.h> 13#include <linux/init.h> 14#include <linux/netfilter_arp.h> 15#include <net/netfilter/nf_tables.h> 16 17static unsigned int 18nft_do_chain_arp(const struct nf_hook_ops *ops, 19 struct sk_buff *skb, 20 const struct net_device *in, 21 const struct net_device *out, 22 int (*okfn)(struct sk_buff *)) 23{ 24 struct nft_pktinfo pkt; 25 26 nft_set_pktinfo(&pkt, ops, skb, in, out); 27 28 return nft_do_chain(&pkt, ops); 29} 30 31static struct nft_af_info nft_af_arp __read_mostly = { 32 .family = NFPROTO_ARP, 33 .nhooks = NF_ARP_NUMHOOKS, 34 .owner = THIS_MODULE, 35 .nops = 1, 36 .hooks = { 37 [NF_ARP_IN] = nft_do_chain_arp, 38 [NF_ARP_OUT] = nft_do_chain_arp, 39 [NF_ARP_FORWARD] = nft_do_chain_arp, 40 }, 41}; 42 43static int nf_tables_arp_init_net(struct net *net) 44{ 45 net->nft.arp = kmalloc(sizeof(struct nft_af_info), GFP_KERNEL); 46 if (net->nft.arp== NULL) 47 return -ENOMEM; 48 49 memcpy(net->nft.arp, &nft_af_arp, sizeof(nft_af_arp)); 50 51 if (nft_register_afinfo(net, net->nft.arp) < 0) 52 goto err; 53 54 return 0; 55err: 56 kfree(net->nft.arp); 57 return -ENOMEM; 58} 59 60static void nf_tables_arp_exit_net(struct net *net) 61{ 62 nft_unregister_afinfo(net->nft.arp); 63 kfree(net->nft.arp); 64} 65 66static struct pernet_operations nf_tables_arp_net_ops = { 67 .init = nf_tables_arp_init_net, 68 .exit = nf_tables_arp_exit_net, 69}; 70 71static const struct nf_chain_type filter_arp = { 72 .name = "filter", 73 .type = NFT_CHAIN_T_DEFAULT, 74 .family = NFPROTO_ARP, 75 .owner = THIS_MODULE, 76 .hook_mask = (1 << NF_ARP_IN) | 77 (1 << NF_ARP_OUT) | 78 (1 << NF_ARP_FORWARD), 79}; 80 81static int __init nf_tables_arp_init(void) 82{ 83 int ret; 84 85 nft_register_chain_type(&filter_arp); 86 ret = register_pernet_subsys(&nf_tables_arp_net_ops); 87 if (ret < 0) 88 nft_unregister_chain_type(&filter_arp); 89 90 return ret; 91} 92 93static void __exit nf_tables_arp_exit(void) 94{ 95 unregister_pernet_subsys(&nf_tables_arp_net_ops); 96 nft_unregister_chain_type(&filter_arp); 97} 98 99module_init(nf_tables_arp_init); 100module_exit(nf_tables_arp_exit); 101 102MODULE_LICENSE("GPL"); 103MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 104MODULE_ALIAS_NFT_FAMILY(3); /* NFPROTO_ARP */ 105