diff options
author | Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 2013-09-30 01:49:47 -0400 |
---|---|---|
committer | Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 2013-09-30 15:33:26 -0400 |
commit | bd3129fc5e8868df74ffa803c7fec527976bbf1c (patch) | |
tree | f437934fa8074b889f4cdfd0f3ac3e1a4ebc3a16 /net/netfilter | |
parent | 60b0fe372499f66e0c965dc0594320438a3b711c (diff) |
netfilter: ipset: order matches and targets separatedly in xt_set.c
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Diffstat (limited to 'net/netfilter')
-rw-r--r-- | net/netfilter/xt_set.c | 188 |
1 files changed, 96 insertions, 92 deletions
diff --git a/net/netfilter/xt_set.c b/net/netfilter/xt_set.c index 31790e789e22..2095488684ff 100644 --- a/net/netfilter/xt_set.c +++ b/net/netfilter/xt_set.c | |||
@@ -109,6 +109,101 @@ set_match_v0_destroy(const struct xt_mtdtor_param *par) | |||
109 | ip_set_nfnl_put(info->match_set.index); | 109 | ip_set_nfnl_put(info->match_set.index); |
110 | } | 110 | } |
111 | 111 | ||
112 | /* Revision 1 match */ | ||
113 | |||
114 | static bool | ||
115 | set_match_v1(const struct sk_buff *skb, struct xt_action_param *par) | ||
116 | { | ||
117 | const struct xt_set_info_match_v1 *info = par->matchinfo; | ||
118 | ADT_OPT(opt, par->family, info->match_set.dim, | ||
119 | info->match_set.flags, 0, UINT_MAX); | ||
120 | |||
121 | if (opt.flags & IPSET_RETURN_NOMATCH) | ||
122 | opt.cmdflags |= IPSET_FLAG_RETURN_NOMATCH; | ||
123 | |||
124 | return match_set(info->match_set.index, skb, par, &opt, | ||
125 | info->match_set.flags & IPSET_INV_MATCH); | ||
126 | } | ||
127 | |||
128 | static int | ||
129 | set_match_v1_checkentry(const struct xt_mtchk_param *par) | ||
130 | { | ||
131 | struct xt_set_info_match_v1 *info = par->matchinfo; | ||
132 | ip_set_id_t index; | ||
133 | |||
134 | index = ip_set_nfnl_get_byindex(info->match_set.index); | ||
135 | |||
136 | if (index == IPSET_INVALID_ID) { | ||
137 | pr_warning("Cannot find set indentified by id %u to match\n", | ||
138 | info->match_set.index); | ||
139 | return -ENOENT; | ||
140 | } | ||
141 | if (info->match_set.dim > IPSET_DIM_MAX) { | ||
142 | pr_warning("Protocol error: set match dimension " | ||
143 | "is over the limit!\n"); | ||
144 | ip_set_nfnl_put(info->match_set.index); | ||
145 | return -ERANGE; | ||
146 | } | ||
147 | |||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | static void | ||
152 | set_match_v1_destroy(const struct xt_mtdtor_param *par) | ||
153 | { | ||
154 | struct xt_set_info_match_v1 *info = par->matchinfo; | ||
155 | |||
156 | ip_set_nfnl_put(info->match_set.index); | ||
157 | } | ||
158 | |||
159 | /* Revision 3 match */ | ||
160 | |||
161 | static bool | ||
162 | match_counter(u64 counter, const struct ip_set_counter_match *info) | ||
163 | { | ||
164 | switch (info->op) { | ||
165 | case IPSET_COUNTER_NONE: | ||
166 | return true; | ||
167 | case IPSET_COUNTER_EQ: | ||
168 | return counter == info->value; | ||
169 | case IPSET_COUNTER_NE: | ||
170 | return counter != info->value; | ||
171 | case IPSET_COUNTER_LT: | ||
172 | return counter < info->value; | ||
173 | case IPSET_COUNTER_GT: | ||
174 | return counter > info->value; | ||
175 | } | ||
176 | return false; | ||
177 | } | ||
178 | |||
179 | static bool | ||
180 | set_match_v3(const struct sk_buff *skb, struct xt_action_param *par) | ||
181 | { | ||
182 | const struct xt_set_info_match_v3 *info = par->matchinfo; | ||
183 | ADT_OPT(opt, par->family, info->match_set.dim, | ||
184 | info->match_set.flags, info->flags, UINT_MAX); | ||
185 | int ret; | ||
186 | |||
187 | if (info->packets.op != IPSET_COUNTER_NONE || | ||
188 | info->bytes.op != IPSET_COUNTER_NONE) | ||
189 | opt.cmdflags |= IPSET_FLAG_MATCH_COUNTERS; | ||
190 | |||
191 | ret = match_set(info->match_set.index, skb, par, &opt, | ||
192 | info->match_set.flags & IPSET_INV_MATCH); | ||
193 | |||
194 | if (!(ret && opt.cmdflags & IPSET_FLAG_MATCH_COUNTERS)) | ||
195 | return ret; | ||
196 | |||
197 | if (!match_counter(opt.ext.packets, &info->packets)) | ||
198 | return 0; | ||
199 | return match_counter(opt.ext.bytes, &info->bytes); | ||
200 | } | ||
201 | |||
202 | #define set_match_v3_checkentry set_match_v1_checkentry | ||
203 | #define set_match_v3_destroy set_match_v1_destroy | ||
204 | |||
205 | /* Revision 0 interface: backward compatible with netfilter/iptables */ | ||
206 | |||
112 | static unsigned int | 207 | static unsigned int |
113 | set_target_v0(struct sk_buff *skb, const struct xt_action_param *par) | 208 | set_target_v0(struct sk_buff *skb, const struct xt_action_param *par) |
114 | { | 209 | { |
@@ -180,52 +275,7 @@ set_target_v0_destroy(const struct xt_tgdtor_param *par) | |||
180 | ip_set_nfnl_put(info->del_set.index); | 275 | ip_set_nfnl_put(info->del_set.index); |
181 | } | 276 | } |
182 | 277 | ||
183 | /* Revision 1 match and target */ | 278 | /* Revision 1 target */ |
184 | |||
185 | static bool | ||
186 | set_match_v1(const struct sk_buff *skb, struct xt_action_param *par) | ||
187 | { | ||
188 | const struct xt_set_info_match_v1 *info = par->matchinfo; | ||
189 | ADT_OPT(opt, par->family, info->match_set.dim, | ||
190 | info->match_set.flags, 0, UINT_MAX); | ||
191 | |||
192 | if (opt.flags & IPSET_RETURN_NOMATCH) | ||
193 | opt.cmdflags |= IPSET_FLAG_RETURN_NOMATCH; | ||
194 | |||
195 | return match_set(info->match_set.index, skb, par, &opt, | ||
196 | info->match_set.flags & IPSET_INV_MATCH); | ||
197 | } | ||
198 | |||
199 | static int | ||
200 | set_match_v1_checkentry(const struct xt_mtchk_param *par) | ||
201 | { | ||
202 | struct xt_set_info_match_v1 *info = par->matchinfo; | ||
203 | ip_set_id_t index; | ||
204 | |||
205 | index = ip_set_nfnl_get_byindex(info->match_set.index); | ||
206 | |||
207 | if (index == IPSET_INVALID_ID) { | ||
208 | pr_warning("Cannot find set indentified by id %u to match\n", | ||
209 | info->match_set.index); | ||
210 | return -ENOENT; | ||
211 | } | ||
212 | if (info->match_set.dim > IPSET_DIM_MAX) { | ||
213 | pr_warning("Protocol error: set match dimension " | ||
214 | "is over the limit!\n"); | ||
215 | ip_set_nfnl_put(info->match_set.index); | ||
216 | return -ERANGE; | ||
217 | } | ||
218 | |||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | static void | ||
223 | set_match_v1_destroy(const struct xt_mtdtor_param *par) | ||
224 | { | ||
225 | struct xt_set_info_match_v1 *info = par->matchinfo; | ||
226 | |||
227 | ip_set_nfnl_put(info->match_set.index); | ||
228 | } | ||
229 | 279 | ||
230 | static unsigned int | 280 | static unsigned int |
231 | set_target_v1(struct sk_buff *skb, const struct xt_action_param *par) | 281 | set_target_v1(struct sk_buff *skb, const struct xt_action_param *par) |
@@ -320,52 +370,6 @@ set_target_v2(struct sk_buff *skb, const struct xt_action_param *par) | |||
320 | #define set_target_v2_checkentry set_target_v1_checkentry | 370 | #define set_target_v2_checkentry set_target_v1_checkentry |
321 | #define set_target_v2_destroy set_target_v1_destroy | 371 | #define set_target_v2_destroy set_target_v1_destroy |
322 | 372 | ||
323 | /* Revision 3 match */ | ||
324 | |||
325 | static bool | ||
326 | match_counter(u64 counter, const struct ip_set_counter_match *info) | ||
327 | { | ||
328 | switch (info->op) { | ||
329 | case IPSET_COUNTER_NONE: | ||
330 | return true; | ||
331 | case IPSET_COUNTER_EQ: | ||
332 | return counter == info->value; | ||
333 | case IPSET_COUNTER_NE: | ||
334 | return counter != info->value; | ||
335 | case IPSET_COUNTER_LT: | ||
336 | return counter < info->value; | ||
337 | case IPSET_COUNTER_GT: | ||
338 | return counter > info->value; | ||
339 | } | ||
340 | return false; | ||
341 | } | ||
342 | |||
343 | static bool | ||
344 | set_match_v3(const struct sk_buff *skb, struct xt_action_param *par) | ||
345 | { | ||
346 | const struct xt_set_info_match_v3 *info = par->matchinfo; | ||
347 | ADT_OPT(opt, par->family, info->match_set.dim, | ||
348 | info->match_set.flags, info->flags, UINT_MAX); | ||
349 | int ret; | ||
350 | |||
351 | if (info->packets.op != IPSET_COUNTER_NONE || | ||
352 | info->bytes.op != IPSET_COUNTER_NONE) | ||
353 | opt.cmdflags |= IPSET_FLAG_MATCH_COUNTERS; | ||
354 | |||
355 | ret = match_set(info->match_set.index, skb, par, &opt, | ||
356 | info->match_set.flags & IPSET_INV_MATCH); | ||
357 | |||
358 | if (!(ret && opt.cmdflags & IPSET_FLAG_MATCH_COUNTERS)) | ||
359 | return ret; | ||
360 | |||
361 | if (!match_counter(opt.ext.packets, &info->packets)) | ||
362 | return 0; | ||
363 | return match_counter(opt.ext.bytes, &info->bytes); | ||
364 | } | ||
365 | |||
366 | #define set_match_v3_checkentry set_match_v1_checkentry | ||
367 | #define set_match_v3_destroy set_match_v1_destroy | ||
368 | |||
369 | static struct xt_match set_matches[] __read_mostly = { | 373 | static struct xt_match set_matches[] __read_mostly = { |
370 | { | 374 | { |
371 | .name = "set", | 375 | .name = "set", |