我有一个需求,需要根据路由器的不同接口来进行流量速率限制,比如控制ssid1的上传速率为10mbps,下载速率为20mbps,lan1的上传速率为30mbps,下载速率为50mbps……上行接口为eth1,所有下行接口都抽象成虚拟网桥br-lan(包括ssid1、ssid2、lan1……)。
现在我尝试使用tc工具来限制流量速率,使用iptables的physdev模块来标记来自不同物理接口的流量,并使用标记的值来限制eth1的qdisc中某个物理接口的上传速度。
当前网桥情况如下(eth0.2对应lan1):
root@cpe:~# brctl show
bridge name bridge id STP enabled interfaces
br-lan 7fff.00001228802a no eth0.2
usbnet0
wlan0
我的配置代码如下:
sysctl -w net.bridge.bridge-nf-call-iptables=1
tc qdisc add dev eth1 root handle 1:0 htb default 1
tc class add dev eth1 parent 1:0 classid 1:1 htb rate 100Mbit
tc class add dev eth1 parent 1:1 classid 1:10 htb rate 10Mbit ceil 10Mbit
tc qdisc add dev eth1 parent 1:10 handle 10: sfq perturb 10
tc filter add dev eth1 parent 1:0 protocol ip prio 1 handle 666 fw classid 1:10
iptables -t mangle -N HAHA
iptables -t mangle -I PREROUTING -m physdev --physdev-in eth0.2 -j HAHA
iptables -t mangle -A HAHA -s 0.0.0.0/0 -j MARK --set-mark 666
root@cpe:~# iptables -t mangle -nvL
Chain PREROUTING (policy ACCEPT 140 packets, 12806 bytes)
pkts bytes target prot opt in out source destination
100 10152 HAHA all -- * * 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-in eth0.2
Chain HAHA (1 references)
pkts bytes target prot opt in out source destination
100 10152 MARK all -- * * 0.0.0.0/0 0.0.0.0/0 MARK set 0x29a
eth0.2 Link encap:Ethernet HWaddr 00:55:80:5C:34:76
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:125556 errors:0 dropped:0 overruns:0 frame:0
TX packets:119526 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:98887328 (94.3 MiB) TX bytes:114959454 (109.6 MiB)
看起来 iptables 规则已经匹配并标记了数据包,但匹配的数量非常少(与我测试中产生的数据包相比)。无论我的限速 tc 规则是否错误,iptables 理论上不应该匹配这么少的数据包,我不知道为什么。
今天我尝试用 ebtables 标记包,但仍然不起作用。
eth0.2 Link encap:Ethernet HWaddr 00:22:96:F5:AB:7C
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:59511 errors:0 dropped:0 overruns:0 frame:0
TX packets:66029 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:34341259 (32.7 MiB) TX bytes:76007190 (72.4 MiB)
root@cpe:~# ebtables -L --Lc
Bridge table: filter
Bridge chain: INPUT, entries: 1, policy: ACCEPT
-i eth0.2 -j mark --mark-set 0x8 --mark-target CONTINUE, pcnt = 450 -- bcnt = 24918
ebtables -t filter -A INPUT -i eth0.2 -j mark --mark-set 8 --mark-target CONTINUE
iptables 匹配到的包数量少是什么原因?该怎么解决?或者有没有更好的方法基于虚拟网桥的物理接口做 QoS?
答案1
好的,我知道原因了,就是因为我没有关闭bypass_fastpath,输入下面命令或者删除mfp.ko后,就好了。
echo 1 > /sys/kernel/fastpath/fp_forward/bypass_fastpath
#or
rm /lib/modules/3.10.33/mfp.ko