Skip to main content

Linux route policy based on tos returning wrong gateway [Resolved]

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 via dev eth0  proto static via dev eth0  proto static via dev eth0  proto static via dev eth0  proto static via dev eth0  proto static via dev eth0  proto static via 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 tos 0x02, when I should get returned as the gateway, I get

root@b22e0eafe06d:~# ip route get tos 0x02 via dev eth0  src

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 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 table 102
root@b22e0eafe06d:~# ip route get via dev eth0  src

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.

Question Credit: Dave Isaacs
Question Reference
Asked December 5, 2018
Posted Under: Network
1 Answers

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.

credit: Dave Isaacs
Answered December 5, 2018
Your Answer