1:说明
此处的自动的意思为:只要用户动态获取到IP地址之后,程序就会自动根据此IP地址配置TC规则,对此在线的用户进行上下行带宽速率的限制。下面的脚本是本人测试过的,在速率限制上面没有问题,就是没有优先级的设置。
2:TC配置脚本如下:
#!/bin/sh
i=0
sum=0;
in_dev="br-lan"
out_dev="br-wan"
onlineUserNum=0;
#dhcp.release=/x86_openwrt/qos_workd/dhcp.leases
#touch tmp_ipaddr.log
tmpfile=tmp_ipaddr.log
CONFIGFILEDIR=/etc/qos
MACADDR_FiLE=$CONFIGFILEDIR/tmp_macAddr.log
DHCP_RELEASE=/var/dhcp.leases
MAX_RATE_LOG=$CONFIGFILEDIR/maxrate.log
TMP_WGET_LOG=$CONFIGFILEDIR/wget.log
TMP_TC_LOG=$CONFIGFILEDIR/tc.log
div_part=0;
print_debug()
{
`$1`
echo "$1" >> $CONFIGFILEDIR/tc.log
}
tcinitfunc()
{
total_down=`cat $MAX_RATE_LOG|grep "maxrate"|cut -d ":" -f 2`
if [ "$total_down"x = ""x ] ; then
total_down=4096
fi
total_down=$(( $total_down * 8 ))
total_up=$(( $total_down / 2 ))
print_debug "tc qdisc add dev $out_dev root handle 1:0 htb default 30 r2q 20 "
print_debug "tc class add dev $out_dev parent 1:0 classid 1:1 htb rate $total_up"kbit" ceil $total_up"kbit" "
print_debug "tc qdisc add dev $in_dev root handle 1: htb default 100"
print_debug "tc class add dev $in_dev parent 1: classid 1:1 htb rate $total_down"kbit" ceil $total_down"kbit" "
}
configTcRule()
{
ipaddr=$1;
#产生唯一MARK值
ipseg3=`echo $ipaddr|cut -d "." -f 3`
ipseg4=`echo $ipaddr|cut -d "." -f 4`
markflag=$(( $ipseg3 + $ipseg4 ))
#当前网络的上下行带宽
total_down=`cat $MAX_RATE_LOG|grep "maxrate"|cut -d ":" -f 2`
if [ "$total_down"x = ""x ] ; then
total_down=4096
fi
total_down=$(( $total_down * 8 ))
# echo $total_down
total_up=$(( $total_down / 2 ))
#可预借带宽
max_up=$(( $total_up / 5 ))
max_down=$(( $total_down / 5 ))
#根据实际的用户数平分网络带宽
if [ "$onlineUserNum" -le 5 ] ;then
# single_up=$(( $total_up / $onlineUserNum ))
# single_down=$(( $total_up/ $onlineUserNum ))
div_part=5;
elif [ "$onlineUserNum" -gt 5 -a "$onlineUserNum" -le 10 ] ;then
div_part=10;
elif [ "$onlineUserNum" -gt 10 -a "$onlineUserNum" -le 15 ] ;then
div_part=15;
elif [ "$onlineUserNum" -gt 15 -a "$onlineUserNum" -le 20 ] ;then
div_part=20;
else
div_part=$onlineUserNum ;
fi
single_up=$(( $total_up / $div_part ))
# single_up=$(( $total_up / $div_part ))
single_down=$(( $total_up/ $div_part ))
echo "CONFIG QOS RULE for: $ipaddr onlineUserNum=$onlineUserNum div_part =$div_part total_down=$total_down"kbit" total_up=$total_up"kbit" ipseg3=$ipseg3 ipseg4= $ipseg4 markflag=$markflag" >> $CONFIGFILEDIR/tc.log
# tc qdisc del dev $out_dev root 2>/dev/null
# tc qdisc del dev $in_dev root 2>/dev/null
# tc qdisc add dev $out_dev root handle 1:0 htb default 30 r2q 20
# print_debug "tc qdisc add dev $out_dev root handle 1:0 htb default 30 r2q 20 "
# tc class add dev $out_dev parent 1:0 classid 1:1 htb rate $total_up"kbit" ceil $total_up"kbit"
# print_debug "tc class add dev $out_dev parent 1:0 classid 1:1 htb rate $total_up"kbit" ceil $total_up"kbit" "
# tc -s class show dev br-wan
# tc -s qdisc ls dev br-wan
# tc -s -d filter show dev br-wan
#upload
# tc class add dev $out_dev parent 1:1 classid 1:$markflag htb rate $single_up"kbit" ceil $max_up"kbit" prio 10 burst 15k quantum 20000
# print_debug " tc class add dev $out_dev parent 1:1 classid 1:$markflag htb rate $single_up"kbit" ceil $max_up"kbit" prio 10 burst 15k quantum 20000"
# tc filter add dev $out_dev parent 1:0 protocol ip prio 10 handle $markflag fw flowid 1:$markflag
# print_debug " tc filter add dev $out_dev parent 1:0 protocol ip prio 10 handle $markflag fw flowid 1:$markflag"
# iptables -t mangle -A POSTROUTING -o $out_dev -s $ipaddr -j MARK --set-mark $markflag
# print_debug "iptables -t mangle -A POSTROUTING -o $out_dev -s $ipaddr -j MARK --set-mark $markflag"
# www等
# tc class add dev $out_dev parent 1:$markflag classid 1:1$i htb rate $single_up ceil $max_up prio 1
# 给大包做标记
# 上传
#www等
# iptables -t mangle -A POSTROUTING -o $out_dev -m length --length 1024:1500 -j MARK --set-mark 4$markflag
print_debug "iptables -t mangle -A POSTROUTING -o $out_dev -s $ipaddr -p tcp -m multiport --dport 80,8080 -j MARK --set-mark 4$markflag"
print_debug "tc class add dev $out_dev parent 1:1 classid 1:2$markflag htb rate $single_up"kbit" ceil $total_up"kbit" prio 1"
print_debug "tc filter add dev $out_dev protocol ip parent 1:0 prio 1 handle 4$markflag fw flowid 1:2$markflag"
print_debug "tc qdisc add dev $out_dev parent 1:2$markflag handle 2$markflag: fq_codel"
#download
print_debug "tc class add dev $in_dev parent 1:1 classid 1:$markflag htb rate $single_down"kbit" ceil $max_down"kbit" prio 1"
print_debug "tc filter add dev $in_dev parent 1: protocol ip prio 100 u32 match ip dst $ipaddr flowid $classid 1:$markflag"
}
deliptable_psotrouting()
{
while read -r line ;do
macaddr=`echo $line |cut -d " " -f 2`
if [ "$macaddr" != "" ] ; then
ipaddr=`echo $line |cut -d " " -f 3`
ipseg3=`echo $ipaddr|cut -d "." -f 3`
ipseg4=`echo $ipaddr|cut -d "." -f 4`
markflag=$(( $ipseg3 + $ipseg4 ))
iptables -t mangle -D POSTROUTING -o $out_dev -s $ipaddr -p tcp -m multiport --dport 80,8080 -j MARK --set-mark 4$markflag
echo "iptables -t mangle -D POSTROUTING -o $out_dev -s $ipaddr -p tcp -m multiport --dport 80,8080 -j MARK --set-mark 4$markflag"
fi
done < $DHCP_RELEASE
}
autoConfigQos()
{
flag_iptables=0;
if ! test -e $MACADDR_FiLE;then
touch $MACADDR_FiLE;
cat /dev/null > $MACADDR_FiLE
fi
if ! test -e $CONFIGFILEDIR/tc.log;then
touch $CONFIGFILEDIR/tc.log;
cat /dev/null > $CONFIGFILEDIR/tc.log
fi
while read -r line ;do
onlineUserNum=$(( $onlineUserNum + 1 ))
done < $DHCP_RELEASE
if [ "$onlineUserNum" -le 5 ] ;then
div_part=5;
if [ "$onlineUserNum" -eq 5 ] ; then
echo "onlineUserNum=$onlineUserNum" > $MACADDR_FiLE
fi
elif [ "$onlineUserNum" -gt 5 -a "$onlineUserNum" -le 10 ] ;then
num=`cat $MACADDR_FiLE|grep "onlineUserNum"|cut -d "=" -f 2`
if [ "$num" = "6" ] ; then
echo "onlineUserNum=$onlineUserNum find num=$num in $MACADDR_FiLE "
else
cat /dev/null > $MACADDR_FiLE
echo "onlineUserNum=6" > $MACADDR_FiLE
echo "=========== === cat /dev/null > $MACADDR_FiLE onlineUserNum=$onlineUserNum =================="
tc qdisc del dev $out_dev root >/dev/null
tc qdisc del dev $in_dev root >/dev/null
flag_iptables=1;
fi
elif [ "$onlineUserNum" -gt 10 -a "$onlineUserNum" -le 15 ] ;then
num=`cat $MACADDR_FiLE|grep "onlineUserNum"|cut -d "=" -f 2`
if [ "$num" = "11" ] ; then
echo "onlineUserNum=$onlineUserNum find num=$num in $MACADDR_FiLE "
else
cat /dev/null > $MACADDR_FiLE
echo "onlineUserNum=11" > $MACADDR_FiLE
echo "=========== === cat /dev/null > $MACADDR_FiLE onlineUserNum=$onlineUserNum =================="
tc qdisc del dev $out_dev root >/dev/null
tc qdisc del dev $in_dev root >/dev/null
flag_iptables=1;
fi
elif [ "$onlineUserNum" -gt 15 -a "$onlineUserNum" -le 20 ] ;then
num=`cat $MACADDR_FiLE|grep "onlineUserNum"|cut -d "=" -f 2`
if [ "$num" = "16" ] ; then
echo "onlineUserNum=$onlineUserNum find num=$num in $MACADDR_FiLE "
else
cat /dev/null > $MACADDR_FiLE
echo "onlineUserNum=16" > $MACADDR_FiLE
echo "=========== === cat /dev/null > $MACADDR_FiLE onlineUserNum=$onlineUserNum =================="
tc qdisc del dev $out_dev root >/dev/null
tc qdisc del dev $in_dev root >/dev/null
flag_iptables=1;
fi
else
div_part=$onlineUserNum ;
fi
if [ "$flag_iptables" -eq 1 ];then
deliptable_psotrouting
fi
while read -r line ;do
macaddr=`echo $line |cut -d " " -f 2`
if [ "$macaddr" != "" ] ; then
macaddrfind=`cat $MACADDR_FiLE|grep $macaddr`
if [ "$macaddrfind" == "" ] ; then
ipaddr=`echo $line |cut -d " " -f 3`
echo $macaddr >> $MACADDR_FiLE
configTcRule $ipaddr
fi
fi
done < $DHCP_RELEASE
}
getNetworkDownLoadRate()
{
i=0
sum=0;
cat /dev/null > $MAX_RATE_LOG
cat /dev/null > $TMP_WGET_LOG
while(($i<5))
do
wget http://cn.wordpress.org/wordpress-3.1-zh_CN.zip >& $TMP_WGET_LOG
maxrate=`cat $TMP_WGET_LOG |grep "save"|cut -d " " -f 3-4 >> $MAX_RATE_LOG`
i=$(($i+1))
done
maxrate=0
while read -r line ;do
findMB=`echo $line|grep "MB/s"`
rate=`echo $line |cut -d " " -f 1|cut -d "(" -f 2|cut -d "." -f 1`
if [ "$findMB" != "" ] ; then
rate=$(( $rate * 1024 ))
fi
echo $rate
if [ $rate -gt $maxrate ] ;then
maxrate=$rate
fi
done < $MAX_RATE_LOG
echo "maxrate:$maxrate" >> $MAX_RATE_LOG
}
tmp=$1
if [ "$tmp" = "netrate" ];then
getNetworkDownLoadRate
elif [ "$tmp" = "qosconfig" ];then
autoConfigQos
elif [ "$tmp" = "deliptables" ];then
deliptable_psotrouting
elif [ "$tmp" = "tcinit" ];then
tcinitfunc
fi