/* * ebtable_broute * * Authors: * Bart De Schuymer * * April, 2002 * * This table lets you choose between routing and bridging for frames * entering on a bridge enslaved nic. This table is traversed before any * other ebtables table. See net/bridge/br_input.c. */ #include #include #include /* EBT_ACCEPT means the frame will be bridged * EBT_DROP means the frame will be routed */ static struct ebt_entries initial_chain = { .name = "BROUTING", .policy = EBT_ACCEPT, }; static struct ebt_replace initial_table = { .name = "broute", .valid_hooks = 1 << NF_BR_BROUTING, .entries_size = sizeof(struct ebt_entries), .hook_entry = { [NF_BR_BROUTING] = &initial_chain, }, .entries = (char *)&initial_chain, }; static int check(const struct ebt_table_info *info, unsigned int valid_hooks) { if (valid_hooks & ~(1 << NF_BR_BROUTING)) return -EINVAL; return 0; } static struct ebt_table broute_table = { .name = "broute", .table = &initial_table, .valid_hooks = 1 << NF_BR_BROUTING, .lock = RW_LOCK_UNLOCKED, .check = check, .me = THIS_MODULE, }; static int ebt_broute(struct sk_buff **pskb) { int ret; ret = ebt_do_table(NF_BR_BROUTING, pskb, (*pskb)->dev, NULL, &broute_table); if (ret == NF_DROP) return 1; /* route it */ return 0; /* bridge it */ } static int __init init(void) { int ret; ret = ebt_register_table(&broute_table); if (ret < 0) return ret; /* see br_input.c */ br_should_route_hook = ebt_broute; return ret; } static void __exit fini(void) { br_should_route_hook = NULL; synchronize_net(); ebt_unregister_table(&broute_table); } module_init(init); module_exit(fini); MODULE_LICENSE("GPL");