Blame view
net/netfilter/xt_set.c
19.6 KB
d2912cb15
|
1 |
// SPDX-License-Identifier: GPL-2.0-only |
d956798d8
|
2 3 4 |
/* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu> * Patrick Schaaf <bof@bof.de> * Martin Josefsson <gandalf@wlug.westbo.se> |
fe03d4745
|
5 |
* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@netfilter.org> |
d956798d8
|
6 7 8 |
*/ /* Kernel module which implements the set match and SET target |
ca0f6a5cd
|
9 10 |
* for netfilter/iptables. */ |
d956798d8
|
11 12 13 |
#include <linux/module.h> #include <linux/skbuff.h> |
d956798d8
|
14 15 |
#include <linux/netfilter/x_tables.h> |
a9756e6f6
|
16 |
#include <linux/netfilter/ipset/ip_set.h> |
a9756e6f6
|
17 |
#include <uapi/linux/netfilter/xt_set.h> |
d956798d8
|
18 19 |
MODULE_LICENSE("GPL"); |
fe03d4745
|
20 |
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>"); |
d956798d8
|
21 22 23 24 25 26 27 28 29 |
MODULE_DESCRIPTION("Xtables: IP set match and target module"); MODULE_ALIAS("xt_SET"); MODULE_ALIAS("ipt_set"); MODULE_ALIAS("ip6t_set"); MODULE_ALIAS("ipt_SET"); MODULE_ALIAS("ip6t_SET"); static inline int match_set(ip_set_id_t index, const struct sk_buff *skb, |
b66554cf0
|
30 |
const struct xt_action_param *par, |
075e64c04
|
31 |
struct ip_set_adt_opt *opt, int inv) |
d956798d8
|
32 |
{ |
b66554cf0
|
33 |
if (ip_set_test(index, skb, par, opt)) |
d956798d8
|
34 35 36 |
inv = !inv; return inv; } |
4750005a8
|
37 38 39 40 41 42 43 44 45 46 47 |
#define ADT_OPT(n, f, d, fs, cfs, t, p, b, po, bo) \ struct ip_set_adt_opt n = { \ .family = f, \ .dim = d, \ .flags = fs, \ .cmdflags = cfs, \ .ext.timeout = t, \ .ext.packets = p, \ .ext.bytes = b, \ .ext.packets_op = po, \ .ext.bytes_op = bo, \ |
127f55912
|
48 |
} |
ac8cc925d
|
49 |
|
d956798d8
|
50 51 52 53 54 55 |
/* Revision 0 interface: backward compatible with netfilter/iptables */ static bool set_match_v0(const struct sk_buff *skb, struct xt_action_param *par) { const struct xt_set_info_match_v0 *info = par->matchinfo; |
ca0f6a5cd
|
56 |
|
613dbd957
|
57 |
ADT_OPT(opt, xt_family(par), info->match_set.u.compat.dim, |
4750005a8
|
58 59 |
info->match_set.u.compat.flags, 0, UINT_MAX, 0, 0, 0, 0); |
d956798d8
|
60 |
|
b66554cf0
|
61 |
return match_set(info->match_set.index, skb, par, &opt, |
d956798d8
|
62 63 64 65 66 67 68 69 70 71 72 73 |
info->match_set.u.compat.flags & IPSET_INV_MATCH); } static void compat_flags(struct xt_set_info_v0 *info) { u_int8_t i; /* Fill out compatibility data according to enum ip_set_kopt */ info->u.compat.dim = IPSET_DIM_ZERO; if (info->u.flags[0] & IPSET_MATCH_INV) info->u.compat.flags |= IPSET_INV_MATCH; |
ca0f6a5cd
|
74 |
for (i = 0; i < IPSET_DIM_MAX - 1 && info->u.flags[i]; i++) { |
d956798d8
|
75 76 |
info->u.compat.dim++; if (info->u.flags[i] & IPSET_SRC) |
ca0f6a5cd
|
77 |
info->u.compat.flags |= (1 << info->u.compat.dim); |
d956798d8
|
78 79 80 81 82 83 84 85 |
} } static int set_match_v0_checkentry(const struct xt_mtchk_param *par) { struct xt_set_info_match_v0 *info = par->matchinfo; ip_set_id_t index; |
1785e8f47
|
86 |
index = ip_set_nfnl_get_byindex(par->net, info->match_set.index); |
d956798d8
|
87 88 |
if (index == IPSET_INVALID_ID) { |
c82b31c5f
|
89 90 91 |
pr_info_ratelimited("Cannot find set identified by id %u to match ", info->match_set.index); |
d956798d8
|
92 93 |
return -ENOENT; } |
ca0f6a5cd
|
94 |
if (info->match_set.u.flags[IPSET_DIM_MAX - 1] != 0) { |
c82b31c5f
|
95 96 |
pr_info_ratelimited("set match dimension is over the limit! "); |
1785e8f47
|
97 |
ip_set_nfnl_put(par->net, info->match_set.index); |
d956798d8
|
98 99 100 101 102 103 104 105 106 107 108 109 110 |
return -ERANGE; } /* Fill out compatibility data */ compat_flags(&info->match_set); return 0; } static void set_match_v0_destroy(const struct xt_mtdtor_param *par) { struct xt_set_info_match_v0 *info = par->matchinfo; |
1785e8f47
|
111 |
ip_set_nfnl_put(par->net, info->match_set.index); |
d956798d8
|
112 |
} |
bd3129fc5
|
113 114 115 116 117 118 |
/* Revision 1 match */ static bool set_match_v1(const struct sk_buff *skb, struct xt_action_param *par) { const struct xt_set_info_match_v1 *info = par->matchinfo; |
ca0f6a5cd
|
119 |
|
613dbd957
|
120 |
ADT_OPT(opt, xt_family(par), info->match_set.dim, |
4750005a8
|
121 122 |
info->match_set.flags, 0, UINT_MAX, 0, 0, 0, 0); |
bd3129fc5
|
123 124 125 126 127 128 129 130 131 132 133 134 135 |
if (opt.flags & IPSET_RETURN_NOMATCH) opt.cmdflags |= IPSET_FLAG_RETURN_NOMATCH; return match_set(info->match_set.index, skb, par, &opt, info->match_set.flags & IPSET_INV_MATCH); } static int set_match_v1_checkentry(const struct xt_mtchk_param *par) { struct xt_set_info_match_v1 *info = par->matchinfo; ip_set_id_t index; |
1785e8f47
|
136 |
index = ip_set_nfnl_get_byindex(par->net, info->match_set.index); |
bd3129fc5
|
137 138 |
if (index == IPSET_INVALID_ID) { |
c82b31c5f
|
139 140 141 |
pr_info_ratelimited("Cannot find set identified by id %u to match ", info->match_set.index); |
bd3129fc5
|
142 143 144 |
return -ENOENT; } if (info->match_set.dim > IPSET_DIM_MAX) { |
c82b31c5f
|
145 146 |
pr_info_ratelimited("set match dimension is over the limit! "); |
1785e8f47
|
147 |
ip_set_nfnl_put(par->net, info->match_set.index); |
bd3129fc5
|
148 149 150 151 152 153 154 155 156 157 |
return -ERANGE; } return 0; } static void set_match_v1_destroy(const struct xt_mtdtor_param *par) { struct xt_set_info_match_v1 *info = par->matchinfo; |
1785e8f47
|
158 |
ip_set_nfnl_put(par->net, info->match_set.index); |
bd3129fc5
|
159 160 161 162 163 |
} /* Revision 3 match */ static bool |
bd3129fc5
|
164 165 166 |
set_match_v3(const struct sk_buff *skb, struct xt_action_param *par) { const struct xt_set_info_match_v3 *info = par->matchinfo; |
ca0f6a5cd
|
167 |
|
613dbd957
|
168 |
ADT_OPT(opt, xt_family(par), info->match_set.dim, |
4750005a8
|
169 170 171 |
info->match_set.flags, info->flags, UINT_MAX, info->packets.value, info->bytes.value, info->packets.op, info->bytes.op); |
bd3129fc5
|
172 173 174 175 |
if (info->packets.op != IPSET_COUNTER_NONE || info->bytes.op != IPSET_COUNTER_NONE) opt.cmdflags |= IPSET_FLAG_MATCH_COUNTERS; |
4750005a8
|
176 177 |
return match_set(info->match_set.index, skb, par, &opt, info->match_set.flags & IPSET_INV_MATCH); |
bd3129fc5
|
178 179 180 181 |
} #define set_match_v3_checkentry set_match_v1_checkentry #define set_match_v3_destroy set_match_v1_destroy |
a51b9199b
|
182 183 184 |
/* Revision 4 match */ static bool |
a51b9199b
|
185 186 187 |
set_match_v4(const struct sk_buff *skb, struct xt_action_param *par) { const struct xt_set_info_match_v4 *info = par->matchinfo; |
ca0f6a5cd
|
188 |
|
613dbd957
|
189 |
ADT_OPT(opt, xt_family(par), info->match_set.dim, |
4750005a8
|
190 191 192 |
info->match_set.flags, info->flags, UINT_MAX, info->packets.value, info->bytes.value, info->packets.op, info->bytes.op); |
a51b9199b
|
193 194 195 196 |
if (info->packets.op != IPSET_COUNTER_NONE || info->bytes.op != IPSET_COUNTER_NONE) opt.cmdflags |= IPSET_FLAG_MATCH_COUNTERS; |
4750005a8
|
197 198 |
return match_set(info->match_set.index, skb, par, &opt, info->match_set.flags & IPSET_INV_MATCH); |
a51b9199b
|
199 200 201 202 |
} #define set_match_v4_checkentry set_match_v1_checkentry #define set_match_v4_destroy set_match_v1_destroy |
bd3129fc5
|
203 |
/* Revision 0 interface: backward compatible with netfilter/iptables */ |
d956798d8
|
204 205 206 207 |
static unsigned int set_target_v0(struct sk_buff *skb, const struct xt_action_param *par) { const struct xt_set_info_target_v0 *info = par->targinfo; |
ca0f6a5cd
|
208 |
|
613dbd957
|
209 |
ADT_OPT(add_opt, xt_family(par), info->add_set.u.compat.dim, |
4750005a8
|
210 211 |
info->add_set.u.compat.flags, 0, UINT_MAX, 0, 0, 0, 0); |
613dbd957
|
212 |
ADT_OPT(del_opt, xt_family(par), info->del_set.u.compat.dim, |
4750005a8
|
213 214 |
info->del_set.u.compat.flags, 0, UINT_MAX, 0, 0, 0, 0); |
d956798d8
|
215 216 |
if (info->add_set.index != IPSET_INVALID_ID) |
b66554cf0
|
217 |
ip_set_add(info->add_set.index, skb, par, &add_opt); |
d956798d8
|
218 |
if (info->del_set.index != IPSET_INVALID_ID) |
b66554cf0
|
219 |
ip_set_del(info->del_set.index, skb, par, &del_opt); |
d956798d8
|
220 221 222 223 224 225 226 227 228 229 230 |
return XT_CONTINUE; } static int set_target_v0_checkentry(const struct xt_tgchk_param *par) { struct xt_set_info_target_v0 *info = par->targinfo; ip_set_id_t index; if (info->add_set.index != IPSET_INVALID_ID) { |
1785e8f47
|
231 |
index = ip_set_nfnl_get_byindex(par->net, info->add_set.index); |
d956798d8
|
232 |
if (index == IPSET_INVALID_ID) { |
c82b31c5f
|
233 234 235 |
pr_info_ratelimited("Cannot find add_set index %u as target ", info->add_set.index); |
d956798d8
|
236 237 238 239 240 |
return -ENOENT; } } if (info->del_set.index != IPSET_INVALID_ID) { |
1785e8f47
|
241 |
index = ip_set_nfnl_get_byindex(par->net, info->del_set.index); |
d956798d8
|
242 |
if (index == IPSET_INVALID_ID) { |
c82b31c5f
|
243 244 245 |
pr_info_ratelimited("Cannot find del_set index %u as target ", info->del_set.index); |
eafbd3fde
|
246 |
if (info->add_set.index != IPSET_INVALID_ID) |
1785e8f47
|
247 |
ip_set_nfnl_put(par->net, info->add_set.index); |
d956798d8
|
248 249 250 |
return -ENOENT; } } |
ca0f6a5cd
|
251 252 |
if (info->add_set.u.flags[IPSET_DIM_MAX - 1] != 0 || info->del_set.u.flags[IPSET_DIM_MAX - 1] != 0) { |
c82b31c5f
|
253 254 |
pr_info_ratelimited("SET target dimension over the limit! "); |
eafbd3fde
|
255 |
if (info->add_set.index != IPSET_INVALID_ID) |
1785e8f47
|
256 |
ip_set_nfnl_put(par->net, info->add_set.index); |
eafbd3fde
|
257 |
if (info->del_set.index != IPSET_INVALID_ID) |
1785e8f47
|
258 |
ip_set_nfnl_put(par->net, info->del_set.index); |
d956798d8
|
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
return -ERANGE; } /* Fill out compatibility data */ compat_flags(&info->add_set); compat_flags(&info->del_set); return 0; } static void set_target_v0_destroy(const struct xt_tgdtor_param *par) { const struct xt_set_info_target_v0 *info = par->targinfo; if (info->add_set.index != IPSET_INVALID_ID) |
1785e8f47
|
275 |
ip_set_nfnl_put(par->net, info->add_set.index); |
d956798d8
|
276 |
if (info->del_set.index != IPSET_INVALID_ID) |
1785e8f47
|
277 |
ip_set_nfnl_put(par->net, info->del_set.index); |
d956798d8
|
278 |
} |
bd3129fc5
|
279 |
/* Revision 1 target */ |
d956798d8
|
280 281 |
static unsigned int |
ac8cc925d
|
282 |
set_target_v1(struct sk_buff *skb, const struct xt_action_param *par) |
d956798d8
|
283 |
{ |
ac8cc925d
|
284 |
const struct xt_set_info_target_v1 *info = par->targinfo; |
ca0f6a5cd
|
285 |
|
613dbd957
|
286 |
ADT_OPT(add_opt, xt_family(par), info->add_set.dim, |
4750005a8
|
287 288 |
info->add_set.flags, 0, UINT_MAX, 0, 0, 0, 0); |
613dbd957
|
289 |
ADT_OPT(del_opt, xt_family(par), info->del_set.dim, |
4750005a8
|
290 291 |
info->del_set.flags, 0, UINT_MAX, 0, 0, 0, 0); |
d956798d8
|
292 293 |
if (info->add_set.index != IPSET_INVALID_ID) |
b66554cf0
|
294 |
ip_set_add(info->add_set.index, skb, par, &add_opt); |
d956798d8
|
295 |
if (info->del_set.index != IPSET_INVALID_ID) |
b66554cf0
|
296 |
ip_set_del(info->del_set.index, skb, par, &del_opt); |
d956798d8
|
297 298 299 300 301 |
return XT_CONTINUE; } static int |
ac8cc925d
|
302 |
set_target_v1_checkentry(const struct xt_tgchk_param *par) |
d956798d8
|
303 |
{ |
ac8cc925d
|
304 |
const struct xt_set_info_target_v1 *info = par->targinfo; |
d956798d8
|
305 306 307 |
ip_set_id_t index; if (info->add_set.index != IPSET_INVALID_ID) { |
1785e8f47
|
308 |
index = ip_set_nfnl_get_byindex(par->net, info->add_set.index); |
d956798d8
|
309 |
if (index == IPSET_INVALID_ID) { |
c82b31c5f
|
310 311 312 |
pr_info_ratelimited("Cannot find add_set index %u as target ", info->add_set.index); |
d956798d8
|
313 314 315 316 317 |
return -ENOENT; } } if (info->del_set.index != IPSET_INVALID_ID) { |
1785e8f47
|
318 |
index = ip_set_nfnl_get_byindex(par->net, info->del_set.index); |
d956798d8
|
319 |
if (index == IPSET_INVALID_ID) { |
c82b31c5f
|
320 321 322 |
pr_info_ratelimited("Cannot find del_set index %u as target ", info->del_set.index); |
eafbd3fde
|
323 |
if (info->add_set.index != IPSET_INVALID_ID) |
1785e8f47
|
324 |
ip_set_nfnl_put(par->net, info->add_set.index); |
d956798d8
|
325 326 327 328 |
return -ENOENT; } } if (info->add_set.dim > IPSET_DIM_MAX || |
eafbd3fde
|
329 |
info->del_set.dim > IPSET_DIM_MAX) { |
c82b31c5f
|
330 331 |
pr_info_ratelimited("SET target dimension over the limit! "); |
eafbd3fde
|
332 |
if (info->add_set.index != IPSET_INVALID_ID) |
1785e8f47
|
333 |
ip_set_nfnl_put(par->net, info->add_set.index); |
eafbd3fde
|
334 |
if (info->del_set.index != IPSET_INVALID_ID) |
1785e8f47
|
335 |
ip_set_nfnl_put(par->net, info->del_set.index); |
d956798d8
|
336 337 338 339 340 341 342 |
return -ERANGE; } return 0; } static void |
ac8cc925d
|
343 |
set_target_v1_destroy(const struct xt_tgdtor_param *par) |
d956798d8
|
344 |
{ |
ac8cc925d
|
345 |
const struct xt_set_info_target_v1 *info = par->targinfo; |
d956798d8
|
346 347 |
if (info->add_set.index != IPSET_INVALID_ID) |
1785e8f47
|
348 |
ip_set_nfnl_put(par->net, info->add_set.index); |
d956798d8
|
349 |
if (info->del_set.index != IPSET_INVALID_ID) |
1785e8f47
|
350 |
ip_set_nfnl_put(par->net, info->del_set.index); |
d956798d8
|
351 |
} |
ac8cc925d
|
352 353 354 355 356 357 |
/* Revision 2 target */ static unsigned int set_target_v2(struct sk_buff *skb, const struct xt_action_param *par) { const struct xt_set_info_target_v2 *info = par->targinfo; |
ca0f6a5cd
|
358 |
|
613dbd957
|
359 |
ADT_OPT(add_opt, xt_family(par), info->add_set.dim, |
4750005a8
|
360 361 |
info->add_set.flags, info->flags, info->timeout, 0, 0, 0, 0); |
613dbd957
|
362 |
ADT_OPT(del_opt, xt_family(par), info->del_set.dim, |
4750005a8
|
363 364 |
info->del_set.flags, 0, UINT_MAX, 0, 0, 0, 0); |
ac8cc925d
|
365 |
|
127f55912
|
366 |
/* Normalize to fit into jiffies */ |
075e64c04
|
367 |
if (add_opt.ext.timeout != IPSET_NO_TIMEOUT && |
30a2e1071
|
368 369 |
add_opt.ext.timeout > IPSET_MAX_TIMEOUT) add_opt.ext.timeout = IPSET_MAX_TIMEOUT; |
ac8cc925d
|
370 |
if (info->add_set.index != IPSET_INVALID_ID) |
b66554cf0
|
371 |
ip_set_add(info->add_set.index, skb, par, &add_opt); |
ac8cc925d
|
372 |
if (info->del_set.index != IPSET_INVALID_ID) |
b66554cf0
|
373 |
ip_set_del(info->del_set.index, skb, par, &del_opt); |
ac8cc925d
|
374 375 376 377 378 379 |
return XT_CONTINUE; } #define set_target_v2_checkentry set_target_v1_checkentry #define set_target_v2_destroy set_target_v1_destroy |
76cea4109
|
380 |
/* Revision 3 target */ |
bec810d97
|
381 |
#define MOPT(opt, member) ((opt).ext.skbinfo.member) |
76cea4109
|
382 383 384 385 |
static unsigned int set_target_v3(struct sk_buff *skb, const struct xt_action_param *par) { const struct xt_set_info_target_v3 *info = par->targinfo; |
ca0f6a5cd
|
386 |
int ret; |
613dbd957
|
387 |
ADT_OPT(add_opt, xt_family(par), info->add_set.dim, |
4750005a8
|
388 389 |
info->add_set.flags, info->flags, info->timeout, 0, 0, 0, 0); |
613dbd957
|
390 |
ADT_OPT(del_opt, xt_family(par), info->del_set.dim, |
4750005a8
|
391 392 |
info->del_set.flags, 0, UINT_MAX, 0, 0, 0, 0); |
613dbd957
|
393 |
ADT_OPT(map_opt, xt_family(par), info->map_set.dim, |
4750005a8
|
394 395 |
info->map_set.flags, 0, UINT_MAX, 0, 0, 0, 0); |
76cea4109
|
396 |
|
76cea4109
|
397 398 |
/* Normalize to fit into jiffies */ if (add_opt.ext.timeout != IPSET_NO_TIMEOUT && |
30a2e1071
|
399 400 |
add_opt.ext.timeout > IPSET_MAX_TIMEOUT) add_opt.ext.timeout = IPSET_MAX_TIMEOUT; |
76cea4109
|
401 402 403 404 405 406 407 408 409 410 411 412 413 |
if (info->add_set.index != IPSET_INVALID_ID) ip_set_add(info->add_set.index, skb, par, &add_opt); if (info->del_set.index != IPSET_INVALID_ID) ip_set_del(info->del_set.index, skb, par, &del_opt); if (info->map_set.index != IPSET_INVALID_ID) { map_opt.cmdflags |= info->flags & (IPSET_FLAG_MAP_SKBMARK | IPSET_FLAG_MAP_SKBPRIO | IPSET_FLAG_MAP_SKBQUEUE); ret = match_set(info->map_set.index, skb, par, &map_opt, info->map_set.flags & IPSET_INV_MATCH); if (!ret) return XT_CONTINUE; if (map_opt.cmdflags & IPSET_FLAG_MAP_SKBMARK) |
bec810d97
|
414 415 |
skb->mark = (skb->mark & ~MOPT(map_opt,skbmarkmask)) ^ MOPT(map_opt, skbmark); |
76cea4109
|
416 |
if (map_opt.cmdflags & IPSET_FLAG_MAP_SKBPRIO) |
bec810d97
|
417 |
skb->priority = MOPT(map_opt, skbprio); |
76cea4109
|
418 419 |
if ((map_opt.cmdflags & IPSET_FLAG_MAP_SKBQUEUE) && skb->dev && |
bec810d97
|
420 421 |
skb->dev->real_num_tx_queues > MOPT(map_opt, skbqueue)) skb_set_queue_mapping(skb, MOPT(map_opt, skbqueue)); |
76cea4109
|
422 423 424 |
} return XT_CONTINUE; } |
76cea4109
|
425 426 427 428 429 |
static int set_target_v3_checkentry(const struct xt_tgchk_param *par) { const struct xt_set_info_target_v3 *info = par->targinfo; ip_set_id_t index; |
b1732e163
|
430 |
int ret = 0; |
76cea4109
|
431 432 433 434 435 |
if (info->add_set.index != IPSET_INVALID_ID) { index = ip_set_nfnl_get_byindex(par->net, info->add_set.index); if (index == IPSET_INVALID_ID) { |
c82b31c5f
|
436 437 438 |
pr_info_ratelimited("Cannot find add_set index %u as target ", info->add_set.index); |
76cea4109
|
439 440 441 442 443 444 445 446 |
return -ENOENT; } } if (info->del_set.index != IPSET_INVALID_ID) { index = ip_set_nfnl_get_byindex(par->net, info->del_set.index); if (index == IPSET_INVALID_ID) { |
c82b31c5f
|
447 448 449 |
pr_info_ratelimited("Cannot find del_set index %u as target ", info->del_set.index); |
b1732e163
|
450 451 |
ret = -ENOENT; goto cleanup_add; |
76cea4109
|
452 453 454 455 456 |
} } if (info->map_set.index != IPSET_INVALID_ID) { if (strncmp(par->table, "mangle", 7)) { |
c82b31c5f
|
457 458 |
pr_info_ratelimited("--map-set only usable from mangle table "); |
b1732e163
|
459 460 |
ret = -EINVAL; goto cleanup_del; |
76cea4109
|
461 462 463 |
} if (((info->flags & IPSET_FLAG_MAP_SKBPRIO) | (info->flags & IPSET_FLAG_MAP_SKBQUEUE)) && |
9dcceb137
|
464 |
(par->hook_mask & ~(1 << NF_INET_FORWARD | |
76cea4109
|
465 466 |
1 << NF_INET_LOCAL_OUT | 1 << NF_INET_POST_ROUTING))) { |
c82b31c5f
|
467 468 |
pr_info_ratelimited("mapping of prio or/and queue is allowed only from OUTPUT/FORWARD/POSTROUTING chains "); |
b1732e163
|
469 470 |
ret = -EINVAL; goto cleanup_del; |
76cea4109
|
471 472 473 474 |
} index = ip_set_nfnl_get_byindex(par->net, info->map_set.index); if (index == IPSET_INVALID_ID) { |
c82b31c5f
|
475 476 477 |
pr_info_ratelimited("Cannot find map_set index %u as target ", info->map_set.index); |
b1732e163
|
478 479 |
ret = -ENOENT; goto cleanup_del; |
76cea4109
|
480 481 482 483 484 485 |
} } if (info->add_set.dim > IPSET_DIM_MAX || info->del_set.dim > IPSET_DIM_MAX || info->map_set.dim > IPSET_DIM_MAX) { |
c82b31c5f
|
486 487 |
pr_info_ratelimited("SET target dimension over the limit! "); |
b1732e163
|
488 489 |
ret = -ERANGE; goto cleanup_mark; |
76cea4109
|
490 491 492 |
} return 0; |
b1732e163
|
493 494 495 496 497 498 499 500 501 502 |
cleanup_mark: if (info->map_set.index != IPSET_INVALID_ID) ip_set_nfnl_put(par->net, info->map_set.index); cleanup_del: if (info->del_set.index != IPSET_INVALID_ID) ip_set_nfnl_put(par->net, info->del_set.index); cleanup_add: if (info->add_set.index != IPSET_INVALID_ID) ip_set_nfnl_put(par->net, info->add_set.index); return ret; |
76cea4109
|
503 504 505 506 507 508 509 510 511 512 513 514 515 516 |
} static void set_target_v3_destroy(const struct xt_tgdtor_param *par) { const struct xt_set_info_target_v3 *info = par->targinfo; if (info->add_set.index != IPSET_INVALID_ID) ip_set_nfnl_put(par->net, info->add_set.index); if (info->del_set.index != IPSET_INVALID_ID) ip_set_nfnl_put(par->net, info->del_set.index); if (info->map_set.index != IPSET_INVALID_ID) ip_set_nfnl_put(par->net, info->map_set.index); } |
d956798d8
|
517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 |
static struct xt_match set_matches[] __read_mostly = { { .name = "set", .family = NFPROTO_IPV4, .revision = 0, .match = set_match_v0, .matchsize = sizeof(struct xt_set_info_match_v0), .checkentry = set_match_v0_checkentry, .destroy = set_match_v0_destroy, .me = THIS_MODULE }, { .name = "set", .family = NFPROTO_IPV4, .revision = 1, |
ac8cc925d
|
532 533 534 535 |
.match = set_match_v1, .matchsize = sizeof(struct xt_set_info_match_v1), .checkentry = set_match_v1_checkentry, .destroy = set_match_v1_destroy, |
d956798d8
|
536 537 538 539 540 541 |
.me = THIS_MODULE }, { .name = "set", .family = NFPROTO_IPV6, .revision = 1, |
ac8cc925d
|
542 543 544 545 |
.match = set_match_v1, .matchsize = sizeof(struct xt_set_info_match_v1), .checkentry = set_match_v1_checkentry, .destroy = set_match_v1_destroy, |
d956798d8
|
546 547 |
.me = THIS_MODULE }, |
3e0304a58
|
548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 |
/* --return-nomatch flag support */ { .name = "set", .family = NFPROTO_IPV4, .revision = 2, .match = set_match_v1, .matchsize = sizeof(struct xt_set_info_match_v1), .checkentry = set_match_v1_checkentry, .destroy = set_match_v1_destroy, .me = THIS_MODULE }, { .name = "set", .family = NFPROTO_IPV6, .revision = 2, .match = set_match_v1, .matchsize = sizeof(struct xt_set_info_match_v1), .checkentry = set_match_v1_checkentry, .destroy = set_match_v1_destroy, .me = THIS_MODULE }, |
6e01781d1
|
569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 |
/* counters support: update, match */ { .name = "set", .family = NFPROTO_IPV4, .revision = 3, .match = set_match_v3, .matchsize = sizeof(struct xt_set_info_match_v3), .checkentry = set_match_v3_checkentry, .destroy = set_match_v3_destroy, .me = THIS_MODULE }, { .name = "set", .family = NFPROTO_IPV6, .revision = 3, .match = set_match_v3, .matchsize = sizeof(struct xt_set_info_match_v3), .checkentry = set_match_v3_checkentry, .destroy = set_match_v3_destroy, .me = THIS_MODULE }, |
a51b9199b
|
590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 |
/* new revision for counters support: update, match */ { .name = "set", .family = NFPROTO_IPV4, .revision = 4, .match = set_match_v4, .matchsize = sizeof(struct xt_set_info_match_v4), .checkentry = set_match_v4_checkentry, .destroy = set_match_v4_destroy, .me = THIS_MODULE }, { .name = "set", .family = NFPROTO_IPV6, .revision = 4, .match = set_match_v4, .matchsize = sizeof(struct xt_set_info_match_v4), .checkentry = set_match_v4_checkentry, .destroy = set_match_v4_destroy, .me = THIS_MODULE }, |
d956798d8
|
611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 |
}; static struct xt_target set_targets[] __read_mostly = { { .name = "SET", .revision = 0, .family = NFPROTO_IPV4, .target = set_target_v0, .targetsize = sizeof(struct xt_set_info_target_v0), .checkentry = set_target_v0_checkentry, .destroy = set_target_v0_destroy, .me = THIS_MODULE }, { .name = "SET", .revision = 1, .family = NFPROTO_IPV4, |
ac8cc925d
|
628 629 630 631 |
.target = set_target_v1, .targetsize = sizeof(struct xt_set_info_target_v1), .checkentry = set_target_v1_checkentry, .destroy = set_target_v1_destroy, |
d956798d8
|
632 633 634 635 636 637 |
.me = THIS_MODULE }, { .name = "SET", .revision = 1, .family = NFPROTO_IPV6, |
ac8cc925d
|
638 639 640 641 642 643 |
.target = set_target_v1, .targetsize = sizeof(struct xt_set_info_target_v1), .checkentry = set_target_v1_checkentry, .destroy = set_target_v1_destroy, .me = THIS_MODULE }, |
3e0304a58
|
644 |
/* --timeout and --exist flags support */ |
ac8cc925d
|
645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 |
{ .name = "SET", .revision = 2, .family = NFPROTO_IPV4, .target = set_target_v2, .targetsize = sizeof(struct xt_set_info_target_v2), .checkentry = set_target_v2_checkentry, .destroy = set_target_v2_destroy, .me = THIS_MODULE }, { .name = "SET", .revision = 2, .family = NFPROTO_IPV6, .target = set_target_v2, .targetsize = sizeof(struct xt_set_info_target_v2), .checkentry = set_target_v2_checkentry, .destroy = set_target_v2_destroy, |
d956798d8
|
663 664 |
.me = THIS_MODULE }, |
76cea4109
|
665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 |
/* --map-set support */ { .name = "SET", .revision = 3, .family = NFPROTO_IPV4, .target = set_target_v3, .targetsize = sizeof(struct xt_set_info_target_v3), .checkentry = set_target_v3_checkentry, .destroy = set_target_v3_destroy, .me = THIS_MODULE }, { .name = "SET", .revision = 3, .family = NFPROTO_IPV6, .target = set_target_v3, .targetsize = sizeof(struct xt_set_info_target_v3), .checkentry = set_target_v3_checkentry, .destroy = set_target_v3_destroy, .me = THIS_MODULE }, |
d956798d8
|
686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 |
}; static int __init xt_set_init(void) { int ret = xt_register_matches(set_matches, ARRAY_SIZE(set_matches)); if (!ret) { ret = xt_register_targets(set_targets, ARRAY_SIZE(set_targets)); if (ret) xt_unregister_matches(set_matches, ARRAY_SIZE(set_matches)); } return ret; } static void __exit xt_set_fini(void) { xt_unregister_matches(set_matches, ARRAY_SIZE(set_matches)); xt_unregister_targets(set_targets, ARRAY_SIZE(set_targets)); } module_init(xt_set_init); module_exit(xt_set_fini); |