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

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

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

~ [ 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.

osdn.jp