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