xt_CONNSECMARK.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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 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. #include <linux/module.h>
  19. #include <linux/skbuff.h>
  20. #include <linux/netfilter/x_tables.h>
  21. #include <linux/netfilter/xt_CONNSECMARK.h>
  22. #include <net/netfilter/nf_conntrack_compat.h>
  23. #define PFX "CONNSECMARK: "
  24. MODULE_LICENSE("GPL");
  25. MODULE_AUTHOR("James Morris <jmorris@redhat.com>");
  26. MODULE_DESCRIPTION("ip[6]tables CONNSECMARK module");
  27. MODULE_ALIAS("ipt_CONNSECMARK");
  28. MODULE_ALIAS("ip6t_CONNSECMARK");
  29. /*
  30. * If the packet has a security mark and the connection does not, copy
  31. * the security mark from the packet to the connection.
  32. */
  33. static void secmark_save(struct sk_buff *skb)
  34. {
  35. if (skb->secmark) {
  36. u32 *connsecmark;
  37. enum ip_conntrack_info ctinfo;
  38. connsecmark = nf_ct_get_secmark(skb, &ctinfo);
  39. if (connsecmark && !*connsecmark)
  40. *connsecmark = skb->secmark;
  41. }
  42. }
  43. /*
  44. * If packet has no security mark, and the connection does, restore the
  45. * security mark from the connection to the packet.
  46. */
  47. static void secmark_restore(struct sk_buff *skb)
  48. {
  49. if (!skb->secmark) {
  50. u32 *connsecmark;
  51. enum ip_conntrack_info ctinfo;
  52. connsecmark = nf_ct_get_secmark(skb, &ctinfo);
  53. if (connsecmark && *connsecmark)
  54. skb->secmark = *connsecmark;
  55. }
  56. }
  57. static unsigned int target(struct sk_buff **pskb, const struct net_device *in,
  58. const struct net_device *out, unsigned int hooknum,
  59. const struct xt_target *target,
  60. const void *targinfo)
  61. {
  62. struct sk_buff *skb = *pskb;
  63. const struct xt_connsecmark_target_info *info = 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 checkentry(const char *tablename, const void *entry,
  77. const struct xt_target *target, void *targinfo,
  78. unsigned int hook_mask)
  79. {
  80. struct xt_connsecmark_target_info *info = targinfo;
  81. if (nf_ct_l3proto_try_module_get(target->family) < 0) {
  82. printk(KERN_WARNING "can't load conntrack support for "
  83. "proto=%d\n", target->family);
  84. return 0;
  85. }
  86. switch (info->mode) {
  87. case CONNSECMARK_SAVE:
  88. case CONNSECMARK_RESTORE:
  89. break;
  90. default:
  91. printk(KERN_INFO PFX "invalid mode: %hu\n", info->mode);
  92. return 0;
  93. }
  94. return 1;
  95. }
  96. static void
  97. destroy(const struct xt_target *target, void *targinfo)
  98. {
  99. nf_ct_l3proto_module_put(target->family);
  100. }
  101. static struct xt_target xt_connsecmark_target[] = {
  102. {
  103. .name = "CONNSECMARK",
  104. .family = AF_INET,
  105. .checkentry = checkentry,
  106. .destroy = destroy,
  107. .target = target,
  108. .targetsize = sizeof(struct xt_connsecmark_target_info),
  109. .table = "mangle",
  110. .me = THIS_MODULE,
  111. },
  112. {
  113. .name = "CONNSECMARK",
  114. .family = AF_INET6,
  115. .checkentry = checkentry,
  116. .destroy = destroy,
  117. .target = target,
  118. .targetsize = sizeof(struct xt_connsecmark_target_info),
  119. .table = "mangle",
  120. .me = THIS_MODULE,
  121. },
  122. };
  123. static int __init xt_connsecmark_init(void)
  124. {
  125. return xt_register_targets(xt_connsecmark_target,
  126. ARRAY_SIZE(xt_connsecmark_target));
  127. }
  128. static void __exit xt_connsecmark_fini(void)
  129. {
  130. xt_unregister_targets(xt_connsecmark_target,
  131. ARRAY_SIZE(xt_connsecmark_target));
  132. }
  133. module_init(xt_connsecmark_init);
  134. module_exit(xt_connsecmark_fini);