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