#!/bin/bash

UP4G=768
DOWN4G=1152
ETHERNET=7500
UPSLOW=100
DOWNSLOW=100
UPSNAIL=10
DOWNSNAIL=10

MSILANIP0=192.168.123.0/24
MSILANIP1=10.0.0.0/8
MSIWANIP1=198.243.4.232/29
MSIWANIP2=205.168.220.224/26
MSIWANIP3=216.241.103.42/27

#test if the virtual interface is up

ifconfig | grep ifb0 &> /dev/null

if [ $? == 0 ]; then
	echo "up" &> /dev/null
else
	modprobe ifb
	ifconfig ifb0 up
fi

#test if prerouting to the virtual interface is in place

tc qdisc show | grep 'wwan0' | grep ffff &> /dev/null

if [ $? != 0 ]; then
	echo "prerouting done"
	tc qdisc add dev wwan0 handle ffff: ingress
	tc filter add dev wwan0 parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb0
fi

#clear all previous rules

tc filter del dev ifb0 &> /dev/null
tc qdisc del dev ifb0 root &> /dev/null
#add rules

tc qdisc add dev ifb0 root handle 1: htb default 15
tc class add dev ifb0 parent 1: classid 1:1 htb rate ${UP4G}kbit ceil ${UP4G}kbit
tc class add dev ifb0 parent 1: classid 1:2 htb rate ${DOWN4G}kbit ceil ${DOWN4G}kbit
tc class add dev ifb0 parent 1: classid 1:3 htb rate ${ETHERNET}kbit ceil ${ETHERNET}kbit
tc class add dev ifb0 parent 1:1 classid 1:10 htb rate ${UP4G}kbit ceil ${UP4G}kbit prio 1
tc class add dev ifb0 parent 1:1 classid 1:11 htb rate ${UP4G}kbit ceil ${UP4G}kbit prio 2

if [ -f /tmp/.slowmedown ] ; then {
tc class add dev ifb0 parent 1:1 classid 1:13 htb rate ${UPSLOW}kbit ceil ${UPSLOW}kbit prio 3
tc class add dev ifb0 parent 1:1 classid 1:15 htb rate ${UPSLOW}kbit ceil ${UPSLOW}kbit prio 4
     }
elif [ -f /tmp/.whoaNelly ] ; then {
echo "ytest"
tc class add dev ifb0 parent 1:1 classid 1:13 htb rate ${UPSNAIL}kbit ceil ${UPSNAIL}kbit prio 3
tc class add dev ifb0 parent 1:1 classid 1:15 htb rate ${UPSNAIL}kbit ceil ${UPSNAIL}kbit prio 4
     }
else {
tc class add dev ifb0 parent 1:1 classid 1:13 htb rate ${UP4G}kbit ceil ${UP4G}kbit prio 3
tc class add dev ifb0 parent 1:1 classid 1:15 htb rate ${UP4G}kbit ceil ${UP4G}kbit prio 4
     }
fi

tc class add dev ifb0 parent 1:2 classid 1:20 htb rate ${DOWN4G}kbit ceil ${DOWN4G}kbit prio 1
tc class add dev ifb0 parent 1:2 classid 1:21 htb rate ${DOWN4G}kbit ceil ${DOWN4G}kbit prio 2

if [ -f /tmp/.slowmedown ] ; then {
tc class add dev ifb0 parent 1:2 classid 1:23 htb rate ${DOWNSLOW}kbit ceil ${DOWNSLOW}kbit prio 3
tc class add dev ifb0 parent 1:2 classid 1:25 htb rate ${DOWNSLOW}kbit ceil ${DOWNSLOW}kbit prio 4
     }
elif [ -f /tmp/.whoaNelly ] ; then {
tc class add dev ifb0 parent 1:2 classid 1:23 htb rate ${DOWNSNAIL}kbit ceil ${DOWNSNAIL}kbit prio 3
tc class add dev ifb0 parent 1:2 classid 1:25 htb rate ${DOWNSNAIL}kbit ceil ${DOWNSNAIL}kbit prio 4
     }
else {
tc class add dev ifb0 parent 1:2 classid 1:23 htb rate ${DOWN4G}kbit ceil ${DOWN4G}kbit prio 3
tc class add dev ifb0 parent 1:2 classid 1:25 htb rate ${DOWN4G}kbit ceil ${DOWN4G}kbit prio 4
     }
fi

tc class add dev ifb0 parent 1:3 classid 1:30 htb rate ${ETHERNET}kbit ceil ${ETHERNET}kbit prio 1
tc class add dev ifb0 parent 1:3 classid 1:31 htb rate ${ETHERNET}kbit ceil ${ETHERNET}kbit prio 2


# Set up u32 classifier to classify the traffic into various flowids
# echo -n "4 "

# To AND From LAN/VPN IPs - local traffic only
tc filter add dev ifb0 parent 1: protocol ip u32 match ip src ${MSILANIP0} match ip dst ${MSILANIP0} flowid 1:31
tc filter add dev ifb0 parent 1: protocol ip u32 match ip src ${MSILANIP1} match ip dst ${MSILANIP1} flowid 1:31

# Not sure if this kind of traffic ever happens but if so it can be fast
tc filter add dev ifb0 parent 1: protocol ip u32  match ip src ${MSILANIP0} match ip dst ${MSILANIP1} flowid 1:31
tc filter add dev ifb0 parent 1: protocol ip u32  match ip src ${MSILANIP1} match ip dst ${MSILANIP0} flowid 1:31

# echo -n "5 "

# DNS need sto be fast regardless of bandwidth cap, so that MSI stuff works as expected
tc filter add dev ifb0 parent 1: protocol ip u32  match ip sport 53 0xffff flowid 1:31
tc filter add dev ifb0 parent 1: protocol ip u32  match ip dport 53 0xffff flowid 1:31

# echo -n "6 "

# MSI IPs are fast regardless of bandwidth cap
tc filter add dev ifb0 parent 1: protocol ip u32  match ip dst ${MSIWANIP1} flowid 1:11
tc filter add dev ifb0 parent 1: protocol ip u32  match ip src ${MSIWANIP1} flowid 1:21
tc filter add dev ifb0 parent 1: protocol ip u32  match ip dst ${MSIWANIP2} flowid 1:11
tc filter add dev ifb0 parent 1: protocol ip u32  match ip src ${MSIWANIP2} flowid 1:21
tc filter add dev ifb0 parent 1: protocol ip u32  match ip dst ${MSIWANIP3} flowid 1:11
tc filter add dev ifb0 parent 1: protocol ip u32  match ip src ${MSIWANIP3} flowid 1:21

# echo -n "7 "

#For some dumb reason this conflicts with the rules above and overrides ip dst $MSIWANIP
# So don\'t do it, even if it seems like a good idea and we need it.
#tc filter add dev ifb0 parent 1: protocol ip u32 \
#    match ip src ${MSILANIP0} flowid 1:13
#Allow fast downloads.
#tc filter add dev ifb0 parent 1: protocol ip u32 \ match ip dst ${MSILANIP0} flowid 1:23

# All unclassified traffic is caught by the default, I think 1:15
# 1:15 is slow or fast depending on bandwidth cap

# echo "DONE."

