Android uses a lot of routing rules and tables, probably one per application.
As can be seen, without such rule added and probably its corresponding fwmark, a packet will hit routing rule 32000: unreachable.
It's a bit frail to do something manually over this mechanism. In particular routing rule 10500 allows (only) root to use outgoing interface ccmni1
, but oif
isn't about allowing a packet to be selected to this interface, it's about allowing a packet from a socket bound to this interface (using SO_BINDTODEVICE
) to be selected (oif
isn't a direct equivalent of iif
which is used for routed packets, and iif lo
is also a special case for non-routed packets).
Many rules receive a firewall mark probably set by equivalent complex iptables rules to select specific routing rules per application (and its specific UID too). I guess there are specific Android APIs to register such rules when an application is installed.
If you want to allow root to use first the main routing table thus avoiding the unreachable fate, among multiple possible choices:
ip rule add pref 998 uidrange 0-0 lookup main
Or if you don't care that any user so any application can use usb0 simply:
ip rule add pref 998 lookup main
This probably won't integrate well with the Android system which might shuffle rules around when applications are installed or started and one can't tell what's left with iptables/nftables (or even along SELinux, tc etc.) about blocking access. Even binding to a socket might be restricted by additional mechanism (see for example: CONFIG_ANDROID_PARANOID_NETWORK
).