57c6d55e33d3a04568e564c796c5b70a25e12766
[deliverable/linux.git] / net / netfilter / xt_MARK.c
1 /* This is a module which is used for setting the NFMARK field of an skb. */
2
3 /* (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10 #include <linux/module.h>
11 #include <linux/skbuff.h>
12 #include <linux/ip.h>
13 #include <net/checksum.h>
14
15 #include <linux/netfilter/x_tables.h>
16 #include <linux/netfilter/xt_MARK.h>
17
18 MODULE_LICENSE("GPL");
19 MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
20 MODULE_DESCRIPTION("ip[6]tables MARK modification module");
21 MODULE_ALIAS("ipt_MARK");
22 MODULE_ALIAS("ip6t_MARK");
23
24 static unsigned int
25 mark_tg_v0(struct sk_buff *skb, const struct net_device *in,
26 const struct net_device *out, unsigned int hooknum,
27 const struct xt_target *target, const void *targinfo)
28 {
29 const struct xt_mark_target_info *markinfo = targinfo;
30
31 skb->mark = markinfo->mark;
32 return XT_CONTINUE;
33 }
34
35 static unsigned int
36 mark_tg(struct sk_buff *skb, const struct net_device *in,
37 const struct net_device *out, unsigned int hooknum,
38 const struct xt_target *target, const void *targinfo)
39 {
40 const struct xt_mark_target_info_v1 *markinfo = targinfo;
41 int mark = 0;
42
43 switch (markinfo->mode) {
44 case XT_MARK_SET:
45 mark = markinfo->mark;
46 break;
47
48 case XT_MARK_AND:
49 mark = skb->mark & markinfo->mark;
50 break;
51
52 case XT_MARK_OR:
53 mark = skb->mark | markinfo->mark;
54 break;
55 }
56
57 skb->mark = mark;
58 return XT_CONTINUE;
59 }
60
61 static bool
62 mark_tg_check_v0(const char *tablename, const void *entry,
63 const struct xt_target *target, void *targinfo,
64 unsigned int hook_mask)
65 {
66 const struct xt_mark_target_info *markinfo = targinfo;
67
68 if (markinfo->mark > 0xffffffff) {
69 printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n");
70 return false;
71 }
72 return true;
73 }
74
75 static bool
76 mark_tg_check(const char *tablename, const void *entry,
77 const struct xt_target *target, void *targinfo,
78 unsigned int hook_mask)
79 {
80 const struct xt_mark_target_info_v1 *markinfo = targinfo;
81
82 if (markinfo->mode != XT_MARK_SET
83 && markinfo->mode != XT_MARK_AND
84 && markinfo->mode != XT_MARK_OR) {
85 printk(KERN_WARNING "MARK: unknown mode %u\n",
86 markinfo->mode);
87 return false;
88 }
89 if (markinfo->mark > 0xffffffff) {
90 printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n");
91 return false;
92 }
93 return true;
94 }
95
96 #ifdef CONFIG_COMPAT
97 struct compat_xt_mark_target_info {
98 compat_ulong_t mark;
99 };
100
101 static void mark_tg_compat_from_user(void *dst, void *src)
102 {
103 const struct compat_xt_mark_target_info *cm = src;
104 struct xt_mark_target_info m = {
105 .mark = cm->mark,
106 };
107 memcpy(dst, &m, sizeof(m));
108 }
109
110 static int mark_tg_compat_to_user(void __user *dst, void *src)
111 {
112 const struct xt_mark_target_info *m = src;
113 struct compat_xt_mark_target_info cm = {
114 .mark = m->mark,
115 };
116 return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0;
117 }
118
119 struct compat_xt_mark_target_info_v1 {
120 compat_ulong_t mark;
121 u_int8_t mode;
122 u_int8_t __pad1;
123 u_int16_t __pad2;
124 };
125
126 static void mark_tg_compat_from_user_v1(void *dst, void *src)
127 {
128 const struct compat_xt_mark_target_info_v1 *cm = src;
129 struct xt_mark_target_info_v1 m = {
130 .mark = cm->mark,
131 .mode = cm->mode,
132 };
133 memcpy(dst, &m, sizeof(m));
134 }
135
136 static int mark_tg_compat_to_user_v1(void __user *dst, void *src)
137 {
138 const struct xt_mark_target_info_v1 *m = src;
139 struct compat_xt_mark_target_info_v1 cm = {
140 .mark = m->mark,
141 .mode = m->mode,
142 };
143 return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0;
144 }
145 #endif /* CONFIG_COMPAT */
146
147 static struct xt_target mark_tg_reg[] __read_mostly = {
148 {
149 .name = "MARK",
150 .family = AF_INET,
151 .revision = 0,
152 .checkentry = mark_tg_check_v0,
153 .target = mark_tg_v0,
154 .targetsize = sizeof(struct xt_mark_target_info),
155 #ifdef CONFIG_COMPAT
156 .compatsize = sizeof(struct compat_xt_mark_target_info),
157 .compat_from_user = mark_tg_compat_from_user,
158 .compat_to_user = mark_tg_compat_to_user,
159 #endif
160 .table = "mangle",
161 .me = THIS_MODULE,
162 },
163 {
164 .name = "MARK",
165 .family = AF_INET,
166 .revision = 1,
167 .checkentry = mark_tg_check,
168 .target = mark_tg,
169 .targetsize = sizeof(struct xt_mark_target_info_v1),
170 #ifdef CONFIG_COMPAT
171 .compatsize = sizeof(struct compat_xt_mark_target_info_v1),
172 .compat_from_user = mark_tg_compat_from_user_v1,
173 .compat_to_user = mark_tg_compat_to_user_v1,
174 #endif
175 .table = "mangle",
176 .me = THIS_MODULE,
177 },
178 {
179 .name = "MARK",
180 .family = AF_INET6,
181 .revision = 0,
182 .checkentry = mark_tg_check_v0,
183 .target = mark_tg_v0,
184 .targetsize = sizeof(struct xt_mark_target_info),
185 #ifdef CONFIG_COMPAT
186 .compatsize = sizeof(struct compat_xt_mark_target_info),
187 .compat_from_user = mark_tg_compat_from_user,
188 .compat_to_user = mark_tg_compat_to_user,
189 #endif
190 .table = "mangle",
191 .me = THIS_MODULE,
192 },
193 {
194 .name = "MARK",
195 .family = AF_INET6,
196 .revision = 1,
197 .checkentry = mark_tg_check,
198 .target = mark_tg,
199 .targetsize = sizeof(struct xt_mark_target_info_v1),
200 #ifdef CONFIG_COMPAT
201 .compatsize = sizeof(struct compat_xt_mark_target_info_v1),
202 .compat_from_user = mark_tg_compat_from_user_v1,
203 .compat_to_user = mark_tg_compat_to_user_v1,
204 #endif
205 .table = "mangle",
206 .me = THIS_MODULE,
207 },
208 };
209
210 static int __init mark_tg_init(void)
211 {
212 return xt_register_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg));
213 }
214
215 static void __exit mark_tg_exit(void)
216 {
217 xt_unregister_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg));
218 }
219
220 module_init(mark_tg_init);
221 module_exit(mark_tg_exit);
This page took 0.033938 seconds and 4 git commands to generate.