|
ebtables - sourceforge page - downloads - browse cvs - bridge - netfilter Free firewall software distributed under GNU General Public License |
||||||||||||
|
Example 5: Rate shaping
This example was given by Dave Stahr (dave<at>stewireless.com). Goal
I'm running Fedora Core 3 with bridge-utils-0.9.6-2 and ebtables-v2.0.6 to rate shape bandwidth for our wireless subscribers, based on their MAC address. This bridge sits between our core wireless link and the switch connected to our servers and internet gateway. A perl script runs out of cron that connects to our mysql database to create the traffic queues automatically. I'm not including that here, but any programmer could figure out how to write their own suited to their own database, etc, or just write the config by hand for smaller networks. We're running on a little 400mhz PentiumII with 128mb RAM and it doesn't even sweat. We have around 500 customers, all rate shaped in their own individual queues. This could hypothetically support up to 20,000 individual traffic queues. This is a very simple setup, but in trying to figure out how to do it, I found many unanswered posts on many web forums by people trying to do this. Bridge configuration
This gives us the ability to log in to the bridge, as well as give the bridge the ability to connect out to our mysql database server, etc: ------------- ifcfg-br0 ------------- DEVICE=br0 ONBOOT=no BOOTPROTO=static IPADDR=192.168.111.11 NETMASK=255.255.255.0 ----------- bridge_up.sh -------------------- #!/bin/bash ifdown eth0 ifdown eth1 ifconfig eth0 0.0.0.0 up ifconfig eth1 0.0.0.0 up brctl addbr br0 brctl addif br0 eth0 brctl addif br0 eth1 ifconfig br0 up ----------- bridge_down.sh -------------------- #!/bin/bash ifdown eth0 ifdown eth1 ifconfig br0 down brctl delbr br0 The rate shaping part
We're using
--------------------------- rateshape -----------------------
#!/bin/bash
#
# All Rates are in Kbits, so in order to gets Bytes divide by 8
# e.g. 25Kbps == 3.125KB/s
#
TC=/sbin/tc
EBTABLES=/sbin/ebtables # Location of ebtables
cd /usr/local/bridge
tc_start() {
$TC qdisc add dev eth0 root handle 1:0 cbq bandwidth 100Mbit avpkt 1000 mpu 64
$TC qdisc add dev eth1 root handle 1:0 cbq bandwidth 100Mbit avpkt 1000 mpu 64
#Customer A
#Two MACs: 00:0D:BD:A4:E1:C8 and 00:20:78:B0:25:7D
#256kbps download speed
${TC} class add dev eth0 parent 1:0 classid 1:1 cbq rate 256KBit allot 1514 prio 1 avpkt 1000 bounded
${TC} filter add dev eth0 parent 1:0 protocol ip handle 1 fw flowid 1:1
${EBTABLES} -A FORWARD -d 00:0D:BD:A4:E1:C8 -j mark --set-mark 1 --mark-target ACCEPT
${EBTABLES} -A FORWARD -d 00:20:78:B0:25:7D -j mark --set-mark 1 --mark-target ACCEPT
#128kbps upload speed
${TC} class add dev eth1 parent 1:0 classid 1:1 cbq rate 128KBit allot 1514 prio 1 avpkt 1000 bounded
${TC} filter add dev eth1 parent 1:0 protocol ip handle 1 fw flowid 1:1
${EBTABLES} -A FORWARD -s 00:0D:BD:A4:E1:C8 -j mark --set-mark 1 --mark-target ACCEPT
${EBTABLES} -A FORWARD -s 00:20:78:B0:25:7D -j mark --set-mark 1 --mark-target ACCEPT
#Customer B
#MAC Address: 00:0D:BD:A4:D6:54
#800kbps download speed
${TC} class add dev eth0 parent 1:0 classid 1:2 cbq rate 800KBit allot 1514 prio 1 avpkt 1000 bounded
${TC} filter add dev eth0 parent 1:0 protocol ip handle 2 fw flowid 1:2
${EBTABLES} -A FORWARD -d 00:0D:BD:A4:D6:54 -j mark --set-mark 2 --mark-target ACCEPT
#64kbps upload speed
${TC} class add dev eth1 parent 1:0 classid 1:2 cbq rate 64KBit allot 1514 prio 1 avpkt 1000 bounded
${TC} filter add dev eth1 parent 1:0 protocol ip handle 2 fw flowid 1:2
${EBTABLES} -A FORWARD -s 00:0D:BD:A4:D6:54 -j mark --set-mark 2 --mark-target ACCEPT
#Customer C
#MAC Address: 00:0A:5E:22:D1:A3
#do not rate shape!
${EBTABLES} -A FORWARD -s 00:0A:5E:22:D1:A3 -j ACCEPT
${EBTABLES} -A FORWARD -d 00:0A:5E:22:D1:A3 -j ACCEPT
#Block anything we didn't specify above.
${EBTABLES} -A FORWARD -j DROP --log
#<my config has over 500 customers and over 1100 MAC addresses>
#Just keep incrementing the classid, handle, flowid, and mark values for each customer's
#individual speed queues.
}
tc_stop() {
./save_and_reset_counters
${EBTABLES} -F
$TC qdisc del dev eth0 root
$TC qdisc del dev eth1 root
}
tc_restart() {
tc_stop
sleep 1
tc_start
}
tc_show() {
echo ""
echo "eth0"
$TC qdisc show dev eth0
$TC class show dev eth0
$TC filter show dev eth0
echo ""
echo "eth1"
$TC qdisc show dev eth1
$TC class show dev eth1
}
tc_stop() {
./save_and_reset_counters
${EBTABLES} -F
$TC qdisc del dev eth0 root
$TC qdisc del dev eth1 root
}
tc_restart() {
tc_stop
sleep 1
tc_start
}
tc_show() {
echo ""
echo "eth0"
$TC qdisc show dev eth0
$TC class show dev eth0
$TC filter show dev eth0
echo ""
echo "eth1"
$TC qdisc show dev eth1
$TC class show dev eth1
$TC filter show dev eth1
}
case "$1" in
start)
echo -n "Starting bandwidth shaping: "
tc_start
echo "done"
;;
stop)
echo -n "Stopping bandwidth shaping: "
tc_stop
echo "done"
;;
restart)
echo -n "Restarting bandwidth shaping: "
tc_restart
echo "done"
;;
show)
tc_show
;;
*)
echo "Usage: rateshape {start|stop|restart|show}"
;;
esac
|
Last modified: Thursday, 22-Sep-2005 05:44:51 PDT.