--- /dev/null
+#!/bin/bash
+#
+# Copyright: George Milescu 2010 - george.milescu@gmail.com
+#
+# Razvan Deaconescu: add support for running in OpenVZ containers (SSH to HN)
+#
+# references:
+# * http://tldp.org/HOWTO/html_single/Traffic-Control-HOWTO/
+# * http://lartc.org/howto/lartc.adv-filter.html#LARTC.ADV-FILTER.U32
+# * http://www.topwebhosts.org/tools/traffic-control.php
+# * http://atmail.com/kb/2009/throttling-bandwidth/
+# * http://www.docstoc.com/docs/20252486/Manual-tc-Packet-Filtering-and-netem
+#
+# This script is to be run on an OpenVZ container. It connects to the
+# hardware node (HN) and configures traffic shaping.
+#
+# SSH is used to connect tot the hardware node - remote user is p2p. The
+# remote user requires sudoed tc access. Hardware node is identified from
+# hostname.
+#
+# tc uses the following units when passed as a parameter.
+# kbps: Kilobytes per second
+# mbps: Megabytes per second
+# kbit: Kilobits per second
+# mbit: Megabits per second
+# bps: Bytes per second
+# Amounts of data can be specified in:
+# kb or k: Kilobytes
+# mb or m: Megabytes
+# mbit: Megabits
+# kbit: Kilobits
+# To get the byte figure from bits, divide the number by 8 bit
+
+usage() {
+ # Print help messages
+ echo "Usage: $0 set interface down-bw down-burst up-bw up-burst"
+ echo " $0 del|reset|show interface"
+ echo "* set - set the limitations or show the status of the limitations"
+ echo " * interface - the network interface that will be limited"
+ echo " * down-bw - upload bandwidth, in Mbps"
+ echo " * down-burst - upload burst, in k"
+ echo " * up-bw - download bandwidth, in Mbps"
+ echo " * up-burst - download burst, in k"
+ echo "* del|reset|show - delete, reset the limitations or show the status of the limitations"
+ echo " * interface - the network interface that will be limited"
+}
+
+if [ $# -lt 2 ]; then
+ usage
+ exit 1
+fi
+
+_tmp=$(hostname)
+# hardware node hostname
+HN=${_tmp%-*}
+# container ID
+CTID=${_tmp#$HN-}
+
+# SSH command
+SSH="ssh -l p2p $HN"
+
+IP_ADDRESS=$(/sbin/ifconfig eth0 | awk '/inet addr/ {split ($2,A,":"); print A[2]}')
+
+# Name of the traffic control command.
+TC="sudo /sbin/tc"
+
+# The action requested (set, del, reset, show limitations)
+ACTION=$1 # Action
+
+# The network interface we're planning on limiting bandwidth for egress
+EGRESS_IF=$2 # Interface
+INGRESS_IF="veth$CTID.0"
+
+# Download limit (in mega bits)
+#DNLD=8mbit # DOWNLOAD Limit
+DNLD=${3}mbit # DOWNLOAD Limit
+
+# Upload limit (in mega bits)
+#UPLD=8mbit # UPLOAD Limit
+UPLD=${5}mbit # UPLOAD Limit
+
+# Burst limit (see http://lartc.org/howto/lartc.qdisc.classless.html#AEN691)
+# Should be $DNLD/8*10ms and $UPLD/8*10ms (meaning 10k) http://mailman.ds9a.nl/pipermail/lartc/2001q4/001972.html ?
+#DL_BURST=100k
+#UP_BURST=100k
+DL_BURST=${4}k
+UP_BURST=${6}k
+
+start() {
+ # Add the egress limitation
+ #
+ # We'll use Hierarchical Token Bucket (HTB) to shape bandwidth.
+ # For detailed configuration options, please consult Linux man
+ # page.
+ $SSH "$TC qdisc add dev $EGRESS_IF root handle 1: htb default 90"
+ $SSH "$TC class add dev $EGRESS_IF parent 1: classid 1:1 htb rate $UPLD ceil $UPLD burst $UP_BURST"
+ $SSH "$TC filter add dev $EGRESS_IF protocol ip parent 1:0 prio 1 u32 match ip src $IP_ADDRESS/32 flowid 1:1"
+
+ # The first line creates the root qdisc, and next one creates a
+ # child qdisc that are to be used to shape download and upload bandwidth.
+ #
+ # The 3rd line creates the filter to match the interface.
+ # The 'dst' IP address is used to limit upload speed, to any host
+
+ # Add the ingress limitation - use virtual Ethernet interface
+ $SSH "$TC qdisc add dev $INGRESS_IF root handle 1: htb default 90"
+ $SSH "$TC class add dev $INGRESS_IF parent 1: classid 1:1 htb rate $DNLD ceil $DNLD burst $DL_BURST"
+ $SSH "$TC filter add dev $INGRESS_IF protocol ip parent 1:0 prio 1 u32 match ip dst $IP_ADDRESS/32 flowid 1:1"
+ #$SSH "$TC qdisc add dev $INGRESS_IF ingress handle ffff:0"
+ # Attach a filter to the ingress qdisc
+ #$SSH "$TC filter add dev $INGRESS_IF protocol ip parent ffff:0 prio 1 u32 match ip src 0.0.0.0/0 police rate $DNLD burst $DL_BURST action drop flowid 0:1"
+}
+
+stop() {
+ # Stop the bandwidth shaping.
+ $SSH "$TC qdisc del dev $EGRESS_IF root"
+ $SSH "$TC qdisc del dev $INGRESS_IF root"
+ #$SSH "$TC qdisc del dev $INGRESS_IF ingress handle ffff:0"
+}
+
+restart() {
+ # Self-explanatory.
+ stop
+ sleep 1
+ start
+}
+
+show() {
+ # Display status of traffic control status.
+ $SSH "$TC -s qdisc ls dev $EGRESS_IF"
+ $SSH "$TC -s qdisc ls dev $INGRESS_IF"
+}
+
+case "$ACTION" in
+ "set")
+ echo -n "Setting bandwidth limitations: "
+ start
+ echo "done"
+ ;;
+
+ "del")
+ echo -n "Deleting bandwidth limitations: "
+ stop
+ echo "done"
+ ;;
+
+ "reset")
+ echo -n "Resetting bandwidth limitations: "
+ restart
+ echo "done"
+ ;;
+
+ "show")
+ echo "Bandwidth limitations status for $EGRESS_IF and $INGRESS_IF:"
+ show
+ echo ""
+ ;;
+
+ *)
+ usage
+ exit 1
+ ;;
+esac
+
+exit 0