linux/net/netfilter/xt_CONNSECMARK.c
<<
>>
Prefs
   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
  26MODULE_LICENSE("GPL");
  27MODULE_AUTHOR("James Morris <jmorris@redhat.com>");
  28MODULE_DESCRIPTION("Xtables: target for copying between connection and security mark");
  29MODULE_ALIAS("ipt_CONNSECMARK");
  30MODULE_ALIAS("ip6t_CONNSECMARK");
  31
  32/*
  33 * If the packet has a security mark and the connection does not, copy
  34 * the security mark from the packet to the connection.
  35 */
  36static void secmark_save(const struct sk_buff *skb)
  37{
  38        if (skb->secmark) {
  39                struct nf_conn *ct;
  40                enum ip_conntrack_info ctinfo;
  41
  42                ct = nf_ct_get(skb, &ctinfo);
  43                if (ct && !ct->secmark) {
  44                        ct->secmark = skb->secmark;
  45                        nf_conntrack_event_cache(IPCT_SECMARK, ct);
  46                }
  47        }
  48}
  49
  50/*
  51 * If packet has no security mark, and the connection does, restore the
  52 * security mark from the connection to the packet.
  53 */
  54static void secmark_restore(struct sk_buff *skb)
  55{
  56        if (!skb->secmark) {
  57                const struct nf_conn *ct;
  58                enum ip_conntrack_info ctinfo;
  59
  60                ct = nf_ct_get(skb, &ctinfo);
  61                if (ct && ct->secmark)
  62                        skb->secmark = ct->secmark;
  63        }
  64}
  65
  66static unsigned int
  67connsecmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
  68{
  69        const struct xt_connsecmark_target_info *info = par->targinfo;
  70
  71        switch (info->mode) {
  72        case CONNSECMARK_SAVE:
  73                secmark_save(skb);
  74                break;
  75
  76        case CONNSECMARK_RESTORE:
  77                secmark_restore(skb);
  78                break;
  79
  80        default:
  81                BUG();
  82        }
  83
  84        return XT_CONTINUE;
  85}
  86
  87static int connsecmark_tg_check(const struct xt_tgchk_param *par)
  88{
  89        const struct xt_connsecmark_target_info *info = par->targinfo;
  90        int ret;
  91
  92        if (strcmp(par->table, "mangle") != 0 &&
  93            strcmp(par->table, "security") != 0) {
  94                pr_info_ratelimited("only valid in \'mangle\' or \'security\' table, not \'%s\'\n",
  95                                    par->table);
  96                return -EINVAL;
  97        }
  98
  99        switch (info->mode) {
 100        case CONNSECMARK_SAVE:
 101        case CONNSECMARK_RESTORE:
 102                break;
 103
 104        default:
 105                pr_info_ratelimited("invalid mode: %hu\n", info->mode);
 106                return -EINVAL;
 107        }
 108
 109        ret = nf_ct_netns_get(par->net, par->family);
 110        if (ret < 0)
 111                pr_info_ratelimited("cannot load conntrack support for proto=%u\n",
 112                                    par->family);
 113        return ret;
 114}
 115
 116static void connsecmark_tg_destroy(const struct xt_tgdtor_param *par)
 117{
 118        nf_ct_netns_put(par->net, par->family);
 119}
 120
 121static struct xt_target connsecmark_tg_reg __read_mostly = {
 122        .name       = "CONNSECMARK",
 123        .revision   = 0,
 124        .family     = NFPROTO_UNSPEC,
 125        .checkentry = connsecmark_tg_check,
 126        .destroy    = connsecmark_tg_destroy,
 127        .target     = connsecmark_tg,
 128        .targetsize = sizeof(struct xt_connsecmark_target_info),
 129        .me         = THIS_MODULE,
 130};
 131
 132static int __init connsecmark_tg_init(void)
 133{
 134        return xt_register_target(&connsecmark_tg_reg);
 135}
 136
 137static void __exit connsecmark_tg_exit(void)
 138{
 139        xt_unregister_target(&connsecmark_tg_reg);
 140}
 141
 142module_init(connsecmark_tg_init);
 143module_exit(connsecmark_tg_exit);
 144