linux网桥做流量控制时使用iptables的MARK问题

linux网桥做流量控制时使用iptables的MARK问题

环境:
        MagicLinux2.0 内核: 2.6.15.3
        iptables版本:iptables v1.3.7
        网桥:bridge-utils-1.2
        route -V : route 1.98
        给内核打了layer7补丁

eth1:外网  eth2:内网

配置网桥:

brctl addbr br0
brctl addif br0 eth1
brctl addif br0 eth2
ifconfig eth1 0.0.0.0
ifconfig eth2 0.0.0.0
ifconfig br0 0.0.0.0

去外网的队列:


tc qdisc add dev eth1 root handle 1: htb default 20

tc class add dev eth1 parent 1: classid 1:1 htb rate 100mbit burst 1k

tc class add dev eth1 parent 1:1 classid 1:10 htb rate 100kbit  burst 1k

tc class add dev eth1 parent 1:1 classid 1:20 htb rate 100mbit burst 1k

tc qdisc add dev eth1 parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev eth1 parent 1:20 handle 20: sfq perturb 10
tc filter add dev eth1 protocol ip parent 1:0 prio 8 handle 11 fw flowid 1:10

进内网的队列:

tc qdisc add dev eth2 root handle 1: htb default 40

tc class add dev eth2 parent 1: classid 1:1 htb rate 100mbit burst 100m

tc class add dev eth2 parent 1:1 classid 1:30 htb rate 100kbit  burst 1k

tc class add dev eth2 parent 1:1 classid 1:40 htb rate 100mbit burst 1k

tc qdisc add dev eth2 parent 1:30 handle 30: sfq perturb 10
tc qdisc add dev eth2 parent 1:40 handle 40: sfq perturb 10
tc filter add dev eth2 protocol ip parent 1:0 prio 8 handle 22 fw flowid 1:30

iptables配置:

iptables -t mangle -F
iptables -t mangle -A PREROUTING -i eth2 -s 90.0.11.66/32 -j MARK --set-mark 11
iptables -t mangle -A PREROUTING -i eth2 -s 90.0.11.66/32 -j RETURN

iptables -t mangle -A PREROUTING -i eth1 -d 90.0.11.66/32 -j MARK --set-mark 22
iptables -t mangle -A PREROUTING -i eth1 -d 90.0.11.66/32 -j RETURN

(对90.0.11.66这个地址限速100kbit,在这里是测试效果的,本意是用layer7来做p2p流量控制的。)

经测试发现速度没有改变,为了查找问题,我用u32试了试效果:


tc qdisc add dev eth1 root handle 1: htb default 20

tc class add dev eth1 parent 1: classid 1:1 htb rate 100mbit burst 1k

tc class add dev eth1 parent 1:1 classid 1:10 htb rate 100kbit  burst 1k

tc class add dev eth1 parent 1:1 classid 1:20 htb rate 100mbit burst 1k

tc qdisc add dev eth1 parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev eth1 parent 1:20 handle 20: sfq perturb 10
tc filter add dev eth1 protocol ip parent 1:0 prio 8 u32 match ip src 90.0.11.66/32 flowid 1:10



tc qdisc add dev eth2 root handle 1: htb default 40

tc class add dev eth2 parent 1: classid 1:1 htb rate 100mbit burst 100m

tc class add dev eth2 parent 1:1 classid 1:30 htb rate 100kbit  burst 1k

tc class add dev eth2 parent 1:1 classid 1:40 htb rate 100mbit burst 99m

tc qdisc add dev eth2 parent 1:30 handle 30: sfq perturb 10
tc qdisc add dev eth2 parent 1:40 handle 40: sfq perturb 10

tc filter add dev eth2 protocol ip parent 1:0 prio 8 u32 match ip dst 90.0.11.66/32 flowid 1:30

测试发现效果很好。后来我怀疑是网桥的问题,我把网桥去掉,做了nat,内部是192.168.1.0网络,外部是90.0.11.0网络。经测试还是老样子,用u32可以,用iptables 的mark 就是不行,百思不得其解。

后来改用cbq队列试了试,还是不行。

tc qdisc add dev eth1 root handle 1: cbq  bandwidth 100mbit avpkt 1000 cell 8

tc class add dev eth1 parent 1: classid 1:1 cbq bandwidth 100mbit rate 100mbit maxburst 20 allot 1514 avpkt 1000 cell 8 weight 1mbit

