• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/net/netfilter/
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_SET_RETURN:
60		// Set connmark and mark, apply mask to mark, do XT_RETURN	- zzz
61		newmark = ct->mark = info->ctmark;
62		newmark &= info->ctmask;
63		if (newmark != skb->mark) {
64			skb->mark = newmark;
65		}
66		//return XT_RETURN;	// set return here will cause traffic blocked !?
67		break;
68	case XT_CONNMARK_SAVE:
69		newmark = (ct->mark & ~info->ctmask) ^
70		          (skb->mark & info->nfmask);
71		if (ct->mark != newmark) {
72			ct->mark = newmark;
73			nf_conntrack_event_cache(IPCT_MARK, ct);
74		}
75		break;
76	case XT_CONNMARK_RESTORE:
77		newmark = (skb->mark & ~info->nfmask) ^
78		          (ct->mark & info->ctmask);
79		skb->mark = newmark;
80		break;
81	}
82
83	return XT_CONTINUE;
84}
85
86static int connmark_tg_check(const struct xt_tgchk_param *par)
87{
88	int ret;
89
90	ret = nf_ct_l3proto_try_module_get(par->family);
91	if (ret < 0)
92		pr_info("cannot load conntrack support for proto=%u\n",
93			par->family);
94	return ret;
95}
96
97static void connmark_tg_destroy(const struct xt_tgdtor_param *par)
98{
99	nf_ct_l3proto_module_put(par->family);
100}
101
102static bool
103connmark_mt(const struct sk_buff *skb, struct xt_action_param *par)
104{
105	const struct xt_connmark_mtinfo1 *info = par->matchinfo;
106	enum ip_conntrack_info ctinfo;
107	const struct nf_conn *ct;
108
109	ct = nf_ct_get(skb, &ctinfo);
110	if (ct == NULL)
111		return false;
112
113	return ((ct->mark & info->mask) == info->mark) ^ info->invert;
114}
115
116static int connmark_mt_check(const struct xt_mtchk_param *par)
117{
118	int ret;
119
120	ret = nf_ct_l3proto_try_module_get(par->family);
121	if (ret < 0)
122		pr_info("cannot load conntrack support for proto=%u\n",
123			par->family);
124	return ret;
125}
126
127static void connmark_mt_destroy(const struct xt_mtdtor_param *par)
128{
129	nf_ct_l3proto_module_put(par->family);
130}
131
132static struct xt_target connmark_tg_reg __read_mostly = {
133	.name           = "CONNMARK",
134	.revision       = 1,
135	.family         = NFPROTO_UNSPEC,
136	.checkentry     = connmark_tg_check,
137	.target         = connmark_tg,
138	.targetsize     = sizeof(struct xt_connmark_tginfo1),
139	.destroy        = connmark_tg_destroy,
140	.me             = THIS_MODULE,
141};
142
143static struct xt_match connmark_mt_reg __read_mostly = {
144	.name           = "connmark",
145	.revision       = 1,
146	.family         = NFPROTO_UNSPEC,
147	.checkentry     = connmark_mt_check,
148	.match          = connmark_mt,
149	.matchsize      = sizeof(struct xt_connmark_mtinfo1),
150	.destroy        = connmark_mt_destroy,
151	.me             = THIS_MODULE,
152};
153
154static int __init connmark_mt_init(void)
155{
156	int ret;
157
158	ret = xt_register_target(&connmark_tg_reg);
159	if (ret < 0)
160		return ret;
161	ret = xt_register_match(&connmark_mt_reg);
162	if (ret < 0) {
163		xt_unregister_target(&connmark_tg_reg);
164		return ret;
165	}
166	return 0;
167}
168
169static void __exit connmark_mt_exit(void)
170{
171	xt_unregister_match(&connmark_mt_reg);
172	xt_unregister_target(&connmark_tg_reg);
173}
174
175module_init(connmark_mt_init);
176module_exit(connmark_mt_exit);
177