1 --- linux-2.4orig/include/linux/skbuff.h Mon Oct 15 16:31:19 2001
2 +++ linux-2.4/include/linux/skbuff.h Fri Oct 19 00:52:13 2001
3 @@ -176,7 +176,7 @@ struct sk_buff {
4 unsigned int len; /* Length of actual data */
6 unsigned int csum; /* Checksum */
7 - unsigned char __unused, /* Dead field, may be reused */
8 + unsigned char from_imq, /* read from imq - dont requeue to imq */
9 cloned, /* head may be cloned (check refcnt to be sure). */
10 pkt_type, /* Packet class */
11 ip_summed; /* Driver fed us an IP checksum */
12 --- linux-2.4orig/include/linux/netdevice.h Mon Oct 15 16:33:39 2001
13 +++ linux-2.4/include/linux/netdevice.h Mon Oct 22 00:28:57 2001
14 @@ -425,6 +425,9 @@ struct packet_type
15 #include <linux/notifier.h>
17 extern struct net_device loopback_dev; /* The loopback */
19 +extern struct net_device imq_dev;
21 extern struct net_device *dev_base; /* All devices */
22 extern rwlock_t dev_base_lock; /* Device list lock */
24 --- linux-2.4orig/net/core/skbuff.c Mon Oct 15 16:28:35 2001
25 +++ linux-2.4/net/core/skbuff.c Mon Oct 15 09:45:07 2001
26 @@ -203,6 +203,7 @@ struct sk_buff *alloc_skb(unsigned int s
27 /* Set up other state */
33 atomic_set(&skb->users, 1);
34 @@ -235,6 +236,7 @@ static inline void skb_headerinit(void *
36 memset(skb->cb, 0, sizeof(skb->cb));
37 skb->pkt_type = PACKET_HOST; /* Default type */
41 skb->security = 0; /* By default packets are insecure */
42 @@ -373,6 +375,7 @@ struct sk_buff *skb_clone(struct sk_buff
50 @@ -427,6 +430,7 @@ static void copy_skb_header(struct sk_bu
51 memcpy(new->cb, old->cb, sizeof(old->cb));
52 atomic_set(&new->users, 1);
53 new->pkt_type=old->pkt_type;
54 + new->from_imq=old->from_imq;
55 new->stamp=old->stamp;
56 new->destructor = NULL;
57 new->security=old->security;
58 --- linux-2.4orig/drivers/net/Config.in Mon Oct 15 16:30:12 2001
59 +++ linux-2.4/drivers/net/Config.in Mon Oct 22 00:39:51 2001
60 @@ -7,6 +7,7 @@ source drivers/net/appletalk/Config.in
62 tristate 'Dummy net driver support' CONFIG_DUMMY
63 tristate 'Bonding driver support' CONFIG_BONDING
64 +bool 'Intermediate queue (IMQ) driver support' CONFIG_IMQ
65 tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER
66 tristate 'Universal TUN/TAP device driver support' CONFIG_TUN
67 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
68 --- linux-2.4orig/drivers/net/Makefile Mon Oct 15 16:30:12 2001
69 +++ linux-2.4/drivers/net/Makefile Mon Oct 22 00:30:07 2001
70 @@ -104,6 +104,7 @@ obj-$(CONFIG_WINBOND_840) += winbond-840
71 obj-$(CONFIG_SUNDANCE) += sundance.o
72 obj-$(CONFIG_HAMACHI) += hamachi.o
73 obj-$(CONFIG_NET) += Space.o setup.o net_init.o loopback.o
74 +obj-$(CONFIG_IMQ) += imq.o
75 obj-$(CONFIG_SEEQ8005) += seeq8005.o
76 obj-$(CONFIG_ETHERTAP) += ethertap.o
77 obj-$(CONFIG_NET_SB1000) += sb1000.o
78 --- linux-2.4orig/Documentation/Configure.help Mon Oct 15 16:31:35 2001
79 +++ linux-2.4/Documentation/Configure.help Mon Oct 22 00:40:49 2001
80 @@ -7116,6 +7116,14 @@ CONFIG_BONDING
81 say M here and read Documentation/modules.txt. The module will be
84 +Intermediate queue device (IMQ)
86 + This is virtual network device which is mainly used as placeholder
87 + for QoS qdisc. The attached qdisc is enqueued with all packets
88 + before they go to their 'home' qdisc.
89 + It enables qdisc to treat network devices as classes and distribute
90 + bandwidth among them.
92 SLIP (serial line) support
94 Say Y if you intend to use SLIP or CSLIP (compressed SLIP) to
95 --- linux-2.4orig/drivers/net/Space.c Mon Oct 15 16:30:12 2001
96 +++ linux-2.4/drivers/net/Space.c Mon Oct 22 00:31:22 2001
97 @@ -632,6 +632,14 @@ static struct net_device tr0_dev = {
98 #define NEXT_DEV (&sbni0_dev)
102 +extern int imq_init(struct net_device *dev);
103 +struct net_device imq_dev =
104 + {"imq", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, imq_init};
106 +#define NEXT_DEV (&imq_dev)
110 * The loopback device is global so it can be directly referenced
111 * by the network code. Also, it must be first on device list.
112 --- linux-2.4orig/drivers/net/imq.c Mon Oct 22 00:26:16 2001
113 +++ linux-2.4/drivers/net/imq.c Mon Oct 15 10:15:41 2001
116 + * INET An implementation of the TCP/IP protocol suite for the LINUX
117 + * operating system. INET is implemented using the BSD Socket
118 + * interface as the means of communication with the user level.
120 + * Pseudo-driver for the intermediate queue interface.
122 + * Authors: Martin Devera, <devik@cdi.cz>
124 + * This program is free software; you can redistribute it and/or
125 + * modify it under the terms of the GNU General Public License
126 + * as published by the Free Software Foundation; either version
127 + * 2 of the License, or (at your option) any later version.
129 +#include <linux/kernel.h>
130 +#include <linux/sched.h>
131 +#include <linux/interrupt.h>
132 +#include <linux/fs.h>
133 +#include <linux/types.h>
134 +#include <linux/string.h>
135 +#include <linux/socket.h>
136 +#include <linux/errno.h>
137 +#include <linux/fcntl.h>
138 +#include <linux/in.h>
139 +#include <linux/init.h>
141 +#include <asm/system.h>
142 +#include <asm/uaccess.h>
145 +#include <linux/inet.h>
146 +#include <linux/netdevice.h>
147 +#include <linux/etherdevice.h>
148 +#include <linux/skbuff.h>
149 +#include <net/sock.h>
150 +#include <linux/if_ether.h> /* For the statistics structure. */
151 +#include <linux/if_arp.h> /* For ARPHRD_ETHER */
154 + * The higher levels take care of making this non-reentrant (it's
155 + * called with bh's disabled).
157 +static int imq_xmit(struct sk_buff *skb, struct net_device *dev)
159 + struct net_device_stats *stats = (struct net_device_stats *)dev->priv;
160 + struct net_device *sdev = skb->dev;
163 + * Optimise so buffers with skb->free=1 are not copied but
164 + * instead are lobbed from tx queue to rx queue
167 + if(atomic_read(&skb->users) != 1)
169 + struct sk_buff *skb2=skb;
170 + skb=skb_clone(skb, GFP_ATOMIC); /* Clone the buffer */
180 + if (dev == sdev || skb->from_imq) {
181 + if (net_ratelimit()) printk (KERN_ERR "imq device is looped !");
186 + /* move the packet into correct device queue */
187 +// skb->protocol=eth_type_trans(skb,dev);
190 + if (dev_queue_xmit(skb) < 0 && net_ratelimit())
191 + printk (KERN_ERR "Can't TX from imq device\n");
193 + dev->last_rx = jiffies;
194 + stats->rx_bytes+=skb->len;
195 + stats->tx_bytes+=skb->len;
196 + stats->rx_packets++;
197 + stats->tx_packets++;
202 +static struct net_device_stats *get_stats(struct net_device *dev)
204 + return (struct net_device_stats *)dev->priv;
207 +/* Initialize the rest of the imq device. */
208 +int __init imq_init(struct net_device *dev)
210 + dev->hard_start_xmit = imq_xmit;
212 + dev->type = ARPHRD_VOID;
214 + dev->tx_queue_len = 100;
215 + dev->flags = IFF_NOARP;
216 + dev->hard_header_len = LL_MAX_HEADER;
217 + dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
218 + if (dev->priv == NULL)
220 + memset(dev->priv, 0, sizeof(struct net_device_stats));
221 + dev->get_stats = get_stats;
224 + * Fill in the generic fields of the device structure.
229 --- linux-2.4orig/net/core/dev.c Mon Oct 15 16:33:13 2001
230 +++ linux-2.4/net/core/dev.c Mon Oct 22 00:47:05 2001
231 @@ -997,6 +1002,22 @@ int dev_queue_xmit(struct sk_buff *skb)
236 + /* special intermediate queue up ? */
237 + if (imq_dev.flags&IFF_UP && !skb->from_imq) {
238 + spin_lock_bh(&imq_dev.queue_lock);
241 + int ret = q->enqueue(skb, q);
243 + qdisc_run(&imq_dev);
244 + spin_unlock_bh(&imq_dev.queue_lock);
245 + return ret == NET_XMIT_BYPASS ? NET_XMIT_SUCCESS : ret;
247 + spin_unlock_bh(&imq_dev.queue_lock);
251 /* Grab device queue */
252 spin_lock_bh(&dev->queue_lock);
254 @@ -1029,12 +1050,16 @@ int dev_queue_xmit(struct sk_buff *skb)
255 dev->xmit_lock_owner = cpu;
257 if (!netif_queue_stopped(dev)) {
259 - dev_queue_xmit_nit(skb,dev);
264 + ) dev_queue_xmit_nit(skb,dev);
266 if (dev->hard_start_xmit(skb, dev) == 0) {
267 dev->xmit_lock_owner = -1;
268 spin_unlock_bh(&dev->xmit_lock);
269 + NET_PROFILE_LEAVE(dev_queue_xmit);
273 --- linux-2.4orig/net/sched/sch_generic.c Sat Jan 27 11:11:47 2001
274 +++ linux-2.4/net/sched/sch_generic.c Mon Oct 22 00:37:52 2001
275 @@ -89,8 +88,12 @@ int qdisc_restart(struct net_device *dev
276 spin_unlock(&dev->queue_lock);
278 if (!netif_queue_stopped(dev)) {
280 - dev_queue_xmit_nit(skb, dev);
281 + /* don't nit intermediate packet here */
286 + ) dev_queue_xmit_nit(skb, dev);
288 if (dev->hard_start_xmit(skb, dev) == 0) {
289 dev->xmit_lock_owner = -1;