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

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

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

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

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | 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