ebtable_broute.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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. #include <linux/netfilter_bridge/ebtables.h>
  14. #include <linux/module.h>
  15. #include <linux/if_bridge.h>
  16. /* EBT_ACCEPT means the frame will be bridged
  17. * EBT_DROP means the frame will be routed
  18. */
  19. static struct ebt_entries initial_chain = {
  20. .name = "BROUTING",
  21. .policy = EBT_ACCEPT,
  22. };
  23. static struct ebt_replace_kernel initial_table = {
  24. .name = "broute",
  25. .valid_hooks = 1 << NF_BR_BROUTING,
  26. .entries_size = sizeof(struct ebt_entries),
  27. .hook_entry = {
  28. [NF_BR_BROUTING] = &initial_chain,
  29. },
  30. .entries = (char *)&initial_chain,
  31. };
  32. static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
  33. {
  34. if (valid_hooks & ~(1 << NF_BR_BROUTING))
  35. return -EINVAL;
  36. return 0;
  37. }
  38. static const struct ebt_table broute_table = {
  39. .name = "broute",
  40. .table = &initial_table,
  41. .valid_hooks = 1 << NF_BR_BROUTING,
  42. .check = check,
  43. .me = THIS_MODULE,
  44. };
  45. static int ebt_broute(struct sk_buff *skb)
  46. {
  47. struct nf_hook_state state;
  48. int ret;
  49. nf_hook_state_init(&state, NULL, NF_BR_BROUTING, INT_MIN,
  50. NFPROTO_BRIDGE, skb->dev, NULL, NULL,
  51. dev_net(skb->dev), NULL);
  52. ret = ebt_do_table(skb, &state, state.net->xt.broute_table);
  53. if (ret == NF_DROP)
  54. return 1; /* route it */
  55. return 0; /* bridge it */
  56. }
  57. static int __net_init broute_net_init(struct net *net)
  58. {
  59. net->xt.broute_table = ebt_register_table(net, &broute_table);
  60. return PTR_ERR_OR_ZERO(net->xt.broute_table);
  61. }
  62. static void __net_exit broute_net_exit(struct net *net)
  63. {
  64. ebt_unregister_table(net, net->xt.broute_table);
  65. }
  66. static struct pernet_operations broute_net_ops = {
  67. .init = broute_net_init,
  68. .exit = broute_net_exit,
  69. };
  70. static int __init ebtable_broute_init(void)
  71. {
  72. int ret;
  73. ret = register_pernet_subsys(&broute_net_ops);
  74. if (ret < 0)
  75. return ret;
  76. /* see br_input.c */
  77. RCU_INIT_POINTER(br_should_route_hook,
  78. (br_should_route_hook_t *)ebt_broute);
  79. return 0;
  80. }
  81. static void __exit ebtable_broute_fini(void)
  82. {
  83. RCU_INIT_POINTER(br_should_route_hook, NULL);
  84. synchronize_net();
  85. unregister_pernet_subsys(&broute_net_ops);
  86. }
  87. module_init(ebtable_broute_init);
  88. module_exit(ebtable_broute_fini);
  89. MODULE_LICENSE("GPL");