]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/linux-2.6.20-imq.diff
Load libata prior udev at installer because some SATA doesnt autoload it
[people/pmueller/ipfire-2.x.git] / src / patches / linux-2.6.20-imq.diff
CommitLineData
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