日期:2014-05-16  浏览次数:20977 次

linux:通过tc对ppp连接自动进行流量控制

tc是基于linux内核的,英文原形应该是Traffic Control,linux都是自带的,无需安装

?

一般服务器在接到客户端ppp连接的请求时,就需要去调用ppp进程来建立ppp连接,而ppp每次连接的时候,都会运行/etc/ppp/目录下的ip-up脚本(Centos、Ubuntu都是一样的),当连接断开的时候,也会调用该目录下的ip-down脚本。所以你就可以在这两个脚本中加入tc流控规则。

?

当然,tc规则都是基于ppp连接的,而不是基于服务器网卡的,所以就需要知道每个ppp连接的网卡名称(device name)。那ppp在调用ip-up和ip-down的时候,肯定都知道这些参数的

?

Centos的ip-up脚本里引用了$1、$6这两个参数

写道
LOGDEVICE=$6
REALDEVICE=$1

?

Ubuntu的ip-up脚本里引用了$1、$2、$3、$4、$5、$6

写道
PPP_IFACE="$1"
PPP_TTY="$2"
PPP_SPEED="$3"
PPP_LOCAL="$4"
PPP_REMOTE="$5"
PPP_IPPARAM="$6"

?

通过变量名称也大概可以知道这些位置参数基本上对应是什么了

最简单的方法,就是在ip-up脚本里加入一行代码

写道
echo "The arg of script ip-up is $*" >> /var/log/ip-up.log

?

然后进行vpn拨号一下,就会发现/var/log/ip-up.log有如下内容:

写道
echo ppp0 /dev/pts/3 115200 172.16.0.1 172.16.0.100 192.168.2.6

??????????????? $1???????? $2??????????? $3???????????? $4????????????? $5??????????????? $6

?

所以这些参数代表什么意思一目了然

$1:ppp连接的接口名称

$2:ppp连接的设备名称

$3:ppp连接的速率 (具体什么速率偶也不太清楚,有点像终端比特率的感觉)

$4:ppp连接的远程虚拟ip

$5:ppp连接的本地虚拟ip

$6:ppp连接客户端的真实IP

?

?

ok,了解这些之后,接下来就是服务器上直接修改了

?

一、修改ip-up文件

?

因为我的流控命令都放在另外一个脚本,所以在ip-up里是调用脚本的,而不是直接运行命令。在ip-up直接放置tc命令也可以。

在ip-up脚本里添加如下内容

写道
file_path=/etc/ppp/tcppp (tc流控脚本)
log_path=/var/log/tcppp (运行日志,所有输出都打印到这个文件里)
current_time=$(date +%F\ %T) (日志中加入时间)
{
if [ -x "$file_path" ];then
echo "$current_time The ppp connect $1 UP!"
echo "--------------> Gateway of $1 : $4"
echo "--------------> IP address of $1 : $5"
echo "--------------> Source ip of $1 : $6"
/bin/sh /etc/ppp/tcppp $1 (调用tc流控脚本,有$1作为参数)
else
echo "$current_time ERROR:The traffic control script $file_path was NOT FOUND!"
fi
} >> $log_path? (所有的echo输出都会重定向到这)
?

?

二、添加tc流控脚本

?

为了方便,就把流控脚本也放到了/etc/ppp目录下,脚本内容如下

写道
#!/bin/sh
#
# This shell script was used for traffic control of ppp connect
# For default the band width is 15 Mbit/s
#

eth=$1
band=2
current_time=$(date +%F\ %T)
NO_ARG=65

usage()
{
echo "USAGE:`basename $0` \$ppp"
echo "ERROR:You should input the name of ppp connect"
exit "$NO_ARG"
}

tc_rule()
{
echo "$current_time Begin traffic control rule."
echo "--------------> PPP Connect: $eth"
echo "--------------> Traffic band: $band Mbit"
tc qdisc del dev "$eth" root > /dev/null 2>&1??? (保险起见,再次删除之前的tc规则)
tc qdisc add dev "$eth" root handle 2: htb default 10??
(以ppp0为根,新建tc规则)
tc class add dev "$eth" parent 2: classid 2:1 htb rate 100mbit ceil 100mbit??
(意思一下总带宽,没太大作用)
tc class add dev "$eth" parent 2:1 classid 2:10 htb rate "$band"mbit burst "$band"mbit ceil "$band"mbit cburst "$band"mbit prio 1
?? (限制速度,rate:总链路忙碌时占用带宽? ceil:总链路空闲时占用带宽,限制带宽大小为变量band的值,这个脚本即2mbit)
echo "--------------> OK!"
exit 0
}


if [ -z "$eth" ];then
usage;
else
tc_rule;
fi

?

其实,关键tc命令就那么几条,起流控作用的就那三条,当然,也可以浓缩为两条

写道
tc qdisc add dev "$eth" root handle 1: htb default 1
tc class add dev "$eth" parent 1: classid 1:1 htb rate "$band"mbit burst "$band"mbit ceil "$band"mbit cburst "$band"mbit prio 1

?

没有tc filter过滤规则,通过default x来设置默认作用的规则。当