Root/
1 | /* |
2 | * Copyright (c) 2006 Patrick McHardy <kaber@trash.net> |
3 | * |
4 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License version 2 as |
6 | * published by the Free Software Foundation. |
7 | * |
8 | * Based on ipt_random and ipt_nth by Fabrice MARIE <fabrice@netfilter.org>. |
9 | */ |
10 | |
11 | #include <linux/init.h> |
12 | #include <linux/spinlock.h> |
13 | #include <linux/skbuff.h> |
14 | #include <linux/net.h> |
15 | |
16 | #include <linux/netfilter/xt_statistic.h> |
17 | #include <linux/netfilter/x_tables.h> |
18 | |
19 | struct xt_statistic_priv { |
20 | uint32_t count; |
21 | }; |
22 | |
23 | MODULE_LICENSE("GPL"); |
24 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); |
25 | MODULE_DESCRIPTION("Xtables: statistics-based matching (\"Nth\", random)"); |
26 | MODULE_ALIAS("ipt_statistic"); |
27 | MODULE_ALIAS("ip6t_statistic"); |
28 | |
29 | static DEFINE_SPINLOCK(nth_lock); |
30 | |
31 | static bool |
32 | statistic_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
33 | { |
34 | const struct xt_statistic_info *info = par->matchinfo; |
35 | bool ret = info->flags & XT_STATISTIC_INVERT; |
36 | |
37 | switch (info->mode) { |
38 | case XT_STATISTIC_MODE_RANDOM: |
39 | if ((net_random() & 0x7FFFFFFF) < info->u.random.probability) |
40 | ret = !ret; |
41 | break; |
42 | case XT_STATISTIC_MODE_NTH: |
43 | spin_lock_bh(&nth_lock); |
44 | if (info->master->count++ == info->u.nth.every) { |
45 | info->master->count = 0; |
46 | ret = !ret; |
47 | } |
48 | spin_unlock_bh(&nth_lock); |
49 | break; |
50 | } |
51 | |
52 | return ret; |
53 | } |
54 | |
55 | static bool statistic_mt_check(const struct xt_mtchk_param *par) |
56 | { |
57 | struct xt_statistic_info *info = par->matchinfo; |
58 | |
59 | if (info->mode > XT_STATISTIC_MODE_MAX || |
60 | info->flags & ~XT_STATISTIC_MASK) |
61 | return false; |
62 | |
63 | info->master = kzalloc(sizeof(*info->master), GFP_KERNEL); |
64 | if (info->master == NULL) { |
65 | printk(KERN_ERR KBUILD_MODNAME ": Out of memory\n"); |
66 | return false; |
67 | } |
68 | info->master->count = info->u.nth.count; |
69 | |
70 | return true; |
71 | } |
72 | |
73 | static void statistic_mt_destroy(const struct xt_mtdtor_param *par) |
74 | { |
75 | const struct xt_statistic_info *info = par->matchinfo; |
76 | |
77 | kfree(info->master); |
78 | } |
79 | |
80 | static struct xt_match xt_statistic_mt_reg __read_mostly = { |
81 | .name = "statistic", |
82 | .revision = 0, |
83 | .family = NFPROTO_UNSPEC, |
84 | .match = statistic_mt, |
85 | .checkentry = statistic_mt_check, |
86 | .destroy = statistic_mt_destroy, |
87 | .matchsize = sizeof(struct xt_statistic_info), |
88 | .me = THIS_MODULE, |
89 | }; |
90 | |
91 | static int __init statistic_mt_init(void) |
92 | { |
93 | return xt_register_match(&xt_statistic_mt_reg); |
94 | } |
95 | |
96 | static void __exit statistic_mt_exit(void) |
97 | { |
98 | xt_unregister_match(&xt_statistic_mt_reg); |
99 | } |
100 | |
101 | module_init(statistic_mt_init); |
102 | module_exit(statistic_mt_exit); |
103 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9