diff options
Diffstat (limited to 'drivers/net/shaper.c')
-rw-r--r-- | drivers/net/shaper.c | 105 |
1 files changed, 52 insertions, 53 deletions
diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c index 88e212043a43..e886e8d7cfdf 100644 --- a/drivers/net/shaper.c +++ b/drivers/net/shaper.c | |||
@@ -8,12 +8,12 @@ | |||
8 | * modify it under the terms of the GNU General Public License | 8 | * modify it under the terms of the GNU General Public License |
9 | * as published by the Free Software Foundation; either version | 9 | * as published by the Free Software Foundation; either version |
10 | * 2 of the License, or (at your option) any later version. | 10 | * 2 of the License, or (at your option) any later version. |
11 | * | ||
12 | * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide | ||
13 | * warranty for any of this software. This material is provided | ||
14 | * "AS-IS" and at no charge. | ||
15 | * | 11 | * |
16 | * | 12 | * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide |
13 | * warranty for any of this software. This material is provided | ||
14 | * "AS-IS" and at no charge. | ||
15 | * | ||
16 | * | ||
17 | * Algorithm: | 17 | * Algorithm: |
18 | * | 18 | * |
19 | * Queue Frame: | 19 | * Queue Frame: |
@@ -26,7 +26,7 @@ | |||
26 | * | 26 | * |
27 | * SHAPER_QLEN Maximum queued frames | 27 | * SHAPER_QLEN Maximum queued frames |
28 | * SHAPER_LATENCY Bounding latency on a frame. Leaving this latency | 28 | * SHAPER_LATENCY Bounding latency on a frame. Leaving this latency |
29 | * window drops the frame. This stops us queueing | 29 | * window drops the frame. This stops us queueing |
30 | * frames for a long time and confusing a remote | 30 | * frames for a long time and confusing a remote |
31 | * host. | 31 | * host. |
32 | * SHAPER_MAXSLIP Maximum time a priority frame may jump forward. | 32 | * SHAPER_MAXSLIP Maximum time a priority frame may jump forward. |
@@ -42,8 +42,8 @@ | |||
42 | * run off a 100-150Hz base clock typically. This gives us a resolution at | 42 | * run off a 100-150Hz base clock typically. This gives us a resolution at |
43 | * 200Kbit/second of about 2Kbit or 256 bytes. Above that our timer | 43 | * 200Kbit/second of about 2Kbit or 256 bytes. Above that our timer |
44 | * resolution may start to cause much more burstiness in the traffic. We | 44 | * resolution may start to cause much more burstiness in the traffic. We |
45 | * could avoid a lot of that by calling kick_shaper() at the end of the | 45 | * could avoid a lot of that by calling kick_shaper() at the end of the |
46 | * tied device transmissions. If you run above about 100K second you | 46 | * tied device transmissions. If you run above about 100K second you |
47 | * may need to tune the supposed speed rate for the right values. | 47 | * may need to tune the supposed speed rate for the right values. |
48 | * | 48 | * |
49 | * BUGS: | 49 | * BUGS: |
@@ -68,8 +68,7 @@ | |||
68 | * Use skb->cb for private data. | 68 | * Use skb->cb for private data. |
69 | * 2000/03 Andi Kleen | 69 | * 2000/03 Andi Kleen |
70 | */ | 70 | */ |
71 | 71 | ||
72 | #include <linux/config.h> | ||
73 | #include <linux/module.h> | 72 | #include <linux/module.h> |
74 | #include <linux/kernel.h> | 73 | #include <linux/kernel.h> |
75 | #include <linux/fcntl.h> | 74 | #include <linux/fcntl.h> |
@@ -88,13 +87,13 @@ | |||
88 | #include <net/dst.h> | 87 | #include <net/dst.h> |
89 | #include <net/arp.h> | 88 | #include <net/arp.h> |
90 | 89 | ||
91 | struct shaper_cb { | 90 | struct shaper_cb { |
92 | unsigned long shapeclock; /* Time it should go out */ | 91 | unsigned long shapeclock; /* Time it should go out */ |
93 | unsigned long shapestamp; /* Stamp for shaper */ | 92 | unsigned long shapestamp; /* Stamp for shaper */ |
94 | __u32 shapelatency; /* Latency on frame */ | 93 | __u32 shapelatency; /* Latency on frame */ |
95 | __u32 shapelen; /* Frame length in clocks */ | 94 | __u32 shapelen; /* Frame length in clocks */ |
96 | __u16 shapepend; /* Pending */ | 95 | __u16 shapepend; /* Pending */ |
97 | }; | 96 | }; |
98 | #define SHAPERCB(skb) ((struct shaper_cb *) ((skb)->cb)) | 97 | #define SHAPERCB(skb) ((struct shaper_cb *) ((skb)->cb)) |
99 | 98 | ||
100 | static int sh_debug; /* Debug flag */ | 99 | static int sh_debug; /* Debug flag */ |
@@ -106,7 +105,7 @@ static void shaper_kick(struct shaper *sh); | |||
106 | /* | 105 | /* |
107 | * Compute clocks on a buffer | 106 | * Compute clocks on a buffer |
108 | */ | 107 | */ |
109 | 108 | ||
110 | static int shaper_clocks(struct shaper *shaper, struct sk_buff *skb) | 109 | static int shaper_clocks(struct shaper *shaper, struct sk_buff *skb) |
111 | { | 110 | { |
112 | int t=skb->len/shaper->bytespertick; | 111 | int t=skb->len/shaper->bytespertick; |
@@ -116,9 +115,9 @@ static int shaper_clocks(struct shaper *shaper, struct sk_buff *skb) | |||
116 | /* | 115 | /* |
117 | * Set the speed of a shaper. We compute this in bytes per tick since | 116 | * Set the speed of a shaper. We compute this in bytes per tick since |
118 | * thats how the machine wants to run. Quoted input is in bits per second | 117 | * thats how the machine wants to run. Quoted input is in bits per second |
119 | * as is traditional (note not BAUD). We assume 8 bit bytes. | 118 | * as is traditional (note not BAUD). We assume 8 bit bytes. |
120 | */ | 119 | */ |
121 | 120 | ||
122 | static void shaper_setspeed(struct shaper *shaper, int bitspersec) | 121 | static void shaper_setspeed(struct shaper *shaper, int bitspersec) |
123 | { | 122 | { |
124 | shaper->bitspersec=bitspersec; | 123 | shaper->bitspersec=bitspersec; |
@@ -130,40 +129,40 @@ static void shaper_setspeed(struct shaper *shaper, int bitspersec) | |||
130 | /* | 129 | /* |
131 | * Throw a frame at a shaper. | 130 | * Throw a frame at a shaper. |
132 | */ | 131 | */ |
133 | 132 | ||
134 | 133 | ||
135 | static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) | 134 | static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) |
136 | { | 135 | { |
137 | struct shaper *shaper = dev->priv; | 136 | struct shaper *shaper = dev->priv; |
138 | struct sk_buff *ptr; | 137 | struct sk_buff *ptr; |
139 | 138 | ||
140 | spin_lock(&shaper->lock); | 139 | spin_lock(&shaper->lock); |
141 | ptr=shaper->sendq.prev; | 140 | ptr=shaper->sendq.prev; |
142 | 141 | ||
143 | /* | 142 | /* |
144 | * Set up our packet details | 143 | * Set up our packet details |
145 | */ | 144 | */ |
146 | 145 | ||
147 | SHAPERCB(skb)->shapelatency=0; | 146 | SHAPERCB(skb)->shapelatency=0; |
148 | SHAPERCB(skb)->shapeclock=shaper->recovery; | 147 | SHAPERCB(skb)->shapeclock=shaper->recovery; |
149 | if(time_before(SHAPERCB(skb)->shapeclock, jiffies)) | 148 | if(time_before(SHAPERCB(skb)->shapeclock, jiffies)) |
150 | SHAPERCB(skb)->shapeclock=jiffies; | 149 | SHAPERCB(skb)->shapeclock=jiffies; |
151 | skb->priority=0; /* short term bug fix */ | 150 | skb->priority=0; /* short term bug fix */ |
152 | SHAPERCB(skb)->shapestamp=jiffies; | 151 | SHAPERCB(skb)->shapestamp=jiffies; |
153 | 152 | ||
154 | /* | 153 | /* |
155 | * Time slots for this packet. | 154 | * Time slots for this packet. |
156 | */ | 155 | */ |
157 | 156 | ||
158 | SHAPERCB(skb)->shapelen= shaper_clocks(shaper,skb); | 157 | SHAPERCB(skb)->shapelen= shaper_clocks(shaper,skb); |
159 | 158 | ||
160 | { | 159 | { |
161 | struct sk_buff *tmp; | 160 | struct sk_buff *tmp; |
162 | /* | 161 | /* |
163 | * Up our shape clock by the time pending on the queue | 162 | * Up our shape clock by the time pending on the queue |
164 | * (Should keep this in the shaper as a variable..) | 163 | * (Should keep this in the shaper as a variable..) |
165 | */ | 164 | */ |
166 | for(tmp=skb_peek(&shaper->sendq); tmp!=NULL && | 165 | for(tmp=skb_peek(&shaper->sendq); tmp!=NULL && |
167 | tmp!=(struct sk_buff *)&shaper->sendq; tmp=tmp->next) | 166 | tmp!=(struct sk_buff *)&shaper->sendq; tmp=tmp->next) |
168 | SHAPERCB(skb)->shapeclock+=SHAPERCB(tmp)->shapelen; | 167 | SHAPERCB(skb)->shapeclock+=SHAPERCB(tmp)->shapelen; |
169 | /* | 168 | /* |
@@ -192,7 +191,7 @@ static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
192 | /* | 191 | /* |
193 | * Transmit from a shaper | 192 | * Transmit from a shaper |
194 | */ | 193 | */ |
195 | 194 | ||
196 | static void shaper_queue_xmit(struct shaper *shaper, struct sk_buff *skb) | 195 | static void shaper_queue_xmit(struct shaper *shaper, struct sk_buff *skb) |
197 | { | 196 | { |
198 | struct sk_buff *newskb=skb_clone(skb, GFP_ATOMIC); | 197 | struct sk_buff *newskb=skb_clone(skb, GFP_ATOMIC); |
@@ -219,7 +218,7 @@ static void shaper_queue_xmit(struct shaper *shaper, struct sk_buff *skb) | |||
219 | /* | 218 | /* |
220 | * Timer handler for shaping clock | 219 | * Timer handler for shaping clock |
221 | */ | 220 | */ |
222 | 221 | ||
223 | static void shaper_timer(unsigned long data) | 222 | static void shaper_timer(unsigned long data) |
224 | { | 223 | { |
225 | struct shaper *shaper = (struct shaper *)data; | 224 | struct shaper *shaper = (struct shaper *)data; |
@@ -230,25 +229,25 @@ static void shaper_timer(unsigned long data) | |||
230 | } | 229 | } |
231 | 230 | ||
232 | /* | 231 | /* |
233 | * Kick a shaper queue and try and do something sensible with the | 232 | * Kick a shaper queue and try and do something sensible with the |
234 | * queue. | 233 | * queue. |
235 | */ | 234 | */ |
236 | 235 | ||
237 | static void shaper_kick(struct shaper *shaper) | 236 | static void shaper_kick(struct shaper *shaper) |
238 | { | 237 | { |
239 | struct sk_buff *skb; | 238 | struct sk_buff *skb; |
240 | 239 | ||
241 | /* | 240 | /* |
242 | * Walk the list (may be empty) | 241 | * Walk the list (may be empty) |
243 | */ | 242 | */ |
244 | 243 | ||
245 | while((skb=skb_peek(&shaper->sendq))!=NULL) | 244 | while((skb=skb_peek(&shaper->sendq))!=NULL) |
246 | { | 245 | { |
247 | /* | 246 | /* |
248 | * Each packet due to go out by now (within an error | 247 | * Each packet due to go out by now (within an error |
249 | * of SHAPER_BURST) gets kicked onto the link | 248 | * of SHAPER_BURST) gets kicked onto the link |
250 | */ | 249 | */ |
251 | 250 | ||
252 | if(sh_debug) | 251 | if(sh_debug) |
253 | printk("Clock = %ld, jiffies = %ld\n", SHAPERCB(skb)->shapeclock, jiffies); | 252 | printk("Clock = %ld, jiffies = %ld\n", SHAPERCB(skb)->shapeclock, jiffies); |
254 | if(time_before_eq(SHAPERCB(skb)->shapeclock, jiffies + SHAPER_BURST)) | 253 | if(time_before_eq(SHAPERCB(skb)->shapeclock, jiffies + SHAPER_BURST)) |
@@ -256,16 +255,16 @@ static void shaper_kick(struct shaper *shaper) | |||
256 | /* | 255 | /* |
257 | * Pull the frame and get interrupts back on. | 256 | * Pull the frame and get interrupts back on. |
258 | */ | 257 | */ |
259 | 258 | ||
260 | skb_unlink(skb, &shaper->sendq); | 259 | skb_unlink(skb, &shaper->sendq); |
261 | if (shaper->recovery < | 260 | if (shaper->recovery < |
262 | SHAPERCB(skb)->shapeclock + SHAPERCB(skb)->shapelen) | 261 | SHAPERCB(skb)->shapeclock + SHAPERCB(skb)->shapelen) |
263 | shaper->recovery = SHAPERCB(skb)->shapeclock + SHAPERCB(skb)->shapelen; | 262 | shaper->recovery = SHAPERCB(skb)->shapeclock + SHAPERCB(skb)->shapelen; |
264 | /* | 263 | /* |
265 | * Pass on to the physical target device via | 264 | * Pass on to the physical target device via |
266 | * our low level packet thrower. | 265 | * our low level packet thrower. |
267 | */ | 266 | */ |
268 | 267 | ||
269 | SHAPERCB(skb)->shapepend=0; | 268 | SHAPERCB(skb)->shapepend=0; |
270 | shaper_queue_xmit(shaper, skb); /* Fire */ | 269 | shaper_queue_xmit(shaper, skb); /* Fire */ |
271 | } | 270 | } |
@@ -276,27 +275,27 @@ static void shaper_kick(struct shaper *shaper) | |||
276 | /* | 275 | /* |
277 | * Next kick. | 276 | * Next kick. |
278 | */ | 277 | */ |
279 | 278 | ||
280 | if(skb!=NULL) | 279 | if(skb!=NULL) |
281 | mod_timer(&shaper->timer, SHAPERCB(skb)->shapeclock); | 280 | mod_timer(&shaper->timer, SHAPERCB(skb)->shapeclock); |
282 | } | 281 | } |
283 | 282 | ||
284 | 283 | ||
285 | /* | 284 | /* |
286 | * Bring the interface up. We just disallow this until a | 285 | * Bring the interface up. We just disallow this until a |
287 | * bind. | 286 | * bind. |
288 | */ | 287 | */ |
289 | 288 | ||
290 | static int shaper_open(struct net_device *dev) | 289 | static int shaper_open(struct net_device *dev) |
291 | { | 290 | { |
292 | struct shaper *shaper=dev->priv; | 291 | struct shaper *shaper=dev->priv; |
293 | 292 | ||
294 | /* | 293 | /* |
295 | * Can't open until attached. | 294 | * Can't open until attached. |
296 | * Also can't open until speed is set, or we'll get | 295 | * Also can't open until speed is set, or we'll get |
297 | * a division by zero. | 296 | * a division by zero. |
298 | */ | 297 | */ |
299 | 298 | ||
300 | if(shaper->dev==NULL) | 299 | if(shaper->dev==NULL) |
301 | return -ENODEV; | 300 | return -ENODEV; |
302 | if(shaper->bitspersec==0) | 301 | if(shaper->bitspersec==0) |
@@ -307,7 +306,7 @@ static int shaper_open(struct net_device *dev) | |||
307 | /* | 306 | /* |
308 | * Closing a shaper flushes the queues. | 307 | * Closing a shaper flushes the queues. |
309 | */ | 308 | */ |
310 | 309 | ||
311 | static int shaper_close(struct net_device *dev) | 310 | static int shaper_close(struct net_device *dev) |
312 | { | 311 | { |
313 | struct shaper *shaper=dev->priv; | 312 | struct shaper *shaper=dev->priv; |
@@ -336,7 +335,7 @@ static struct net_device_stats *shaper_get_stats(struct net_device *dev) | |||
336 | return &sh->stats; | 335 | return &sh->stats; |
337 | } | 336 | } |
338 | 337 | ||
339 | static int shaper_header(struct sk_buff *skb, struct net_device *dev, | 338 | static int shaper_header(struct sk_buff *skb, struct net_device *dev, |
340 | unsigned short type, void *daddr, void *saddr, unsigned len) | 339 | unsigned short type, void *daddr, void *saddr, unsigned len) |
341 | { | 340 | { |
342 | struct shaper *sh=dev->priv; | 341 | struct shaper *sh=dev->priv; |
@@ -396,7 +395,7 @@ static int shaper_neigh_setup(struct neighbour *n) | |||
396 | n->ops = &arp_broken_ops; | 395 | n->ops = &arp_broken_ops; |
397 | n->output = n->ops->output; | 396 | n->output = n->ops->output; |
398 | } | 397 | } |
399 | #endif | 398 | #endif |
400 | return 0; | 399 | return 0; |
401 | } | 400 | } |
402 | 401 | ||
@@ -408,7 +407,7 @@ static int shaper_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p) | |||
408 | p->ucast_probes = 0; | 407 | p->ucast_probes = 0; |
409 | p->mcast_probes = 0; | 408 | p->mcast_probes = 0; |
410 | } | 409 | } |
411 | #endif | 410 | #endif |
412 | return 0; | 411 | return 0; |
413 | } | 412 | } |
414 | 413 | ||
@@ -433,7 +432,7 @@ static int shaper_attach(struct net_device *shdev, struct shaper *sh, struct net | |||
433 | } | 432 | } |
434 | else | 433 | else |
435 | shdev->hard_header = NULL; | 434 | shdev->hard_header = NULL; |
436 | 435 | ||
437 | if(dev->rebuild_header) | 436 | if(dev->rebuild_header) |
438 | { | 437 | { |
439 | sh->rebuild_header = dev->rebuild_header; | 438 | sh->rebuild_header = dev->rebuild_header; |
@@ -441,7 +440,7 @@ static int shaper_attach(struct net_device *shdev, struct shaper *sh, struct net | |||
441 | } | 440 | } |
442 | else | 441 | else |
443 | shdev->rebuild_header = NULL; | 442 | shdev->rebuild_header = NULL; |
444 | 443 | ||
445 | #if 0 | 444 | #if 0 |
446 | if(dev->hard_header_cache) | 445 | if(dev->hard_header_cache) |
447 | { | 446 | { |
@@ -452,7 +451,7 @@ static int shaper_attach(struct net_device *shdev, struct shaper *sh, struct net | |||
452 | { | 451 | { |
453 | shdev->hard_header_cache= NULL; | 452 | shdev->hard_header_cache= NULL; |
454 | } | 453 | } |
455 | 454 | ||
456 | if(dev->header_cache_update) | 455 | if(dev->header_cache_update) |
457 | { | 456 | { |
458 | sh->header_cache_update = dev->header_cache_update; | 457 | sh->header_cache_update = dev->header_cache_update; |
@@ -465,7 +464,7 @@ static int shaper_attach(struct net_device *shdev, struct shaper *sh, struct net | |||
465 | shdev->hard_header_cache = NULL; | 464 | shdev->hard_header_cache = NULL; |
466 | #endif | 465 | #endif |
467 | shdev->neigh_setup = shaper_neigh_setup_dev; | 466 | shdev->neigh_setup = shaper_neigh_setup_dev; |
468 | 467 | ||
469 | shdev->hard_header_len=dev->hard_header_len; | 468 | shdev->hard_header_len=dev->hard_header_len; |
470 | shdev->type=dev->type; | 469 | shdev->type=dev->type; |
471 | shdev->addr_len=dev->addr_len; | 470 | shdev->addr_len=dev->addr_len; |
@@ -478,13 +477,13 @@ static int shaper_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
478 | { | 477 | { |
479 | struct shaperconf *ss= (struct shaperconf *)&ifr->ifr_ifru; | 478 | struct shaperconf *ss= (struct shaperconf *)&ifr->ifr_ifru; |
480 | struct shaper *sh=dev->priv; | 479 | struct shaper *sh=dev->priv; |
481 | 480 | ||
482 | if(ss->ss_cmd == SHAPER_SET_DEV || ss->ss_cmd == SHAPER_SET_SPEED) | 481 | if(ss->ss_cmd == SHAPER_SET_DEV || ss->ss_cmd == SHAPER_SET_SPEED) |
483 | { | 482 | { |
484 | if(!capable(CAP_NET_ADMIN)) | 483 | if(!capable(CAP_NET_ADMIN)) |
485 | return -EPERM; | 484 | return -EPERM; |
486 | } | 485 | } |
487 | 486 | ||
488 | switch(ss->ss_cmd) | 487 | switch(ss->ss_cmd) |
489 | { | 488 | { |
490 | case SHAPER_SET_DEV: | 489 | case SHAPER_SET_DEV: |
@@ -526,7 +525,7 @@ static void shaper_init_priv(struct net_device *dev) | |||
526 | /* | 525 | /* |
527 | * Add a shaper device to the system | 526 | * Add a shaper device to the system |
528 | */ | 527 | */ |
529 | 528 | ||
530 | static void __init shaper_setup(struct net_device *dev) | 529 | static void __init shaper_setup(struct net_device *dev) |
531 | { | 530 | { |
532 | /* | 531 | /* |
@@ -542,11 +541,11 @@ static void __init shaper_setup(struct net_device *dev) | |||
542 | dev->hard_start_xmit = shaper_start_xmit; | 541 | dev->hard_start_xmit = shaper_start_xmit; |
543 | dev->get_stats = shaper_get_stats; | 542 | dev->get_stats = shaper_get_stats; |
544 | dev->set_multicast_list = NULL; | 543 | dev->set_multicast_list = NULL; |
545 | 544 | ||
546 | /* | 545 | /* |
547 | * Intialise the packet queues | 546 | * Intialise the packet queues |
548 | */ | 547 | */ |
549 | 548 | ||
550 | /* | 549 | /* |
551 | * Handlers for when we attach to a device. | 550 | * Handlers for when we attach to a device. |
552 | */ | 551 | */ |
@@ -567,7 +566,7 @@ static void __init shaper_setup(struct net_device *dev) | |||
567 | dev->tx_queue_len = 10; | 566 | dev->tx_queue_len = 10; |
568 | dev->flags = 0; | 567 | dev->flags = 0; |
569 | } | 568 | } |
570 | 569 | ||
571 | static int shapers = 1; | 570 | static int shapers = 1; |
572 | #ifdef MODULE | 571 | #ifdef MODULE |
573 | 572 | ||
@@ -611,7 +610,7 @@ static int __init shaper_init(void) | |||
611 | snprintf(name, IFNAMSIZ, "shaper%d", i); | 610 | snprintf(name, IFNAMSIZ, "shaper%d", i); |
612 | dev = alloc_netdev(sizeof(struct shaper), name, | 611 | dev = alloc_netdev(sizeof(struct shaper), name, |
613 | shaper_setup); | 612 | shaper_setup); |
614 | if (!dev) | 613 | if (!dev) |
615 | break; | 614 | break; |
616 | 615 | ||
617 | if (register_netdev(dev)) { | 616 | if (register_netdev(dev)) { |