如果您需要数千条规则,例如,如果您有很多客户端或计算机,并且它们都具有不同的 QoS 规范,您可能会发现内核花费大量时间来匹配所有这些规则。
默认情况下,所有过滤器都驻留在一个大的链中,该链按照优先级降序进行匹配。如果您有 1000 条规则,则可能需要 1000 次检查才能确定如何处理数据包。
如果您有 256 个链,每个链包含四个规则,匹配速度会快得多 - 如果您可以将数据包分配到这 256 个链中,以便正确的规则在那里。
哈希使这成为可能。假设您的网络中有 1024 个有线调制解调器客户,其 IP 地址范围从 1.2.0.0 到 1.2.3.255,并且每个客户都必须进入另一个类别,例如“lite”、“regular”和“premium”。那么您将拥有 1024 条这样的规则
# tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \ 1.2.0.0 classid 1:1 # tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \ 1.2.0.1 classid 1:1 ... # tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \ 1.2.3.254 classid 1:3 # tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \ 1.2.3.255 classid 1:2 |
为了加速此过程,我们可以使用 IP 地址的最后一部分作为“哈希键”。然后我们得到 256 个表,第一个表如下所示
# tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \ 1.2.0.0 classid 1:1 # tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \ 1.2.1.0 classid 1:1 # tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \ 1.2.2.0 classid 1:3 # tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \ 1.2.3.0 classid 1:2 |
下一个表的开头如下所示
# tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \ 1.2.0.1 classid 1:1 ... |
这样,最多只需要四次检查,平均两次。
配置非常复杂,但是当您拥有如此多规则时,它非常值得。首先我们创建一个过滤器根,然后我们创建一个包含 256 个条目的表
# tc filter add dev eth1 parent 1:0 prio 5 protocol ip u32 # tc filter add dev eth1 parent 1:0 prio 5 handle 2: protocol ip u32 divisor 256 |
现在我们向创建的表中的条目添加一些规则
# tc filter add dev eth1 protocol ip parent 1:0 prio 5 u32 ht 2:7b: \ match ip src 1.2.0.123 flowid 1:1 # tc filter add dev eth1 protocol ip parent 1:0 prio 5 u32 ht 2:7b: \ match ip src 1.2.1.123 flowid 1:2 # tc filter add dev eth1 protocol ip parent 1:0 prio 5 u32 ht 2:7b: \ match ip src 1.2.3.123 flowid 1:3 # tc filter add dev eth1 protocol ip parent 1:0 prio 5 u32 ht 2:7b: \ match ip src 1.2.4.123 flowid 1:2 |
接下来创建一个“哈希过滤器”,将流量定向到哈希表中的正确条目
# tc filter add dev eth1 protocol ip parent 1:0 prio 5 u32 ht 800:: \ match ip src 1.2.0.0/16 \ hashkey mask 0x000000ff at 12 \ link 2: |
这非常复杂,但它在实践中确实有效,并且性能将是惊人的。请注意,可以对本示例进行改进,使其达到每个链包含 1 个过滤器的理想情况!