From 965223a8d0131ba1cebd9ce9a1642ed5d23ba4f8 Mon Sep 17 00:00:00 2001 From: Martino Trevisan Date: Wed, 4 Dec 2019 17:17:40 +0100 Subject: [PATCH] Initial Commit --- apply_shaping.sh | 233 +++++++++++++++++++++++++++++++++++++++++++++++ profiles.csv | 27 ++++++ 2 files changed, 260 insertions(+) create mode 100644 apply_shaping.sh create mode 100644 profiles.csv diff --git a/apply_shaping.sh b/apply_shaping.sh new file mode 100644 index 0000000..75c0797 --- /dev/null +++ b/apply_shaping.sh @@ -0,0 +1,233 @@ +#!/bin/bash + +# Default values +PROFILE_FILE="profiles.csv" +VIRTUAL=ifb0 +DEFAULT_DOWNLOAD="40000mbit" +DEFAULT_UPLOAD="40000mbit" +DEFAULT_RTT="0ms" + +# Utility Function +function go() { + if [ "$DRY_RUN" = true ]; then + echo "+ $*" + else + eval "$*" + fi + return $? +} + +# Parse Args +DRY_RUN=false +REMOVE=false +OPERATOR="" +COUNTRY="" +TECHNOLOGY="" +QUALITY="" +INTERFACE="" + +while getopts "o:c:t:q:i:rhd" flag +do + case $flag in + o) OPERATOR=$OPTARG;; + c) COUNTRY=$OPTARG;; + t) TECHNOLOGY=$OPTARG;; + q) QUALITY=$OPTARG;; + i) INTERFACE=$OPTARG;; + r) REMOVE=true;; + d) DRY_RUN=true;; + h) echo "Usage: apply_shaping.sh -o operator -c country -t technology -q quality -i interface [-r] [-d] [-h]" ; exit ;; + esac +done + + +# Remove rules +if [ "$REMOVE" = true ]; then + + # Check arguments are correct + if [ -z "$OPERATOR" ] && [ -z "$COUNTRY" ] && [ -z "$TECHNOLOGY" ] \ + && [ -z "$QUALITY" ] && [ -z "$INTERFACE" ]; then + echo "Removing shaping rules" + + # Remove module IFB + go rmmod ifb 2>/dev/null + + # Remove all TC policies + for INTERFACE in $( ifconfig | grep HWaddr | grep -v ifb | cut -d " " -f 1 ) ; do + + go tc qdisc del root dev $INTERFACE 2>/dev/null + go tc qdisc del dev $INTERFACE handle ffff: ingress 2>/dev/null + + done + + else + echo "When removing rules, all other arguemnts must be empty" + fi + +else + if [ -z "$OPERATOR" ] || [ -z "$COUNTRY" ] || [ -z "$TECHNOLOGY" ] \ + || [ -z "$QUALITY" ] || [ -z "$INTERFACE" ]; then + echo "You should specify all of operator,country, technology, quality and interface" + else + echo "Imposing shaping on interface: $INTERFACE" + + # Search for profile + search=$( cat $PROFILE_FILE | tail -n +2 | \ + awk -F , "(\$1==\"$OPERATOR\") && (\$2==\"$COUNTRY\") \ + && (\$3==\"$TECHNOLOGY\") && (\$4==\"$QUALITY\")" ) + + if [ -z "$search" ] ; then + echo "Cannot find selected profile" + else + + # Print infos + echo "Imposing profile:" + echo " Operator: $OPERATOR" + echo " Country: $COUNTRY" + echo " Technology: $TECHNOLOGY" + echo " Quality: $QUALITY" + + DOWNLOAD=$(echo $search | cut -d , -f 5) + UPLOAD=$(echo $search | cut -d , -f 6) + RTT_AVG=$(echo $search | cut -d , -f 7) + RTT_SDEV=$(echo $search | cut -d , -f 8) + + echo "Parameters are:" + echo " Download [kbps]: $DOWNLOAD" + echo " Upload [kbps]: $UPLOAD" + echo " RTT [ms]: $RTT_AVG +- $RTT_SDEV" + + # Impose shaping + + # Create virtual interfaces + go rmmod ifb 2>/dev/null + go modprobe ifb numifbs=1 + go ip link set dev $VIRTUAL up + + # Create rules + # Clear old + go tc qdisc del root dev $INTERFACE 2>/dev/null # clear outgoing + go tc qdisc del dev $INTERFACE handle ffff: ingress 2>/dev/null # clear incoming + go tc qdisc del root dev $VIRTUAL 2>/dev/null + + + # Create Device Pipes + go tc qdisc add dev $INTERFACE handle ffff: ingress + go tc filter add dev $INTERFACE parent ffff: protocol ip u32 match u32 0 0 \ + action mirred egress redirect dev $VIRTUAL + + + # INCOMING + # Speed + go tc qdisc add dev $VIRTUAL root handle 2: htb default 10 + go tc class add dev $VIRTUAL parent 2: classid 2:1 htb rate $DEFAULT_DOWNLOAD + go tc class add dev $VIRTUAL parent 2:1 classid 2:10 htb rate ${DOWNLOAD}kbit + + + # OUTGOING + # Speed + go tc qdisc add dev $INTERFACE root handle 1: htb default 11 + go tc class add dev $INTERFACE parent 1: classid 1:1 htb rate $DEFAULT_UPLOAD + go tc class add dev $INTERFACE parent 1:1 classid 1:11 htb rate ${UPLOAD}kbit + # Delay + go tc qdisc add dev $INTERFACE parent 1:11 handle 10: netem delay ${RTT_AVG}ms ${RTT_SDEV}ms distribution normal + + fi + + + fi +fi + + + + +exit + + +if [ "$REMOVE" = true ]; then + # Remove old shaping rules + echo "Removing all traffic shaping" + + # Remove module IFB + go rmmod ifb 2>/dev/null + + # Remove all TC policies + for INTERFACE in $( ifconfig | grep HWaddr | grep -v ifb | cut -d " " -f 1 ) ; do + + go tc qdisc del root dev $INTERFACE 2>/dev/null + go tc qdisc del dev $INTERFACE handle ffff: ingress 2>/dev/null + + done + +else + # Create rules + NB_RULES=$( echo $RULES | wc -w) + echo "Setting shaping on $NB_RULES interfaces" + + #Create virtual interfaces + go rmmod ifb 2>/dev/null + go modprobe ifb numifbs=$NB_RULES + + i=0 + for RULE in $RULES ; do + + # Get values + INTERFACE=$(echo $RULE | cut -d : -f 1) + DOWNLOAD=$(echo $RULE | cut -d : -f 2) + UPLOAD=$(echo $RULE | cut -d : -f 3) + RTT=$(echo $RULE | cut -d : -f 4) + LOSS=$(echo $RULE | cut -d : -f 5) + + if [ -z "$DOWNLOAD" ]; then DOWNLOAD=$DEFAULT_DOWNLOAD ; fi + if [ -z "$UPLOAD" ]; then UPLOAD=$DEFAULT_UPLOAD ; fi + if [ -z "$RTT" ]; then RTT=$DEFAULT_RTT ; fi + if [ -z "$LOSS" ]; then LOSS=$DEFAULT_LOSS ; fi + + echo "Interface $INTERFACE:" + echo " Download: $DOWNLOAD" + echo " Upload: $UPLOAD" + echo " RTT: $RTT" + echo " Loss: $LOSS" + + # Determine virtual interface and set it up + VIRTUAL=ifb${i} + ip link set dev $VIRTUAL up + + # Clear old + go tc qdisc del root dev $INTERFACE 2>/dev/null # clear outgoing + go tc qdisc del dev $INTERFACE handle ffff: ingress 2>/dev/null # clear incoming + go tc qdisc del root dev $VIRTUAL 2>/dev/null + + + # Create Device Pipes + go tc qdisc add dev $INTERFACE handle ffff: ingress + go tc filter add dev $INTERFACE parent ffff: protocol ip u32 match u32 0 0 \ + action mirred egress redirect dev $VIRTUAL + + + # INCOMING + # Speed + go tc qdisc add dev $VIRTUAL root handle 2: htb default 10 + go tc class add dev $VIRTUAL parent 2: classid 2:1 htb rate $DEFAULT_DOWNLOAD + go tc class add dev $VIRTUAL parent 2:1 classid 2:10 htb rate $DOWNLOAD + # Loss rate + go tc qdisc add dev $VIRTUAL parent 2:10 handle 20: netem loss $LOSS + + + # OUTGOING + # Speed + go tc qdisc add dev $INTERFACE root handle 1: htb default 11 + go tc class add dev $INTERFACE parent 1: classid 1:1 htb rate $DEFAULT_UPLOAD + go tc class add dev $INTERFACE parent 1:1 classid 1:11 htb rate $UPLOAD + # Delay + go tc qdisc add dev $INTERFACE parent 1:11 handle 10: netem delay $RTT loss $LOSS + # Loss + + # Increment Counter + i=$(( $i + 1 )) + + done + + +fi + diff --git a/profiles.csv b/profiles.csv new file mode 100644 index 0000000..91ddc90 --- /dev/null +++ b/profiles.csv @@ -0,0 +1,27 @@ +operator,country,rat,signal_quality,download_kbps,upload_kbps,latency_ms_avg,latency_ms_stdev +3,sweden,3G,bad,3075.1625206571275,908.556253720688,145.32302383897778,90.8346100265561 +3,sweden,3G,good,13908.556434239368,2942.7036121531464,81.28050962600047,37.05237849834911 +3,sweden,3G,medium,11504.463813567636,2534.2379851467545,83.66007643655166,49.55400330062306 +3,sweden,4G,good,33300.98217045987,11338.093465680797,83.0254072603541,44.21141968723388 +3,sweden,4G,medium,19750.631978392492,3490.106871864862,84.59163119231556,46.009529940037716 +net1,norway,4G,bad,3295.6665022168213,149.74674246273133,112.90237110487114,82.04472736690624 +net1,norway,4G,good,18771.20664570202,11634.685026654533,111.57185146473576,48.16729256164683 +net1,norway,4G,medium,12675.957648153251,1930.2024307679649,107.6240798233494,57.88568968680676 +telenor,norway,3G,good,12242.951087747222,3441.331787874993,98.79122555107779,56.959362595351394 +telenor,norway,3G,medium,11140.146152187746,930.1395916261956,116.30346053083251,87.10609013464038 +telenor,norway,4G,bad,22905.49984678181,1500.4135271085122,83.33413069917137,39.020774628073205 +telenor,norway,4G,good,35638.47807286335,16417.91154955117,89.61577918141055,40.09922258201716 +telenor,norway,4G,medium,23927.88325180164,3954.514618531522,86.38483031551375,39.8540561606916 +telenor,sweden,3G,good,16226.3913421666,3328.018778076208,88.02011922669901,44.25315158448999 +telenor,sweden,3G,medium,9713.455450285692,2304.626847067011,92.52294807343232,38.844014310836975 +telenor,sweden,4G,good,22856.327027888008,10143.744824294152,90.50945481798671,48.43372291047463 +telenor,sweden,4G,medium,10590.223886262243,2344.183427402598,88.64674810704422,48.403777215757984 +telia,norway,3G,good,6192.611203511721,1997.3185079926611,87.68797736419066,59.8399174433793 +telia,norway,3G,medium,3265.61398595305,1457.2524804538364,106.51113844839007,75.49551351196635 +telia,norway,4G,bad,11495.552495723465,1521.0927399755633,101.60515559191359,63.765902042777654 +telia,norway,4G,good,21487.635846014542,15707.74864908961,92.86137251178297,43.84838140515734 +telia,norway,4G,medium,17146.69771713526,3021.190339270585,95.53354794805004,50.707682649453496 +telia,sweden,3G,good,16733.749779888218,3362.620488703752,131.93499289088138,55.10156983990105 +telia,sweden,3G,medium,11588.37967283065,2259.95112831988,145.95942031539738,59.569917792058504 +telia,sweden,4G,good,53954.87190708256,21181.03261207894,91.85231065904635,45.93133354604078 +telia,sweden,4G,medium,28648.29771023976,4224.282864079301,104.5041425140391,56.76313884877055