我有一个在 Docker 上运行的模拟自组织网络,使用 Ubuntu 16.04 作为基础。
我有许多路由表。有问题的表(表 102)显示如下:
root@b22e0eafe06d:~# ip route show table 102
172.17.0.3 via 172.17.0.3 dev eth0 proto static
172.17.0.4 via 172.17.0.4 dev eth0 proto static
172.17.0.5 via 172.17.0.3 dev eth0 proto static
172.17.0.6 via 172.17.0.3 dev eth0 proto static
172.17.0.7 via 172.17.0.3 dev eth0 proto static
172.17.0.8 via 172.17.0.3 dev eth0 proto static
172.17.0.9 via 172.17.0.3 dev eth0 proto static
还有一些策略规则,其中一条规则将 ToS 设置为 0x02 的任何内容定向到表 102:
root@b22e0eafe06d:~# ip rule list
0: from all lookup local
1: from all tos 0x02 lookup 102
2: from all tos 0x04 lookup 104
3: from all tos 0x06 lookup 106
4: from all tos 0x08 lookup 108
32766: from all lookup main
32767: from all lookup default
但是,当我执行时ip route get 172.17.0.9 tos 0x02
,当我应该172.17.0.3
作为网关返回时,我得到了172.17.0.4
:
root@b22e0eafe06d:~# ip route get 172.17.0.9 tos 0x02
172.17.0.9 via 172.17.0.4 dev eth0 src 172.17.0.2
cache
这恰好是使用主路由表时要选择的网关。我怀疑由于某种原因,引用 tos 0x02 的规则不匹配。
我用一条规则替换了规则 1,该规则将所有发往 172.17.0.9 的数据包发送到表 102,并且成功了。我得出的结论是表 102 有效,但出于某种原因,tos 0x02 上的匹配无效。
root@b22e0eafe06d:~# ip rule del priority 1
root@b22e0eafe06d:~# ip rule add to 172.17.0.9 table 102
root@b22e0eafe06d:~# ip route get 172.17.0.9
172.17.0.9 via 172.17.0.3 dev eth0 src 172.17.0.2
cache
有什么解释吗?
顺便说一句,当我尝试使用其他 tos 值(例如 0x04、0x08)进行路由时,它看起来可以正常工作。0x02 会出现问题。我使用自定义 tos 值进行测试。
答案1
弄清楚了,问题在于我使用的 tos 值。
在数据包头中,tos 由 8 位表示。有许多 RFC 规定了如何解释这些位,但在所有情况下,只有最高 6 位与 tos 相关。最低 2 位保留用于附加信息(例如,拥塞通知)。
在策略规则中设置 tos 时,您要设置整个字段(所有 8 位)。由于我使用的 0x02 值仅设置 2s 列位,因此它被解释为 0x00(基本上没有 tos)。
因此,重要的是要记住,当您选择 tos 值时,在分配它们之前将位向左移动 2 个位置。