Help with mangle rules and dualwan routing on v7.20.1

I’m kind of getting crazy on this one, and might use some help understanding what i’m doing wrong.

I use RouterOS (started with v6 and now everything on v7 for quite some time) in different networks, and in one of them i’m facing a situation I cannot get to working properly. I’m pretty sure this worked as expected on v6 and, with some minor changes, worked on v7 as well for quite some time. But I was facing some problems and, after some troubleshooting, I found it’s not working anymore on v7.20.1. I’m not sure when it stopped working, I just know it’s not working now. I’m not saying this is a v7.20.1 problem whatsoever, it’s just not working on this version anymore.

I have 2 different ISPs, both of them established via pppoe-client, and both ISPs deliveres me a static public IPv4 address.

I just want, using mangle rules, that external accesses that arrives to the ISP1 IP (on pppoe1) to get routed back to internet via ISP1 (pppoe1), and external accesses that arrives to the ISP2 IP (on pppoe2) to get routed back to internet via ISP2 (pppoe2). And this is not working as expected, despite i’m completely sure it worked with this configs (on v6 plus “/routing table” on v7) for quite some time.

Routing specific traffic to ISP1 or ISP2, via mangle prerouting rules, works flawlessly. I just can’t get accesses TO the Mikrotik router (mangle=input) to get routed back to the correct pppoe interface (mangle=output) on the way out.

I adjusted mangle (input and output) rules to have log=yes, I can clearly see packets are being marked on the mangle input, and they traverses mangle output with the correct routing-mark. Despite having the correct routing-mark (for ISP2 for example), they are not routed accordingly, and uses regular default route (from main) to get back to the internet. It’s OK for ISP1 IP, which is default route with distance 1, but ISP2 IP, which is default route with distance 2, is getting routed back via ISP1 (pppoe1) and that’s not OK. Traffic, despite “routing-markED” is not processed with that routing table and chooses route using main table.

(fasttrack is completely disabled on this MK router, so no fasttrack problem related)

My configs ….

/interface pppoe-client add interface=ether1 keepalive-timeout=60 name=pppoe1 comment="linq" ...
/interface pppoe-client add interface=ether2 keepalive-timeout=60 name=pppoe2 comment="simdigital" ...

/routing table add fib name=linq
/routing table add fib name=simdigital

/ip route add distance=1 dst-address=0.0.0.0/0 gateway=pppoe1 routing-table=linq suppress-hw-offload=no
/ip route add distance=1 dst-address=0.0.0.0/0 gateway=pppoe2 routing-table=simdigital suppress-hw-offload=no

/ip firewall mangle
# marking packets arriving on PUBLICIP1 and PUBLICIP2 with appropriate tags
add action=mark-connection chain=input connection-mark=no-mark dst-address=<LINQPUBLICIP> in-interface=pppoe1 new-connection-mark=arrived-linq
add action=mark-connection chain=input connection-mark=no-mark dst-address=<SIMDIGITALPUBLICIP> in-interface=pppoe2 new-connection-mark=arrived-simdigital

# setting routing-marks based on connection-marks
add action=mark-routing chain=output connection-mark=arrived-linq new-routing-mark=linq
add action=mark-routing chain=output connection-mark=arrived-simdigital new-routing-mark=simdigital

# routing specific networks, to pppoe1 or pppoe2, with mangle prerouting, works as expected
/ip firewall mangle
add action=mark-routing chain=prerouting dst-address-list=!RFC1918 in-interface=VLAN-100-COLABORADORES new-routing-mark=simdigital src-address=172.26.0.0/16
add action=mark-routing chain=prerouting dst-address-list=!RFC1918 in-interface=VLAN-150-ALUNOS new-routing-mark=simdigital src-address=172.27.0.0/16


The only way I could get it to work was completely dropping mangle input and mangle output rules, and creating “routing rules” rules:

/routing rule
add action=lookup-only-in-table src-address=PUBLICIP1 table=linq
add action=lookup-only-in-table src-address=PUBLICIP2 table=simdigital

