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 63795aa6efSPatrick McHardy ebt_in_hook(const struct nf_hook_ops *ops, struct sk_buff *skb, 64795aa6efSPatrick McHardy const struct net_device *in, const struct net_device *out, 65795aa6efSPatrick McHardy int (*okfn)(struct sk_buff *)) 661da177e4SLinus Torvalds { 67795aa6efSPatrick McHardy return ebt_do_table(ops->hooknum, skb, in, out, 68795aa6efSPatrick McHardy dev_net(in)->xt.frame_filter); 694aad1093SAlexey Dobriyan } 704aad1093SAlexey Dobriyan 714aad1093SAlexey Dobriyan static unsigned int 72795aa6efSPatrick McHardy ebt_out_hook(const struct nf_hook_ops *ops, struct sk_buff *skb, 73795aa6efSPatrick McHardy const struct net_device *in, const struct net_device *out, 74795aa6efSPatrick McHardy int (*okfn)(struct sk_buff *)) 754aad1093SAlexey Dobriyan { 76795aa6efSPatrick McHardy return ebt_do_table(ops->hooknum, skb, in, out, 77795aa6efSPatrick McHardy dev_net(out)->xt.frame_filter); 781da177e4SLinus Torvalds } 791da177e4SLinus Torvalds 801999414aSPatrick McHardy static struct nf_hook_ops ebt_ops_filter[] __read_mostly = { 811da177e4SLinus Torvalds { 824aad1093SAlexey Dobriyan .hook = ebt_in_hook, 831da177e4SLinus Torvalds .owner = THIS_MODULE, 8424c232d8SJan Engelhardt .pf = NFPROTO_BRIDGE, 851da177e4SLinus Torvalds .hooknum = NF_BR_LOCAL_IN, 861da177e4SLinus Torvalds .priority = NF_BR_PRI_FILTER_BRIDGED, 871da177e4SLinus Torvalds }, 881da177e4SLinus Torvalds { 894aad1093SAlexey Dobriyan .hook = ebt_in_hook, 901da177e4SLinus Torvalds .owner = THIS_MODULE, 9124c232d8SJan Engelhardt .pf = NFPROTO_BRIDGE, 921da177e4SLinus Torvalds .hooknum = NF_BR_FORWARD, 931da177e4SLinus Torvalds .priority = NF_BR_PRI_FILTER_BRIDGED, 941da177e4SLinus Torvalds }, 951da177e4SLinus Torvalds { 964aad1093SAlexey Dobriyan .hook = ebt_out_hook, 971da177e4SLinus Torvalds .owner = THIS_MODULE, 9824c232d8SJan Engelhardt .pf = NFPROTO_BRIDGE, 991da177e4SLinus Torvalds .hooknum = NF_BR_LOCAL_OUT, 1001da177e4SLinus Torvalds .priority = NF_BR_PRI_FILTER_OTHER, 1011da177e4SLinus Torvalds }, 1021da177e4SLinus Torvalds }; 1031da177e4SLinus Torvalds 1044aad1093SAlexey Dobriyan static int __net_init frame_filter_net_init(struct net *net) 1054aad1093SAlexey Dobriyan { 1064aad1093SAlexey Dobriyan net->xt.frame_filter = ebt_register_table(net, &frame_filter); 1078c6ffba0SRusty Russell return PTR_ERR_OR_ZERO(net->xt.frame_filter); 1084aad1093SAlexey Dobriyan } 1094aad1093SAlexey Dobriyan 1104aad1093SAlexey Dobriyan static void __net_exit frame_filter_net_exit(struct net *net) 1114aad1093SAlexey Dobriyan { 112f54e9367SAlexey Dobriyan ebt_unregister_table(net, net->xt.frame_filter); 1134aad1093SAlexey Dobriyan } 1144aad1093SAlexey Dobriyan 1154aad1093SAlexey Dobriyan static struct pernet_operations frame_filter_net_ops = { 1164aad1093SAlexey Dobriyan .init = frame_filter_net_init, 1174aad1093SAlexey Dobriyan .exit = frame_filter_net_exit, 1184aad1093SAlexey Dobriyan }; 1194aad1093SAlexey Dobriyan 12065b4b4e8SAndrew Morton static int __init ebtable_filter_init(void) 1211da177e4SLinus Torvalds { 122e40f51a3SAlexey Dobriyan int ret; 1231da177e4SLinus Torvalds 1244aad1093SAlexey Dobriyan ret = register_pernet_subsys(&frame_filter_net_ops); 1254aad1093SAlexey Dobriyan if (ret < 0) 1264aad1093SAlexey Dobriyan return ret; 127e40f51a3SAlexey Dobriyan ret = nf_register_hooks(ebt_ops_filter, ARRAY_SIZE(ebt_ops_filter)); 128e40f51a3SAlexey Dobriyan if (ret < 0) 1294aad1093SAlexey Dobriyan unregister_pernet_subsys(&frame_filter_net_ops); 1301da177e4SLinus Torvalds return ret; 1311da177e4SLinus Torvalds } 1321da177e4SLinus Torvalds 13365b4b4e8SAndrew Morton static void __exit ebtable_filter_fini(void) 1341da177e4SLinus Torvalds { 135e40f51a3SAlexey Dobriyan nf_unregister_hooks(ebt_ops_filter, ARRAY_SIZE(ebt_ops_filter)); 1364aad1093SAlexey Dobriyan unregister_pernet_subsys(&frame_filter_net_ops); 1371da177e4SLinus Torvalds } 1381da177e4SLinus Torvalds 13965b4b4e8SAndrew Morton module_init(ebtable_filter_init); 14065b4b4e8SAndrew Morton module_exit(ebtable_filter_fini); 1411da177e4SLinus Torvalds MODULE_LICENSE("GPL"); 142