immortalwrt/package/jsda/luci-app-qosv4/files/usr/bin/qosv4
2019-07-29 03:03:28 +08:00

433 lines
16 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/sh
#copyright by zhoutao0712 V4 moded zjhzzyf
#变量初始化(速率单位是KB/S)
#UIP="192.168.1."
#NET="192.168.100.0/24"
#IPS="2"
#IPE="20"
#UP=1135
#DOWN=1175
#UPLOADR=1
#UPLOADC=15
#DOWNLOADR=10
#DOWNLOADC=$((DOWN*9/10))
#UPLOADR2=1
#UPLOADC2=5
#DOWNLOADR2=2
#DOWNLOADC2=$((DOWN*6/10))
#DOWNLOADR 单IP下载保证带宽DOWNLOADR=10
#DOWNLOADc 单IP下载最大带宽DOWNLOADC=$((DOWN*9/10))
#IPS限速开始IP地址
#IPE限速结束IP地址
#IPS和IPE最好不要填写2---254不然脚本运行时间会比较长会多占用一些内存。
#效率上如果采用了u32 hashv4.0和智能QOS修改版本就没影响。
#UP=35总上传带宽。我的ADSL虽然是50KB/S但为了低延迟还是填35吧
#DOWN=175:总下载带宽。我的ADSL虽然是205KB/S但为了低延迟还是填175吧
#UPLOADR=2:单IP上传保证带宽2KB/S就很OK了。
#UPLOADC=15:单IP上传最大带宽ADSL也就填这么多了搞QQ视频应该没问题。
#UPLOADR2=1:被“惩罚”后的单IP上传保证带宽。
#UPLOADC2=5被“惩罚”后的单IP上传UDP最大带宽一般不要超过6KB/S
#DOWNLOADR2:被“惩罚”后的单IP下载保证带宽
#DOWNLOADC2:被“惩罚”后的单IP下载最大带宽
. /lib/functions.sh
load_modules(){
rmmod imq
insmod imq numdevs=1
insmod cls_fw
insmod sch_hfsc
insmod sch_sfq
insmod sch_red
insmod sch_htb
insmod sch_prio
insmod ipt_multiport
insmod ipt_CONNMARK
insmod ipt_length
insmod ipt_IMQ
insmod ipt_hashlimit
insmod cls_u32
insmod xt_connlimit
insmod xt_connbytes
}
lan_net(){
lan_ipaddr=$(uci get network.lan.ipaddr)
lan_netmask=$(uci get network.lan.netmask)
calc=$(ipcalc.sh $lan_ipaddr $lan_netmask)
prefix=${calc##*=}
lan_network=${calc##*NETWORK=}
lan_network=$(echo $lan_network | sed 's/.PRE.*//')
NET="$lan_network/$prefix"
UIP=$(uci get network.lan.ipaddr|awk -F "." '{print $1"."$2"."$3 }')
qos_interface=$(uci -P /var/state get network.wan.ifname 2>/dev/null)
if [ -z $qos_interface ] ; then
qos_interface=$(uci -P /var/state get network.wan.device 2>/dev/null)
fi
}
#装载核心模块,创建QOS专用链
qos_start(){
#ifconfig $qos_interface up
ifconfig imq0 up
iptables -t mangle -N QOSDOWN
iptables -t mangle -N QOSUP
iptables -t mangle -A PREROUTING ! -p icmp -s $NET ! -d $NET -j QOSUP
#iptables -t mangle -I PREROUTING -p udp --dport 53 -j ACCEPT
iptables -t mangle -I POSTROUTING ! -p icmp -d $NET ! -s $NET -j QOSDOWN
#iptables -t mangle -I POSTROUTING -p udp --dport 53 -j ACCEPT
iptables -t mangle -A OUTPUT -o br-lan -j ACCEPT
iptables -t mangle -A INPUT -i br-lan -j ACCEPT
#iptables -t mangle -I OUTPUT -p udp --dport 53 -j ACCEPT
#iptables -t mangle -I INPUT -p udp --dport 53 -j ACCEPT
#iptables -t mangle -A OUTPUT -d ! $NET -j QOSUP
iptables -t mangle -A INPUT ! -s $NET -j QOSDOWN
#iptables -t mangle -A OUTPUT -j QOSUP
#iptables -t mangle -A INPUT -j QOSDOWN
iptables -t mangle -A QOSDOWN -p udp -m multiport --ports 53,67,68 -j RETURN
iptables -t mangle -A QOSUP -p udp -m multiport --destination-port 53,67,68 -j RETURN
iptables -t mangle -N PUNISH0
iptables -t mangle -A QOSUP -p udp -j PUNISH0
iptables -t mangle -A PUNISH0 -m hashlimit --hashlimit 100/sec --hashlimit-mode srcip --hashlimit-name udplmt -j RETURN
iptables -t mangle -A PUNISH0 -m recent --rcheck --seconds 20 -j DROP
iptables -t mangle -A PUNISH0 -m recent --set
iptables -t mangle -N NEWCONN
iptables -t mangle -A QOSUP -m state --state NEW -j NEWCONN
echo "line 99"
iptables -t mangle -A NEWCONN ! -p tcp -m connlimit --connlimit-above 100 -j DROP
iptables -t mangle -A NEWCONN -p tcp -m connlimit --connlimit-above 200 -j DROP
echo "line 102"
iptables -t mangle -A QOSDOWN -p tcp ! --syn -m length --length :128 -j RETURN
iptables -t mangle -A QOSUP -p tcp ! --syn -m length --length :80 -j RETURN
iptables -t mangle -A QOSDOWN -d $NET -j IMQ --todev 0
#iptables -t mangle -A QOSUP -s $NET -j IMQ --todev 1
#小包web浏览和游戏爆发队列限速 #在5秒内平均下载速率小于10KB/S的IP进入高优先级队列253
iptables -t mangle -N BCOUNT
iptables -t mangle -A QOSDOWN -p tcp -m length --length :768 -j MARK --set-mark 255
iptables -t mangle -A QOSUP -p tcp -m length --length :512 -j MARK --set-mark 255
iptables -t mangle -A QOSDOWN -p tcp -m multiport --sports 80,443,25,110 -j BCOUNT
echo "line 117"
iptables -t mangle -A QOSUP -p tcp -m multiport --sports 80,443,25,110 -m connbytes --connbytes :51200 --connbytes-dir both --connbytes-mode bytes -j MARK --set-mark 254
iptables -t mangle -A QOSUP -p tcp -m multiport --dports 80,443,25,110 -j BCOUNT
iptables -t mangle -A QOSDOWN -p tcp -m multiport --sports 80,443,25,110 -m connbytes --connbytes :102400 --connbytes-dir both --connbytes-mode bytes -j MARK --set-mark 254
echo "line 121"
#iptables -t mangle -A QOSDOWN -p tcp -m multiport --sports 80,443,25,110 -m bcount --range :153600 -j MARK --set-mark 254
#iptables -t mangle -A QOSUP -p tcp -m multiport --dports 80,443,25,110 -m bcount --range :51200 -j MARK --set-mark 254
iptables -t mangle -A QOSDOWN -m recent --rdest --rcheck --seconds 120 -j MARK --set-mark 253
iptables -t mangle -A QOSUP -p udp -m recent --rcheck --seconds 120 -j MARK --set-mark 253
iptables -t mangle -A QOSDOWN -j MARK --set-mark 252
iptables -t mangle -A QOSUP -j MARK --set-mark 252
echo "line 129"
#根队列初始化
#tc qdisc del dev imq0 root
#tc qdisc del dev $qos_interface root
echo "line 133"
tc qdisc add dev imq0 root handle 1: htb default 999
tc qdisc add dev $qos_interface root handle 1: htb default 999
tc class add dev $qos_interface parent 1: classid 1:1 htb rate $((UP))kbps
tc class add dev imq0 parent 1: classid 1:1 htb rate $((DOWN))kbps
#小包web浏览和游戏爆发队列限速
tc class add dev imq0 parent 1:1 classid 1:5000 htb rate $((DOWN/5))kbps quantum 15000 prio 1
tc filter add dev imq0 parent 1:0 protocol ip prio 5 handle 255 fw flowid 1:5000
tc class add dev $qos_interface parent 1:1 classid 1:5000 htb rate $((UP))kbps quantum 15000 prio 1
tc filter add dev $qos_interface parent 1:0 protocol ip prio 5 handle 255 fw flowid 1:5000
tc class add dev imq0 parent 1:1 classid 1:4000 htb rate $((DOWN/10))kbps ceil $((DOWN*6/10))kbps quantum 8000 prio 3
tc filter add dev imq0 parent 1:0 protocol ip prio 10 handle 254 fw flowid 1:4000
tc class add dev $qos_interface parent 1:1 classid 1:4000 htb rate $((UP/10))kbps ceil $((UP/2))kbps quantum 1500 prio 3
tc filter add dev $qos_interface parent 1:0 protocol ip prio 10 handle 254 fw flowid 1:4000
tc class add dev $qos_interface parent 1:1 classid 1:3000 htb rate $((UP/3))kbps ceil $((UP))kbps
tc class add dev imq0 parent 1:1 classid 1:3000 htb rate $((DOWN/3))kbps ceil $((DOWN))kbps
tc filter add dev $qos_interface parent 1:0 protocol ip prio 20 handle 253 fw flowid 1:3000
tc filter add dev imq0 parent 1:0 protocol ip prio 20 handle 253 fw flowid 1:3000
tc class add dev $qos_interface parent 1:1 classid 1:2000 htb rate $((UP*2/3))kbps ceil $((UP))kbps
tc class add dev imq0 parent 1:1 classid 1:2000 htb rate $((DOWN*2/3))kbps ceil $((DOWN))kbps
tc filter add dev $qos_interface parent 1:0 protocol ip prio 15 handle 252 fw flowid 1:2000
tc filter add dev imq0 parent 1:0 protocol ip prio 15 handle 252 fw flowid 1:2000
tc filter add dev imq0 parent 1:3000 prio 200 handle f0: protocol ip u32 divisor 256
tc filter add dev imq0 protocol ip parent 1:3000 prio 200 u32 ht 800:: match ip dst $NET hashkey mask 0x000000ff at 16 link f0:
tc filter add dev $qos_interface parent 1:3000 prio 200 handle f0: protocol ip u32 divisor 256
tc filter add dev $qos_interface protocol ip parent 1:3000 prio 200 u32 ht 800:: match ip src $NET hashkey mask 0x000000ff at 12 link f0:
tc filter add dev imq0 parent 1:2000 prio 100 handle f1: protocol ip u32 divisor 256
tc filter add dev imq0 protocol ip parent 1:2000 prio 100 u32 ht 801:: match ip dst $NET hashkey mask 0x000000ff at 16 link f1:
tc filter add dev $qos_interface parent 1:2000 prio 100 handle f1: protocol ip u32 divisor 256
tc filter add dev $qos_interface protocol ip parent 1:2000 prio 100 u32 ht 801:: match ip src $NET hashkey mask 0x000000ff at 12 link f1:
}
#所有普通IP单独限速
qos_ip_limit()
{
n=$(echo $limit_ip |cut -d "." -f4)
m=$(printf "%x\n" $n)
echo "$limit_ip start limit"
tc class add dev $qos_interface parent 1:3000 classid 1:${n}f htb rate $((UPLOADR2))kbps ceil $((UPLOADC2))kbps quantum 1500 prio 7
tc class add dev imq0 parent 1:3000 classid 1:${n}f htb rate $((DOWNLOADR2))kbps ceil $((DOWNLOADC2))kbps quantum 1500 prio 7
tc qdisc add dev $qos_interface parent 1:${n}f handle ${n}f bfifo limit 8kb
tc qdisc add dev imq0 parent 1:${n}f handle ${n}f sfq perturb 15
tc filter add dev $qos_interface parent 1:3000 protocol ip prio 200 u32 ht f0:${m}: match ip src 0/0 flowid 1:${n}f
tc filter add dev imq0 parent 1:3000 protocol ip prio 200 u32 ht f0:${m}: match ip dst 0/0 flowid 1:${n}f
tc class add dev $qos_interface parent 1:2000 classid 1:${n}a htb rate $((UPLOADR))kbps ceil $((UPLOADC))kbps quantum 1500 prio $ip_prio
tc class add dev imq0 parent 1:2000 classid 1:${n}a htb rate $((DOWNLOADR))kbps ceil $((DOWNLOADC))kbps quantum 2000 prio $ip_prio
tc qdisc add dev $qos_interface parent 1:${n}a handle ${n}a bfifo limit 8kb
tc qdisc add dev imq0 parent 1:${n}a handle ${n}a sfq perturb 15
tc filter add dev $qos_interface parent 1:2000 protocol ip prio 100 u32 ht f1:${m}: match ip src 0/0 flowid 1:${n}a
tc filter add dev imq0 parent 1:2000 protocol ip prio 100 u32 ht f1:${m}: match ip dst 0/0 flowid 1:${n}a
echo "$limit_ip end limit"
}
qos_ip_limit_2(){
tc class add dev $qos_interface parent 1:1 classid 1:999 htb rate 1kbps ceil $((UP/5))kbps quantum 1500 prio 7
tc class add dev imq0 parent 1:1 classid 1:999 htb rate 2kbps ceil $((DOWN))kbps quantum 1500 prio 7
}
#192.168.1.8,192.168.1.80-192.168.1.90有zhoutao0712发放的免死金牌
qos_else(){
#iptables -t mangle -I PUNISH0 -m iprange --src-range 192.168.1.80-192.168.1.90 -j RETURN
iptables -t mangle -I PUNISH0 -s $nolimit_ip -j RETURN
}
qos_transmission_limit(){
config_get enable $1 enable
config_get downlimit $1 downlimit
config_get uplimit $1 uplimit
echo "transmission limit enable=$enable "
transmission_enable=$(uci get transmission.@transmission[0].enable)
transmission_enabled=$(uci get transmission.@transmission[0].enabled)
echo "transmission-daemon enable=$transmission_enable"
echo "transmission-daemon enabled=$transmission_enabled"
if [ "$transmission_enable" == "1" -o "$transmission_enabled" == "1" ];then
if [ "$enable" == "1" ];then
echo " transmission limit ........downlimit=$downlimit uplimit=$uplimit"
transmission-remote --downlimit $downlimit
transmission-remote --uplimit $uplimit
echo "1" > /tmp/transmission-flag
else
echo " transmission no limit oooooooooo"
transmission-remote --no-downlimit
transmission-remote --no-uplimit
echo "0" > /tmp/transmission-flag
fi
fi
}
#加入例行任务5分钟执行一次当有ip在线的时候按需开启transmission限速和qos限速。
#当只有1个IP在线时候关闭内网QOS限速 。
#当没有IP在线时候关闭QOS限速 关闭transmission限速。
qos_scheduler(){
echo "qos_scheduler start....."
wait_time="5"
[ -z "$(cat /etc/crontabs/root| grep qos_scheduler)" ]&&echo -e "*/${wait_time} * * * * sh /tmp/qos_scheduler #qos_scheduler#" >> /etc/crontabs/root
cat >/tmp/qos_scheduler <<"EOF"
[ -e /tmp/qosv4_nolimit_mac ]&&mac_list=$(cat /tmp/qosv4_nolimit_mac)
local RUN="ip neigh| grep : ${mac_list} |grep -c $UIP"
ip_num=`eval $RUN`
old_ip_num=$(cat /tmp/qosv4_old_ip_num)
echo "new_ip_num=$ip_num"
echo "old_ip_num=$old_ip_num"
#如果在线ip和上次相同 退出
if [ "$ip_num" -eq "$old_ip_num" ]
then
ip neigh flush dev br-lan
echo "在线ip和上次相同"
exit
fi
qosv4_transmission_enabl=$(uci get qosv4.@transmission_limit[0].enable)
qosv4_transmission_uplimit=$(uci get qosv4.@transmission_limit[0].uplimit)
qosv4_transmission_downlimit=$(uci get qosv4.@transmission_limit[0].downlimit)
transmission_enable=$(uci get transmission.@transmission[0].enable)
transmission_enabled=$(uci get transmission.@transmission[0].enabled)
#如果在线ip为1 关闭内网QOS限速 根据设置开启 transmission限速然后退出
if [ "$ip_num" -eq "1" ]
then
ifconfig imq0 down
ifconfig $qos_interface down
if [ "$transmission_enable" == "1" -o "$transmission_enabled" == "1" ];then
if [ "$qosv4_transmission_enabl" == "1" ];then
echo " transmission limit ........downlimit=$qosv4_transmission_downlimit uplimit=$qosv4_transmission_uplimit"
transmission-remote --downlimit $qosv4_transmission_downlimit
transmission-remote --uplimit $qosv4_transmission_uplimit
else
transmission-remote --no-downlimit
transmission-remote --no-uplimit
echo "0" > /tmp/transmission-flag
fi
fi
ip neigh flush dev br-lan
echo "$ip_num" >/tmp/qosv4_old_ip_num
exit
fi
# 当没有IP在线时候关闭QOS限速 关闭transmission限速。
if [ "$ip_num" -eq "0" ]
then
ifconfig imq0 down
ifconfig $qos_interface down
if [ "$transmission_enable" == "1" -o "$transmission_enabled" == "1" ];then
transmission-remote --no-downlimit
transmission-remote --no-uplimit
fi
fi
ip neigh flush dev br-lan
echo "$ip_num" >/tmp/qosv4_old_ip_num
exit
fi
#如果在线ip 大于1 开启内网QOS限速 开启transmission限速
if [ $(ifconfig |grep -c imq0) -eq 0 ]
then
ifconfig imq0 up
ifconfig $qos_interface up
echo "cass 3"
fi
if [ "$transmission_enable" == "1" -o "$transmission_enabled" == "1" ];then
if [ "$qosv4_transmission_enabl" == "1" ];then
echo " transmission limit ........downlimit=$qosv4_transmission_downlimit uplimit=$qosv4_transmission_uplimit"
transmission-remote --downlimit $qosv4_transmission_downlimit
transmission-remote --uplimit $qosv4_transmission_uplimit
else
transmission-remote --no-downlimit
transmission-remote --no-uplimit
echo "0" > /tmp/transmission-flag
fi
fi
ip neigh flush dev br-lan
echo "$ip_num" >/tmp/qosv4_old_ip_num
EOF
}
qos_stop(){
for iface in $(tc qdisc show | grep htb | awk '{print $5}'); do
tc qdisc del dev "$iface" root
done
iptables -t mangle -D PREROUTING ! -p icmp -s $NET ! -d $NET -j QOSUP
iptables -t mangle -D POSTROUTING ! -p icmp -d $NET ! -s $NET -j QOSDOWN
iptables -t mangle -D OUTPUT -o br-lan -j ACCEPT
iptables -t mangle -D INPUT -i br-lan -j ACCEPT
iptables -t mangle -D OUTPUT ! -d $NET -j QOSUP
iptables -t mangle -D INPUT ! -s $NET -j QOSDOWN
iptables -t mangle -D OUTPUT -j QOSUP
iptables -t mangle -D INPUT -j QOSDOWN
iptables -t mangle -D PREROUTING -p udp --dport 53 -j ACCEPT
iptables -t mangle -D POSTROUTING -p udp --dport 53 -j ACCEPT
iptables -t mangle -D OUTPUT -p udp --dport 53 -j ACCEPT
iptables -t mangle -D INPUT --dport 53 -j ACCEPT
iptables -t mangle -F QOSDOWN
iptables -t mangle -F QOSUP
iptables -t mangle -F PUNISH0
iptables -t mangle -F NEWCONN
iptables -t mangle -F BCOUNT
iptables -t mangle -X QOSDOWN
iptables -t mangle -X QOSUP
iptables -t mangle -X PUNISH0
iptables -t mangle -X NEWCONN
iptables -t mangle -X BCOUNT
}
qos_config_get(){
config_get enable $1 enable
config_get UP $1 UP
config_get DOWN $1 DOWN
config_get UPLOADR2 $1 UPLOADR2
config_get UPLOADC2 $1 UPLOADC2
config_get DOWNLOADR2 $1 DOWNLOADR2
config_get DOWNLOADC2 $1 DOWNLOADC2
config_get UPLOADR $1 UPLOADR
config_get DOWNLOADR $1 DOWNLOADR
config_get qos_scheduler $1 qos_scheduler
}
qos_limit_ip_get(){
config_get enable $1 enable
config_get limit_ip $1 limit_ip
config_get ip_prio $1 ip_prio
config_get UPLOADC $1 UPLOADC
config_get DOWNLOADC $1 DOWNLOADC
echo "enable=$enable limit_ip=$limit_ip ip_prio=$ip_prio UPLOADC=$UPLOADC DOWNLOADC=$DOWNLOADC"
[ "$enable" == "1" ]&&qos_ip_limit
}
qos_nolimit_ip_get(){
config_get enable $1 enable
config_get nolimit_ip $1 nolimit_ip
config_get nolimit_mac $1 nolimit_mac
[ "$enable" == "1" ]&&printf "|grep -v $nolimit_mac " >>/tmp/qosv4_nolimit_mac
}
lan_net
config_load qosv4
case $1 in
start)
qos_stop >/dev/null 2>&1
qos_stop >/dev/null 2>&1
echo "start qos v4........"
rm -rf /tmp/qosv4_nolimit_mac
config_foreach qos_config_get qos_settings
echo "qosv4 enable=$enable "
if [ "$enable" == "1" ];then
load_modules >/dev/null 2>&1
qos_start
config_foreach qos_limit_ip_get qos_ip
qos_ip_limit_2
config_foreach qos_nolimit_ip_get qos_nolimit_ip
config_foreach qos_transmission_limit transmission_limit
else
qos_stop >/dev/null 2>&1
qos_stop >/dev/null 2>&1
fi
echo "qos_scheduler = $qos_scheduler"
if [ "$qos_scheduler" == "1" ];then
qos_scheduler
else
[ -n "$(cat /etc/crontabs/root| grep qos_scheduler)" ]&& sed -i -e '/qos_scheduler/d' /etc/crontabs/root
fi
;;
stop)
qos_stop >/dev/null 2>&1
qos_stop >/dev/null 2>&1
;;
esac