tc u32 – 如何在最近的内核中匹配L2协议?

我有一个很好的整形器,在linux网桥上build立了哈希filter。 简而言之, br0连接externalinternal物理接口,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(我没有build立香草核),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的dst地址)。 没关系,似乎更合乎逻辑,至于我。

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 0at -2at -4at -6或类似的。 我有零点命中的主要问题是计数—这个filter根本就没有被检查,换句话说就是“错误的协议”。

请,任何人,帮助我:-)

谢谢!

在最近的内核中,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 

我不得不这样做。 我发现@Thusitha提出的答案是为新内核做的正确方法。

用Debian wheezy内核3.2.0-4和iproutetesting(从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 

我build议使用wireshark捕获用户空间中可见的界面,并使用它来编写filter。 我想知道如果接口是由于某种原因剥离VLAN标签(尽pipe被configuration为桥接透明)。 也许它是添加额外的标签或东西?

你可以用ebtables标记vlan包。

 # mark packets according to the vlan id ebtables -i br0 -A PREROUTING -p 802_1Q --vlan-id 1 -j mark --mark-set 1 ebtables -i br0 -A PREROUTING -p 802_1Q --vlan-id 5 -j mark --mark-set 2 

然后根据标记进行整形。 ebtables和iptables共享相同的标记。

还没有做到这一点呢。 所以它是一个预感。

尝试closuresvlan接口上的reorder_hdr选项。 如果重新sorting头选项被启用,那么来自帧的标签正被移除。 通过命令ip -d link list dev vlan_iface检查它。