xt_CONNSECMARK.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. * This module is used to copy security markings from packets
  3. * to connections, and restore security markings from connections
  4. * back to packets. This would normally be performed in conjunction
  5. * with the SECMARK target and state match.
  6. *
  7. * Based somewhat on CONNMARK:
  8. * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
  9. * by Henrik Nordstrom <hno@marasystems.com>
  10. *
  11. * (C) 2006,2008 Red Hat, Inc., James Morris <jmorris@redhat.com>
  12. *
  13. * This program is free software; you can redistribute it and/or modify
  14. * it under the terms of the GNU General Public License version 2 as
  15. * published by the Free Software Foundation.
  16. *
  17. */
  18. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  19. #include <linux/module.h>
  20. #include <linux/skbuff.h>
  21. #include <linux/netfilter/x_tables.h>
  22. #include <linux/netfilter/xt_CONNSECMARK.h>
  23. #include <net/netfilter/nf_conntrack.h>
  24. #include <net/netfilter/nf_conntrack_ecache.h>
  25. MODULE_LICENSE("GPL");
  26. MODULE_AUTHOR("James Morris <jmorris@redhat.com>");
  27. MODULE_DESCRIPTION("Xtables: target for copying between connection and security mark");
  28. MODULE_ALIAS("ipt_CONNSECMARK");
  29. MODULE_ALIAS("ip6t_CONNSECMARK");
  30. /*
  31. * If the packet has a security mark and the connection does not, copy
  32. * the security mark from the packet to the connection.
  33. */
  34. static void secmark_save(const struct sk_buff *skb)
  35. {
  36. if (skb->secmark) {
  37. struct nf_conn *ct;
  38. enum ip_conntrack_info ctinfo;
  39. ct = nf_ct_get(skb, &ctinfo);
  40. if (ct && !ct->secmark) {
  41. ct->secmark = skb->secmark;
  42. nf_conntrack_event_cache(IPCT_SECMARK, ct);
  43. }
  44. }
  45. }
  46. /*
  47. * If packet has no security mark, and the connection does, restore the
  48. * security mark from the connection to the packet.
  49. */
  50. static void secmark_restore(struct sk_buff *skb)
  51. {
  52. if (!skb->secmark) {
  53. const struct nf_conn *ct;
  54. enum ip_conntrack_info ctinfo;
  55. ct = nf_ct_get(skb, &ctinfo);
  56. if (ct && ct->secmark)
  57. skb->secmark = ct->secmark;
  58. }
  59. }
  60. static unsigned int
  61. connsecmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
  62. {
  63. const struct xt_connsecmark_target_info *info = par->targinfo;
  64. switch (info->mode) {
  65. case CONNSECMARK_SAVE:
  66. secmark_save(skb);
  67. break;
  68. case CONNSECMARK_RESTORE:
  69. secmark_restore(skb);
  70. break;
  71. default:
  72. BUG();
  73. }
  74. return XT_CONTINUE;
  75. }
  76. static int connsecmark_tg_check(const struct xt_tgchk_param *par)
  77. {
  78. const struct xt_connsecmark_target_info *info = par->targinfo;
  79. int ret;
  80. if (strcmp(par->table, "mangle") != 0 &&
  81. strcmp(par->table, "security") != 0) {
  82. pr_info("target only valid in the \'mangle\' "
  83. "or \'security\' tables, not \'%s\'.\n", par->table);
  84. return -EINVAL;
  85. }
  86. switch (info->mode) {
  87. case CONNSECMARK_SAVE:
  88. case CONNSECMARK_RESTORE:
  89. break;
  90. default:
  91. pr_info("invalid mode: %hu\n", info->mode);
  92. return -EINVAL;
  93. }
  94. ret = nf_ct_l3proto_try_module_get(par->family);
  95. if (ret < 0)
  96. pr_info("cannot load conntrack support for proto=%u\n",
  97. par->family);
  98. return ret;
  99. }
  100. static void connsecmark_tg_destroy(const struct xt_tgdtor_param *par)
  101. {
  102. nf_ct_l3proto_module_put(par->family);
  103. }
  104. static struct xt_target connsecmark_tg_reg __read_mostly = {
  105. .name = "CONNSECMARK",
  106. .revision = 0,
  107. .family = NFPROTO_UNSPEC,
  108. .checkentry = connsecmark_tg_check,
  109. .destroy = connsecmark_tg_destroy,
  110. .target = connsecmark_tg,
  111. .targetsize = sizeof(struct xt_connsecmark_target_info),
  112. .me = THIS_MODULE,
  113. };
  114. static int __init connsecmark_tg_init(void)
  115. {
  116. return xt_register_target(&connsecmark_tg_reg);
  117. }
  118. static void __exit connsecmark_tg_exit(void)
  119. {
  120. xt_unregister_target(&connsecmark_tg_reg);
  121. }
  122. module_init(connsecmark_tg_init);
  123. module_exit(connsecmark_tg_exit);