1 --- linux-2.2.17orig/include/linux/skbuff.h Thu May 13 19:33:17 1999
2 +++ linux-2.2/include/linux/skbuff.h Mon Oct 15 21:03:31 2001
3 @@ -85,6 +85,9 @@ struct sk_buff {
4 pkt_type, /* Packet class */
5 pkt_bridged, /* Tracker for bridging */
6 ip_summed; /* Driver fed us an IP checksum */
8 + short from_imq; /* Pkt from IMQ */
10 __u32 priority; /* Packet queueing priority */
11 atomic_t users; /* User count - see datagram.c,tcp.c */
12 unsigned short protocol; /* Packet protocol from driver. */
13 --- linux-2.2.17orig/include/linux/netdevice.h Tue Jan 4 19:12:25 2000
14 +++ linux-2.2/include/linux/netdevice.h Mon Oct 15 21:35:35 2001
15 @@ -335,6 +335,9 @@ struct packet_type
16 #include <linux/notifier.h>
18 extern struct device loopback_dev; /* The loopback */
20 +extern struct device imq_dev; /* The IMQ */
22 extern struct device *dev_base; /* All devices */
23 extern struct packet_type *ptype_base[16]; /* Hashed types */
24 extern int netdev_dropping;
25 --- linux-2.2.17orig/net/core/skbuff.c Sun Mar 7 19:12:18 1999
26 +++ linux-2.2/net/core/skbuff.c Mon Oct 15 21:06:41 2001
29 skb->destructor = NULL;
30 skb->pkt_type = PACKET_HOST; /* Default type */
34 skb->prev = skb->next = NULL;
39 atomic_set(&n->users, 1);
40 n->pkt_type=skb->pkt_type;
42 + n->from_imq=skb->from_imq;
46 n->security=skb->security;
49 atomic_set(&n->users, 1);
50 n->pkt_type=skb->pkt_type;
52 + n->from_imq=skb->from_imq;
56 n->security=skb->security;
57 --- linux-2.2.17orig/drivers/net/Config.in Sun Sep 9 22:23:47 2001
58 +++ linux-2.2/drivers/net/Config.in Mon Oct 15 21:40:48 2001
59 @@ -21,6 +21,7 @@ tristate 'Dummy net driver support' CONF
60 tristate 'Bonding driver support' CONFIG_BONDING
61 tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER
62 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
63 + bool 'IMQ (intermediate queue device) support' CONFIG_IMQ
64 if [ "$CONFIG_NETLINK" = "y" ]; then
65 tristate 'Ethertap network tap' CONFIG_ETHERTAP
67 --- linux-2.2.17orig/drivers/net/Makefile Sun Sep 9 22:23:47 2001
68 +++ linux-2.2/drivers/net/Makefile Mon Oct 15 21:41:59 2001
69 @@ -55,6 +55,10 @@ ifeq ($(CONFIG_NET),y)
70 L_OBJS += Space.o net_init.o loopback.o
73 +ifeq ($(CONFIG_IMQ),y)
77 ifeq ($(CONFIG_SEEQ8005),y)
80 --- linux-2.2.17orig/Documentation/Configure.help Sun Sep 9 22:23:46 2001
81 +++ linux-2.2/Documentation/Configure.help Mon Oct 15 22:04:15 2001
82 @@ -16738,6 +16738,14 @@
83 If you do not have a CompactPCI model CP1400 or CP1500, or
84 another UltraSPARC-IIi-cEngine boardset with digital display,
85 you should say N to this option.
87 +Intermediate queue device (IMQ)
89 + This is virtual network device which is mainly used as placeholder
90 + for QoS qdisc. The attached qdisc is enqueued with all packets
91 + before they go to their 'home' qdisc.
92 + It enables qdisc to treat network devices as classes and distribute
93 + bandwidth among them.
95 CP1XXX Hardware Watchdog support
96 CONFIG_WATCHDOG_CP1XXX
97 --- linux-2.2.17orig/drivers/net/Space.c Sun Sep 9 22:23:47 2001
98 +++ linux-2.2/drivers/net/Space.c Mon Oct 15 22:34:03 2001
99 @@ -979,6 +979,14 @@ static struct device tr0_dev = {
101 #define NEXT_DEV (&escon0_dev)
105 + extern int imq_init(struct device *dev);
106 + struct device imq_dev =
107 + {"imq", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, imq_init};
109 +#define NEXT_DEV (&imq_dev)
112 extern int loopback_init(struct device *dev);
113 struct device loopback_dev = {
114 --- linux-2.2.17orig/drivers/net/imq.c Tue Oct 16 12:52:09 2001
115 +++ linux-2.2/drivers/net/imq.c Mon Oct 15 22:40:46 2001
118 + * Pseudo-driver for the intermediate queue interface.
120 + * Authors: Martin Devera, <devik@cdi.cz>
122 + * This program is free software; you can redistribute it and/or
123 + * modify it under the terms of the GNU General Public License
124 + * as published by the Free Software Foundation; either version
125 + * 2 of the License, or (at your option) any later version.
127 +#include <linux/kernel.h>
128 +#include <linux/sched.h>
129 +#include <linux/interrupt.h>
130 +#include <linux/fs.h>
131 +#include <linux/types.h>
132 +#include <linux/string.h>
133 +#include <linux/socket.h>
134 +#include <linux/errno.h>
135 +#include <linux/fcntl.h>
136 +#include <linux/in.h>
137 +#include <linux/init.h>
139 +#include <asm/system.h>
140 +#include <asm/uaccess.h>
143 +#include <linux/inet.h>
144 +#include <linux/netdevice.h>
145 +#include <linux/etherdevice.h>
146 +#include <linux/skbuff.h>
147 +#include <net/sock.h>
150 + * The higher levels take care of making this non-reentrant (it's
151 + * called with bh's disabled).
153 +static int imq_xmit(struct sk_buff *skb, struct device *dev)
155 + struct net_device_stats *stats = (struct net_device_stats *)dev->priv;
156 + struct device *sdev = skb->dev;
159 + * Optimise so buffers with skb->free=1 are not copied but
160 + * instead are lobbed from tx queue to rx queue
163 + if(atomic_read(&skb->users) != 1)
165 + struct sk_buff *skb2=skb;
166 + skb=skb_clone(skb, GFP_ATOMIC); /* Clone the buffer */
176 + if (dev == sdev || skb->from_imq) {
177 + if (net_ratelimit()) printk (KERN_ERR "imq device is looped !");
182 + /* move the packet into correct device queue */
185 + if (dev_queue_xmit(skb) < 0 && net_ratelimit())
186 + printk (KERN_ERR "Can't TX from imq device\n");
188 + dev->last_rx = jiffies;
189 + stats->rx_bytes+=skb->len;
190 + stats->tx_bytes+=skb->len;
191 + stats->rx_packets++;
192 + stats->tx_packets++;
197 +static struct net_device_stats *get_stats(struct device *dev)
199 + return (struct net_device_stats *)dev->priv;
202 +/* Initialize the rest of the imq device. */
203 +__initfunc(int imq_init(struct device *dev))
205 + dev->hard_start_xmit = imq_xmit;
209 + dev->tx_queue_len = 100;
210 + dev->flags = IFF_NOARP;
211 + dev->hard_header_len = LL_MAX_HEADER;
212 + dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
213 + if (dev->priv == NULL)
215 + memset(dev->priv, 0, sizeof(struct net_device_stats));
216 + dev->get_stats = get_stats;
220 --- linux-2.2.17orig/net/core/dev.c Sun Sep 9 22:23:50 2001
221 +++ linux-2.2/net/core/dev.c Mon Oct 15 22:23:30 2001
222 @@ -595,6 +595,21 @@ int dev_queue_xmit(struct sk_buff *skb)
227 + /* if skb have not visited enabled IMQ yet then push it there */
229 + if (imq_dev.flags&IFF_UP && !skb->from_imq && q->enqueue) {
230 + q->enqueue(skb, q);
231 + qdisc_wakeup(&imq_dev);
234 +#ifdef CONFIG_NET_PROFILE
235 + NET_PROFILE_LEAVE(dev_queue_xmit);
244 @@ -618,8 +633,11 @@ int dev_queue_xmit(struct sk_buff *skb)
247 if (dev->flags&IFF_UP) {
249 - dev_queue_xmit_nit(skb,dev);
254 + ) dev_queue_xmit_nit(skb,dev);
255 if (dev->hard_start_xmit(skb, dev) == 0) {
258 --- linux-2.2.17orig/net/sched/sch_generic.c Wed Oct 27 02:53:42 1999
259 +++ linux-2.2/net/sched/sch_generic.c Mon Oct 15 21:29:27 2001
260 @@ -53,8 +53,11 @@ int qdisc_restart(struct device *dev)
263 if ((skb = q->dequeue(q)) != NULL) {
265 - dev_queue_xmit_nit(skb, dev);
270 + ) dev_queue_xmit_nit(skb, dev);
272 if (dev->hard_start_xmit(skb, dev) == 0) {
273 q->tx_last = jiffies;