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 331da177e4SLinus Torvalds static struct ebt_replace 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 531da177e4SLinus Torvalds static 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 .lock = RW_LOCK_UNLOCKED, 591da177e4SLinus Torvalds .check = check, 601da177e4SLinus Torvalds .me = THIS_MODULE, 611da177e4SLinus Torvalds }; 621da177e4SLinus Torvalds 631da177e4SLinus Torvalds static unsigned int 641da177e4SLinus Torvalds ebt_hook (unsigned int hook, struct sk_buff **pskb, const struct net_device *in, 651da177e4SLinus Torvalds const struct net_device *out, int (*okfn)(struct sk_buff *)) 661da177e4SLinus Torvalds { 671da177e4SLinus Torvalds return ebt_do_table(hook, pskb, in, out, &frame_filter); 681da177e4SLinus Torvalds } 691da177e4SLinus Torvalds 701da177e4SLinus Torvalds static struct nf_hook_ops ebt_ops_filter[] = { 711da177e4SLinus Torvalds { 721da177e4SLinus Torvalds .hook = ebt_hook, 731da177e4SLinus Torvalds .owner = THIS_MODULE, 741da177e4SLinus Torvalds .pf = PF_BRIDGE, 751da177e4SLinus Torvalds .hooknum = NF_BR_LOCAL_IN, 761da177e4SLinus Torvalds .priority = NF_BR_PRI_FILTER_BRIDGED, 771da177e4SLinus Torvalds }, 781da177e4SLinus Torvalds { 791da177e4SLinus Torvalds .hook = ebt_hook, 801da177e4SLinus Torvalds .owner = THIS_MODULE, 811da177e4SLinus Torvalds .pf = PF_BRIDGE, 821da177e4SLinus Torvalds .hooknum = NF_BR_FORWARD, 831da177e4SLinus Torvalds .priority = NF_BR_PRI_FILTER_BRIDGED, 841da177e4SLinus Torvalds }, 851da177e4SLinus Torvalds { 861da177e4SLinus Torvalds .hook = ebt_hook, 871da177e4SLinus Torvalds .owner = THIS_MODULE, 881da177e4SLinus Torvalds .pf = PF_BRIDGE, 891da177e4SLinus Torvalds .hooknum = NF_BR_LOCAL_OUT, 901da177e4SLinus Torvalds .priority = NF_BR_PRI_FILTER_OTHER, 911da177e4SLinus Torvalds }, 921da177e4SLinus Torvalds }; 931da177e4SLinus Torvalds 9465b4b4e8SAndrew Morton static int __init ebtable_filter_init(void) 951da177e4SLinus Torvalds { 961da177e4SLinus Torvalds int i, j, ret; 971da177e4SLinus Torvalds 981da177e4SLinus Torvalds ret = ebt_register_table(&frame_filter); 991da177e4SLinus Torvalds if (ret < 0) 1001da177e4SLinus Torvalds return ret; 1011da177e4SLinus Torvalds for (i = 0; i < ARRAY_SIZE(ebt_ops_filter); i++) 1021da177e4SLinus Torvalds if ((ret = nf_register_hook(&ebt_ops_filter[i])) < 0) 1031da177e4SLinus Torvalds goto cleanup; 1041da177e4SLinus Torvalds return ret; 1051da177e4SLinus Torvalds cleanup: 1061da177e4SLinus Torvalds for (j = 0; j < i; j++) 1071da177e4SLinus Torvalds nf_unregister_hook(&ebt_ops_filter[j]); 1081da177e4SLinus Torvalds ebt_unregister_table(&frame_filter); 1091da177e4SLinus Torvalds return ret; 1101da177e4SLinus Torvalds } 1111da177e4SLinus Torvalds 11265b4b4e8SAndrew Morton static void __exit ebtable_filter_fini(void) 1131da177e4SLinus Torvalds { 1141da177e4SLinus Torvalds int i; 1151da177e4SLinus Torvalds 1161da177e4SLinus Torvalds for (i = 0; i < ARRAY_SIZE(ebt_ops_filter); i++) 1171da177e4SLinus Torvalds nf_unregister_hook(&ebt_ops_filter[i]); 1181da177e4SLinus Torvalds ebt_unregister_table(&frame_filter); 1191da177e4SLinus Torvalds } 1201da177e4SLinus Torvalds 12165b4b4e8SAndrew Morton module_init(ebtable_filter_init); 12265b4b4e8SAndrew Morton module_exit(ebtable_filter_fini); 1231da177e4SLinus Torvalds MODULE_LICENSE("GPL"); 124