aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2013-09-30 01:49:47 -0400
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2013-09-30 15:33:26 -0400
commitbd3129fc5e8868df74ffa803c7fec527976bbf1c (patch)
treef437934fa8074b889f4cdfd0f3ac3e1a4ebc3a16 /net/netfilter
parent60b0fe372499f66e0c965dc0594320438a3b711c (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.c188
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
114static bool
115set_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
128static int
129set_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
151static void
152set_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
161static bool
162match_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
179static bool
180set_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
112static unsigned int 207static unsigned int
113set_target_v0(struct sk_buff *skb, const struct xt_action_param *par) 208set_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
185static bool
186set_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
199static int
200set_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
222static void
223set_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
230static unsigned int 280static unsigned int
231set_target_v1(struct sk_buff *skb, const struct xt_action_param *par) 281set_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
325static bool
326match_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
343static bool
344set_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
369static struct xt_match set_matches[] __read_mostly = { 373static struct xt_match set_matches[] __read_mostly = {
370 { 374 {
371 .name = "set", 375 .name = "set",