#!/bin/sh # # Bandwidth script to allow max 500Kbit of 10Mbit from subnet 192.168.0.0/24 through this ASL-box.
# ------------------------------------------- # First of all - this is just a SIMPLE EXAMPLE of CBQ power. # Don't ask me "why" and "how" [:)] # # This is an example of using CBQ (Class Based Queueing) and policy-based # filter for building smart ethernet shapers. All CBQ parameters are # correct for Linux ETHERNET (eth0,1,2..) interfaces only! It works for # ARCNET too (just set bandwidth parameter to 2Mbit). # # The configuration says, that we will control traffic on 10Mbit ethernet # device eth0 and the traffic going from network 192.168.0.0/24 will be # processed with priority 5 and shaped to rate of 500Kbit. # # Note that you can of course control outgoing traffic only. If you # want to control traffic in both directions, you must set up CBQ # for both interfaces. # # Consider the following example: # # +---------+ 192.168.0.0 # INTERNET -----eth1-| linux |-eth0------*-[clients] # +---------+ # # Imagine you want to shape traffic from internet to the client to # 500Kbit and traffic in the opposite direction to 500Kbit. You need # to setup shapers on both eth0 and eth1 interfaces, thus you need # two config parts. # -------------------------------------------
# Clearly we have one main class 'School'. # We decide that the "School" should be restricted to 500Kbits of # down- and upstream traffic. # Setting up traffic control is done with the iproute2 tool tc.
#----------------------------------- # Set bandwidth restriction on eth0: #-----------------------------------
# Ok, lots of numbers here. # What has happened? We have configured the 'queueing discipline' of eth0. # With 'root' we denote that this is the root discipline. # We have given it the handle '10:'. We want to do CBQ, so we mention that # on the command line as well. We tell the kernel that it can allocate 10Mbit # and that the average packet size is somewhere around 1000 octets.
# Now we need to generate our root class, from which all others descend:
# Even more numbers to worry about - the Linux CBQ implementation is very generic. # With 'parent 10:0' we indicate that this class descends from the root of qdisc # handle '10:' we generated earlier. With 'classid 10:1' we name this class. # We really don't tell the kernel a lot more, we just generate a class that # completely fills the available device. We also specify that the MTU (plus some # overhead) is 1514 octets. We also 'weight' this class with 1Mbit - a tuning parameter (1/10 of bandwidth).
# We allocate 500Kbit (SCHOOL), and indicate that this class # must not exceed this by adding the 'bounded' parameter. Otherwise this class # would have started borrowing bandwidth from other classes. # #To make this a bit clearer, a diagram which shows our classes: # +-------------[10: 10Mbit]----------+ # |+------- -[10:1 root 10Mbit]------+| # || || # || +-[10:100 500Kbit]-+ || # || | | || # || | SCHOOL | || # || | | || # || +------------------+ || # || || # |+---------------------------------+| # +-----------------------------------+ # # Ok, now we have told the kernel what our classes are, but not yet how to # manage the queues. We do this presently, in one fell swoop for this class.
# In this case we install the Stochastic Fairness Queueing discipline (sfq), # which is not quite fair, but works well up to high bandwidths without burning # up CPU cycles. There are other queueing disciplines available which are better, # but need more CPU. The Token Bucket Filter is often used.
# Now there is only one thing left to do and that is to explain to the kernel # which packets belong to which class. Initially we will do this natively with iproute2, # but more interesting applicationsare possible in combination with netfilter.
tc filter add dev eth0 parent 10:0 protocol ip prio 100 u32 match ip dst 192.168.0.0/24 flowid 10:100
# Here is is assumed that all our IP addresses (192.168.0.0/24) should be considered # to be part of the SCHOOL(10:100). The u32 match is a very simple one - more # sophisticated matching rules are possible when using netfilter to mark our # packets, which we can than match on in tc.
# Now we have fairly divided the downstream bandwidth, we need to do the same # for the upstream. For brevity's sake, all in one go:
#------------------------------------ # Set bandwidth restriction on eth1: #------------------------------------ tc qdisc add dev eth1 root handle 20: cbq bandwidth 10Mbit avpkt 1000 tc class add dev eth1 parent 20:0 classid 20:1 cbq bandwidth 10Mbit rate 10Mbit allot 1514 weight 1Mbit prio 5 maxburst 20 avpkt 1000 tc class add dev eth1 parent 20:1 classid 20:100 cbq bandwidth 10Mbit rate 500Kbit allot 1514 weight 50Kbit prio 5 maxburst 20 avpkt 1000 bounded tc qdisc add dev eth1 parent 20:100 sfq quantum 1514b perturb 15 tc filter add dev eth1 parent 20:0 protocol ip prio 100 u32 match ip src 192.168.0.0/24 flowid 20:100
Init this script from /etc/rc.d/ Create a symbolic link between bandwidth.sh and S15bandwidth in /etc/rc.d/rc2.d/ : ln -s ../bandwidth.sh S15bandwidth now it will start (automatic) when you reboot.
Display CBQ setup with these commands (for instance on eth0): tc qdisc show dev eth0 tc class show dev eth0
I am having troubles getting this script to run. The only thing that I can find missing is the "S15bandwidth" in the /etc/rc.d/rc2.d/
I ran the: ln -s ../bandwidth.sh S15bandwidth
It went through fine, so I assumed I was all good, BUT it didn't work when I rebooted the box- So, I started poking around and found that missing.. Where do you get it?