ebt_mark.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * ebt_mark
  4. *
  5. * Authors:
  6. * Bart De Schuymer <bdschuym@pandora.be>
  7. *
  8. * July, 2002
  9. *
  10. */
  11. /* The mark target can be used in any chain,
  12. * I believe adding a mangle table just for marking is total overkill.
  13. * Marking a frame doesn't really change anything in the frame anyway.
  14. */
  15. #include <linux/module.h>
  16. #include <linux/netfilter/x_tables.h>
  17. #include <linux/netfilter_bridge/ebtables.h>
  18. #include <linux/netfilter_bridge/ebt_mark_t.h>
  19. static unsigned int
  20. ebt_mark_tg(struct sk_buff *skb, const struct xt_action_param *par)
  21. {
  22. const struct ebt_mark_t_info *info = par->targinfo;
  23. int action = info->target & -16;
  24. if (action == MARK_SET_VALUE)
  25. skb->mark = info->mark;
  26. else if (action == MARK_OR_VALUE)
  27. skb->mark |= info->mark;
  28. else if (action == MARK_AND_VALUE)
  29. skb->mark &= info->mark;
  30. else
  31. skb->mark ^= info->mark;
  32. return info->target | ~EBT_VERDICT_BITS;
  33. }
  34. static int ebt_mark_tg_check(const struct xt_tgchk_param *par)
  35. {
  36. const struct ebt_mark_t_info *info = par->targinfo;
  37. int tmp;
  38. tmp = info->target | ~EBT_VERDICT_BITS;
  39. if (BASE_CHAIN && tmp == EBT_RETURN)
  40. return -EINVAL;
  41. if (ebt_invalid_target(tmp))
  42. return -EINVAL;
  43. tmp = info->target & ~EBT_VERDICT_BITS;
  44. if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE &&
  45. tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE)
  46. return -EINVAL;
  47. return 0;
  48. }
  49. #ifdef CONFIG_COMPAT
  50. struct compat_ebt_mark_t_info {
  51. compat_ulong_t mark;
  52. compat_uint_t target;
  53. };
  54. static void mark_tg_compat_from_user(void *dst, const void *src)
  55. {
  56. const struct compat_ebt_mark_t_info *user = src;
  57. struct ebt_mark_t_info *kern = dst;
  58. kern->mark = user->mark;
  59. kern->target = user->target;
  60. }
  61. static int mark_tg_compat_to_user(void __user *dst, const void *src)
  62. {
  63. struct compat_ebt_mark_t_info __user *user = dst;
  64. const struct ebt_mark_t_info *kern = src;
  65. if (put_user(kern->mark, &user->mark) ||
  66. put_user(kern->target, &user->target))
  67. return -EFAULT;
  68. return 0;
  69. }
  70. #endif
  71. static struct xt_target ebt_mark_tg_reg __read_mostly = {
  72. .name = "mark",
  73. .revision = 0,
  74. .family = NFPROTO_BRIDGE,
  75. .target = ebt_mark_tg,
  76. .checkentry = ebt_mark_tg_check,
  77. .targetsize = sizeof(struct ebt_mark_t_info),
  78. #ifdef CONFIG_COMPAT
  79. .compatsize = sizeof(struct compat_ebt_mark_t_info),
  80. .compat_from_user = mark_tg_compat_from_user,
  81. .compat_to_user = mark_tg_compat_to_user,
  82. #endif
  83. .me = THIS_MODULE,
  84. };
  85. static int __init ebt_mark_init(void)
  86. {
  87. return xt_register_target(&ebt_mark_tg_reg);
  88. }
  89. static void __exit ebt_mark_fini(void)
  90. {
  91. xt_unregister_target(&ebt_mark_tg_reg);
  92. }
  93. module_init(ebt_mark_init);
  94. module_exit(ebt_mark_fini);
  95. MODULE_DESCRIPTION("Ebtables: Packet mark modification");
  96. MODULE_LICENSE("GPL");