11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * ebtable_filter 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Authors: 51da177e4SLinus Torvalds * Bart De Schuymer <bdschuym@pandora.be> 61da177e4SLinus Torvalds * 71da177e4SLinus Torvalds * April, 2002 81da177e4SLinus Torvalds * 91da177e4SLinus Torvalds */ 101da177e4SLinus Torvalds 111da177e4SLinus Torvalds #include <linux/netfilter_bridge/ebtables.h> 121da177e4SLinus Torvalds #include <linux/module.h> 131da177e4SLinus Torvalds 141da177e4SLinus Torvalds #define FILTER_VALID_HOOKS ((1 << NF_BR_LOCAL_IN) | (1 << NF_BR_FORWARD) | \ 151da177e4SLinus Torvalds (1 << NF_BR_LOCAL_OUT)) 161da177e4SLinus Torvalds 171da177e4SLinus Torvalds static struct ebt_entries initial_chains[] = 181da177e4SLinus Torvalds { 191da177e4SLinus Torvalds { 201da177e4SLinus Torvalds .name = "INPUT", 211da177e4SLinus Torvalds .policy = EBT_ACCEPT, 221da177e4SLinus Torvalds }, 231da177e4SLinus Torvalds { 241da177e4SLinus Torvalds .name = "FORWARD", 251da177e4SLinus Torvalds .policy = EBT_ACCEPT, 261da177e4SLinus Torvalds }, 271da177e4SLinus Torvalds { 281da177e4SLinus Torvalds .name = "OUTPUT", 291da177e4SLinus Torvalds .policy = EBT_ACCEPT, 301da177e4SLinus Torvalds }, 311da177e4SLinus Torvalds }; 321da177e4SLinus Torvalds 331e419cd9SAl Viro static struct ebt_replace_kernel initial_table = 341da177e4SLinus Torvalds { 351da177e4SLinus Torvalds .name = "filter", 361da177e4SLinus Torvalds .valid_hooks = FILTER_VALID_HOOKS, 371da177e4SLinus Torvalds .entries_size = 3 * sizeof(struct ebt_entries), 381da177e4SLinus Torvalds .hook_entry = { 391da177e4SLinus Torvalds [NF_BR_LOCAL_IN] = &initial_chains[0], 401da177e4SLinus Torvalds [NF_BR_FORWARD] = &initial_chains[1], 411da177e4SLinus Torvalds [NF_BR_LOCAL_OUT] = &initial_chains[2], 421da177e4SLinus Torvalds }, 431da177e4SLinus Torvalds .entries = (char *)initial_chains, 441da177e4SLinus Torvalds }; 451da177e4SLinus Torvalds 461da177e4SLinus Torvalds static int check(const struct ebt_table_info *info, unsigned int valid_hooks) 471da177e4SLinus Torvalds { 481da177e4SLinus Torvalds if (valid_hooks & ~FILTER_VALID_HOOKS) 491da177e4SLinus Torvalds return -EINVAL; 501da177e4SLinus Torvalds return 0; 511da177e4SLinus Torvalds } 521da177e4SLinus Torvalds 5335aad0ffSJan Engelhardt static const struct ebt_table frame_filter = 541da177e4SLinus Torvalds { 551da177e4SLinus Torvalds .name = "filter", 561da177e4SLinus Torvalds .table = &initial_table, 571da177e4SLinus Torvalds .valid_hooks = FILTER_VALID_HOOKS, 581da177e4SLinus Torvalds .check = check, 591da177e4SLinus Torvalds .me = THIS_MODULE, 601da177e4SLinus Torvalds }; 611da177e4SLinus Torvalds 621da177e4SLinus Torvalds static unsigned int 634aad1093SAlexey Dobriyan ebt_in_hook(unsigned int hook, struct sk_buff *skb, const struct net_device *in, 641da177e4SLinus Torvalds const struct net_device *out, int (*okfn)(struct sk_buff *)) 651da177e4SLinus Torvalds { 664aad1093SAlexey Dobriyan return ebt_do_table(hook, skb, in, out, dev_net(in)->xt.frame_filter); 674aad1093SAlexey Dobriyan } 684aad1093SAlexey Dobriyan 694aad1093SAlexey Dobriyan static unsigned int 704aad1093SAlexey Dobriyan ebt_out_hook(unsigned int hook, struct sk_buff *skb, const struct net_device *in, 714aad1093SAlexey Dobriyan const struct net_device *out, int (*okfn)(struct sk_buff *)) 724aad1093SAlexey Dobriyan { 734aad1093SAlexey Dobriyan return ebt_do_table(hook, skb, in, out, dev_net(out)->xt.frame_filter); 741da177e4SLinus Torvalds } 751da177e4SLinus Torvalds 761999414aSPatrick McHardy static struct nf_hook_ops ebt_ops_filter[] __read_mostly = { 771da177e4SLinus Torvalds { 784aad1093SAlexey Dobriyan .hook = ebt_in_hook, 791da177e4SLinus Torvalds .owner = THIS_MODULE, 8024c232d8SJan Engelhardt .pf = NFPROTO_BRIDGE, 811da177e4SLinus Torvalds .hooknum = NF_BR_LOCAL_IN, 821da177e4SLinus Torvalds .priority = NF_BR_PRI_FILTER_BRIDGED, 831da177e4SLinus Torvalds }, 841da177e4SLinus Torvalds { 854aad1093SAlexey Dobriyan .hook = ebt_in_hook, 861da177e4SLinus Torvalds .owner = THIS_MODULE, 8724c232d8SJan Engelhardt .pf = NFPROTO_BRIDGE, 881da177e4SLinus Torvalds .hooknum = NF_BR_FORWARD, 891da177e4SLinus Torvalds .priority = NF_BR_PRI_FILTER_BRIDGED, 901da177e4SLinus Torvalds }, 911da177e4SLinus Torvalds { 924aad1093SAlexey Dobriyan .hook = ebt_out_hook, 931da177e4SLinus Torvalds .owner = THIS_MODULE, 9424c232d8SJan Engelhardt .pf = NFPROTO_BRIDGE, 951da177e4SLinus Torvalds .hooknum = NF_BR_LOCAL_OUT, 961da177e4SLinus Torvalds .priority = NF_BR_PRI_FILTER_OTHER, 971da177e4SLinus Torvalds }, 981da177e4SLinus Torvalds }; 991da177e4SLinus Torvalds 1004aad1093SAlexey Dobriyan static int __net_init frame_filter_net_init(struct net *net) 1014aad1093SAlexey Dobriyan { 1024aad1093SAlexey Dobriyan net->xt.frame_filter = ebt_register_table(net, &frame_filter); 1038c6ffba0SRusty Russell return PTR_ERR_OR_ZERO(net->xt.frame_filter); 1044aad1093SAlexey Dobriyan } 1054aad1093SAlexey Dobriyan 1064aad1093SAlexey Dobriyan static void __net_exit frame_filter_net_exit(struct net *net) 1074aad1093SAlexey Dobriyan { 108f54e9367SAlexey Dobriyan ebt_unregister_table(net, net->xt.frame_filter); 1094aad1093SAlexey Dobriyan } 1104aad1093SAlexey Dobriyan 1114aad1093SAlexey Dobriyan static struct pernet_operations frame_filter_net_ops = { 1124aad1093SAlexey Dobriyan .init = frame_filter_net_init, 1134aad1093SAlexey Dobriyan .exit = frame_filter_net_exit, 1144aad1093SAlexey Dobriyan }; 1154aad1093SAlexey Dobriyan 11665b4b4e8SAndrew Morton static int __init ebtable_filter_init(void) 1171da177e4SLinus Torvalds { 118e40f51a3SAlexey Dobriyan int ret; 1191da177e4SLinus Torvalds 1204aad1093SAlexey Dobriyan ret = register_pernet_subsys(&frame_filter_net_ops); 1214aad1093SAlexey Dobriyan if (ret < 0) 1224aad1093SAlexey Dobriyan return ret; 123e40f51a3SAlexey Dobriyan ret = nf_register_hooks(ebt_ops_filter, ARRAY_SIZE(ebt_ops_filter)); 124e40f51a3SAlexey Dobriyan if (ret < 0) 1254aad1093SAlexey Dobriyan unregister_pernet_subsys(&frame_filter_net_ops); 1261da177e4SLinus Torvalds return ret; 1271da177e4SLinus Torvalds } 1281da177e4SLinus Torvalds 12965b4b4e8SAndrew Morton static void __exit ebtable_filter_fini(void) 1301da177e4SLinus Torvalds { 131e40f51a3SAlexey Dobriyan nf_unregister_hooks(ebt_ops_filter, ARRAY_SIZE(ebt_ops_filter)); 1324aad1093SAlexey Dobriyan unregister_pernet_subsys(&frame_filter_net_ops); 1331da177e4SLinus Torvalds } 1341da177e4SLinus Torvalds 13565b4b4e8SAndrew Morton module_init(ebtable_filter_init); 13665b4b4e8SAndrew Morton module_exit(ebtable_filter_fini); 1371da177e4SLinus Torvalds MODULE_LICENSE("GPL"); 138