Skip to content

Instantly share code, notes, and snippets.

@magnific0
Forked from ole1986/traffic-control.sh
Created December 1, 2017 12:37
Show Gist options
  • Select an option

  • Save magnific0/e2a3ee492dda58f07df5984aacbea5e5 to your computer and use it in GitHub Desktop.

Select an option

Save magnific0/e2a3ee492dda58f07df5984aacbea5e5 to your computer and use it in GitHub Desktop.

Revisions

  1. @ole1986 ole1986 revised this gist Jan 8, 2017. 1 changed file with 52 additions and 18 deletions.
    70 changes: 52 additions & 18 deletions traffic-control.sh
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    #!/bin/bash

    VERSION="1.0.1"
    VERSION="1.0.2"
    # Interface connect to out lan
    INTERFACE="eth0"
    # Interface virtual for incomming traffic
    @@ -29,6 +29,10 @@ function show_usage {
    echo " --dspeed=<speed>: define the download speed (default: 128kbit)"
    echo " <IP> : the ip address to limit the traffic for"
    echo
    echo "Changelog:"
    echo "v1.0.2 - make use of the 'tc change' instead of removing"
    echo "v1.0.1 - add uspeed and dspeed to setup limit as argument"
    echo "v1.0.0 - initial version"
    }

    function remove_tc {
    @@ -39,28 +43,40 @@ function remove_tc {
    if [[ $(tc qdisc | grep '^qdisc htb 2:') ]]; then
    tc qdisc del dev $INTERFACE handle ffff: ingress
    tc qdisc del root dev $VIRTUAL
    #tc qdisc add dev $INTERFACE handle ffff: ingress
    # Unload the virtual network module
    ip link set dev $VIRTUAL down
    modprobe -r ifb
    fi
    # Unload the virtual network module
    ip link set dev $VIRTUAL down
    modprobe -r ifb
    }

    function tc_outgoing {
    echo "Limit outgoing traffic"

    # Add classes per ip
    tc qdisc add dev $INTERFACE root handle 1: htb
    # update outgoing speed (if already exists)
    if [[ $(tc class show dev $INTERFACE |grep '^class htb 1:1') ]]; then
    TCC="tc class change"
    else
    # Add classes per ip
    tc qdisc add dev $INTERFACE root handle 1: htb
    TCC="tc class add"
    fi

    echo "- upload speed $SPEED_UPLOAD"
    tc class add dev $INTERFACE parent 1: classid 1:1 htb rate $SPEED_UPLOAD
    $TCC dev $INTERFACE parent 1: classid 1:1 htb rate $SPEED_UPLOAD
    if [ $DELAY -gt 0 ]; then
    TCN="tc qdisc add"
    [[ $(tc qdisc |grep '^qdisc netem 10:') ]] && TCN="tc qdisc change"
    echo "- latency ${DELAY}ms"
    tc qdisc add dev $INTERFACE parent 1:1 handle 10: netem delay ${DELAY}ms
    $TCN dev $INTERFACE parent 1:1 handle 10: netem delay ${DELAY}ms
    fi

    # Match ip and put it into the respective class
    echo "- filter on IP $ADDRESS"
    tc filter add dev $INTERFACE protocol ip parent 1: prio 1 u32 match ip dst $ADDRESS flowid 1:1
    TCF="tc filter add"
    if [[ $(tc filter show dev $INTERFACE | grep '^filter parent 1: protocol ip pref 1') ]]; then
    TCF="tc filter change"
    fi
    $TCF dev $INTERFACE protocol ip parent 1: prio 1 u32 match ip dst $ADDRESS flowid 1:1
    }

    function tc_incoming {
    @@ -69,20 +85,38 @@ function tc_incoming {
    ip link set dev $VIRTUAL up

    echo "Limit incoming traffic"
    tc qdisc add dev $INTERFACE handle ffff: ingress
    # Redirecto ingress eth0 to egress ifb0
    tc filter add dev $INTERFACE parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev $VIRTUAL
    # Add classes per ip
    tc qdisc add dev $VIRTUAL root handle 2: htb

    # update incoming speed (if already exists)
    if [[ $(tc class show dev $VIRTUAL |grep '^class htb 2:1') ]]; then
    TCC="tc class change"
    else
    tc qdisc add dev $INTERFACE handle ffff: ingress
    # Redirecto ingress eth0 to egress ifb0
    tc filter add dev $INTERFACE parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev $VIRTUAL
    # Add classes per ip
    tc qdisc add dev $VIRTUAL root handle 2: htb

    TCC="tc class add"
    fi

    echo "- download speed $SPEED_DOWNLOAD"
    tc class add dev $VIRTUAL parent 2: classid 2:1 htb rate $SPEED_DOWNLOAD
    $TCC dev $VIRTUAL parent 2: classid 2:1 htb rate $SPEED_DOWNLOAD

    if [ $DELAY -gt 0 ]; then
    TCN="tc qdisc add"
    [[ $(tc qdisc |grep '^qdisc netem 20:') ]] && TCN="tc qdisc change"

    echo "- latency ${DELAY}ms"
    tc qdisc add dev $VIRTUAL parent 2:1 handle 20: netem delay ${DELAY}ms
    $TCN dev $VIRTUAL parent 2:1 handle 20: netem delay ${DELAY}ms
    fi

    echo "- filter on IP $ADDRESS"
    tc filter add dev $VIRTUAL protocol ip parent 2: prio 1 u32 match ip src $ADDRESS flowid 2:1
    TCF="tc filter add"
    if [[ $(tc filter show dev $VIRTUAL | grep '^filter parent 1: protocol ip pref 1') ]]; then
    TCF="tc filter change"
    fi

    $TCF dev $VIRTUAL protocol ip parent 2: prio 1 u32 match ip src $ADDRESS flowid 2:1
    }

    if [ $# -eq 0 ]; then
  2. @ole1986 ole1986 revised this gist Jan 8, 2017. 1 changed file with 25 additions and 14 deletions.
    39 changes: 25 additions & 14 deletions traffic-control.sh
    Original file line number Diff line number Diff line change
    @@ -1,42 +1,48 @@
    #!/bin/bash

    VERSION="1.0.0"
    VERSION="1.0.1"
    # Interface connect to out lan
    INTERFACE="eth0"
    # Interface virtual for incomming traffic
    VIRTUAL="ifb0"
    # set the direction (1 = outgoing only, 2 = incoming only 3 = both)
    DIRECTION=3
    # Speed
    SPEED_DOWNLOAD="25kbit"
    SPEED_UPLOAD="25kbit"
    SPEED_DOWNLOAD="128kbit"
    SPEED_UPLOAD="128kbit"
    # Delay in milliseconds (0 = no delay)
    DELAY=1000
    DELAY=700

    function show_usage {
    echo
    echo "Bandwidth Control using TC"
    echo "Version: $VERSION | Author: ole1986"
    echo
    echo "Usage: $1 [-r|--remove] [-i|--incoming] [-o|--outgoing] <IP>"
    echo "Usage: $1 [-r|--remove] [-i|--incoming] [-o|--outgoing] [-d|--delay=] [--uspeed=] [--dspeed=] <IP>"
    echo
    echo "Arguments:"
    echo " -r|--remove : removes all traffic control being set"
    echo " -i|--incoming : limit the bandwidth only for incoming packetes"
    echo " -o|--outgoing : limit the bandwidth only for outgoing packetes"
    echo " -d|--delay=700 : define the latency in milliseconds (default: 700)"
    echo " --uspeed=<speed>: define the upload speed (default: 128kbit)"
    echo " --dspeed=<speed>: define the download speed (default: 128kbit)"
    echo " <IP> : the ip address to limit the traffic for"
    echo
    }

    function remove_tc {
    echo "Unlimit traffic on $INTERFACE (in/out)"
    # clean up outgoing
    tc qdisc del root dev $INTERFACE
    [[ $(tc qdisc |grep '^qdisc htb 1:') ]] && tc qdisc del root dev $INTERFACE
    # clean up incoming
    tc qdisc del dev $INTERFACE handle ffff: ingress
    tc qdisc del root dev $VIRTUAL
    tc qdisc add dev $INTERFACE handle ffff: ingress
    if [[ $(tc qdisc | grep '^qdisc htb 2:') ]]; then
    tc qdisc del dev $INTERFACE handle ffff: ingress
    tc qdisc del root dev $VIRTUAL
    #tc qdisc add dev $INTERFACE handle ffff: ingress
    fi
    # Unload the virtual network module
    ip link set dev $VIRTUAL down
    modprobe -r ifb
    }

    @@ -63,7 +69,7 @@ function tc_incoming {
    ip link set dev $VIRTUAL up

    echo "Limit incoming traffic"

    tc qdisc add dev $INTERFACE handle ffff: ingress
    # Redirecto ingress eth0 to egress ifb0
    tc filter add dev $INTERFACE parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev $VIRTUAL
    # Add classes per ip
    @@ -103,15 +109,20 @@ case $i in
    DELAY=${i#*=}
    shift
    ;;
    --uspeed=*)
    SPEED_UPLOAD="${i#*=}"
    shift
    ;;
    --dspeed=*)
    SPEED_DOWNLOAD="${i#*=}"
    shift
    ;;
    esac
    done

    remove_tc

    if [[ -n $1 ]]; then
    ADDRESS=$1
    echo $ADDRESS
    fi
    [ -n $1 ] && ADDRESS=$1

    [ $DIRECTION -eq 0 ] && exit 0

  3. @ole1986 ole1986 revised this gist Jan 8, 2017. No changes.
  4. @ole1986 ole1986 created this gist Jan 8, 2017.
    130 changes: 130 additions & 0 deletions traffic-control.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,130 @@
    #!/bin/bash

    VERSION="1.0.0"
    # Interface connect to out lan
    INTERFACE="eth0"
    # Interface virtual for incomming traffic
    VIRTUAL="ifb0"
    # set the direction (1 = outgoing only, 2 = incoming only 3 = both)
    DIRECTION=3
    # Speed
    SPEED_DOWNLOAD="25kbit"
    SPEED_UPLOAD="25kbit"
    # Delay in milliseconds (0 = no delay)
    DELAY=1000

    function show_usage {
    echo
    echo "Bandwidth Control using TC"
    echo "Version: $VERSION | Author: ole1986"
    echo
    echo "Usage: $1 [-r|--remove] [-i|--incoming] [-o|--outgoing] <IP>"
    echo
    echo "Arguments:"
    echo " -r|--remove : removes all traffic control being set"
    echo " -i|--incoming : limit the bandwidth only for incoming packetes"
    echo " -o|--outgoing : limit the bandwidth only for outgoing packetes"
    echo " <IP> : the ip address to limit the traffic for"
    echo
    }

    function remove_tc {
    echo "Unlimit traffic on $INTERFACE (in/out)"
    # clean up outgoing
    tc qdisc del root dev $INTERFACE
    # clean up incoming
    tc qdisc del dev $INTERFACE handle ffff: ingress
    tc qdisc del root dev $VIRTUAL
    tc qdisc add dev $INTERFACE handle ffff: ingress
    # Unload the virtual network module
    modprobe -r ifb
    }

    function tc_outgoing {
    echo "Limit outgoing traffic"

    # Add classes per ip
    tc qdisc add dev $INTERFACE root handle 1: htb
    echo "- upload speed $SPEED_UPLOAD"
    tc class add dev $INTERFACE parent 1: classid 1:1 htb rate $SPEED_UPLOAD
    if [ $DELAY -gt 0 ]; then
    echo "- latency ${DELAY}ms"
    tc qdisc add dev $INTERFACE parent 1:1 handle 10: netem delay ${DELAY}ms
    fi

    # Match ip and put it into the respective class
    echo "- filter on IP $ADDRESS"
    tc filter add dev $INTERFACE protocol ip parent 1: prio 1 u32 match ip dst $ADDRESS flowid 1:1
    }

    function tc_incoming {
    # setup virtual interface to redirect incoming traffic
    modprobe ifb numifbs=1
    ip link set dev $VIRTUAL up

    echo "Limit incoming traffic"

    # Redirecto ingress eth0 to egress ifb0
    tc filter add dev $INTERFACE parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev $VIRTUAL
    # Add classes per ip
    tc qdisc add dev $VIRTUAL root handle 2: htb
    echo "- download speed $SPEED_DOWNLOAD"
    tc class add dev $VIRTUAL parent 2: classid 2:1 htb rate $SPEED_DOWNLOAD
    if [ $DELAY -gt 0 ]; then
    echo "- latency ${DELAY}ms"
    tc qdisc add dev $VIRTUAL parent 2:1 handle 20: netem delay ${DELAY}ms
    fi

    echo "- filter on IP $ADDRESS"
    tc filter add dev $VIRTUAL protocol ip parent 2: prio 1 u32 match ip src $ADDRESS flowid 2:1
    }

    if [ $# -eq 0 ]; then
    show_usage $0
    exit 0
    fi

    for i in "$@"
    do
    case $i in
    --remove|-r)
    DIRECTION=0
    shift # past argument with no value
    ;;
    --outgoing|-o)
    DIRECTION=1
    shift
    ;;
    --incoming|-i)
    DIRECTION=2
    shift
    ;;
    -d=*|--delay=*)
    DELAY=${i#*=}
    shift
    ;;
    esac
    done

    remove_tc

    if [[ -n $1 ]]; then
    ADDRESS=$1
    echo $ADDRESS
    fi

    [ $DIRECTION -eq 0 ] && exit 0

    if [ -z $ADDRESS ]; then
    echo
    echo "No IP address defined"
    exit 0
    fi

    [ $DIRECTION -eq 1 ] && tc_outgoing
    [ $DIRECTION -eq 2 ] && tc_incoming

    if [ $DIRECTION -eq 3 ]; then
    tc_outgoing
    tc_incoming
    fi