diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/xt_CONNMARK.c | 134 |
1 files changed, 11 insertions, 123 deletions
diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c index d6e5ab463277..593457068ae1 100644 --- a/net/netfilter/xt_CONNMARK.c +++ b/net/netfilter/xt_CONNMARK.c | |||
@@ -36,45 +36,6 @@ MODULE_ALIAS("ip6t_CONNMARK"); | |||
36 | #include <net/netfilter/nf_conntrack_ecache.h> | 36 | #include <net/netfilter/nf_conntrack_ecache.h> |
37 | 37 | ||
38 | static unsigned int | 38 | static unsigned int |
39 | connmark_tg_v0(struct sk_buff *skb, const struct xt_target_param *par) | ||
40 | { | ||
41 | const struct xt_connmark_target_info *markinfo = par->targinfo; | ||
42 | struct nf_conn *ct; | ||
43 | enum ip_conntrack_info ctinfo; | ||
44 | u_int32_t diff; | ||
45 | u_int32_t mark; | ||
46 | u_int32_t newmark; | ||
47 | |||
48 | ct = nf_ct_get(skb, &ctinfo); | ||
49 | if (ct) { | ||
50 | switch(markinfo->mode) { | ||
51 | case XT_CONNMARK_SET: | ||
52 | newmark = (ct->mark & ~markinfo->mask) | markinfo->mark; | ||
53 | if (newmark != ct->mark) { | ||
54 | ct->mark = newmark; | ||
55 | nf_conntrack_event_cache(IPCT_MARK, ct); | ||
56 | } | ||
57 | break; | ||
58 | case XT_CONNMARK_SAVE: | ||
59 | newmark = (ct->mark & ~markinfo->mask) | | ||
60 | (skb->mark & markinfo->mask); | ||
61 | if (ct->mark != newmark) { | ||
62 | ct->mark = newmark; | ||
63 | nf_conntrack_event_cache(IPCT_MARK, ct); | ||
64 | } | ||
65 | break; | ||
66 | case XT_CONNMARK_RESTORE: | ||
67 | mark = skb->mark; | ||
68 | diff = (ct->mark ^ mark) & markinfo->mask; | ||
69 | skb->mark = mark ^ diff; | ||
70 | break; | ||
71 | } | ||
72 | } | ||
73 | |||
74 | return XT_CONTINUE; | ||
75 | } | ||
76 | |||
77 | static unsigned int | ||
78 | connmark_tg(struct sk_buff *skb, const struct xt_target_param *par) | 39 | connmark_tg(struct sk_buff *skb, const struct xt_target_param *par) |
79 | { | 40 | { |
80 | const struct xt_connmark_tginfo1 *info = par->targinfo; | 41 | const struct xt_connmark_tginfo1 *info = par->targinfo; |
@@ -112,30 +73,6 @@ connmark_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
112 | return XT_CONTINUE; | 73 | return XT_CONTINUE; |
113 | } | 74 | } |
114 | 75 | ||
115 | static bool connmark_tg_check_v0(const struct xt_tgchk_param *par) | ||
116 | { | ||
117 | const struct xt_connmark_target_info *matchinfo = par->targinfo; | ||
118 | |||
119 | if (matchinfo->mode == XT_CONNMARK_RESTORE) { | ||
120 | if (strcmp(par->table, "mangle") != 0) { | ||
121 | printk(KERN_WARNING "CONNMARK: restore can only be " | ||
122 | "called from \"mangle\" table, not \"%s\"\n", | ||
123 | par->table); | ||
124 | return false; | ||
125 | } | ||
126 | } | ||
127 | if (matchinfo->mark > 0xffffffff || matchinfo->mask > 0xffffffff) { | ||
128 | printk(KERN_WARNING "CONNMARK: Only supports 32bit mark\n"); | ||
129 | return false; | ||
130 | } | ||
131 | if (nf_ct_l3proto_try_module_get(par->family) < 0) { | ||
132 | printk(KERN_WARNING "can't load conntrack support for " | ||
133 | "proto=%u\n", par->family); | ||
134 | return false; | ||
135 | } | ||
136 | return true; | ||
137 | } | ||
138 | |||
139 | static bool connmark_tg_check(const struct xt_tgchk_param *par) | 76 | static bool connmark_tg_check(const struct xt_tgchk_param *par) |
140 | { | 77 | { |
141 | if (nf_ct_l3proto_try_module_get(par->family) < 0) { | 78 | if (nf_ct_l3proto_try_module_get(par->family) < 0) { |
@@ -151,74 +88,25 @@ static void connmark_tg_destroy(const struct xt_tgdtor_param *par) | |||
151 | nf_ct_l3proto_module_put(par->family); | 88 | nf_ct_l3proto_module_put(par->family); |
152 | } | 89 | } |
153 | 90 | ||
154 | #ifdef CONFIG_COMPAT | 91 | static struct xt_target connmark_tg_reg __read_mostly = { |
155 | struct compat_xt_connmark_target_info { | 92 | .name = "CONNMARK", |
156 | compat_ulong_t mark, mask; | 93 | .revision = 1, |
157 | u_int8_t mode; | 94 | .family = NFPROTO_UNSPEC, |
158 | u_int8_t __pad1; | 95 | .checkentry = connmark_tg_check, |
159 | u_int16_t __pad2; | 96 | .target = connmark_tg, |
160 | }; | 97 | .targetsize = sizeof(struct xt_connmark_tginfo1), |
161 | 98 | .destroy = connmark_tg_destroy, | |
162 | static void connmark_tg_compat_from_user_v0(void *dst, void *src) | 99 | .me = THIS_MODULE, |
163 | { | ||
164 | const struct compat_xt_connmark_target_info *cm = src; | ||
165 | struct xt_connmark_target_info m = { | ||
166 | .mark = cm->mark, | ||
167 | .mask = cm->mask, | ||
168 | .mode = cm->mode, | ||
169 | }; | ||
170 | memcpy(dst, &m, sizeof(m)); | ||
171 | } | ||
172 | |||
173 | static int connmark_tg_compat_to_user_v0(void __user *dst, void *src) | ||
174 | { | ||
175 | const struct xt_connmark_target_info *m = src; | ||
176 | struct compat_xt_connmark_target_info cm = { | ||
177 | .mark = m->mark, | ||
178 | .mask = m->mask, | ||
179 | .mode = m->mode, | ||
180 | }; | ||
181 | return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0; | ||
182 | } | ||
183 | #endif /* CONFIG_COMPAT */ | ||
184 | |||
185 | static struct xt_target connmark_tg_reg[] __read_mostly = { | ||
186 | { | ||
187 | .name = "CONNMARK", | ||
188 | .revision = 0, | ||
189 | .family = NFPROTO_UNSPEC, | ||
190 | .checkentry = connmark_tg_check_v0, | ||
191 | .destroy = connmark_tg_destroy, | ||
192 | .target = connmark_tg_v0, | ||
193 | .targetsize = sizeof(struct xt_connmark_target_info), | ||
194 | #ifdef CONFIG_COMPAT | ||
195 | .compatsize = sizeof(struct compat_xt_connmark_target_info), | ||
196 | .compat_from_user = connmark_tg_compat_from_user_v0, | ||
197 | .compat_to_user = connmark_tg_compat_to_user_v0, | ||
198 | #endif | ||
199 | .me = THIS_MODULE | ||
200 | }, | ||
201 | { | ||
202 | .name = "CONNMARK", | ||
203 | .revision = 1, | ||
204 | .family = NFPROTO_UNSPEC, | ||
205 | .checkentry = connmark_tg_check, | ||
206 | .target = connmark_tg, | ||
207 | .targetsize = sizeof(struct xt_connmark_tginfo1), | ||
208 | .destroy = connmark_tg_destroy, | ||
209 | .me = THIS_MODULE, | ||
210 | }, | ||
211 | }; | 100 | }; |
212 | 101 | ||
213 | static int __init connmark_tg_init(void) | 102 | static int __init connmark_tg_init(void) |
214 | { | 103 | { |
215 | return xt_register_targets(connmark_tg_reg, | 104 | return xt_register_target(&connmark_tg_reg); |
216 | ARRAY_SIZE(connmark_tg_reg)); | ||
217 | } | 105 | } |
218 | 106 | ||
219 | static void __exit connmark_tg_exit(void) | 107 | static void __exit connmark_tg_exit(void) |
220 | { | 108 | { |
221 | xt_unregister_targets(connmark_tg_reg, ARRAY_SIZE(connmark_tg_reg)); | 109 | xt_unregister_target(&connmark_tg_reg); |
222 | } | 110 | } |
223 | 111 | ||
224 | module_init(connmark_tg_init); | 112 | module_init(connmark_tg_init); |