diff options
author | Jan Engelhardt <jengelh@medozas.de> | 2010-02-26 14:20:32 +0100 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-03-17 15:48:36 +0100 |
commit | b8f00ba27e4acc4a2224360ce3aa8a22354434c5 (patch) | |
tree | 60b9e536bc19ba6d4ddacd4bac5ebec1da9dc1d7 /net/netfilter/xt_connmark.c | |
parent | 28b949885f80efb87d7cebdcf879c99db12c37bd (diff) |
netfilter: xtables: merge xt_CONNMARK into xt_connmark
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
Diffstat (limited to 'net/netfilter/xt_connmark.c')
-rw-r--r-- | net/netfilter/xt_connmark.c | 84 |
1 files changed, 81 insertions, 3 deletions
diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c index 122aa8b0147..d184515604b 100644 --- a/net/netfilter/xt_connmark.c +++ b/net/netfilter/xt_connmark.c @@ -1,5 +1,5 @@ /* - * xt_connmark - Netfilter module to match connection mark values + * xt_connmark - Netfilter module to operate on connection marks * * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> * by Henrik Nordstrom <hno@marasystems.com> @@ -24,15 +24,71 @@ #include <linux/module.h> #include <linux/skbuff.h> #include <net/netfilter/nf_conntrack.h> +#include <net/netfilter/nf_conntrack_ecache.h> #include <linux/netfilter/x_tables.h> #include <linux/netfilter/xt_connmark.h> MODULE_AUTHOR("Henrik Nordstrom <hno@marasystems.com>"); -MODULE_DESCRIPTION("Xtables: connection mark match"); +MODULE_DESCRIPTION("Xtables: connection mark operations"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("ipt_CONNMARK"); +MODULE_ALIAS("ip6t_CONNMARK"); MODULE_ALIAS("ipt_connmark"); MODULE_ALIAS("ip6t_connmark"); +static unsigned int +connmark_tg(struct sk_buff *skb, const struct xt_target_param *par) +{ + const struct xt_connmark_tginfo1 *info = par->targinfo; + enum ip_conntrack_info ctinfo; + struct nf_conn *ct; + u_int32_t newmark; + + ct = nf_ct_get(skb, &ctinfo); + if (ct == NULL) + return XT_CONTINUE; + + switch (info->mode) { + case XT_CONNMARK_SET: + newmark = (ct->mark & ~info->ctmask) ^ info->ctmark; + if (ct->mark != newmark) { + ct->mark = newmark; + nf_conntrack_event_cache(IPCT_MARK, ct); + } + break; + case XT_CONNMARK_SAVE: + newmark = (ct->mark & ~info->ctmask) ^ + (skb->mark & info->nfmask); + if (ct->mark != newmark) { + ct->mark = newmark; + nf_conntrack_event_cache(IPCT_MARK, ct); + } + break; + case XT_CONNMARK_RESTORE: + newmark = (skb->mark & ~info->nfmask) ^ + (ct->mark & info->ctmask); + skb->mark = newmark; + break; + } + + return XT_CONTINUE; +} + +static bool connmark_tg_check(const struct xt_tgchk_param *par) +{ + if (nf_ct_l3proto_try_module_get(par->family) < 0) { + printk(KERN_WARNING "cannot load conntrack support for " + "proto=%u\n", par->family); + return false; + } + return true; +} + +static void connmark_tg_destroy(const struct xt_tgdtor_param *par) +{ + nf_ct_l3proto_module_put(par->family); +} + static bool connmark_mt(const struct sk_buff *skb, const struct xt_match_param *par) { @@ -62,6 +118,17 @@ static void connmark_mt_destroy(const struct xt_mtdtor_param *par) nf_ct_l3proto_module_put(par->family); } +static struct xt_target connmark_tg_reg __read_mostly = { + .name = "CONNMARK", + .revision = 1, + .family = NFPROTO_UNSPEC, + .checkentry = connmark_tg_check, + .target = connmark_tg, + .targetsize = sizeof(struct xt_connmark_tginfo1), + .destroy = connmark_tg_destroy, + .me = THIS_MODULE, +}; + static struct xt_match connmark_mt_reg __read_mostly = { .name = "connmark", .revision = 1, @@ -75,12 +142,23 @@ static struct xt_match connmark_mt_reg __read_mostly = { static int __init connmark_mt_init(void) { - return xt_register_match(&connmark_mt_reg); + int ret; + + ret = xt_register_target(&connmark_tg_reg); + if (ret < 0) + return ret; + ret = xt_register_match(&connmark_mt_reg); + if (ret < 0) { + xt_unregister_target(&connmark_tg_reg); + return ret; + } + return 0; } static void __exit connmark_mt_exit(void) { xt_unregister_match(&connmark_mt_reg); + xt_unregister_target(&connmark_tg_reg); } module_init(connmark_mt_init); |