I figured out the main problem:

(local process) -> (routing decision) -> [raw:output] ->
  contrack -> [mangle:output] -> (reroute check) ->
  [nat:output] -> [filter:output] -> ...

When the local process generates a packet, the network stack
takes the routing decision really early on. In our case earlier
then we are able to mark with iptables the packets. That happens
in the mangle table and therefore the policy routing table is
not considered at this point.

My naive assumption was that the reroute check would be done
unconditionally. Unfortunately, this is not true.

The reroute check is only done if the packet was modified in
the mangle output chain. So for example if you look at a simple
ping the code path relevant to route is:

net/ipv4/ping.c:
  ping_v4_sendmsg()
    ip_route_output_flow()

net/ipv4/netfilter/iptable_mangle.c
  ipt_mangle_out()
    ip_route_me_harder()
      ip_route_output_key()
        ip_route_output_flow()

That means the NAT rule is necessary, e.g.

iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 192.168.1.100

The policy routing table is not completely useless. For example the
process could mark its packet on its own. Another possible way is to
have a cgroup controller setting the SO_MARK or we teach the policy
routing table to match on sk_classid (cls cgroup controller).

Back to original problem. I am preparing a patch for adding
the missing NAT rules which should fix this problem.

Obviously, we don't need both the policy routing table and the
NAT rules. But I am reluctant to rip out the policy routing code at this
point. Maybe someone is using it already.

cheers,
daniel
_______________________________________________
connman mailing list
connman@connman.net
https://lists.connman.net/mailman/listinfo/connman

Reply via email to