我有一个很好的整形器,带有散列过滤功能,是在 Linux 桥上构建的。简而言之,br0
连接external
和internal
物理接口、VLAN 标记数据包是“透明”桥接的(我的意思是,没有 VLAN 接口)。
现在,不同的内核有不同的做法。我可能对确切的内核版本范围有误,请原谅。谢谢。
2.6.26
因此,在 debian 2.6.26 及更高版本(我相信最高到 2.6.32)中 --- 可以这样做:
tc filter add dev internal protocol 802.1q parent 1:0 prio 100 \
u32 ht 1:64 match ip dst 192.168.1.100 flowid 1:200
这里,“内核”将“协议”字段中的两个字节与 0x8100 匹配,但将 ip 数据包的开头算作“零位置”(如果我的英语有点不清楚,请原谅我的英语)。
2.6.32
再次,在 debian(我没有构建 vanilla 内核)2.6.32-5 --- 这有效:
tc filter add dev internal protocol 802.1q parent 1:0 prio 100 \
u32 ht 1:64 match ip dst 192.168.1.100 at 20 flowid 1:200
这里,“内核”与协议匹配,但计算从该协议头开始的偏移量 --- 我必须将 4 个字节添加到偏移量(20,而不是目标地址的 16)。没问题,对我来说似乎更合乎逻辑。
3.2.11,目前最新稳定版本
这是可行的 --- 就好像根本没有 802.1q 标签:
tc filter add dev internal protocol ip parent 1:0 prio 100 \
u32 ht 1:64 match ip dst 192.168.1.100 flowid 1:200
问题是我到目前为止还没有找到匹配 802.1q 标签的方法。
匹配过去的 802.1q 标签
我之前可以这样做:
tc filter add dev internal protocol 802.1q parent 1:0 prio 100 \
u32 match u16 0x0ed8 0x0fff at -4 flowid 1:300
现在我无法将 802.1q 标签与at 0
、at -2
、at -4
或at -6
类似的东西匹配。我的主要问题是没有命中数数--- 这个过滤器根本没有被检查,换句话说是“错误的协议”。
请任何人帮助我:-)
谢谢!
答案1
在最近的内核中,VLAN 标记已从 skb 中删除。请尝试以下操作在 skb 中进行元匹配:
tc filter add dev internal protocol all parent 1:0 prio 100 basic match 'meta(vlan mask 0xfff eq 0x0ed8)' flowid 1:300
答案2
我必须这样做。我发现@Thusitha 建议的答案是针对新内核的正确方法。
使用 Debian wheezy 内核 3.2.0-4 和 iproute(tc 命令的来源)版本 20120521-3+b3 进行测试
这是完整的脚本,其中的tc filter
行几乎与@Thusitha 指定的完全一致
function qos() {
if="$1"
vlan1="$2"
vlan2="$3"
# delete previous
tc qdisc del dev $if root >/dev/null 2>&1
tc qdisc del dev $if ingress >/dev/null 2>&1
# Root HTB for $if
tc qdisc add dev $if root handle 1: htb r2q 1 default 1
# Root class to borrow from
tc class add dev $if parent 1: classid 1:1 htb quantum 1000000 rate 500mbit ceil 500mbit burst 64k prio 2
tc qdisc add dev $if parent 1:1 handle 101 sfq perturb 10
# class for vlan1
tc class add dev $if parent 1:1 classid 1:106 htb quantum 1000000 rate 1.00mbit ceil 1.00mbit burst 6k
tc qdisc add dev $if parent 1:106 handle 107 sfq perturb 10
tc filter add dev $if protocol all parent 1: prio 100 basic match "meta(vlan mask 0xfff eq ${vlan1})" flowid 1:106
# class for vlan2
tc class add dev $if parent 1:1 classid 1:108 htb quantum 1000000 rate 1.00mbit ceil 10.00mbit burst 6k
tc qdisc add dev $if parent 1:108 handle 108 sfq perturb 10
tc filter add dev $if protocol all parent 1: prio 100 basic match "meta(vlan mask 0xfff eq ${vlan2})" flowid 1:108
}
qos eth1 1234 1235
qos eth2 2345 2346
答案3
我建议使用 wireshark 捕获通过接口的内容(在用户空间中可见),并使用它来编写过滤器。我想知道接口是否出于某种原因剥离了 VLAN 标签(尽管配置为透明桥接)。也许是添加了额外的标签之类的?
答案4
尝试关闭reorder_hdr
VLAN 接口上的选项。如果启用了重新排序标头选项,则会删除帧中的标签。使用命令检查ip -d link list dev vlan_iface
。