Hello,
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:
Code:
10: from all fwmark 0x1000 lookup routeit
20: from all lookup unreach
ip route list table routeit
Code:
default via 1.2.3.4 dev eth0
ip route list table unreach
Code:
unreachable 10.0.0.0/8
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 1.2.3.4, but wireshark shows packets being sent to the MAC address of 1.2.3.4).
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)?
Thanks