1/* 2 * Copyright (c) 2012-2014 Patrick McHardy <kaber@trash.net> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 */ 8 9#include <linux/init.h> 10#include <linux/module.h> 11#include <linux/ip.h> 12#include <linux/netfilter_ipv4.h> 13#include <linux/netfilter_ipv6.h> 14#include <net/netfilter/nf_tables.h> 15#include <net/netfilter/nf_tables_ipv4.h> 16#include <net/netfilter/nf_tables_ipv6.h> 17#include <net/ip.h> 18 19static void nft_inet_hook_ops_init(struct nf_hook_ops *ops, unsigned int n) 20{ 21 struct nft_af_info *afi; 22 23 if (n == 1) 24 afi = &nft_af_ipv4; 25 else 26 afi = &nft_af_ipv6; 27 28 ops->pf = afi->family; 29 if (afi->hooks[ops->hooknum]) 30 ops->hook = afi->hooks[ops->hooknum]; 31} 32 33static struct nft_af_info nft_af_inet __read_mostly = { 34 .family = NFPROTO_INET, 35 .nhooks = NF_INET_NUMHOOKS, 36 .owner = THIS_MODULE, 37 .nops = 2, 38 .hook_ops_init = nft_inet_hook_ops_init, 39}; 40 41static int __net_init nf_tables_inet_init_net(struct net *net) 42{ 43 net->nft.inet = kmalloc(sizeof(struct nft_af_info), GFP_KERNEL); 44 if (net->nft.inet == NULL) 45 return -ENOMEM; 46 memcpy(net->nft.inet, &nft_af_inet, sizeof(nft_af_inet)); 47 48 if (nft_register_afinfo(net, net->nft.inet) < 0) 49 goto err; 50 51 return 0; 52 53err: 54 kfree(net->nft.inet); 55 return -ENOMEM; 56} 57 58static void __net_exit nf_tables_inet_exit_net(struct net *net) 59{ 60 nft_unregister_afinfo(net->nft.inet); 61 kfree(net->nft.inet); 62} 63 64static struct pernet_operations nf_tables_inet_net_ops = { 65 .init = nf_tables_inet_init_net, 66 .exit = nf_tables_inet_exit_net, 67}; 68 69static const struct nf_chain_type filter_inet = { 70 .name = "filter", 71 .type = NFT_CHAIN_T_DEFAULT, 72 .family = NFPROTO_INET, 73 .owner = THIS_MODULE, 74 .hook_mask = (1 << NF_INET_LOCAL_IN) | 75 (1 << NF_INET_LOCAL_OUT) | 76 (1 << NF_INET_FORWARD) | 77 (1 << NF_INET_PRE_ROUTING) | 78 (1 << NF_INET_POST_ROUTING), 79}; 80 81static int __init nf_tables_inet_init(void) 82{ 83 int ret; 84 85 nft_register_chain_type(&filter_inet); 86 ret = register_pernet_subsys(&nf_tables_inet_net_ops); 87 if (ret < 0) 88 nft_unregister_chain_type(&filter_inet); 89 90 return ret; 91} 92 93static void __exit nf_tables_inet_exit(void) 94{ 95 unregister_pernet_subsys(&nf_tables_inet_net_ops); 96 nft_unregister_chain_type(&filter_inet); 97} 98 99module_init(nf_tables_inet_init); 100module_exit(nf_tables_inet_exit); 101 102MODULE_LICENSE("GPL"); 103MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 104MODULE_ALIAS_NFT_FAMILY(1); 105