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 1797ad8b53Stanxiaojun static struct ebt_entries initial_chains[] = { 181da177e4SLinus Torvalds { 191da177e4SLinus Torvalds .name = "INPUT", 201da177e4SLinus Torvalds .policy = EBT_ACCEPT, 211da177e4SLinus Torvalds }, 221da177e4SLinus Torvalds { 231da177e4SLinus Torvalds .name = "FORWARD", 241da177e4SLinus Torvalds .policy = EBT_ACCEPT, 251da177e4SLinus Torvalds }, 261da177e4SLinus Torvalds { 271da177e4SLinus Torvalds .name = "OUTPUT", 281da177e4SLinus Torvalds .policy = EBT_ACCEPT, 291da177e4SLinus Torvalds }, 301da177e4SLinus Torvalds }; 311da177e4SLinus Torvalds 3297ad8b53Stanxiaojun static struct ebt_replace_kernel initial_table = { 331da177e4SLinus Torvalds .name = "filter", 341da177e4SLinus Torvalds .valid_hooks = FILTER_VALID_HOOKS, 351da177e4SLinus Torvalds .entries_size = 3 * sizeof(struct ebt_entries), 361da177e4SLinus Torvalds .hook_entry = { 371da177e4SLinus Torvalds [NF_BR_LOCAL_IN] = &initial_chains[0], 381da177e4SLinus Torvalds [NF_BR_FORWARD] = &initial_chains[1], 391da177e4SLinus Torvalds [NF_BR_LOCAL_OUT] = &initial_chains[2], 401da177e4SLinus Torvalds }, 411da177e4SLinus Torvalds .entries = (char *)initial_chains, 421da177e4SLinus Torvalds }; 431da177e4SLinus Torvalds 441da177e4SLinus Torvalds static int check(const struct ebt_table_info *info, unsigned int valid_hooks) 451da177e4SLinus Torvalds { 461da177e4SLinus Torvalds if (valid_hooks & ~FILTER_VALID_HOOKS) 471da177e4SLinus Torvalds return -EINVAL; 481da177e4SLinus Torvalds return 0; 491da177e4SLinus Torvalds } 501da177e4SLinus Torvalds 5197ad8b53Stanxiaojun static const struct ebt_table frame_filter = { 521da177e4SLinus Torvalds .name = "filter", 531da177e4SLinus Torvalds .table = &initial_table, 541da177e4SLinus Torvalds .valid_hooks = FILTER_VALID_HOOKS, 551da177e4SLinus Torvalds .check = check, 561da177e4SLinus Torvalds .me = THIS_MODULE, 571da177e4SLinus Torvalds }; 581da177e4SLinus Torvalds 591da177e4SLinus Torvalds static unsigned int 60795aa6efSPatrick McHardy ebt_in_hook(const struct nf_hook_ops *ops, struct sk_buff *skb, 61795aa6efSPatrick McHardy const struct net_device *in, const struct net_device *out, 62795aa6efSPatrick McHardy int (*okfn)(struct sk_buff *)) 631da177e4SLinus Torvalds { 64795aa6efSPatrick McHardy return ebt_do_table(ops->hooknum, skb, in, out, 65795aa6efSPatrick McHardy dev_net(in)->xt.frame_filter); 664aad1093SAlexey Dobriyan } 674aad1093SAlexey Dobriyan 684aad1093SAlexey Dobriyan static unsigned int 69795aa6efSPatrick McHardy ebt_out_hook(const struct nf_hook_ops *ops, struct sk_buff *skb, 70795aa6efSPatrick McHardy const struct net_device *in, const struct net_device *out, 71795aa6efSPatrick McHardy int (*okfn)(struct sk_buff *)) 724aad1093SAlexey Dobriyan { 73795aa6efSPatrick McHardy return ebt_do_table(ops->hooknum, skb, in, out, 74795aa6efSPatrick McHardy dev_net(out)->xt.frame_filter); 751da177e4SLinus Torvalds } 761da177e4SLinus Torvalds 771999414aSPatrick McHardy static struct nf_hook_ops ebt_ops_filter[] __read_mostly = { 781da177e4SLinus Torvalds { 794aad1093SAlexey Dobriyan .hook = ebt_in_hook, 801da177e4SLinus Torvalds .owner = THIS_MODULE, 8124c232d8SJan Engelhardt .pf = NFPROTO_BRIDGE, 821da177e4SLinus Torvalds .hooknum = NF_BR_LOCAL_IN, 831da177e4SLinus Torvalds .priority = NF_BR_PRI_FILTER_BRIDGED, 841da177e4SLinus Torvalds }, 851da177e4SLinus Torvalds { 864aad1093SAlexey Dobriyan .hook = ebt_in_hook, 871da177e4SLinus Torvalds .owner = THIS_MODULE, 8824c232d8SJan Engelhardt .pf = NFPROTO_BRIDGE, 891da177e4SLinus Torvalds .hooknum = NF_BR_FORWARD, 901da177e4SLinus Torvalds .priority = NF_BR_PRI_FILTER_BRIDGED, 911da177e4SLinus Torvalds }, 921da177e4SLinus Torvalds { 934aad1093SAlexey Dobriyan .hook = ebt_out_hook, 941da177e4SLinus Torvalds .owner = THIS_MODULE, 9524c232d8SJan Engelhardt .pf = NFPROTO_BRIDGE, 961da177e4SLinus Torvalds .hooknum = NF_BR_LOCAL_OUT, 971da177e4SLinus Torvalds .priority = NF_BR_PRI_FILTER_OTHER, 981da177e4SLinus Torvalds }, 991da177e4SLinus Torvalds }; 1001da177e4SLinus Torvalds 1014aad1093SAlexey Dobriyan static int __net_init frame_filter_net_init(struct net *net) 1024aad1093SAlexey Dobriyan { 1034aad1093SAlexey Dobriyan net->xt.frame_filter = ebt_register_table(net, &frame_filter); 1048c6ffba0SRusty Russell return PTR_ERR_OR_ZERO(net->xt.frame_filter); 1054aad1093SAlexey Dobriyan } 1064aad1093SAlexey Dobriyan 1074aad1093SAlexey Dobriyan static void __net_exit frame_filter_net_exit(struct net *net) 1084aad1093SAlexey Dobriyan { 109f54e9367SAlexey Dobriyan ebt_unregister_table(net, net->xt.frame_filter); 1104aad1093SAlexey Dobriyan } 1114aad1093SAlexey Dobriyan 1124aad1093SAlexey Dobriyan static struct pernet_operations frame_filter_net_ops = { 1134aad1093SAlexey Dobriyan .init = frame_filter_net_init, 1144aad1093SAlexey Dobriyan .exit = frame_filter_net_exit, 1154aad1093SAlexey Dobriyan }; 1164aad1093SAlexey Dobriyan 11765b4b4e8SAndrew Morton static int __init ebtable_filter_init(void) 1181da177e4SLinus Torvalds { 119e40f51a3SAlexey Dobriyan int ret; 1201da177e4SLinus Torvalds 1214aad1093SAlexey Dobriyan ret = register_pernet_subsys(&frame_filter_net_ops); 1224aad1093SAlexey Dobriyan if (ret < 0) 1234aad1093SAlexey Dobriyan return ret; 124e40f51a3SAlexey Dobriyan ret = nf_register_hooks(ebt_ops_filter, ARRAY_SIZE(ebt_ops_filter)); 125e40f51a3SAlexey Dobriyan if (ret < 0) 1264aad1093SAlexey Dobriyan unregister_pernet_subsys(&frame_filter_net_ops); 1271da177e4SLinus Torvalds return ret; 1281da177e4SLinus Torvalds } 1291da177e4SLinus Torvalds 13065b4b4e8SAndrew Morton static void __exit ebtable_filter_fini(void) 1311da177e4SLinus Torvalds { 132e40f51a3SAlexey Dobriyan nf_unregister_hooks(ebt_ops_filter, ARRAY_SIZE(ebt_ops_filter)); 1334aad1093SAlexey Dobriyan unregister_pernet_subsys(&frame_filter_net_ops); 1341da177e4SLinus Torvalds } 1351da177e4SLinus Torvalds 13665b4b4e8SAndrew Morton module_init(ebtable_filter_init); 13765b4b4e8SAndrew Morton module_exit(ebtable_filter_fini); 1381da177e4SLinus Torvalds MODULE_LICENSE("GPL"); 139