~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/netfilter/xt_set.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php