tc限速:
ipp2p只能识别p2p连接请求,而不能识别所有p2p包,必须和CONNMARK目标结合在一起使用(目前只支持TCP协议标识)
#通过iptables给数据包打标记
#结果:每一个标记为P2P连接的包被标记为“1”
#从MARK目标中恢复标记
iptables -A PREROUTING -t mangle -p tcp -j CONNMARK --restore-mark
#接收所有非0标记的包
iptables -A PREROUTING -t mangle -p tcp -m mark ! --mark 0 -j ACCEPT
#将ipp2p连接标记为“1”
iptables -A PREROUTING -t mangle -p tcp -m ipp2p --xltest -j MARK --set-mark 1
#保存所有标记为“1”的包到CONNMARK中
iptables -A PREROUTING -t mangle -p tcp -m mark --mark 1 -j CONNMARK --save-mark
#清空已有的队列(清空tc规则)
tc qdisc del dev eth0 root
#定义一个根,默认匹配信道 1(这条命令分配了HTB队列规定给eth0并且指定了一个名称为(handle 句柄1:),这个名称用于标识它下面的子类,default 1的意思是没有被分类的流量被分配到类1:1)
注:一般(不仅仅是HTB其他所有TC的队列和类),句柄都被写成X:Y,这里X、Y都是队列规定的整数型的标识符,而队列规定的句柄标识符的Y必须是0,句柄的类的标识符的数值必须是一个非零的整数,“1:”等同于“1:0”
tc qdisc add dev eth0 root handle 1: htb default 1
#下载信道限速在20kbps,对符合标记1的用户使用定义的类1:2信道(特定的FWMARK标记值(hanlde x fw))
第一行:在队列1:下创建了一个根类1:1,并且定义了HTB队列规定作为这个根类的父类。一个根类的子类可以相互借用带宽,但是根类之间不能相互借用带宽。
第二行:创建子类1:2 ,并分配20kbps的带宽。。
第三行:通过filter(过滤器)为数据包分类。
注:重复dev eth0描述,是因为本地接口比如eth0 和 eth1 他们各自都可能会有类的句柄表示为1:1。参数ceil指定了一个类可以用的最大带宽,用来限制类可以借用多少带宽,其数值应该至少和它所在的类的速率一样高。
tc class add dev eth0 parent 1: classid 1:1 htb rate 1000Kbps ceil 1000Kbps
tc class add dev eth0 parent 1:1 classid 1:2 htb rate 20Kbps ceil 20Kbps
tc filter add dev eth0 parent 1:0 protocol ip handle 1 fw classid 1:2
查看用tc命令设置网卡流量的情况:
tc –s qdisc ls dev eth1
tc –s class ls dev eth1
(dos下查看网络状态命令netstat –n)
查看包是否被打上标记:
cat /proc/net/ip_conntrack [|grep “192.168.9.6”]
or
cat /proc/net/ip_conntrack [|grep “mark=2”]
完整脚本:
#!/bin/bash
echo "recompile ipp2p"
make uninstall && make && make install -C /home/liuxl/sources/ipp2p-0.99.15
echo "reset iptables'rules and insmod ipt_ipp2p"
iptables -t mangle -F
iptables -F
rmmod ipt_ipp2p
insmod /home/liuxl/sources/ipp2p-0.99.15/ipt_ipp2p.o
#iptables -A FORWARD -m ipp2p --xltest -j DROP
iptables -A PREROUTING -t mangle -p tcp -j CONNMARK --restore-mark
iptables -A PREROUTING -t mangle -p tcp -m mark ! --mark 0 -j ACCEPT
iptables -A PREROUTING -t mangle -p tcp -m ipp2p --xltest -j MARK --set-mark 1
iptables -A PREROUTING -t mangle -p tcp -m mark --mark 1 -j CONNMARK --save-mark
tc qdisc del dev eth0 root
tc qdisc add dev eth0 root handle 1: htb default 1
tc class add dev eth0 parent 1: classid 1:1 htb rate 1000Kbps ceil 1000Kbps
tc class add dev eth0 parent 1:1 classid 1:2 htb rate 20Kbps ceil 20Kbps
tc filter add dev eth0 parent 1:0 protocol ip handle 1 fw classid 1:2
PS:tc中的流量处理由三种对象控制:
Qdisc(排队规则):
它是queueing discipline的简写。无论何时,内核如果需要通过某个网络接口发送数据包,它都需要按照为这个接口配置的qdisc把数据包加入队列。然后,内核会尽可能多地从qdisc里面取出数据包,把它们交给网络适配器驱动模块。最简单的qdisc是pfifo它不对进入的数据包做任何的处理,数据包采用先入先出的方式通过队列。不过它会保持网络接口一时无法处理的数据包。
Class(类)
某些qdisc可以包含一些类别,不同的类别中可以包含更深入的qdisc,通过这些细分的qdisc还可以为进入的队列的数据包排队。通过设置各种类别数据包的离队次序,qdisc可以为设置网络数据流量的优先级。
Filter(过滤器)
用于为数据包分类,决定它们按照何种qdisc进入队列。无论何时数据包进入一个划分子类的类别中,都需要进行分类。使用filter分类时,内核会调用附属于这个类(class)的所有过滤器,直到返回一个判决。如果没有判决返回,就作进一步的处理,而处理方式和qdisc有关。(filter是在QDisc内部,它们不能作为主体)