xt_connmark.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. * xt_connmark - Netfilter module to operate on connection marks
  3. *
  4. * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
  5. * by Henrik Nordstrom <hno@marasystems.com>
  6. * Copyright © CC Computer Consultants GmbH, 2007 - 2008
  7. * Jan Engelhardt <jengelh@medozas.de>
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, see <http://www.gnu.org/licenses/>.
  21. */
  22. #include <linux/module.h>
  23. #include <linux/skbuff.h>
  24. #include <net/netfilter/nf_conntrack.h>
  25. #include <net/netfilter/nf_conntrack_ecache.h>
  26. #include <linux/netfilter/x_tables.h>
  27. #include <linux/netfilter/xt_connmark.h>
  28. MODULE_AUTHOR("Henrik Nordstrom <hno@marasystems.com>");
  29. MODULE_DESCRIPTION("Xtables: connection mark operations");
  30. MODULE_LICENSE("GPL");
  31. MODULE_ALIAS("ipt_CONNMARK");
  32. MODULE_ALIAS("ip6t_CONNMARK");
  33. MODULE_ALIAS("ipt_connmark");
  34. MODULE_ALIAS("ip6t_connmark");
  35. static unsigned int
  36. connmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
  37. {
  38. const struct xt_connmark_tginfo1 *info = par->targinfo;
  39. enum ip_conntrack_info ctinfo;
  40. struct nf_conn *ct;
  41. u_int32_t newmark;
  42. ct = nf_ct_get(skb, &ctinfo);
  43. if (ct == NULL)
  44. return XT_CONTINUE;
  45. switch (info->mode) {
  46. case XT_CONNMARK_SET:
  47. newmark = (ct->mark & ~info->ctmask) ^ info->ctmark;
  48. if (ct->mark != newmark) {
  49. ct->mark = newmark;
  50. nf_conntrack_event_cache(IPCT_MARK, ct);
  51. }
  52. break;
  53. case XT_CONNMARK_SAVE:
  54. newmark = (ct->mark & ~info->ctmask) ^
  55. (skb->mark & info->nfmask);
  56. if (ct->mark != newmark) {
  57. ct->mark = newmark;
  58. nf_conntrack_event_cache(IPCT_MARK, ct);
  59. }
  60. break;
  61. case XT_CONNMARK_RESTORE:
  62. newmark = (skb->mark & ~info->nfmask) ^
  63. (ct->mark & info->ctmask);
  64. skb->mark = newmark;
  65. break;
  66. }
  67. return XT_CONTINUE;
  68. }
  69. static int connmark_tg_check(const struct xt_tgchk_param *par)
  70. {
  71. int ret;
  72. ret = nf_ct_l3proto_try_module_get(par->family);
  73. if (ret < 0)
  74. pr_info("cannot load conntrack support for proto=%u\n",
  75. par->family);
  76. return ret;
  77. }
  78. static void connmark_tg_destroy(const struct xt_tgdtor_param *par)
  79. {
  80. nf_ct_l3proto_module_put(par->family);
  81. }
  82. static bool
  83. connmark_mt(const struct sk_buff *skb, struct xt_action_param *par)
  84. {
  85. const struct xt_connmark_mtinfo1 *info = par->matchinfo;
  86. enum ip_conntrack_info ctinfo;
  87. const struct nf_conn *ct;
  88. ct = nf_ct_get(skb, &ctinfo);
  89. if (ct == NULL)
  90. return false;
  91. return ((ct->mark & info->mask) == info->mark) ^ info->invert;
  92. }
  93. static int connmark_mt_check(const struct xt_mtchk_param *par)
  94. {
  95. int ret;
  96. ret = nf_ct_l3proto_try_module_get(par->family);
  97. if (ret < 0)
  98. pr_info("cannot load conntrack support for proto=%u\n",
  99. par->family);
  100. return ret;
  101. }
  102. static void connmark_mt_destroy(const struct xt_mtdtor_param *par)
  103. {
  104. nf_ct_l3proto_module_put(par->family);
  105. }
  106. static struct xt_target connmark_tg_reg __read_mostly = {
  107. .name = "CONNMARK",
  108. .revision = 1,
  109. .family = NFPROTO_UNSPEC,
  110. .checkentry = connmark_tg_check,
  111. .target = connmark_tg,
  112. .targetsize = sizeof(struct xt_connmark_tginfo1),
  113. .destroy = connmark_tg_destroy,
  114. .me = THIS_MODULE,
  115. };
  116. static struct xt_match connmark_mt_reg __read_mostly = {
  117. .name = "connmark",
  118. .revision = 1,
  119. .family = NFPROTO_UNSPEC,
  120. .checkentry = connmark_mt_check,
  121. .match = connmark_mt,
  122. .matchsize = sizeof(struct xt_connmark_mtinfo1),
  123. .destroy = connmark_mt_destroy,
  124. .me = THIS_MODULE,
  125. };
  126. static int __init connmark_mt_init(void)
  127. {
  128. int ret;
  129. ret = xt_register_target(&connmark_tg_reg);
  130. if (ret < 0)
  131. return ret;
  132. ret = xt_register_match(&connmark_mt_reg);
  133. if (ret < 0) {
  134. xt_unregister_target(&connmark_tg_reg);
  135. return ret;
  136. }
  137. return 0;
  138. }
  139. static void __exit connmark_mt_exit(void)
  140. {
  141. xt_unregister_match(&connmark_mt_reg);
  142. xt_unregister_target(&connmark_tg_reg);
  143. }
  144. module_init(connmark_mt_init);
  145. module_exit(connmark_mt_exit);