tc class add dev eth1 parent 1: classid 1:10 cbq bandwidth 100mbit rate 100kbit  maxburst 20 allot 1514 avpkt 1000 cell 8 weight 1mbit

tc class add dev eth1 parent 1: classid 1:20 cbq bandwidth 100mbit rate 100mbit  maxburst 20 allot 1514 avpkt 1000 cell 8 weight 1mbit


tc filter add dev eth1 protocol ip parent 1:0 prio 8 handle 11 fw flowid 1:10
tc filter add dev eth1 protocol ip parent 1:0 prio 4 handle 22 fw flowid 1:10

iptables -t mangle -F
iptables -t mangle -A PREROUTING -i eth2 -s 192.168.1.6/32 -j MARK --set-mark 11
iptables -t mangle -A PREROUTING -i eth2 -s 192.168.1.6/32 -j RETURN
iptables -t mangle -A PREROUTING -i eth2 -j MARK --set-mark 22


tc qdisc add dev eth2 root handle 1: cbq  bandwidth 100mbit avpkt 1000 cell 8

tc class add dev eth2 parent 1: classid 1:1 cbq bandwidth 100mbit rate 100mbit maxburst 20 allot 1514 avpkt 1000 cell 8 weight 1mbit

tc class add dev eth2 parent 1:1 classid 1:30 cbq bandwidth 100mbit rate 100kbit  maxburst 20 allot 1514 avpkt 1000 cell 8 weight 1mbit

tc class add dev eth2 parent 1:1 classid 1:40 cbq bandwidth 100mbit rate 100mbit  maxburst 20 allot 1514 avpkt 1000 cell 8 weight 1mbit


tc filter add dev eth2 protocol ip parent 1:0 prio 8 handle 33 fw flowid 1:30
tc filter add dev eth2 protocol ip parent 1:0 prio 4 handle 44 fw flowid 1:40

iptables -t mangle -A PREROUTING -i eth1 -d 192.168.1.6/32 -j MARK --set-mark 33
iptables -t mangle -A PREROUTING -i eth1 -d 192.168.1.6/32 -j RETURN
iptables -t mangle -A PREROUTING -i eth1 -j MARK --set-mark 44

如此看来,问题应该是出在mark上了。我加载的模块:lsmod|grep ip
ipt_layer7             10668  0
ipt_MARK                1536  4
ipt_MASQUERADE          2048  1
iptable_nat             5764  1
ipt_ipp2p               6784  0
ip_nat_ftp              2176  0
ip_nat                 12460  3 ipt_MASQUERADE,iptable_nat,ip_nat_ftp
ip_conntrack_ftp        5616  1 ip_nat_ftp
ip_conntrack           34508  5 ipt_MASQUERADE,iptable_nat,ip_nat_ftp,ip_nat,ip_conntrack_ftp
nfnetlink               3864  2 ip_nat,ip_conntrack
iptable_filter          1664  0
iptable_mangle          1792  1
ip_tables              16000  7 ipt_layer7,ipt_MARK,ipt_MASQUERADE,iptable_nat,ipt_ipp2p,iptable_filter,iptable_mangle

不知道是缺少补丁还是iptables的问题。MagicLinux2.0自带的iptables版本是1.3.6,我自己编译的1.3.7。

兄弟姐妹们,你们有何高见?? :time:1 :time:1 :time:1

在网桥模式下使用下列脚本没有问题:
iptables -t mangle -A FORWARD -m physdev --physdev-in eth2 --physdev-out eth1 -s 90.0.11.66/32 -j MARK --set-mark 11
iptables -t mangle -A FORWARD -m physdev --physdev-in eth1 --physdev-out eth2 -d 90.0.11.66/32 -j MARK --set-mark 22

网上看到的绝大部分都使用的PREROUTING ,我测试了数百遍了,不管是 -s 还是 -d 就算加上-m physdev 也还是不打标,使用FORWARD -m physdev 可以匹配到。

另外,经过数百遍的测试发现,如果不使用-j MARK ,而使用 -j DROP 不存在上面各楼提到的问题,不管是使用mangle还是filter用-s或-d都可以解决问题。使用MARK的话就要用FORWARD -m physdev 了,不知道其他的同志们遇到过类似的问题没有。
好像 PREROUTING  这个链只有做NAT的时候才启用吧
网桥模式下只有FORWARD INPUT OUTPUT 3个链起做用
不知道是不是这样