]>
Commit | Line | Data |
---|---|---|
0906fd96 AM |
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 */ | |
5 | unsigned int data_len; | |
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> | |
16 | ||
17 | extern struct net_device loopback_dev; /* The loopback */ | |
18 | +#ifdef CONFIG_IMQ | |
19 | +extern struct net_device imq_dev; | |
20 | +#endif | |
21 | extern struct net_device *dev_base; /* All devices */ | |
22 | extern rwlock_t dev_base_lock; /* Device list lock */ | |
23 | ||
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 */ | |
28 | skb->len = 0; | |
29 | skb->cloned = 0; | |
30 | + skb->from_imq = 0; | |
31 | skb->data_len = 0; | |
32 | ||
33 | atomic_set(&skb->users, 1); | |
34 | @@ -235,6 +236,7 @@ static inline void skb_headerinit(void * | |
35 | skb->dst = NULL; | |
36 | memset(skb->cb, 0, sizeof(skb->cb)); | |
37 | skb->pkt_type = PACKET_HOST; /* Default type */ | |
38 | + skb->from_imq = 0; | |
39 | skb->ip_summed = 0; | |
40 | skb->priority = 0; | |
41 | skb->security = 0; /* By default packets are insecure */ | |
42 | @@ -373,6 +375,7 @@ struct sk_buff *skb_clone(struct sk_buff | |
43 | C(data_len); | |
44 | C(csum); | |
45 | n->cloned = 1; | |
46 | + C(from_imq); | |
47 | C(pkt_type); | |
48 | C(ip_summed); | |
49 | C(priority); | |
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 | |
61 | ||
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 | |
82 | called bonding.o. | |
83 | ||
84 | +Intermediate queue device (IMQ) | |
85 | +CONFIG_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. | |
91 | + | |
92 | SLIP (serial line) support | |
93 | CONFIG_SLIP | |
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) | |
99 | #endif | |
100 | ||
101 | +#ifdef CONFIG_IMQ | |
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}; | |
105 | +#undef NEXT_DEV | |
106 | +#define NEXT_DEV (&imq_dev) | |
107 | +#endif | |
108 | + | |
109 | /* | |
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 | |
114 | @@ -0,0 +1,114 @@ | |
115 | +/* | |
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. | |
119 | + * | |
120 | + * Pseudo-driver for the intermediate queue interface. | |
121 | + * | |
122 | + * Authors: Martin Devera, <devik@cdi.cz> | |
123 | + * | |
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. | |
128 | + */ | |
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> | |
140 | + | |
141 | +#include <asm/system.h> | |
142 | +#include <asm/uaccess.h> | |
143 | +#include <asm/io.h> | |
144 | + | |
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 */ | |
152 | + | |
153 | +/* | |
154 | + * The higher levels take care of making this non-reentrant (it's | |
155 | + * called with bh's disabled). | |
156 | + */ | |
157 | +static int imq_xmit(struct sk_buff *skb, struct net_device *dev) | |
158 | +{ | |
159 | + struct net_device_stats *stats = (struct net_device_stats *)dev->priv; | |
160 | + struct net_device *sdev = skb->dev; | |
161 | + | |
162 | + /* | |
163 | + * Optimise so buffers with skb->free=1 are not copied but | |
164 | + * instead are lobbed from tx queue to rx queue | |
165 | + */ | |
166 | + | |
167 | + if(atomic_read(&skb->users) != 1) | |
168 | + { | |
169 | + struct sk_buff *skb2=skb; | |
170 | + skb=skb_clone(skb, GFP_ATOMIC); /* Clone the buffer */ | |
171 | + if(skb==NULL) { | |
172 | + kfree_skb(skb2); | |
173 | + return 0; | |
174 | + } | |
175 | + kfree_skb(skb2); | |
176 | + } | |
177 | + else | |
178 | + skb_orphan(skb); | |
179 | + | |
180 | + if (dev == sdev || skb->from_imq) { | |
181 | + if (net_ratelimit()) printk (KERN_ERR "imq device is looped !"); | |
182 | + kfree_skb(skb); | |
183 | + return 0; | |
184 | + } | |
185 | + | |
186 | + /* move the packet into correct device queue */ | |
187 | +// skb->protocol=eth_type_trans(skb,dev); | |
188 | + skb->dev = sdev; | |
189 | + skb->from_imq = 1; | |
190 | + if (dev_queue_xmit(skb) < 0 && net_ratelimit()) | |
191 | + printk (KERN_ERR "Can't TX from imq device\n"); | |
192 | + | |
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++; | |
198 | + | |
199 | + return(0); | |
200 | +} | |
201 | + | |
202 | +static struct net_device_stats *get_stats(struct net_device *dev) | |
203 | +{ | |
204 | + return (struct net_device_stats *)dev->priv; | |
205 | +} | |
206 | + | |
207 | +/* Initialize the rest of the imq device. */ | |
208 | +int __init imq_init(struct net_device *dev) | |
209 | +{ | |
210 | + dev->hard_start_xmit = imq_xmit; | |
211 | + | |
212 | + dev->type = ARPHRD_VOID; | |
213 | + dev->mtu = 1500; | |
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) | |
219 | + return -ENOMEM; | |
220 | + memset(dev->priv, 0, sizeof(struct net_device_stats)); | |
221 | + dev->get_stats = get_stats; | |
222 | + | |
223 | + /* | |
224 | + * Fill in the generic fields of the device structure. | |
225 | + */ | |
226 | + | |
227 | + return(0); | |
228 | +}; | |
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) | |
232 | return -ENOMEM; | |
233 | } | |
234 | ||
235 | +#ifdef CONFIG_IMQ | |
236 | + /* special intermediate queue up ? */ | |
237 | + if (imq_dev.flags&IFF_UP && !skb->from_imq) { | |
238 | + spin_lock_bh(&imq_dev.queue_lock); | |
239 | + q = imq_dev.qdisc; | |
240 | + if (q->enqueue) { | |
241 | + int ret = q->enqueue(skb, q); | |
242 | + | |
243 | + qdisc_run(&imq_dev); | |
244 | + spin_unlock_bh(&imq_dev.queue_lock); | |
245 | + return ret == NET_XMIT_BYPASS ? NET_XMIT_SUCCESS : ret; | |
246 | + } | |
247 | + spin_unlock_bh(&imq_dev.queue_lock); | |
248 | + } | |
249 | +#endif | |
250 | + | |
251 | /* Grab device queue */ | |
252 | spin_lock_bh(&dev->queue_lock); | |
253 | q = dev->qdisc; | |
254 | @@ -1029,12 +1050,16 @@ int dev_queue_xmit(struct sk_buff *skb) | |
255 | dev->xmit_lock_owner = cpu; | |
256 | ||
257 | if (!netif_queue_stopped(dev)) { | |
258 | - if (netdev_nit) | |
259 | - dev_queue_xmit_nit(skb,dev); | |
260 | + if (netdev_nit | |
261 | +#ifdef CONFIG_IMQ | |
262 | + && !skb->from_imq | |
263 | +#endif | |
264 | + ) dev_queue_xmit_nit(skb,dev); | |
265 | ||
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); | |
270 | return 0; | |
271 | } | |
272 | } | |
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); | |
277 | ||
278 | if (!netif_queue_stopped(dev)) { | |
279 | - if (netdev_nit) | |
280 | - dev_queue_xmit_nit(skb, dev); | |
281 | + /* don't nit intermediate packet here */ | |
282 | + if (netdev_nit | |
283 | +#ifdef CONFIG_IMQ | |
284 | + && !skb->from_imq | |
285 | +#endif | |
286 | + ) dev_queue_xmit_nit(skb, dev); | |
287 | ||
288 | if (dev->hard_start_xmit(skb, dev) == 0) { | |
289 | dev->xmit_lock_owner = -1; |