-1

I have a simulated ad-hoc network running on Docker, using Ubuntu 16.04 as a base.

I have a number of routing tables. The table in question, table 102, appears as:

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

There are also some policy rules, include one which directs anything with a ToS setting of 0x02 to table 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

However, when I do an ip route get 172.17.0.9 tos 0x02, when I should get 172.17.0.3 returned as the gateway, I get 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

This happens to be the gateway that would be selected is the main routing table was used. I suspect that the rule referencing tos 0x02 is not matching for some reason.

I replaced rule 1 with a rule that sends all packets destined to 172.17.0.9 to table 102, and that worked. I conclude that table 102 is working, but for some reason matching on tos 0x02 is not.

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

Any explanations?

BTW, when I try routing with other tos values, such as 0x04, 0x08, it looks to be working. It is 0x02 that is giving a problem. I am using custom tos values for testing purposes.

1 Answers1

0

Figured it out, and the issue is the tos values I was using.

In a packet header, the tos is represented by 8 bits. There are numerous RFCs that govern how these bits are interpreted, but in all cases only the highest 6 bits are relevant to the tos. The lowest 2 bits are reserved for additional information (for example, congestion notification).

When setting the tos in a policy rule, you are setting the entire field (all 8 bits). Since the value of 0x02 I was using only sets the 2s column bits, it was being interpreted as 0x00 (essentially no tos at all).

Therefore it is important to remember that when you are choosing tos values, shift the bits 2 positions to the left before assigning them.