And while that worked, I’m facing similar problems on other networks that receives public dynamic addresses on the pppoe client interfaces, so I was trying to find how to fix it without using “routing rule”, as IP addresses on those are dynamic (and I’d like to avoid using PPP profile scripting to update rules, I know I can do that) and I don’t know them to setup correct “routing rule” rules. I was trying to find out what I’m doing wrong with the mangle (and ip route) rules that i’m completely sure worked previously.

I have researched this a lot, and seems most people fails to create the “routing tables”, which is not my case. I really can’t see what I’m doing wrong. Fasttrack is also usually involved, which is completely disabled round here.

Thanks for any help on that and thanks for the patient to read to the end :slight_smile:

1 Like

Did you disable the fasttrack rule?

Yes, fasttrack is completely disabled as explained on the original post. The “default” fasttrack rule was removed, “IP Settings” shows fasttrack counters all zeroed.

Assume you already have PPPoE Client and IPv4/IPv6 addresses/prefixes setup…

The /ip(v6) route, firewall mangle and /routing settings you need for linq is the following.

/routing table
add comment="linq" disabled=no fib name=pppoe1
/ip firewall mangle
add action=mark-connection chain=input comment="correct reverse path pppoe1 input" \
    connection-mark=no-mark connection-state=new in-interface=pppoe1 \
    new-connection-mark=pppoe1 passthrough=no
add action=mark-routing chain=output comment="correct reverse path pppoe1 output" \
    connection-mark=pppoe1 new-routing-mark=pppoe1 passthrough=no
add action=mark-connection chain=forward comment="correct reverse path pppoe1 forward" \
    connection-mark=no-mark connection-state=new in-interface=pppoe1 \
    new-connection-mark=pppoe1 passthrough=no
add action=mark-routing chain=prerouting comment="correct reverse path pppoe1 prerouting" \
    connection-mark=pppoe1 in-interface=!pppoe1 new-routing-mark=pppoe1 passthrough=no
/ip route
add comment="linq" disabled=no distance=1 dst-address=0.0.0.0/0 gateway=pppoe1 \
    routing-table=pppoe1 scope=30 target-scope=10
/ipv6 route
add comment="linq" disabled=no distance=1 dst-address=::/0 gateway=pppoe1 pref-src="" \
    routing-table=pppoe1 scope=30 target-scope=10
/ipv6 firewall mangle
add action=mark-connection chain=input comment="correct reverse path pppoe1 input" \
    connection-mark=no-mark connection-state=new in-interface=pppoe1 \
    new-connection-mark=pppoe1 passthrough=no
add action=mark-routing chain=output comment="correct reverse path pppoe1 output" \
    connection-mark=pppoe1 new-routing-mark=pppoe1 passthrough=no
add action=mark-connection chain=forward comment="correct reverse path pppoe1 forward" \
    connection-mark=no-mark connection-state=new in-interface=pppoe1 \
    new-connection-mark=pppoe1 passthrough=no
add action=mark-routing chain=prerouting comment="correct reverse path pppoe1 prerouting" \
    connection-mark=pppoe1 in-interface=!pppoe1 new-routing-mark=pppoe1 passthrough=no
/routing rule
add action=lookup comment="linq" disabled=no min-prefix=0 routing-mark=pppoe1 table=main
add action=lookup comment="linq" disabled=no routing-mark=pppoe1 table=pppoe1


And for the other ISP, just replacelinqandpppoe1to appropriate names and repeat the settings.

BTW, the fasttrack rule can be enabled withconnection-mark=no-mark, as long as you pair amark-connectionrule for eachmark-routingrule.

Inspired by RouterOS在多个上游情况下正确设置返回包的默认路由 | Drown in Codes, modified for RouterOS v7 and my needs.

Full config required.
/export file=anynameyouwish (minus router serial number, any public WANIP information, keys )
Details on type of load balancing being used if any.
Details on any failover planning if any.

Any external users coming into the LAN (port forwarding)
Any external users coming to the WAN ( to use router services like wireguard )
Any internal users need specific WAN they have to go out on.