Root/
1 | /* |
2 | * (C) 2007 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 | #include <linux/module.h> |
9 | #include <linux/skbuff.h> |
10 | #include <linux/gen_stats.h> |
11 | |
12 | #include <linux/netfilter/x_tables.h> |
13 | #include <linux/netfilter/xt_rateest.h> |
14 | #include <net/netfilter/xt_rateest.h> |
15 | |
16 | |
17 | static bool |
18 | xt_rateest_mt(const struct sk_buff *skb, struct xt_action_param *par) |
19 | { |
20 | const struct xt_rateest_match_info *info = par->matchinfo; |
21 | struct gnet_stats_rate_est *r; |
22 | u_int32_t bps1, bps2, pps1, pps2; |
23 | bool ret = true; |
24 | |
25 | spin_lock_bh(&info->est1->lock); |
26 | r = &info->est1->rstats; |
27 | if (info->flags & XT_RATEEST_MATCH_DELTA) { |
28 | bps1 = info->bps1 >= r->bps ? info->bps1 - r->bps : 0; |
29 | pps1 = info->pps1 >= r->pps ? info->pps1 - r->pps : 0; |
30 | } else { |
31 | bps1 = r->bps; |
32 | pps1 = r->pps; |
33 | } |
34 | spin_unlock_bh(&info->est1->lock); |
35 | |
36 | if (info->flags & XT_RATEEST_MATCH_ABS) { |
37 | bps2 = info->bps2; |
38 | pps2 = info->pps2; |
39 | } else { |
40 | spin_lock_bh(&info->est2->lock); |
41 | r = &info->est2->rstats; |
42 | if (info->flags & XT_RATEEST_MATCH_DELTA) { |
43 | bps2 = info->bps2 >= r->bps ? info->bps2 - r->bps : 0; |
44 | pps2 = info->pps2 >= r->pps ? info->pps2 - r->pps : 0; |
45 | } else { |
46 | bps2 = r->bps; |
47 | pps2 = r->pps; |
48 | } |
49 | spin_unlock_bh(&info->est2->lock); |
50 | } |
51 | |
52 | switch (info->mode) { |
53 | case XT_RATEEST_MATCH_LT: |
54 | if (info->flags & XT_RATEEST_MATCH_BPS) |
55 | ret &= bps1 < bps2; |
56 | if (info->flags & XT_RATEEST_MATCH_PPS) |
57 | ret &= pps1 < pps2; |
58 | break; |
59 | case XT_RATEEST_MATCH_GT: |
60 | if (info->flags & XT_RATEEST_MATCH_BPS) |
61 | ret &= bps1 > bps2; |
62 | if (info->flags & XT_RATEEST_MATCH_PPS) |
63 | ret &= pps1 > pps2; |
64 | break; |
65 | case XT_RATEEST_MATCH_EQ: |
66 | if (info->flags & XT_RATEEST_MATCH_BPS) |
67 | ret &= bps1 == bps2; |
68 | if (info->flags & XT_RATEEST_MATCH_PPS) |
69 | ret &= pps1 == pps2; |
70 | break; |
71 | } |
72 | |
73 | ret ^= info->flags & XT_RATEEST_MATCH_INVERT ? true : false; |
74 | return ret; |
75 | } |
76 | |
77 | static int xt_rateest_mt_checkentry(const struct xt_mtchk_param *par) |
78 | { |
79 | struct xt_rateest_match_info *info = par->matchinfo; |
80 | struct xt_rateest *est1, *est2; |
81 | int ret = false; |
82 | |
83 | if (hweight32(info->flags & (XT_RATEEST_MATCH_ABS | |
84 | XT_RATEEST_MATCH_REL)) != 1) |
85 | goto err1; |
86 | |
87 | if (!(info->flags & (XT_RATEEST_MATCH_BPS | XT_RATEEST_MATCH_PPS))) |
88 | goto err1; |
89 | |
90 | switch (info->mode) { |
91 | case XT_RATEEST_MATCH_EQ: |
92 | case XT_RATEEST_MATCH_LT: |
93 | case XT_RATEEST_MATCH_GT: |
94 | break; |
95 | default: |
96 | goto err1; |
97 | } |
98 | |
99 | ret = -ENOENT; |
100 | est1 = xt_rateest_lookup(info->name1); |
101 | if (!est1) |
102 | goto err1; |
103 | |
104 | if (info->flags & XT_RATEEST_MATCH_REL) { |
105 | est2 = xt_rateest_lookup(info->name2); |
106 | if (!est2) |
107 | goto err2; |
108 | } else |
109 | est2 = NULL; |
110 | |
111 | |
112 | info->est1 = est1; |
113 | info->est2 = est2; |
114 | return 0; |
115 | |
116 | err2: |
117 | xt_rateest_put(est1); |
118 | err1: |
119 | return -EINVAL; |
120 | } |
121 | |
122 | static void xt_rateest_mt_destroy(const struct xt_mtdtor_param *par) |
123 | { |
124 | struct xt_rateest_match_info *info = par->matchinfo; |
125 | |
126 | xt_rateest_put(info->est1); |
127 | if (info->est2) |
128 | xt_rateest_put(info->est2); |
129 | } |
130 | |
131 | static struct xt_match xt_rateest_mt_reg __read_mostly = { |
132 | .name = "rateest", |
133 | .revision = 0, |
134 | .family = NFPROTO_UNSPEC, |
135 | .match = xt_rateest_mt, |
136 | .checkentry = xt_rateest_mt_checkentry, |
137 | .destroy = xt_rateest_mt_destroy, |
138 | .matchsize = sizeof(struct xt_rateest_match_info), |
139 | .me = THIS_MODULE, |
140 | }; |
141 | |
142 | static int __init xt_rateest_mt_init(void) |
143 | { |
144 | return xt_register_match(&xt_rateest_mt_reg); |
145 | } |
146 | |
147 | static void __exit xt_rateest_mt_fini(void) |
148 | { |
149 | xt_unregister_match(&xt_rateest_mt_reg); |
150 | } |
151 | |
152 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); |
153 | MODULE_LICENSE("GPL"); |
154 | MODULE_DESCRIPTION("xtables rate estimator match"); |
155 | MODULE_ALIAS("ipt_rateest"); |
156 | MODULE_ALIAS("ip6t_rateest"); |
157 | module_init(xt_rateest_mt_init); |
158 | module_exit(xt_rateest_mt_fini); |
159 |
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