使用 u32 选择器的数据包过滤不起作用

使用 u32 选择器的数据包过滤不起作用

我正在尝试弄清楚我集成到 RaspberryPI 中的 QoS 解决方案是否有效。

我发现基于端口的流量分类不起作用,因此我尝试在我的 Ubuntu 机器上检查所提到的 QoS 解决方案中使用的过滤器。

这是我的虚拟设置:(eno1是连接Raspberry的以太网接口)

# Root qdisc is prio with 3 bands
sudo tc qdisc add dev eno1 root handle 1: prio bands 3
# Band 1 - port 2323 with low rate, high packet loss probability and big delay
sudo tc qdisc add dev eno1 parent 1:1 netem rate 8kbit delay 500ms loss 0.3% 25%
sudo tc filter add dev eno1 parent 1:0 protocol ip u32 match ip dport 2323 0xffff classid 1:1
sudo tc filter add dev eno1 parent 1:0 protocol ip u32 match ip sport 2323 0xffff classid 1:1
# Band 2 qdisc is tbf and filter is outbound SMTP
sudo tc qdisc add dev eno1 parent 1:2 tbf rate 1mbit buffer 100000 latency 100s
sudo tc filter add dev eno1 parent 1:0 protocol ip u32 match ip dport 25 0xffff classid 1:2
sudo tc filter add dev eno1 parent 1:0 protocol ip u32 match ip sport 25 0xffff classid 1:2
# Band 3 qdisc is sfq and filter is anything unfiltered
sudo tc qdisc add dev eno1 parent 1:3 sfq perturb 16
sudo tc filter add dev eno1 parent 1:0 protocol ip prio 9 u32 match u8 0 0 classid 1:3

我限制了速率,并对进出端口 2323 的所有流量增加了相当大的延迟。 不幸的是,所有数据包都经过了频段 3:

hping3 192.168.2.10 -p 25 -c 5
HPING 192.168.2.10 (eno1 192.168.2.10): NO FLAGS are set, 40 headers + 0 data bytes
len=46 ip=192.168.2.10 ttl=64 DF id=0 sport=25 flags=RA seq=0 win=0 rtt=3.8 ms
len=46 ip=192.168.2.10 ttl=64 DF id=0 sport=25 flags=RA seq=1 win=0 rtt=3.7 ms
len=46 ip=192.168.2.10 ttl=64 DF id=0 sport=25 flags=RA seq=2 win=0 rtt=3.5 ms
len=46 ip=192.168.2.10 ttl=64 DF id=0 sport=25 flags=RA seq=3 win=0 rtt=3.2 ms
len=46 ip=192.168.2.10 ttl=64 DF id=0 sport=25 flags=RA seq=4 win=0 rtt=3.1 ms

--- 192.168.2.10 hping statistic ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max = 3.1/3.5/3.8 ms

tc -s -d qdisc show dev eno1       
qdisc prio 1: root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
 Sent 2612 bytes 26 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 
qdisc tbf 800d: parent 1:2 rate 1Mbit burst 100000b/1 mpu 0b lat 100.0s linklayer ethernet 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 
qdisc netem 800c: parent 1:1 limit 1000 delay 500.0ms loss 0.3% 25% rate 8Kbit
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 
qdisc sfq 800e: parent 1:3 limit 127p quantum 1514b depth 127 flows 128/1024 divisor 1024 perturb 16sec 
 Sent 2612 bytes 26 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0

但是如果我向 iptables 添加以下规则,数据包就会被正确分类:

iptables -t mangle -A POSTROUTING -o eno1 -p tcp --dport 2323 -j CLASSIFY --set-class 1:1

我不想在这里添加更多的 tc/hping 输出,因为这会使我的问题太长,但我看到 hping 统计数据中有 500ms 的延迟,并且我发送到端口 2323 的数据包显示在 tc 统计数据中。

有人能建议在哪里搜索问题吗?为什么 u32 选择器不起作用?

提前致谢。

答案1

请注意下文:在tc filter ...语法中,prefprio是同义词,因此我将使用pref/preference 而不是/priority,以避免与中使用的classful qdisc 中prio的不相关内容混淆。priopriotc qdisc ...

上述 1:2 和 1:3 的前两组tc filter规则未指定任何优先级,因此每组规则都继承了默认优先级:从 49152 开始依次递减:默认情况下,较新的规则优先于先前的规则。优先级为 9 的最后一个命令将始终首先被评估。

以下是显示的过滤规则。它们按优先顺序显示:

# tc -s filter show dev eno1
filter parent 1: protocol ip pref 9 u32 chain 0 
filter parent 1: protocol ip pref 9 u32 chain 0 fh 804: ht divisor 1 
filter parent 1: protocol ip pref 9 u32 chain 0 fh 804::800 order 2048 key ht 804 bkt 0 flowid 1:3 not_in_hw  (rule hit 5 success 5)
  match 00000000/00000000 at 0 (success 5 ) 
filter parent 1: protocol ip pref 49149 u32 chain 0 
filter parent 1: protocol ip pref 49149 u32 chain 0 fh 803: ht divisor 1 
filter parent 1: protocol ip pref 49149 u32 chain 0 fh 803::800 order 2048 key ht 803 bkt 0 flowid 1:2 not_in_hw  (rule hit 0 success 0)
  match 00190000/ffff0000 at 20 (success 0 ) 
filter parent 1: protocol ip pref 49150 u32 chain 0 
filter parent 1: protocol ip pref 49150 u32 chain 0 fh 802: ht divisor 1 
filter parent 1: protocol ip pref 49150 u32 chain 0 fh 802::800 order 2048 key ht 802 bkt 0 flowid 1:2 not_in_hw  (rule hit 0 success 0)
  match 00000019/0000ffff at 20 (success 0 ) 
filter parent 1: protocol ip pref 49151 u32 chain 0 
filter parent 1: protocol ip pref 49151 u32 chain 0 fh 801: ht divisor 1 
filter parent 1: protocol ip pref 49151 u32 chain 0 fh 801::800 order 2048 key ht 801 bkt 0 flowid 1:1 not_in_hw  (rule hit 0 success 0)
  match 09130000/ffff0000 at 20 (success 0 ) 
filter parent 1: protocol ip pref 49152 u32 chain 0 
filter parent 1: protocol ip pref 49152 u32 chain 0 fh 800: ht divisor 1 
filter parent 1: protocol ip pref 49152 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1 not_in_hw  (rule hit 0 success 0)
  match 00000913/0000ffff at 20 (success 0 ) 

因此,请始终为每条过滤规则指定一个首选项,对于必须首先匹配的规则,使用较低的值,对于充当默认规则角色的规则,使用最高的值。除非这些首选项适用于非常相似的过滤器(例如,sport/dport 到相同的 classid),否则每个值都应该不同。

相关内容