1/* 2 * ebtable_broute 3 * 4 * Authors: 5 * Bart De Schuymer <bdschuym@pandora.be> 6 * 7 * April, 2002 8 * 9 * This table lets you choose between routing and bridging for frames 10 * entering on a bridge enslaved nic. This table is traversed before any 11 * other ebtables table. See net/bridge/br_input.c. 12 */ 13 14#include <linux/netfilter_bridge/ebtables.h> 15#include <linux/module.h> 16#include <linux/if_bridge.h> 17 18/* EBT_ACCEPT means the frame will be bridged 19 * EBT_DROP means the frame will be routed 20 */ 21static struct ebt_entries initial_chain = { 22 .name = "BROUTING", 23 .policy = EBT_ACCEPT, 24}; 25 26static struct ebt_replace_kernel initial_table = 27{ 28 .name = "broute", 29 .valid_hooks = 1 << NF_BR_BROUTING, 30 .entries_size = sizeof(struct ebt_entries), 31 .hook_entry = { 32 [NF_BR_BROUTING] = &initial_chain, 33 }, 34 .entries = (char *)&initial_chain, 35}; 36 37static int check(const struct ebt_table_info *info, unsigned int valid_hooks) 38{ 39 if (valid_hooks & ~(1 << NF_BR_BROUTING)) 40 return -EINVAL; 41 return 0; 42} 43 44static struct ebt_table broute_table = 45{ 46 .name = "broute", 47 .table = &initial_table, 48 .valid_hooks = 1 << NF_BR_BROUTING, 49 .lock = RW_LOCK_UNLOCKED, 50 .check = check, 51 .me = THIS_MODULE, 52}; 53 54static int ebt_broute(struct sk_buff **pskb) 55{ 56 int ret; 57 58 ret = ebt_do_table(NF_BR_BROUTING, pskb, (*pskb)->dev, NULL, 59 &broute_table); 60 if (ret == NF_DROP) 61 return 1; /* route it */ 62 return 0; /* bridge it */ 63} 64 65static int __init ebtable_broute_init(void) 66{ 67 int ret; 68 69 ret = ebt_register_table(&broute_table); 70 if (ret < 0) 71 return ret; 72 /* see br_input.c */ 73 br_should_route_hook = ebt_broute; 74 return ret; 75} 76 77static void __exit ebtable_broute_fini(void) 78{ 79 br_should_route_hook = NULL; 80 synchronize_net(); 81 ebt_unregister_table(&broute_table); 82} 83 84module_init(ebtable_broute_init); 85module_exit(ebtable_broute_fini); 86MODULE_LICENSE("GPL"); 87