xt_connmark.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22. */
  23. #include <linux/module.h>
  24. #include <linux/skbuff.h>
  25. #include <net/netfilter/nf_conntrack.h>
  26. #include <net/netfilter/nf_conntrack_ecache.h>
  27. #include <linux/netfilter/x_tables.h>
  28. #include <linux/netfilter/xt_connmark.h>
  29. MODULE_AUTHOR("Henrik Nordstrom <hno@marasystems.com>");
  30. MODULE_DESCRIPTION("Xtables: connection mark operations");
  31. MODULE_LICENSE("GPL");
  32. MODULE_ALIAS("ipt_CONNMARK");
  33. MODULE_ALIAS("ip6t_CONNMARK");
  34. MODULE_ALIAS("ipt_connmark");
  35. MODULE_ALIAS("ip6t_connmark");
  36. static unsigned int
  37. connmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
  38. {
  39. const struct xt_connmark_tginfo1 *info = par->targinfo;
  40. enum ip_conntrack_info ctinfo;
  41. struct nf_conn *ct;
  42. u_int32_t newmark;
  43. ct = nf_ct_get(skb, &ctinfo);
  44. if (ct == NULL)
  45. return XT_CONTINUE;
  46. switch (info->mode) {
  47. case XT_CONNMARK_SET:
  48. newmark = (ct->mark & ~info->ctmask) ^ info->ctmark;
  49. if (ct->mark != newmark) {
  50. ct->mark = newmark;
  51. nf_conntrack_event_cache(IPCT_MARK, ct);
  52. }
  53. break;
  54. case XT_CONNMARK_SAVE:
  55. newmark = (ct->mark & ~info->ctmask) ^
  56. (skb->mark & info->nfmask);
  57. if (ct->mark != newmark) {
  58. ct->mark = newmark;
  59. nf_conntrack_event_cache(IPCT_MARK, ct);
  60. }
  61. break;
  62. case XT_CONNMARK_RESTORE:
  63. newmark = (skb->mark & ~info->nfmask) ^
  64. (ct->mark & info->ctmask);
  65. skb->mark = newmark;
  66. break;
  67. }
  68. return XT_CONTINUE;
  69. }
  70. static int connmark_tg_check(const struct xt_tgchk_param *par)
  71. {
  72. int ret;
  73. ret = nf_ct_l3proto_try_module_get(par->family);
  74. if (ret < 0)
  75. pr_info("cannot load conntrack support for proto=%u\n",
  76. par->family);
  77. return ret;
  78. }
  79. static void connmark_tg_destroy(const struct xt_tgdtor_param *par)
  80. {
  81. nf_ct_l3proto_module_put(par->family);
  82. }
  83. static bool
  84. connmark_mt(const struct sk_buff *skb, struct xt_action_param *par)
  85. {
  86. const struct xt_connmark_mtinfo1 *info = par->matchinfo;
  87. enum ip_conntrack_info ctinfo;
  88. const struct nf_conn *ct;
  89. ct = nf_ct_get(skb, &ctinfo);
  90. if (ct == NULL)
  91. return false;
  92. return ((ct->mark & info->mask) == info->mark) ^ info->invert;
  93. }
  94. static int connmark_mt_check(const struct xt_mtchk_param *par)
  95. {
  96. int ret;
  97. ret = nf_ct_l3proto_try_module_get(par->family);
  98. if (ret < 0)
  99. pr_info("cannot load conntrack support for proto=%u\n",
  100. par->family);
  101. return ret;
  102. }
  103. static void connmark_mt_destroy(const struct xt_mtdtor_param *par)
  104. {
  105. nf_ct_l3proto_module_put(par->family);
  106. }
  107. static struct xt_target connmark_tg_reg __read_mostly = {
  108. .name = "CONNMARK",
  109. .revision = 1,
  110. .family = NFPROTO_UNSPEC,
  111. .checkentry = connmark_tg_check,
  112. .target = connmark_tg,
  113. .targetsize = sizeof(struct xt_connmark_tginfo1),
  114. .destroy = connmark_tg_destroy,
  115. .me = THIS_MODULE,
  116. };
  117. static struct xt_match connmark_mt_reg __read_mostly = {
  118. .name = "connmark",
  119. .revision = 1,
  120. .family = NFPROTO_UNSPEC,
  121. .checkentry = connmark_mt_check,
  122. .match = connmark_mt,
  123. .matchsize = sizeof(struct xt_connmark_mtinfo1),
  124. .destroy = connmark_mt_destroy,
  125. .me = THIS_MODULE,
  126. };
  127. static int __init connmark_mt_init(void)
  128. {
  129. int ret;
  130. ret = xt_register_target(&connmark_tg_reg);
  131. if (ret < 0)
  132. return ret;
  133. ret = xt_register_match(&connmark_mt_reg);
  134. if (ret < 0) {
  135. xt_unregister_target(&connmark_tg_reg);
  136. return ret;
  137. }
  138. return 0;
  139. }
  140. static void __exit connmark_mt_exit(void)
  141. {
  142. xt_unregister_match(&connmark_mt_reg);
  143. xt_unregister_target(&connmark_tg_reg);
  144. }
  145. module_init(connmark_mt_init);
  146. module_exit(connmark_mt_exit);