]>
Commit | Line | Data |
---|---|---|
c7445b87 AF |
1 | --- linux-2.6.20.7-original/drivers/net/imq.c 1970-01-01 02:00:00.000000000 +0200\r |
2 | +++ linux-2.6.20.7/drivers/net/imq.c 2007-04-19 16:22:34.000000000 +0300\r | |
3 | @@ -0,0 +1,402 @@\r | |
4 | +/*\r | |
5 | + * Pseudo-driver for the intermediate queue device.\r | |
6 | + *\r | |
7 | + * This program is free software; you can redistribute it and/or\r | |
8 | + * modify it under the terms of the GNU General Public License\r | |
9 | + * as published by the Free Software Foundation; either version\r | |
10 | + * 2 of the License, or (at your option) any later version.\r | |
11 | + *\r | |
12 | + * Authors: Patrick McHardy, <kaber@trash.net>\r | |
13 | + *\r | |
14 | + * The first version was written by Martin Devera, <devik@cdi.cz>\r | |
15 | + *\r | |
16 | + * Credits: Jan Rafaj <imq2t@cedric.vabo.cz>\r | |
17 | + * - Update patch to 2.4.21\r | |
18 | + * Sebastian Strollo <sstrollo@nortelnetworks.com>\r | |
19 | + * - Fix "Dead-loop on netdevice imq"-issue\r | |
20 | + * Marcel Sebek <sebek64@post.cz>\r | |
21 | + * - Update to 2.6.2-rc1\r | |
22 | + *\r | |
23 | + * After some time of inactivity there is a group taking care\r | |
24 | + * of IMQ again: http://www.linuximq.net\r | |
25 | + *\r | |
26 | + *\r | |
27 | + * 2004/06/30 - New version of IMQ patch to kernels <=2.6.7 including\r | |
28 | + * the following changes:\r | |
29 | + *\r | |
30 | + * - Correction of ipv6 support "+"s issue (Hasso Tepper)\r | |
31 | + * - Correction of imq_init_devs() issue that resulted in\r | |
32 | + * kernel OOPS unloading IMQ as module (Norbert Buchmuller)\r | |
33 | + * - Addition of functionality to choose number of IMQ devices\r | |
34 | + * during kernel config (Andre Correa)\r | |
35 | + * - Addition of functionality to choose how IMQ hooks on\r | |
36 | + * PRE and POSTROUTING (after or before NAT) (Andre Correa)\r | |
37 | + * - Cosmetic corrections (Norbert Buchmuller) (Andre Correa)\r | |
38 | + *\r | |
39 | + *\r | |
40 | + * 2005/12/16 - IMQ versions between 2.6.7 and 2.6.13 were\r | |
41 | + * released with almost no problems. 2.6.14-x was released\r | |
42 | + * with some important changes: nfcache was removed; After\r | |
43 | + * some weeks of trouble we figured out that some IMQ fields\r | |
44 | + * in skb were missing in skbuff.c - skb_clone and copy_skb_header.\r | |
45 | + * These functions are correctly patched by this new patch version.\r | |
46 | + *\r | |
47 | + * Thanks for all who helped to figure out all the problems with\r | |
48 | + * 2.6.14.x: Patrick McHardy, Rune Kock, VeNoMouS, Max CtRiX,\r | |
49 | + * Kevin Shanahan, Richard Lucassen, Valery Dachev (hopefully\r | |
50 | + * I didn't forget anybody). I apologize again for my lack of time.\r | |
51 | + *\r | |
52 | + * More info at: http://www.linuximq.net/ (Andre Correa)\r | |
53 | + */\r | |
54 | +\r | |
55 | +#include <linux/module.h>\r | |
56 | +#include <linux/kernel.h>\r | |
57 | +#include <linux/moduleparam.h>\r | |
58 | +#include <linux/skbuff.h>\r | |
59 | +#include <linux/netdevice.h>\r | |
60 | +#include <linux/rtnetlink.h>\r | |
61 | +#include <linux/if_arp.h>\r | |
62 | +#include <linux/netfilter.h>\r | |
63 | +#include <linux/netfilter_ipv4.h>\r | |
64 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)\r | |
65 | + #include <linux/netfilter_ipv6.h>\r | |
66 | +#endif\r | |
67 | +#include <linux/imq.h>\r | |
68 | +#include <net/pkt_sched.h>\r | |
69 | +\r | |
70 | +extern int qdisc_restart1(struct net_device *dev);\r | |
71 | +\r | |
72 | +static nf_hookfn imq_nf_hook;\r | |
73 | +\r | |
74 | +static struct nf_hook_ops imq_ingress_ipv4 = {\r | |
75 | + .hook = imq_nf_hook,\r | |
76 | + .owner = THIS_MODULE,\r | |
77 | + .pf = PF_INET,\r | |
78 | + .hooknum = NF_IP_PRE_ROUTING,\r | |
79 | +#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)\r | |
80 | + .priority = NF_IP_PRI_MANGLE + 1\r | |
81 | +#else\r | |
82 | + .priority = NF_IP_PRI_NAT_DST + 1\r | |
83 | +#endif\r | |
84 | +};\r | |
85 | +\r | |
86 | +static struct nf_hook_ops imq_egress_ipv4 = {\r | |
87 | + .hook = imq_nf_hook,\r | |
88 | + .owner = THIS_MODULE,\r | |
89 | + .pf = PF_INET,\r | |
90 | + .hooknum = NF_IP_POST_ROUTING,\r | |
91 | +#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)\r | |
92 | + .priority = NF_IP_PRI_LAST\r | |
93 | +#else\r | |
94 | + .priority = NF_IP_PRI_NAT_SRC - 1\r | |
95 | +#endif\r | |
96 | +};\r | |
97 | +\r | |
98 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)\r | |
99 | +static struct nf_hook_ops imq_ingress_ipv6 = {\r | |
100 | + .hook = imq_nf_hook,\r | |
101 | + .owner = THIS_MODULE,\r | |
102 | + .pf = PF_INET6,\r | |
103 | + .hooknum = NF_IP6_PRE_ROUTING,\r | |
104 | +#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)\r | |
105 | + .priority = NF_IP6_PRI_MANGLE + 1\r | |
106 | +#else\r | |
107 | + .priority = NF_IP6_PRI_NAT_DST + 1\r | |
108 | +#endif\r | |
109 | +};\r | |
110 | +\r | |
111 | +static struct nf_hook_ops imq_egress_ipv6 = {\r | |
112 | + .hook = imq_nf_hook,\r | |
113 | + .owner = THIS_MODULE,\r | |
114 | + .pf = PF_INET6,\r | |
115 | + .hooknum = NF_IP6_POST_ROUTING,\r | |
116 | +#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)\r | |
117 | + .priority = NF_IP6_PRI_LAST\r | |
118 | +#else\r | |
119 | + .priority = NF_IP6_PRI_NAT_SRC - 1\r | |
120 | +#endif\r | |
121 | +};\r | |
122 | +#endif\r | |
123 | +\r | |
124 | +#if defined(CONFIG_IMQ_NUM_DEVS)\r | |
125 | +static unsigned int numdevs = CONFIG_IMQ_NUM_DEVS;\r | |
126 | +#else\r | |
127 | +static unsigned int numdevs = 2;\r | |
128 | +#endif\r | |
129 | +\r | |
130 | +static struct net_device *imq_devs;\r | |
131 | +\r | |
132 | +static struct net_device_stats *imq_get_stats(struct net_device *dev)\r | |
133 | +{\r | |
134 | + return (struct net_device_stats *)dev->priv;\r | |
135 | +}\r | |
136 | +\r | |
137 | +/* called for packets kfree'd in qdiscs at places other than enqueue */\r | |
138 | +static void imq_skb_destructor(struct sk_buff *skb)\r | |
139 | +{\r | |
140 | + struct nf_info *info = skb->nf_info;\r | |
141 | +\r | |
142 | + if (info) {\r | |
143 | + if (info->indev)\r | |
144 | + dev_put(info->indev);\r | |
145 | + if (info->outdev)\r | |
146 | + dev_put(info->outdev);\r | |
147 | + kfree(info);\r | |
148 | + }\r | |
149 | +}\r | |
150 | +\r | |
151 | +static int imq_dev_xmit(struct sk_buff *skb, struct net_device *dev)\r | |
152 | +{\r | |
153 | + struct net_device_stats *stats = (struct net_device_stats*) dev->priv;\r | |
154 | +\r | |
155 | + stats->tx_bytes += skb->len;\r | |
156 | + stats->tx_packets++;\r | |
157 | +\r | |
158 | + skb->imq_flags = 0;\r | |
159 | + skb->destructor = NULL;\r | |
160 | +\r | |
161 | + dev->trans_start = jiffies;\r | |
162 | + nf_reinject(skb, skb->nf_info, NF_ACCEPT);\r | |
163 | + return 0;\r | |
164 | +}\r | |
165 | +\r | |
166 | +static int imq_nf_queue(struct sk_buff *skb, struct nf_info *info, unsigned queue_num, void *data)\r | |
167 | +{\r | |
168 | + struct net_device *dev;\r | |
169 | + struct net_device_stats *stats;\r | |
170 | + struct sk_buff *skb2 = NULL;\r | |
171 | + struct Qdisc *q;\r | |
172 | + unsigned int index = skb->imq_flags&IMQ_F_IFMASK;\r | |
173 | + int ret = -1;\r | |
174 | +\r | |
175 | + if (index > numdevs)\r | |
176 | + return -1;\r | |
177 | +\r | |
178 | + dev = imq_devs + index;\r | |
179 | + if (!(dev->flags & IFF_UP)) {\r | |
180 | + skb->imq_flags = 0;\r | |
181 | + nf_reinject(skb, info, NF_ACCEPT);\r | |
182 | + return 0;\r | |
183 | + }\r | |
184 | + dev->last_rx = jiffies;\r | |
185 | +\r | |
186 | + if (skb->destructor) {\r | |
187 | + skb2 = skb;\r | |
188 | + skb = skb_clone(skb, GFP_ATOMIC);\r | |
189 | + if (!skb)\r | |
190 | + return -1;\r | |
191 | + }\r | |
192 | + skb->nf_info = info;\r | |
193 | +\r | |
194 | + stats = (struct net_device_stats *)dev->priv;\r | |
195 | + stats->rx_bytes+= skb->len;\r | |
196 | + stats->rx_packets++;\r | |
197 | +\r | |
198 | + spin_lock_bh(&dev->queue_lock);\r | |
199 | + q = dev->qdisc;\r | |
200 | + if (q->enqueue) {\r | |
201 | + q->enqueue(skb_get(skb), q);\r | |
202 | + if (skb_shared(skb)) {\r | |
203 | + skb->destructor = imq_skb_destructor;\r | |
204 | + kfree_skb(skb);\r | |
205 | + ret = 0;\r | |
206 | + }\r | |
207 | + }\r | |
208 | + if (spin_is_locked(&dev->_xmit_lock))\r | |
209 | + netif_schedule(dev);\r | |
210 | + else\r | |
211 | + while (!netif_queue_stopped(dev) && qdisc_restart1(dev) < 0)\r | |
212 | + /* NOTHING */;\r | |
213 | +\r | |
214 | + spin_unlock_bh(&dev->queue_lock);\r | |
215 | +\r | |
216 | + if (skb2)\r | |
217 | + kfree_skb(ret ? skb : skb2);\r | |
218 | +\r | |
219 | + return ret;\r | |
220 | +}\r | |
221 | +\r | |
222 | +static struct nf_queue_handler nfqh = {\r | |
223 | + .name = "imq",\r | |
224 | + .outfn = imq_nf_queue,\r | |
225 | +};\r | |
226 | +\r | |
227 | +static unsigned int imq_nf_hook(unsigned int hook, struct sk_buff **pskb,\r | |
228 | + const struct net_device *indev,\r | |
229 | + const struct net_device *outdev,\r | |
230 | + int (*okfn)(struct sk_buff *))\r | |
231 | +{\r | |
232 | + if ((*pskb)->imq_flags & IMQ_F_ENQUEUE)\r | |
233 | + return NF_QUEUE;\r | |
234 | +\r | |
235 | + return NF_ACCEPT;\r | |
236 | +}\r | |
237 | +\r | |
238 | +\r | |
239 | +static int __init imq_init_hooks(void)\r | |
240 | +{\r | |
241 | + int err;\r | |
242 | +\r | |
243 | + err = nf_register_queue_handler(PF_INET, &nfqh);\r | |
244 | + if (err > 0)\r | |
245 | + goto err1;\r | |
246 | + if ((err = nf_register_hook(&imq_ingress_ipv4)))\r | |
247 | + goto err2;\r | |
248 | + if ((err = nf_register_hook(&imq_egress_ipv4)))\r | |
249 | + goto err3;\r | |
250 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)\r | |
251 | + if ((err = nf_register_queue_handler(PF_INET6, &nfqh)))\r | |
252 | + goto err4;\r | |
253 | + if ((err = nf_register_hook(&imq_ingress_ipv6)))\r | |
254 | + goto err5;\r | |
255 | + if ((err = nf_register_hook(&imq_egress_ipv6)))\r | |
256 | + goto err6;\r | |
257 | +#endif\r | |
258 | +\r | |
259 | + return 0;\r | |
260 | +\r | |
261 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)\r | |
262 | +err6:\r | |
263 | + nf_unregister_hook(&imq_ingress_ipv6);\r | |
264 | +err5:\r | |
265 | + nf_unregister_queue_handler(PF_INET6);\r | |
266 | +err4:\r | |
267 | + nf_unregister_hook(&imq_egress_ipv6);\r | |
268 | +#endif\r | |
269 | +err3:\r | |
270 | + nf_unregister_hook(&imq_ingress_ipv4);\r | |
271 | +err2:\r | |
272 | + nf_unregister_queue_handler(PF_INET);\r | |
273 | +err1:\r | |
274 | + return err;\r | |
275 | +}\r | |
276 | +\r | |
277 | +static void __exit imq_unhook(void)\r | |
278 | +{\r | |
279 | + nf_unregister_hook(&imq_ingress_ipv4);\r | |
280 | + nf_unregister_hook(&imq_egress_ipv4);\r | |
281 | + nf_unregister_queue_handler(PF_INET);\r | |
282 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)\r | |
283 | + nf_unregister_hook(&imq_ingress_ipv6);\r | |
284 | + nf_unregister_hook(&imq_egress_ipv6);\r | |
285 | + nf_unregister_queue_handler(PF_INET6);\r | |
286 | +#endif\r | |
287 | +}\r | |
288 | +\r | |
289 | +static int __init imq_dev_init(struct net_device *dev)\r | |
290 | +{\r | |
291 | + dev->hard_start_xmit = imq_dev_xmit;\r | |
292 | + dev->type = ARPHRD_VOID;\r | |
293 | + dev->mtu = 16000;\r | |
294 | + dev->tx_queue_len = 11000;\r | |
295 | + dev->flags = IFF_NOARP;\r | |
296 | + dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);\r | |
297 | + if (dev->priv == NULL)\r | |
298 | + return -ENOMEM;\r | |
299 | + memset(dev->priv, 0, sizeof(struct net_device_stats));\r | |
300 | + dev->get_stats = imq_get_stats;\r | |
301 | +\r | |
302 | + return 0;\r | |
303 | +}\r | |
304 | +\r | |
305 | +static void imq_dev_uninit(struct net_device *dev)\r | |
306 | +{\r | |
307 | + kfree(dev->priv);\r | |
308 | +}\r | |
309 | +\r | |
310 | +static int __init imq_init_devs(void)\r | |
311 | +{\r | |
312 | + struct net_device *dev;\r | |
313 | + int i,j;\r | |
314 | + j = numdevs;\r | |
315 | +\r | |
316 | + if (!numdevs || numdevs > IMQ_MAX_DEVS) {\r | |
317 | + printk(KERN_ERR "IMQ: numdevs has to be betweed 1 and %u\n",\r | |
318 | + IMQ_MAX_DEVS);\r | |
319 | + return -EINVAL;\r | |
320 | + }\r | |
321 | +\r | |
322 | + imq_devs = kmalloc(sizeof(struct net_device) * numdevs, GFP_KERNEL);\r | |
323 | + if (!imq_devs)\r | |
324 | + return -ENOMEM;\r | |
325 | + memset(imq_devs, 0, sizeof(struct net_device) * numdevs);\r | |
326 | +\r | |
327 | + /* we start counting at zero */\r | |
328 | + numdevs--;\r | |
329 | +\r | |
330 | + for (i = 0, dev = imq_devs; i <= numdevs; i++, dev++) {\r | |
331 | + SET_MODULE_OWNER(dev);\r | |
332 | + strcpy(dev->name, "imq%d");\r | |
333 | + dev->init = imq_dev_init;\r | |
334 | + dev->uninit = imq_dev_uninit;\r | |
335 | +\r | |
336 | + if (register_netdev(dev) < 0)\r | |
337 | + goto err_register;\r | |
338 | + }\r | |
339 | + printk(KERN_INFO "IMQ starting with %u devices...\n", j);\r | |
340 | + return 0;\r | |
341 | +\r | |
342 | +err_register:\r | |
343 | + for (; i; i--)\r | |
344 | + unregister_netdev(--dev);\r | |
345 | + kfree(imq_devs);\r | |
346 | + return -EIO;\r | |
347 | +}\r | |
348 | +\r | |
349 | +static void imq_cleanup_devs(void)\r | |
350 | +{\r | |
351 | + int i;\r | |
352 | + struct net_device *dev = imq_devs;\r | |
353 | +\r | |
354 | + for (i = 0; i <= numdevs; i++)\r | |
355 | + unregister_netdev(dev++);\r | |
356 | +\r | |
357 | + kfree(imq_devs);\r | |
358 | +}\r | |
359 | +\r | |
360 | +static int __init imq_init_module(void)\r | |
361 | +{\r | |
362 | + int err;\r | |
363 | +\r | |
364 | + if ((err = imq_init_devs())) {\r | |
365 | + printk(KERN_ERR "IMQ: Error trying imq_init_devs()\n");\r | |
366 | + return err;\r | |
367 | + }\r | |
368 | + if ((err = imq_init_hooks())) {\r | |
369 | + printk(KERN_ERR "IMQ: Error trying imq_init_hooks()\n");\r | |
370 | + imq_cleanup_devs();\r | |
371 | + return err;\r | |
372 | + }\r | |
373 | +\r | |
374 | + printk(KERN_INFO "IMQ driver loaded successfully.\n");\r | |
375 | +\r | |
376 | +#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)\r | |
377 | + printk(KERN_INFO "\tHooking IMQ before NAT on PREROUTING.\n");\r | |
378 | +#else\r | |
379 | + printk(KERN_INFO "\tHooking IMQ after NAT on PREROUTING.\n");\r | |
380 | +#endif\r | |
381 | +#if defined(CONFIG_IMQ_BEHAVIOR_AB) || defined(CONFIG_IMQ_BEHAVIOR_BB)\r | |
382 | + printk(KERN_INFO "\tHooking IMQ before NAT on POSTROUTING.\n");\r | |
383 | +#else\r | |
384 | + printk(KERN_INFO "\tHooking IMQ after NAT on POSTROUTING.\n");\r | |
385 | +#endif\r | |
386 | +\r | |
387 | + return 0;\r | |
388 | +}\r | |
389 | +\r | |
390 | +static void __exit imq_cleanup_module(void)\r | |
391 | +{\r | |
392 | + imq_unhook();\r | |
393 | + imq_cleanup_devs();\r | |
394 | + printk(KERN_INFO "IMQ driver unloaded successfully.\n");\r | |
395 | +}\r | |
396 | +\r | |
397 | +\r | |
398 | +module_init(imq_init_module);\r | |
399 | +module_exit(imq_cleanup_module);\r | |
400 | +\r | |
401 | +module_param(numdevs, int, 0);\r | |
402 | +MODULE_PARM_DESC(numdevs, "number of IMQ devices (how many imq* devices will be created)");\r | |
403 | +MODULE_AUTHOR("http://www.linuximq.net");\r | |
404 | +MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information.");\r | |
405 | +MODULE_LICENSE("GPL");\r | |
406 | --- linux-2.6.20.7-original/drivers/net/Kconfig 2007-04-13 23:48:14.000000000 +0300\r | |
407 | +++ linux-2.6.20.7/drivers/net/Kconfig 2007-04-19 16:22:34.000000000 +0300\r | |
408 | @@ -96,6 +96,129 @@\r | |
409 | To compile this driver as a module, choose M here: the module\r | |
410 | will be called eql. If unsure, say N.\r | |
411 | \r | |
412 | +config IMQ\r | |
413 | + tristate "IMQ (intermediate queueing device) support"\r | |
414 | + depends on NETDEVICES && NETFILTER\r | |
415 | + ---help---\r | |
416 | + The IMQ device(s) is used as placeholder for QoS queueing\r | |
417 | + disciplines. Every packet entering/leaving the IP stack can be\r | |
418 | + directed through the IMQ device where it's enqueued/dequeued to the\r | |
419 | + attached qdisc. This allows you to treat network devices as classes\r | |
420 | + and distribute bandwidth among them. Iptables is used to specify\r | |
421 | + through which IMQ device, if any, packets travel.\r | |
422 | +\r | |
423 | + More information at: http://www.linuximq.net/\r | |
424 | +\r | |
425 | + To compile this driver as a module, choose M here: the module\r | |
426 | + will be called imq. If unsure, say N.\r | |
427 | +\r | |
428 | +choice\r | |
429 | + prompt "IMQ behavior (PRE/POSTROUTING)"\r | |
430 | + depends on IMQ\r | |
431 | + default IMQ_BEHAVIOR_AB\r | |
432 | + help\r | |
433 | +\r | |
434 | + This settings defines how IMQ behaves in respect to its\r | |
435 | + hooking in PREROUTING and POSTROUTING.\r | |
436 | +\r | |
437 | + IMQ can work in any of the following ways:\r | |
438 | +\r | |
439 | + PREROUTING | POSTROUTING\r | |
440 | + -----------------|-------------------\r | |
441 | + #1 After NAT | After NAT\r | |
442 | + #2 After NAT | Before NAT\r | |
443 | + #3 Before NAT | After NAT\r | |
444 | + #4 Before NAT | Before NAT\r | |
445 | +\r | |
446 | + The default behavior is to hook before NAT on PREROUTING\r | |
447 | + and after NAT on POSTROUTING (#3).\r | |
448 | +\r | |
449 | + This settings are specially usefull when trying to use IMQ\r | |
450 | + to shape NATed clients.\r | |
451 | +\r | |
452 | + More information can be found at: www.linuximq.net\r | |
453 | +\r | |
454 | + If not sure leave the default settings alone.\r | |
455 | +\r | |
456 | +config IMQ_BEHAVIOR_AA\r | |
457 | + bool "IMQ AA"\r | |
458 | + help\r | |
459 | + This settings defines how IMQ behaves in respect to its\r | |
460 | + hooking in PREROUTING and POSTROUTING.\r | |
461 | +\r | |
462 | + Choosing this option will make IMQ hook like this:\r | |
463 | +\r | |
464 | + PREROUTING: After NAT\r | |
465 | + POSTROUTING: After NAT\r | |
466 | +\r | |
467 | + More information can be found at: www.linuximq.net\r | |
468 | +\r | |
469 | + If not sure leave the default settings alone.\r | |
470 | +\r | |
471 | +config IMQ_BEHAVIOR_AB\r | |
472 | + bool "IMQ AB"\r | |
473 | + help\r | |
474 | + This settings defines how IMQ behaves in respect to its\r | |
475 | + hooking in PREROUTING and POSTROUTING.\r | |
476 | +\r | |
477 | + Choosing this option will make IMQ hook like this:\r | |
478 | +\r | |
479 | + PREROUTING: After NAT\r | |
480 | + POSTROUTING: Before NAT\r | |
481 | +\r | |
482 | + More information can be found at: www.linuximq.net\r | |
483 | +\r | |
484 | + If not sure leave the default settings alone.\r | |
485 | +\r | |
486 | +config IMQ_BEHAVIOR_BA\r | |
487 | + bool "IMQ BA"\r | |
488 | + help\r | |
489 | + This settings defines how IMQ behaves in respect to its\r | |
490 | + hooking in PREROUTING and POSTROUTING.\r | |
491 | +\r | |
492 | + Choosing this option will make IMQ hook like this:\r | |
493 | +\r | |
494 | + PREROUTING: Before NAT\r | |
495 | + POSTROUTING: After NAT\r | |
496 | +\r | |
497 | + More information can be found at: www.linuximq.net\r | |
498 | +\r | |
499 | + If not sure leave the default settings alone.\r | |
500 | +\r | |
501 | +config IMQ_BEHAVIOR_BB\r | |
502 | + bool "IMQ BB"\r | |
503 | + help\r | |
504 | + This settings defines how IMQ behaves in respect to its\r | |
505 | + hooking in PREROUTING and POSTROUTING.\r | |
506 | +\r | |
507 | + Choosing this option will make IMQ hook like this:\r | |
508 | +\r | |
509 | + PREROUTING: Before NAT\r | |
510 | + POSTROUTING: Before NAT\r | |
511 | +\r | |
512 | + More information can be found at: www.linuximq.net\r | |
513 | +\r | |
514 | + If not sure leave the default settings alone.\r | |
515 | +\r | |
516 | +endchoice\r | |
517 | +\r | |
518 | +config IMQ_NUM_DEVS\r | |
519 | +\r | |
520 | + int "Number of IMQ devices"\r | |
521 | + range 2 16\r | |
522 | + depends on IMQ\r | |
523 | + default "2"\r | |
524 | + help\r | |
525 | +\r | |
526 | + This settings defines how many IMQ devices will be \r | |
527 | + created.\r | |
528 | +\r | |
529 | + The default value is 2.\r | |
530 | +\r | |
531 | + More information can be found at: www.linuximq.net\r | |
532 | +\r | |
533 | + If not sure leave the default settings alone.\r | |
534 | +\r | |
535 | config TUN\r | |
536 | tristate "Universal TUN/TAP device driver support"\r | |
537 | select CRC32\r | |
538 | --- linux-2.6.20.7-original/drivers/net/Makefile 2007-04-13 23:48:14.000000000 +0300\r | |
539 | +++ linux-2.6.20.7/drivers/net/Makefile 2007-04-19 16:22:34.000000000 +0300\r | |
540 | @@ -124,6 +124,7 @@\r | |
541 | obj-$(CONFIG_SLHC) += slhc.o\r | |
542 | \r | |
543 | obj-$(CONFIG_DUMMY) += dummy.o\r | |
544 | +obj-$(CONFIG_IMQ) += imq.o\r | |
545 | obj-$(CONFIG_IFB) += ifb.o\r | |
546 | obj-$(CONFIG_DE600) += de600.o\r | |
547 | obj-$(CONFIG_DE620) += de620.o\r | |
548 | --- linux-2.6.20.7-original/include/linux/imq.h 1970-01-01 02:00:00.000000000 +0200\r | |
549 | +++ linux-2.6.20.7/include/linux/imq.h 2007-04-19 16:22:34.000000000 +0300\r | |
550 | @@ -0,0 +1,9 @@\r | |
551 | +#ifndef _IMQ_H\r | |
552 | +#define _IMQ_H\r | |
553 | +\r | |
554 | +#define IMQ_MAX_DEVS 16\r | |
555 | +\r | |
556 | +#define IMQ_F_IFMASK 0x7f\r | |
557 | +#define IMQ_F_ENQUEUE 0x80\r | |
558 | +\r | |
559 | +#endif /* _IMQ_H */\r | |
560 | --- linux-2.6.20.7-original/include/linux/netfilter_ipv4/ipt_IMQ.h 1970-01-01 02:00:00.000000000 +0200\r | |
561 | +++ linux-2.6.20.7/include/linux/netfilter_ipv4/ipt_IMQ.h 2007-04-19 16:22:34.000000000 +0300\r | |
562 | @@ -0,0 +1,8 @@\r | |
563 | +#ifndef _IPT_IMQ_H\r | |
564 | +#define _IPT_IMQ_H\r | |
565 | +\r | |
566 | +struct ipt_imq_info {\r | |
567 | + unsigned int todev; /* target imq device */\r | |
568 | +};\r | |
569 | +\r | |
570 | +#endif /* _IPT_IMQ_H */\r | |
571 | --- linux-2.6.20.7-original/include/linux/netfilter_ipv6/ip6t_IMQ.h 1970-01-01 02:00:00.000000000 +0200\r | |
572 | +++ linux-2.6.20.7/include/linux/netfilter_ipv6/ip6t_IMQ.h 2007-04-19 16:22:34.000000000 +0300\r | |
573 | @@ -0,0 +1,8 @@\r | |
574 | +#ifndef _IP6T_IMQ_H\r | |
575 | +#define _IP6T_IMQ_H\r | |
576 | +\r | |
577 | +struct ip6t_imq_info {\r | |
578 | + unsigned int todev; /* target imq device */\r | |
579 | +};\r | |
580 | +\r | |
581 | +#endif /* _IP6T_IMQ_H */\r | |
582 | --- linux-2.6.20.7-original/include/linux/skbuff.h 2007-04-13 23:48:14.000000000 +0300\r | |
583 | +++ linux-2.6.20.7/include/linux/skbuff.h 2007-04-19 16:22:34.000000000 +0300\r | |
584 | @@ -294,6 +294,10 @@\r | |
585 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)\r | |
586 | struct sk_buff *nfct_reasm;\r | |
587 | #endif\r | |
588 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)\r | |
589 | + unsigned char imq_flags;\r | |
590 | + struct nf_info *nf_info;\r | |
591 | +#endif\r | |
592 | #ifdef CONFIG_BRIDGE_NETFILTER\r | |
593 | struct nf_bridge_info *nf_bridge;\r | |
594 | #endif\r | |
595 | --- linux-2.6.20.7-original/net/core/dev.c 2007-04-13 23:48:14.000000000 +0300\r | |
596 | +++ linux-2.6.20.7/net/core/dev.c 2007-04-19 16:22:34.000000000 +0300\r | |
597 | @@ -94,6 +94,9 @@\r | |
598 | #include <linux/skbuff.h>\r | |
599 | #include <net/sock.h>\r | |
600 | #include <linux/rtnetlink.h>\r | |
601 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)\r | |
602 | +#include <linux/imq.h>\r | |
603 | +#endif\r | |
604 | #include <linux/proc_fs.h>\r | |
605 | #include <linux/seq_file.h>\r | |
606 | #include <linux/stat.h>\r | |
607 | @@ -1343,7 +1346,11 @@\r | |
608 | int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)\r | |
609 | {\r | |
610 | if (likely(!skb->next)) {\r | |
611 | - if (netdev_nit)\r | |
612 | + if (netdev_nit\r | |
613 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)\r | |
614 | + && !(skb->imq_flags & IMQ_F_ENQUEUE)\r | |
615 | +#endif\r | |
616 | + )\r | |
617 | dev_queue_xmit_nit(skb, dev);\r | |
618 | \r | |
619 | if (netif_needs_gso(dev, skb)) {\r | |
620 | --- linux-2.6.20.7-original/net/core/skbuff.c 2007-04-13 23:48:14.000000000 +0300\r | |
621 | +++ linux-2.6.20.7/net/core/skbuff.c 2007-04-19 16:22:34.000000000 +0300\r | |
622 | @@ -486,6 +486,10 @@\r | |
623 | C(nfct_reasm);\r | |
624 | nf_conntrack_get_reasm(skb->nfct_reasm);\r | |
625 | #endif\r | |
626 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)\r | |
627 | + C(imq_flags);\r | |
628 | + C(nf_info);\r | |
629 | +#endif /*CONFIG_IMQ*/\r | |
630 | #ifdef CONFIG_BRIDGE_NETFILTER\r | |
631 | C(nf_bridge);\r | |
632 | nf_bridge_get(skb->nf_bridge);\r | |
633 | @@ -550,6 +554,10 @@\r | |
634 | #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)\r | |
635 | new->ipvs_property = old->ipvs_property;\r | |
636 | #endif\r | |
637 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)\r | |
638 | + new->imq_flags = old->imq_flags;\r | |
639 | + new->nf_info = old->nf_info;\r | |
640 | +#endif /*CONFIG_IMQ*/\r | |
641 | #ifdef CONFIG_BRIDGE_NETFILTER\r | |
642 | new->nf_bridge = old->nf_bridge;\r | |
643 | nf_bridge_get(old->nf_bridge);\r | |
644 | --- linux-2.6.20.7-original/net/ipv4/netfilter/ipt_IMQ.c 1970-01-01 02:00:00.000000000 +0200\r | |
645 | +++ linux-2.6.20.7/net/ipv4/netfilter/ipt_IMQ.c 2007-04-19 16:22:34.000000000 +0300\r | |
646 | @@ -0,0 +1,71 @@\r | |
647 | +/*\r | |
648 | + * This target marks packets to be enqueued to an imq device\r | |
649 | + */\r | |
650 | +#include <linux/module.h>\r | |
651 | +#include <linux/skbuff.h>\r | |
652 | +#include <linux/netfilter_ipv4/ip_tables.h>\r | |
653 | +#include <linux/netfilter_ipv4/ipt_IMQ.h>\r | |
654 | +#include <linux/imq.h>\r | |
655 | +\r | |
656 | +static unsigned int imq_target(struct sk_buff **pskb,\r | |
657 | + const struct net_device *in,\r | |
658 | + const struct net_device *out,\r | |
659 | + unsigned int hooknum,\r | |
660 | + const struct xt_target *target,\r | |
661 | + const void *targinfo)\r | |
662 | +{\r | |
663 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)targinfo;\r | |
664 | +\r | |
665 | + (*pskb)->imq_flags = mr->todev | IMQ_F_ENQUEUE;\r | |
666 | +\r | |
667 | + return IPT_CONTINUE;\r | |
668 | +}\r | |
669 | +\r | |
670 | +static int imq_checkentry(const char *tablename,\r | |
671 | + const void *e,\r | |
672 | + const struct xt_target *target,\r | |
673 | + void *targinfo,\r | |
674 | + unsigned int hook_mask)\r | |
675 | +{\r | |
676 | + struct ipt_imq_info *mr;\r | |
677 | +\r | |
678 | + mr = (struct ipt_imq_info*)targinfo;\r | |
679 | +\r | |
680 | + if (mr->todev > IMQ_MAX_DEVS) {\r | |
681 | + printk(KERN_WARNING\r | |
682 | + "IMQ: invalid device specified, highest is %u\n",\r | |
683 | + IMQ_MAX_DEVS);\r | |
684 | + return 0;\r | |
685 | + }\r | |
686 | +\r | |
687 | + return 1;\r | |
688 | +}\r | |
689 | +\r | |
690 | +static struct ipt_target ipt_imq_reg = {\r | |
691 | + .name = "IMQ",\r | |
692 | + .target = imq_target,\r | |
693 | + .targetsize = sizeof(struct ipt_imq_info),\r | |
694 | + .checkentry = imq_checkentry,\r | |
695 | + .me = THIS_MODULE,\r | |
696 | + .table = "mangle"\r | |
697 | +};\r | |
698 | +\r | |
699 | +static int __init init(void)\r | |
700 | +{\r | |
701 | + if (ipt_register_target(&ipt_imq_reg))\r | |
702 | + return -EINVAL;\r | |
703 | +\r | |
704 | + return 0;\r | |
705 | +}\r | |
706 | +\r | |
707 | +static void __exit fini(void)\r | |
708 | +{\r | |
709 | + ipt_unregister_target(&ipt_imq_reg);\r | |
710 | +}\r | |
711 | +\r | |
712 | +module_init(init);\r | |
713 | +module_exit(fini);\r | |
714 | +\r | |
715 | +MODULE_AUTHOR("http://www.linuximq.net");\r | |
716 | +MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information.");\r | |
717 | +MODULE_LICENSE("GPL");\r | |
718 | --- linux-2.6.20.7-original/net/ipv4/netfilter/Kconfig 2007-04-13 23:48:14.000000000 +0300\r | |
719 | +++ linux-2.6.20.7/net/ipv4/netfilter/Kconfig 2007-04-19 16:22:34.000000000 +0300\r | |
720 | @@ -591,6 +591,17 @@\r | |
721 | \r | |
722 | To compile it as a module, choose M here. If unsure, say N.\r | |
723 | \r | |
724 | +config IP_NF_TARGET_IMQ\r | |
725 | + tristate "IMQ target support"\r | |
726 | + depends on IP_NF_MANGLE\r | |
727 | + help\r | |
728 | + This option adds a `IMQ' target which is used to specify if and\r | |
729 | + to which IMQ device packets should get enqueued/dequeued.\r | |
730 | +\r | |
731 | + For more information visit: http://www.linuximq.net/\r | |
732 | +\r | |
733 | + To compile it as a module, choose M here. If unsure, say N.\r | |
734 | +\r | |
735 | config IP_NF_TARGET_TOS\r | |
736 | tristate "TOS target support"\r | |
737 | depends on IP_NF_MANGLE\r | |
738 | --- linux-2.6.20.7-original/net/ipv4/netfilter/Makefile 2007-04-13 23:48:14.000000000 +0300\r | |
739 | +++ linux-2.6.20.7/net/ipv4/netfilter/Makefile 2007-04-19 16:22:34.000000000 +0300\r | |
740 | @@ -96,6 +96,7 @@\r | |
741 | obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o\r | |
742 | obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o\r | |
743 | obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o\r | |
744 | +obj-$(CONFIG_IP_NF_TARGET_IMQ) += ipt_IMQ.o\r | |
745 | obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o\r | |
746 | obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o\r | |
747 | obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o\r | |
748 | --- linux-2.6.20.7-original/net/ipv6/netfilter/ip6t_IMQ.c 1970-01-01 02:00:00.000000000 +0200\r | |
749 | +++ linux-2.6.20.7/net/ipv6/netfilter/ip6t_IMQ.c 2007-04-19 16:22:34.000000000 +0300\r | |
750 | @@ -0,0 +1,71 @@\r | |
751 | +/*\r | |
752 | + * This target marks packets to be enqueued to an imq device\r | |
753 | + */\r | |
754 | +#include <linux/module.h>\r | |
755 | +#include <linux/skbuff.h>\r | |
756 | +#include <linux/netfilter_ipv6/ip6_tables.h>\r | |
757 | +#include <linux/netfilter_ipv6/ip6t_IMQ.h>\r | |
758 | +#include <linux/imq.h>\r | |
759 | +\r | |
760 | +static unsigned int imq_target(struct sk_buff **pskb,\r | |
761 | + const struct net_device *in,\r | |
762 | + const struct net_device *out,\r | |
763 | + unsigned int hooknum,\r | |
764 | + const struct xt_target *target,\r | |
765 | + const void *targinfo)\r | |
766 | +{\r | |
767 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)targinfo;\r | |
768 | +\r | |
769 | + (*pskb)->imq_flags = mr->todev | IMQ_F_ENQUEUE;\r | |
770 | +\r | |
771 | + return IP6T_CONTINUE;\r | |
772 | +}\r | |
773 | +\r | |
774 | +static int imq_checkentry(const char *tablename,\r | |
775 | + const void *entry,\r | |
776 | + const struct xt_target *target,\r | |
777 | + void *targinfo,\r | |
778 | + unsigned int hook_mask)\r | |
779 | +{\r | |
780 | + struct ip6t_imq_info *mr;\r | |
781 | +\r | |
782 | + mr = (struct ip6t_imq_info*)targinfo;\r | |
783 | +\r | |
784 | + if (mr->todev > IMQ_MAX_DEVS) {\r | |
785 | + printk(KERN_WARNING\r | |
786 | + "IMQ: invalid device specified, highest is %u\n",\r | |
787 | + IMQ_MAX_DEVS);\r | |
788 | + return 0;\r | |
789 | + }\r | |
790 | +\r | |
791 | + return 1;\r | |
792 | +}\r | |
793 | +\r | |
794 | +static struct ip6t_target ip6t_imq_reg = {\r | |
795 | + .name = "IMQ",\r | |
796 | + .target = imq_target,\r | |
797 | + .targetsize = sizeof(struct ip6t_imq_info),\r | |
798 | + .table = "mangle",\r | |
799 | + .checkentry = imq_checkentry,\r | |
800 | + .me = THIS_MODULE\r | |
801 | +};\r | |
802 | +\r | |
803 | +static int __init init(void)\r | |
804 | +{\r | |
805 | + if (ip6t_register_target(&ip6t_imq_reg))\r | |
806 | + return -EINVAL;\r | |
807 | +\r | |
808 | + return 0;\r | |
809 | +}\r | |
810 | +\r | |
811 | +static void __exit fini(void)\r | |
812 | +{\r | |
813 | + ip6t_unregister_target(&ip6t_imq_reg);\r | |
814 | +}\r | |
815 | +\r | |
816 | +module_init(init);\r | |
817 | +module_exit(fini);\r | |
818 | +\r | |
819 | +MODULE_AUTHOR("http://www.linuximq.net");\r | |
820 | +MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information.");\r | |
821 | +MODULE_LICENSE("GPL");\r | |
822 | --- linux-2.6.20.7-original/net/ipv6/netfilter/Kconfig 2007-04-13 23:48:14.000000000 +0300\r | |
823 | +++ linux-2.6.20.7/net/ipv6/netfilter/Kconfig 2007-04-19 16:22:34.000000000 +0300\r | |
824 | @@ -164,6 +164,15 @@\r | |
825 | \r | |
826 | To compile it as a module, choose M here. If unsure, say N.\r | |
827 | \r | |
828 | +config IP6_NF_TARGET_IMQ\r | |
829 | + tristate "IMQ target support"\r | |
830 | + depends on IP6_NF_MANGLE\r | |
831 | + help\r | |
832 | + This option adds a `IMQ' target which is used to specify if and\r | |
833 | + to which imq device packets should get enqueued/dequeued.\r | |
834 | +\r | |
835 | + To compile it as a module, choose M here. If unsure, say N.\r | |
836 | +\r | |
837 | config IP6_NF_TARGET_HL\r | |
838 | tristate 'HL (hoplimit) target support'\r | |
839 | depends on IP6_NF_MANGLE\r | |
840 | --- linux-2.6.20.7-original/net/ipv6/netfilter/Makefile 2007-04-13 23:48:14.000000000 +0300\r | |
841 | +++ linux-2.6.20.7/net/ipv6/netfilter/Makefile 2007-04-19 16:22:34.000000000 +0300\r | |
842 | @@ -13,6 +13,7 @@\r | |
843 | obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o\r | |
844 | obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o\r | |
845 | obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o\r | |
846 | +obj-$(CONFIG_IP6_NF_TARGET_IMQ) += ip6t_IMQ.o\r | |
847 | obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o\r | |
848 | obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o\r | |
849 | obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o\r | |
850 | --- linux-2.6.20.7-original/net/sched/sch_generic.c 2007-04-13 23:48:14.000000000 +0300\r | |
851 | +++ linux-2.6.20.7/net/sched/sch_generic.c 2007-04-19 16:22:34.000000000 +0300\r | |
852 | @@ -87,7 +87,6 @@\r | |
853 | \r | |
854 | NOTE: Called under dev->queue_lock with locally disabled BH.\r | |
855 | */\r | |
856 | -\r | |
857 | static inline int qdisc_restart(struct net_device *dev)\r | |
858 | {\r | |
859 | struct Qdisc *q = dev->qdisc;\r | |
860 | @@ -181,6 +180,11 @@\r | |
861 | return q->q.qlen;\r | |
862 | }\r | |
863 | \r | |
864 | +int qdisc_restart1(struct net_device *dev)\r | |
865 | +{\r | |
866 | + return qdisc_restart(dev);\r | |
867 | +}\r | |
868 | +\r | |
869 | void __qdisc_run(struct net_device *dev)\r | |
870 | {\r | |
871 | if (unlikely(dev->qdisc == &noop_qdisc))\r | |
872 | @@ -617,3 +621,4 @@\r | |
873 | EXPORT_SYMBOL(qdisc_reset);\r | |
874 | EXPORT_SYMBOL(qdisc_lock_tree);\r | |
875 | EXPORT_SYMBOL(qdisc_unlock_tree);\r | |
876 | +EXPORT_SYMBOL(qdisc_restart1);\r |