Jun 16, 2010
My issue is with linux routing tables using iproute2, coupled with the iptables MARK target. When I create a rule to lookup a table with iproute2, and the routing table routes an address as type unreachable (or blackhole, or prohibit), if a higher priority rule does a lookup to another table that routes the address as type unicast but that higher priority rule also matches on a fwmark, the packet to that address is never generated locally to even go through iptables packet filtering/mangling in order to mark it, because the lower priority rule that doesn't match on a fwmark says it's unreachable. For example, I have 2 rules installed with ip:
View 2 Replies
10: from all fwmark 0x1000 lookup routeit
20: from all lookup unreach
ip route list table routeit
Now, in the packet filter, I have an iptables rule to mark packets to destination 10.0.0.5 with 0x1000 in the mangle table and OUTPUT chain. When I generate a packet locally to 10.0.0.5, all programs get ENETUNREACH (tested with strace). However, if I take out the route entry that 10.0.0.0/8 is unreachable, it all works fine and the routes in the routeit table get applied to marked packets (I know because my default gateway would not be 220.127.116.11, but wireshark shows packets being sent to the MAC address of 18.104.22.168).
The best I can surmise is that when generating a packet locally, the kernel tests the routing tables in priority order but without any mark to see if it is unreachable/blackhole/prohibit, and doesn't even bother generating the packet and traversing iptables rules to see if it would eventually be marked and thus routed somewhere. Then I assume after that step, it traverses iptables rules, then traverses the routing tables again to find a route. So is there any way around this behavior besides adding fake routes to the routing table (e.g. routing 10.0.0.5 to dev lo in the unreach table in this example)?