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