fbc648b1bc011f6afe8ccf829d4691eac73e1023
[openwrt-10.03/.git] / target / linux / generic-2.4 / patches / 621-netfilter_random.patch
1 --- a/Documentation/Configure.help
2 +++ b/Documentation/Configure.help
3 @@ -2914,6 +2914,15 @@ CONFIG_IP_NF_MATCH_MAC
4    If you want to compile it as a module, say M here and read
5    <file:Documentation/modules.txt>.  If unsure, say `N'.
6  
7 +Random match support
8 +CONFIG_IP_NF_MATCH_RANDOM
9 +  This option adds a `random' match,
10 +  which allow you to match packets randomly
11 +  following a given probability.
12
13 +  If you want to compile it as a module, say M here and read
14 +  Documentation/modules.txt.  If unsure, say `N'.
15 +
16  Netfilter MARK match support
17  CONFIG_IP_NF_MATCH_MARK
18    Netfilter mark matching allows you to match packets based on the
19 @@ -3229,6 +3238,7 @@ CONFIG_IP_NF_MATCH_HELPER
20    If you want to compile it as a module, say M here and read
21    Documentation/modules.txt.  If unsure, say `Y'.
22  
23 +
24  TCPMSS match support
25  CONFIG_IP_NF_MATCH_TCPMSS
26    This option adds a `tcpmss' match, which allows you to examine the
27 @@ -3318,6 +3328,14 @@ CONFIG_IP6_NF_MATCH_MAC
28    If you want to compile it as a module, say M here and read
29    <file:Documentation/modules.txt>.  If unsure, say `N'.
30  
31 +CONFIG_IP6_NF_MATCH_RANDOM
32 +  This option adds a `random' match,
33 +  which allow you to match packets randomly
34 +  following a given probability.
35
36 +  If you want to compile it as a module, say M here and read
37 +  Documentation/modules.txt.  If unsure, say `N'.
38 +
39  length match support
40  CONFIG_IP6_NF_MATCH_LENGTH
41    This option allows you to match the length of a packet against a
42 --- /dev/null
43 +++ b/include/linux/netfilter_ipv4/ipt_random.h
44 @@ -0,0 +1,11 @@
45 +#ifndef _IPT_RAND_H
46 +#define _IPT_RAND_H
47 +
48 +#include <linux/param.h>
49 +#include <linux/types.h>
50 +
51 +struct ipt_rand_info {
52 +       u_int8_t average;
53 +};
54 +
55 +#endif /*_IPT_RAND_H*/
56 --- /dev/null
57 +++ b/include/linux/netfilter_ipv6/ip6t_random.h
58 @@ -0,0 +1,11 @@
59 +#ifndef _IP6T_RAND_H
60 +#define _IP6T_RAND_H
61 +
62 +#include <linux/param.h>
63 +#include <linux/types.h>
64 +
65 +struct ip6t_rand_info {
66 +       u_int8_t average;
67 +};
68 +
69 +#endif /*_IP6T_RAND_H*/
70 --- a/net/ipv4/netfilter/Config.in
71 +++ b/net/ipv4/netfilter/Config.in
72 @@ -32,6 +32,7 @@ if [ "$CONFIG_IP_NF_IPTABLES" != "n" ]; 
73    dep_tristate '  netfilter MARK match support' CONFIG_IP_NF_MATCH_MARK $CONFIG_IP_NF_IPTABLES
74    dep_tristate '  Multiple port match support' CONFIG_IP_NF_MATCH_MULTIPORT $CONFIG_IP_NF_IPTABLES
75    dep_tristate '  TOS match support' CONFIG_IP_NF_MATCH_TOS $CONFIG_IP_NF_IPTABLES
76 +  dep_tristate '  random match support' CONFIG_IP_NF_MATCH_RANDOM $CONFIG_IP_NF_IPTABLES
77    dep_tristate '  condition match support' CONFIG_IP_NF_MATCH_CONDITION $CONFIG_IP_NF_IPTABLES
78    dep_tristate '  recent match support' CONFIG_IP_NF_MATCH_RECENT $CONFIG_IP_NF_IPTABLES
79    dep_tristate '  ECN match support' CONFIG_IP_NF_MATCH_ECN $CONFIG_IP_NF_IPTABLES
80 --- /dev/null
81 +++ b/net/ipv4/netfilter/ipt_random.c
82 @@ -0,0 +1,96 @@
83 +/*
84 +  This is a module which is used for a "random" match support.
85 +  This file is distributed under the terms of the GNU General Public
86 +  License (GPL). Copies of the GPL can be obtained from:
87 +     ftp://prep.ai.mit.edu/pub/gnu/GPL
88 +
89 +  2001-10-14 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
90 +*/
91 +
92 +#include <linux/module.h>
93 +#include <linux/skbuff.h>
94 +#include <linux/ip.h>
95 +#include <linux/random.h>
96 +#include <net/tcp.h>
97 +#include <linux/spinlock.h>
98 +#include <linux/netfilter_ipv4/ip_tables.h>
99 +#include <linux/netfilter_ipv4/ipt_random.h>
100 +
101 +MODULE_LICENSE("GPL");
102 +
103 +static int
104 +ipt_rand_match(const struct sk_buff *pskb,
105 +              const struct net_device *in,
106 +              const struct net_device *out,
107 +              const void *matchinfo,
108 +              int offset,
109 +              const void *hdr,
110 +              u_int16_t datalen,
111 +              int *hotdrop)
112 +{
113 +       /* Parameters from userspace */
114 +       const struct ipt_rand_info *info = matchinfo;
115 +       u_int8_t random_number;
116 +
117 +       /* get 1 random number from the kernel random number generation routine */
118 +       get_random_bytes((void *)(&random_number), 1);
119 +
120 +       /* Do we match ? */
121 +       if (random_number <= info->average)
122 +               return 1;
123 +       else
124 +               return 0;
125 +}
126 +
127 +static int
128 +ipt_rand_checkentry(const char *tablename,
129 +                  const struct ipt_ip *e,
130 +                  void *matchinfo,
131 +                  unsigned int matchsize,
132 +                  unsigned int hook_mask)
133 +{
134 +       /* Parameters from userspace */
135 +       const struct ipt_rand_info *info = matchinfo;
136 +
137 +       if (matchsize != IPT_ALIGN(sizeof(struct ipt_rand_info))) {
138 +               printk("ipt_random: matchsize %u != %u\n", matchsize,
139 +                      IPT_ALIGN(sizeof(struct ipt_rand_info)));
140 +               return 0;
141 +       }
142 +
143 +       /* must be  1 <= average % <= 99 */
144 +       /* 1  x 2.55 = 2   */
145 +       /* 99 x 2.55 = 252 */
146 +       if ((info->average < 2) || (info->average > 252)) {
147 +               printk("ipt_random:  invalid average %u\n", info->average);
148 +               return 0;
149 +       }
150 +
151 +       return 1;
152 +}
153 +
154 +static struct ipt_match ipt_rand_reg = { 
155 +       {NULL, NULL},
156 +       "random",
157 +       ipt_rand_match,
158 +       ipt_rand_checkentry,
159 +       NULL,
160 +       THIS_MODULE };
161 +
162 +static int __init init(void)
163 +{
164 +       if (ipt_register_match(&ipt_rand_reg))
165 +               return -EINVAL;
166 +
167 +       printk("ipt_random match loaded\n");
168 +       return 0;
169 +}
170 +
171 +static void __exit fini(void)
172 +{
173 +       ipt_unregister_match(&ipt_rand_reg);
174 +       printk("ipt_random match unloaded\n");
175 +}
176 +
177 +module_init(init);
178 +module_exit(fini);
179 --- a/net/ipv4/netfilter/Makefile
180 +++ b/net/ipv4/netfilter/Makefile
181 @@ -93,6 +93,8 @@ obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_o
182  obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
183  obj-$(CONFIG_IP_NF_MATCH_CONDITION) += ipt_condition.o
184  
185 +obj-$(CONFIG_IP_NF_MATCH_RANDOM) += ipt_random.o
186 +
187  obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
188  
189  obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
190 --- a/net/ipv6/netfilter/Config.in
191 +++ b/net/ipv6/netfilter/Config.in
192 @@ -19,6 +19,7 @@ if [ "$CONFIG_IP6_NF_IPTABLES" != "n" ];
193    dep_tristate '  limit match support' CONFIG_IP6_NF_MATCH_LIMIT $CONFIG_IP6_NF_IPTABLES
194    dep_tristate '  condition match support' CONFIG_IP6_NF_MATCH_CONDITION $CONFIG_IP6_NF_IPTABLES
195    dep_tristate '  MAC address match support' CONFIG_IP6_NF_MATCH_MAC $CONFIG_IP6_NF_IPTABLES
196 +  dep_tristate '  Random match support' CONFIG_IP6_NF_MATCH_RANDOM $CONFIG_IP6_NF_IPTABLES
197    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
198      dep_tristate '  Routing header match support (EXPERIMENTAL)' CONFIG_IP6_NF_MATCH_RT $CONFIG_IP6_NF_IPTABLES
199    fi
200 --- /dev/null
201 +++ b/net/ipv6/netfilter/ip6t_random.c
202 @@ -0,0 +1,97 @@
203 +/*
204 +  This is a module which is used for a "random" match support.
205 +  This file is distributed under the terms of the GNU General Public
206 +  License (GPL). Copies of the GPL can be obtained from:
207 +     ftp://prep.ai.mit.edu/pub/gnu/GPL
208 +
209 +  2001-10-14 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
210 +  2003-04-30 Maciej Soltysiak <solt@dns.toxicfilms.tv> : IPv6 Port
211 +*/
212 +
213 +#include <linux/module.h>
214 +#include <linux/skbuff.h>
215 +#include <linux/ip.h>
216 +#include <linux/random.h>
217 +#include <net/tcp.h>
218 +#include <linux/spinlock.h>
219 +#include <linux/netfilter_ipv6/ip6_tables.h>
220 +#include <linux/netfilter_ipv6/ip6t_random.h>
221 +
222 +MODULE_LICENSE("GPL");
223 +
224 +static int
225 +ip6t_rand_match(const struct sk_buff *pskb,
226 +              const struct net_device *in,
227 +              const struct net_device *out,
228 +              const void *matchinfo,
229 +              int offset,
230 +              const void *hdr,
231 +              u_int16_t datalen,
232 +              int *hotdrop)
233 +{
234 +       /* Parameters from userspace */
235 +       const struct ip6t_rand_info *info = matchinfo;
236 +       u_int8_t random_number;
237 +
238 +       /* get 1 random number from the kernel random number generation routine */
239 +       get_random_bytes((void *)(&random_number), 1);
240 +
241 +       /* Do we match ? */
242 +       if (random_number <= info->average)
243 +               return 1;
244 +       else
245 +               return 0;
246 +}
247 +
248 +static int
249 +ip6t_rand_checkentry(const char *tablename,
250 +                  const struct ip6t_ip6 *e,
251 +                  void *matchinfo,
252 +                  unsigned int matchsize,
253 +                  unsigned int hook_mask)
254 +{
255 +       /* Parameters from userspace */
256 +       const struct ip6t_rand_info *info = matchinfo;
257 +
258 +       if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_rand_info))) {
259 +               printk("ip6t_random: matchsize %u != %u\n", matchsize,
260 +                      IP6T_ALIGN(sizeof(struct ip6t_rand_info)));
261 +               return 0;
262 +       }
263 +
264 +       /* must be  1 <= average % <= 99 */
265 +       /* 1  x 2.55 = 2   */
266 +       /* 99 x 2.55 = 252 */
267 +       if ((info->average < 2) || (info->average > 252)) {
268 +               printk("ip6t_random:  invalid average %u\n", info->average);
269 +               return 0;
270 +       }
271 +
272 +       return 1;
273 +}
274 +
275 +static struct ip6t_match ip6t_rand_reg = { 
276 +       {NULL, NULL},
277 +       "random",
278 +       ip6t_rand_match,
279 +       ip6t_rand_checkentry,
280 +       NULL,
281 +       THIS_MODULE };
282 +
283 +static int __init init(void)
284 +{
285 +       if (ip6t_register_match(&ip6t_rand_reg))
286 +               return -EINVAL;
287 +
288 +       printk("ip6t_random match loaded\n");
289 +       return 0;
290 +}
291 +
292 +static void __exit fini(void)
293 +{
294 +       ip6t_unregister_match(&ip6t_rand_reg);
295 +       printk("ip6t_random match unloaded\n");
296 +}
297 +
298 +module_init(init);
299 +module_exit(fini);
300 --- a/net/ipv6/netfilter/Makefile
301 +++ b/net/ipv6/netfilter/Makefile
302 @@ -32,6 +32,7 @@ obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t
303  obj-$(CONFIG_IP6_NF_TARGET_IMQ) += ip6t_IMQ.o
304  obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
305  obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
306 +obj-$(CONFIG_IP6_NF_MATCH_RANDOM) += ip6t_random.o
307  obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
308  
309  include $(TOPDIR)/Rules.make