ebt_mark.c 2.6 KB

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