It turns out you could almost do it with policy routing if you moved the ppp / wlan interface definitions from table 255 (local) or inserted a rule with priority -1.. either way it just won't let you do it.. and frankly what we'd like to achieve is a bit counter-intuitive.. so I can't really blame it
At startup time the kernel configures the default RPDB consisting of three rules: 1. Priority: 0, Selector: match anything, Action: lookup routing table local (ID 255). The local table is a special routing table containing high priority control routes for local and broadcast addresses. Rule 0 is special. It cannot be deleted or overridden. 2. Priority: 32766, Selector: match anything, Action: lookup routing table main (ID 254). The main table is the normal routing table contain‐ ing all non-policy routes. This rule may be deleted and/or overridden with other ones by the administrator. 3. Priority: 32767, Selector: match anything, Action: lookup routing table default (ID 253). The default table is empty. It is reserved for some post-processing if no previous default rules selected the packet. This rule may also be deleted.
More working.. pppd doesn't as it stands offer a way of obtaining the allocated local and peer IP address without setting the ppp interface. This means ppp0 could be set to a clashing IP addresss the moment a link is established between the device and the apn.. Even if pppX is down, the fact the local address has been defined could screw up a wlan connection. For example.. if wlan0 is talking to 192.168.1.200, then ppp0 is started and receives a local address 192.168.1.200, even if ppp0 is never brought "up", the clash still takes effect and the established connection to 192.168.1.200 will fail.
I've created a couple of scripts that will tie into PPPD. First is /etc/ppp/ip-pre-up . This script is run when pppX is configured, but before it is brought up.