ebt_redirect.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * ebt_redirect
  4. *
  5. * Authors:
  6. * Bart De Schuymer <bdschuym@pandora.be>
  7. *
  8. * April, 2002
  9. *
  10. */
  11. #include <linux/module.h>
  12. #include <net/sock.h>
  13. #include "../br_private.h"
  14. #include <linux/netfilter.h>
  15. #include <linux/netfilter/x_tables.h>
  16. #include <linux/netfilter_bridge/ebtables.h>
  17. #include <linux/netfilter_bridge/ebt_redirect.h>
  18. static unsigned int
  19. ebt_redirect_tg(struct sk_buff *skb, const struct xt_action_param *par)
  20. {
  21. const struct ebt_redirect_info *info = par->targinfo;
  22. if (skb_ensure_writable(skb, 0))
  23. return EBT_DROP;
  24. if (xt_hooknum(par) != NF_BR_BROUTING)
  25. /* rcu_read_lock()ed by nf_hook_thresh */
  26. ether_addr_copy(eth_hdr(skb)->h_dest,
  27. br_port_get_rcu(xt_in(par))->br->dev->dev_addr);
  28. else
  29. ether_addr_copy(eth_hdr(skb)->h_dest, xt_in(par)->dev_addr);
  30. skb->pkt_type = PACKET_HOST;
  31. return info->target;
  32. }
  33. static int ebt_redirect_tg_check(const struct xt_tgchk_param *par)
  34. {
  35. const struct ebt_redirect_info *info = par->targinfo;
  36. unsigned int hook_mask;
  37. if (BASE_CHAIN && info->target == EBT_RETURN)
  38. return -EINVAL;
  39. hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS);
  40. if ((strcmp(par->table, "nat") != 0 ||
  41. hook_mask & ~(1 << NF_BR_PRE_ROUTING)) &&
  42. (strcmp(par->table, "broute") != 0 ||
  43. hook_mask & ~(1 << NF_BR_BROUTING)))
  44. return -EINVAL;
  45. if (ebt_invalid_target(info->target))
  46. return -EINVAL;
  47. return 0;
  48. }
  49. static struct xt_target ebt_redirect_tg_reg __read_mostly = {
  50. .name = "redirect",
  51. .revision = 0,
  52. .family = NFPROTO_BRIDGE,
  53. .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_PRE_ROUTING) |
  54. (1 << NF_BR_BROUTING),
  55. .target = ebt_redirect_tg,
  56. .checkentry = ebt_redirect_tg_check,
  57. .targetsize = sizeof(struct ebt_redirect_info),
  58. .me = THIS_MODULE,
  59. };
  60. static int __init ebt_redirect_init(void)
  61. {
  62. return xt_register_target(&ebt_redirect_tg_reg);
  63. }
  64. static void __exit ebt_redirect_fini(void)
  65. {
  66. xt_unregister_target(&ebt_redirect_tg_reg);
  67. }
  68. module_init(ebt_redirect_init);
  69. module_exit(ebt_redirect_fini);
  70. MODULE_DESCRIPTION("Ebtables: Packet redirection to localhost");
  71. MODULE_LICENSE("GPL");