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

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

我有一个很好的整形器,带有散列过滤功能,是在 Linux 桥上构建的。简而言之,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(我没有构建 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 0at -2at -4at -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_hdrVLAN 接口上的选项。如果启用了重新排序标头选项,则会删除帧中的标签。使用命令检查ip -d link list dev vlan_iface

相关内容