1/* 2 * Copyright (c) 2008 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/init.h> 13#include <linux/module.h> 14#include <linux/netfilter_bridge.h> 15#include <net/netfilter/nf_tables.h> 16 17static unsigned int 18nft_do_chain_bridge(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_bridge __read_mostly = { 32 .family = NFPROTO_BRIDGE, 33 .nhooks = NF_BR_NUMHOOKS, 34 .owner = THIS_MODULE, 35 .nops = 1, 36 .hooks = { 37 [NF_BR_PRE_ROUTING] = nft_do_chain_bridge, 38 [NF_BR_LOCAL_IN] = nft_do_chain_bridge, 39 [NF_BR_FORWARD] = nft_do_chain_bridge, 40 [NF_BR_LOCAL_OUT] = nft_do_chain_bridge, 41 [NF_BR_POST_ROUTING] = nft_do_chain_bridge, 42 }, 43}; 44 45static int nf_tables_bridge_init_net(struct net *net) 46{ 47 net->nft.bridge = kmalloc(sizeof(struct nft_af_info), GFP_KERNEL); 48 if (net->nft.bridge == NULL) 49 return -ENOMEM; 50 51 memcpy(net->nft.bridge, &nft_af_bridge, sizeof(nft_af_bridge)); 52 53 if (nft_register_afinfo(net, net->nft.bridge) < 0) 54 goto err; 55 56 return 0; 57err: 58 kfree(net->nft.bridge); 59 return -ENOMEM; 60} 61 62static void nf_tables_bridge_exit_net(struct net *net) 63{ 64 nft_unregister_afinfo(net->nft.bridge); 65 kfree(net->nft.bridge); 66} 67 68static struct pernet_operations nf_tables_bridge_net_ops = { 69 .init = nf_tables_bridge_init_net, 70 .exit = nf_tables_bridge_exit_net, 71}; 72 73static const struct nf_chain_type filter_bridge = { 74 .name = "filter", 75 .type = NFT_CHAIN_T_DEFAULT, 76 .family = NFPROTO_BRIDGE, 77 .owner = THIS_MODULE, 78 .hook_mask = (1 << NF_BR_PRE_ROUTING) | 79 (1 << NF_BR_LOCAL_IN) | 80 (1 << NF_BR_FORWARD) | 81 (1 << NF_BR_LOCAL_OUT) | 82 (1 << NF_BR_POST_ROUTING), 83}; 84 85static int __init nf_tables_bridge_init(void) 86{ 87 int ret; 88 89 nft_register_chain_type(&filter_bridge); 90 ret = register_pernet_subsys(&nf_tables_bridge_net_ops); 91 if (ret < 0) 92 nft_unregister_chain_type(&filter_bridge); 93 94 return ret; 95} 96 97static void __exit nf_tables_bridge_exit(void) 98{ 99 unregister_pernet_subsys(&nf_tables_bridge_net_ops); 100 nft_unregister_chain_type(&filter_bridge); 101} 102 103module_init(nf_tables_bridge_init); 104module_exit(nf_tables_bridge_exit); 105 106MODULE_LICENSE("GPL"); 107MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 108MODULE_ALIAS_NFT_FAMILY(AF_BRIDGE); 109