3-ISPs Load Balancing - need help

Hello everyone. Need some help on triple ISP config with PCC load balancing. Looking for assistance to please look at the mangle & routing rules. Also the DHCP-client script. Config & concerns are below.

HEX on ROS 7.13.4 using winbox
ISP1: ether1 (100/100)
ISP2: ether2 (100/100)
ISP3: ether3 (100/100)
Lan Bridge: ether 4 & ether5

Concerns:
Mangle rules: I’m not sure if the rules are correct, the ordering of the rules, using passthrough properly, etc. For some reason, when WAN-3 is disabled (interface disabled or cable unplugged), the prerouting mangle rules for ether3 (ISP3 / to_ISP3) still have traffic, also shown in connection tracking. I delete the connections but still connections repopulate like it’s connected. The output chain for ether2 & ether3 barely have any traffic. Most is on ether1, a lot of it. Leading to believe load balancing isn’t working as intended because I mucked something up.

dhcp-client: The dhcp-client creates a default route for each ISP (not sure I should be doing this or it’s ok). I also create new routes for routing tables to_ISPs. Found a script to update the gateway & also delete the connections when the gateway IP changes. Problem is, neither work. The GW is not being updated nor are the connections being killed/deleted. I don’t know anything about scripts. I’ve tried copy/paste script in the dhcp-client advanced tab in winbox & also using the terminal.

/interface list
add comment=defconf name=WAN
add comment=defconf name=LAN

/interface bridge port
add bridge="Lan Bridge" interface=ether4
add bridge="Lan Bridge" interface=ether5

/ip firewall connection tracking
set tcp-established-timeout=12h loose-tcp-tracking=no

/ip settings
set max-neighbor-entries=4096 rp-filter=loose

/interface list member
add interface=ether1 list=WAN
add interface=ether2 list=WAN
add interface=ether3 list=WAN
add interface="Lan Bridge" list=LAN

/routing table
add fib name=to_ISP1
add fib name=to_ISP2
add fib name=to_ISP3

/ip dhcp-client 
add interface=ether1 add-default-route=yes script=":if (\$bound=1) do={\r\
    \n    /ip/route/set [find where comment=\"ISP1\"] gateway=\$\"gateway-address\"\r\
    \n}\r\
    \n\r\
    \n/ip/firewall/connection/remove [find connection-mark=\"ISP1_conn\"]\r\
    \n/ip/firewall/connection/remove [find connection-mark=\"ISP2_conn\"]\r\
    \n/ip/firewall/connection/remove [find connection-mark=\"ISP3_conn\"]" use-peer-dns=no use-peer-ntp=no
add interface=ether2 add-default-route=yes default-route-distance=2 script=":if (\$bound=1) do={\r\
    \n    /ip/route/set [find where comment=\"ISP2\"] gateway=\$\"gateway-address\"\r\
    \n}\r\
    \n\r\
    \n/ip/firewall/connection/remove [find connection-mark=\"ISP1_conn\"]\r\
    \n/ip/firewall/connection/remove [find connection-mark=\"ISP2_conn\"]\r\
    \n/ip/firewall/connection/remove [find connection-mark=\"ISP3_conn\"]" use-peer-dns=no use-peer-ntp=no
add interface=ether3 add-default-route=yes default-route-distance=3 script=":if (\$bound=1) do={\r\
    \n    /ip/route/set [find where comment=\"ISP3\"] gateway=\$\"gateway-address\"\r\
    \n}\r\
    \n\r\
    \n/ip/firewall/connection/remove [find connection-mark=\"ISP1_conn\"]\r\
    \n/ip/firewall/connection/remove [find connection-mark=\"ISP2_conn\"]\r\
    \n/ip/firewall/connection/remove [find connection-mark=\"ISP3_conn\"]" use-peer-dns=no use-peer-ntp=no

/ip firewall filter
add action=accept chain=input comment="defconf: accept established,related,untracked" connection-state=established,related,untracked disabled=no
add action=drop chain=input comment="defconf: drop invalid" connection-state=invalid disabled=no
add action=accept chain=input comment="defconf: accept ICMP" disabled=no protocol=icmp
add action=accept chain=input comment="defconf: accept to local loopback" disabled=no dst-address=127.0.0.1
add action=accept chain=input comment="admin access" disabled=no in-interface-list=LAN src-address-list=admin
add action=accept chain=input comment="allow LAN DNS queries-TCP" disabled=no dst-port=53 in-interface-list=LAN protocol=tcp
add action=accept chain=input comment="allow LAN DNS/NTP queries-UDP" disabled=no dst-port=53,123 in-interface-list=LAN protocol=udp
add action=drop chain=input comment="drop all else" disabled=no
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" connection-state=established,related disabled=no hw-offload=yes
add action=accept chain=forward comment="defconf: accept established,related,untracked" connection-state=established,related,untracked disabled=no
add action=drop chain=forward comment="defconf: drop invalid" connection-state=invalid disabled=no
add action=accept chain=forward comment="internet access" disabled=no in-interface-list=LAN out-interface-list=WAN
add action=accept chain=forward comment="port forwarding" connection-nat-state=dstnat disabled=no
add action=accept chain=forward comment="allow multi-subnet access" disabled=no dst-address-list=expected-address-from-LAN src-address-list=expected-address-from-LAN in-interface-list=LAN out-interface-list=LAN
add action=drop chain=forward comment="drop all else" disabled=no

/ip firewall mangle
add action=accept chain=prerouting comment="Lan Bridge access" dst-address-list=expected-address-from-LAN in-interface-list=LAN
add action=mark-connection chain=prerouting comment="mark all new incoming connections" connection-mark=no-mark connection-state=new in-interface=ether1 new-connection-mark=ISP1_conn passthrough=yes
add action=mark-connection chain=prerouting connection-mark=no-mark connection-state=new in-interface=ether2 new-connection-mark=ISP2_conn passthrough=yes
add action=mark-connection chain=prerouting connection-mark=no-mark connection-state=new in-interface=ether3 new-connection-mark=ISP3_conn passthrough=yes
add action=mark-connection chain=prerouting comment="divide traffic into three groups" connection-mark=no-mark connection-state=new dst-address-type=!local in-interface-list=LAN new-connection-mark=ISP1_conn passthrough=yes per-connection-classifier=src-address-and-port:3/0
add action=mark-connection chain=prerouting connection-mark=no-mark connection-state=new dst-address-type=!local in-interface-list=LAN new-connection-mark=ISP2_conn passthrough=yes per-connection-classifier=src-address-and-port:3/1
add action=mark-connection chain=prerouting connection-mark=no-mark connection-state=new dst-address-type=!local in-interface-list=LAN new-connection-mark=ISP3_conn passthrough=yes per-connection-classifier=src-address-and-port:3/2
add action=mark-routing chain=prerouting comment="distribute traffic across ISP's" connection-mark=ISP1_conn in-interface-list=LAN new-routing-mark=to_ISP1 passthrough=yes
add action=mark-routing chain=prerouting connection-mark=ISP2_conn in-interface-list=LAN new-routing-mark=to_ISP2 passthrough=yes
add action=mark-routing chain=prerouting connection-mark=ISP3_conn in-interface-list=LAN new-routing-mark=to_ISP3 passthrough=yes
add action=mark-routing chain=output comment="force connection to table" connection-mark=ISP1_conn new-routing-mark=to_ISP1 passthrough=no
add action=mark-routing chain=output connection-mark=ISP2_conn new-routing-mark=to_ISP2 passthrough=no
add action=mark-routing chain=output connection-mark=ISP3_conn new-routing-mark=to_ISP3 passthrough=no

/ip firewall nat
add action=masquerade chain=srcnat comment="ISP1 - Masquerade" out-interface=ether1
add action=masquerade chain=srcnat comment="ISP2 - Masquerade" out-interface=ether2
add action=masquerade chain=srcnat comment="ISP3 - Masquerade" out-interface=ether3

/ip route
add check-gateway=ping gateway=ISP1-IP routing-table=to_ISP1 distance=1 comment="ISP1"
add check-gateway=ping gateway=ISP2-IP routing-table=to_ISP2 distance=1 comment="ISP2"
add check-gateway=ping gateway=ISP3-IP routing-table=to_ISP3 distance=1 comment="ISP3"

Can you confirm that ISP1,2,3 are providing static fixed WANIPs, or dynamic WANIps
Are they all from the same provider?
Do you have any external traffic going to the router itself (aka wireguard handshake for example)
Do you have any LAN servers that external traffic expects to hit…

Hello Mesquite. Thank you for looking.
Yes, the ISP’s are all dynamic
Different providers for each ISP
No wireguard (had it but removed it).
There is a server on the Lan Bridge that is accessible externally via port forwarding (I didn’t provide that NAT rule for it)

Okay, well since you have servers in the mix External traffic to LAN, then we have to account for that traffic to ensure its goes back out the same WAN it came in.
Since you have no external traffic to the router itself,VPN etc, there is no need to mangle that traffic.

  1. The other thing I noted is that you have hoisted in the fact that for actual IP routes where we need to identify the gateway IP of ISP1,2,3 we need to ensure that the current gateway IP is used and thus we need scripts, However your scripts are long winded and seem to involve removing connection marks… I am not aware of this effort, and IMHO its added complexity not required or desired. So I will propose what I would do for each of the three IP DHCP Client script settings. Just modify the other two by changing the parameter number used.

Select in IP DHCP client : In DHCP TAB → Add default route=yes. In Advanced TAB → Set default route distance=255. What we are doing is forcing the update of the gateway IP and not interfering with any of our manually created routes. In advance tab script area:

:if ($bound=1) do={
:local gw [ /ip dhcp-client get $“gateway-address” ]
/ip route set [ find comment=“ISP1-MainTable” gateway!=$gw ] gateway=$gw
/ip route set [ find comment=“ISP1-SpecificTable” gateway!=$gw ] gateway=$gw
}

Next lets tackle the ROUTES…
We need to establish the basic IP routes for the router on the main table.
They are missing!!

/ip route
add check-gateway=ping dst-address=0.0.0.0/0 gateway=Current_ISP1-gatewayIP-address routing-table**=main** distance=1 comment=“ISP1-MainTable
add check-gateway=ping dst-address=0.0.0.0/0 gateway=Current_ISP2-gatewayIP-address routing-table**=main** distance=2 comment=“ISP2-MainTable”
add check-gateway=ping dst-address=0.0.0.0/0 gateway=Current_ISP3-gatewayIP-address routing-table**=main** distance=3 comment=“ISP3-MainTable”

Then the specific tables you have created already… check-gateway=ping is not useful here, each table is separate and availability determined on main table execution.
Neither is distance.

/ip route
add dst-address=0.0.0.0/0 gateway=Current_ISP1-gatewayIP-address routing-table=to_ISP1 comment=“ISP1-SpecificTable
add dst-address=0.0.0.0/0 gateway=Current_ISP2-gatewayIP-address routing-table=to_ISP2 comment=“ISP2-SpecificTable”
add dst-address=0.0.0.0/0 gateway=Current_ISP3-gatewayIP-address routing-table=to_ISP3 comment=“ISP3-SpecificTable”

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Lets tackle the servers issue…
2. Cover off Server traffic before any PCC rules!!

The first thing to do is mark traffic entering the WAN externally and being forwarded to the LAN.
/ip mangle
add chain=forward action=mark-connections connection-mark=no-mark in-interface=ether1
new connection-mark=WAN1-conn passthrough=yes
add chain=forward action=mark-connections connection-mark=no-mark in-interface=ether2
new connection-mark=WAN2-conn passthrough=yes
add chain=forward action=mark-connections connection-mark=no-mark in-interface=ether3
new connection-mark=WAN3-conn passthrough=yes

Then we route that traffic out the same WAN.
/ip mangle
add chain=prerouting action=mark-routing connection-mark=WAN1-conn
new-routing-mark=to_ISP1 src-address-list=Servers passthrough=no
add chain=prerouting action=mark-routing connection-mark=WAN2-conn
new-routing-mark=to_ISP2 src-address-list=Servers passthrough=no
add chain=prerouting action=mark-routing connection-mark=WAN3-conn
new-routing-mark=to_ISP3 src-address-list=Servers passthrough=no

What we are doing is saying any of the external traffic with those markings being replied to by the servers needs to go out the specific wan table.
You could also simply use in-interface-list=LAN instead, your choice…

In any case in the order of mangle rules make sure the above ones are entered first!

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Now lets look at those PCC rules. The first thing we do is mark connections not going to local address types and being forwarded from the LAN.

(edit fixed chains to prerouting)
add chain=prerouting action=mark-connection connection-mark=no-mark dst-address-type=!local
in-interface-list=LAN new-connection-mark=ISP1_conn passthrough=yes
per-connection-classifier=src-address-and-port:3/0
add chain=prerouting action=mark-connection connection-mark=no-mark dst-address-type=!local
in-interface-list=LAN new-connection-mark=ISP2_conn passthrough=yes
per-connection-classifier=src-address-and-port:3/1
add chain=prerouting action=mark-connection connection-mark=no-mark dst-address-type=!local
in-interface-list=LAN new-connection-mark=ISP3_conn passthrough=yes
per-connection-classifier=src-address-and-port:3/2

Next we route-mark the connection marked traffic back through the specific table and thus WAN…

add chain=prerouting action=mark-routing in-interface-list=LAN connection-mark=ISP1_conn
new-routing-mark=to_ISP1 passthrough=no
add chain=prerouting action=mark-routing in-interface-list=LAN connection-mark=ISP2_conn
new-routing-mark=to_ISP2 passthrough=no
add chain=prerouting action=mark-routing in-interface-list=LAN connection-mark=ISP3_conn
new-routing-mark=to_ISP3 passthrough=no

DONE… the rest of the mangle rules you have are not required.

MODIFY FORWARD CHAIN FASTRACK RULE TO:
add action=fasttrack-connection chain=forward comment=“defconf: fasttrack” connection-state=established,related disabled=no hw-offload=yes connection-mark=no-mark

Thank you Mesquite. I will adjust the config & report back shortly

A couple of things to think about once we get the rudimentary setup working properly.
Did you want recursive routing, meaning check the connectivity not from router to ISP but from router do public DNS on the web.
Rare to happen but its possible the router and the ISP talk but the ISP to the internet is broken and thats why people use recursive routing.

Second is failover. Right now its basic failover based on the setup in the main routes

If ISP1 fails its pCC traffic will go to ISP2.
If ISP2 failts its pCC traffic will go to ISP1
if ISP3 fails its pCC traffic will go to ISP1

By changing the distances on the main routes you can select how traffic is re-routed upon a failure.
There is another option a bit more complex…
What If you wanted the PCC traffic from a failed WAN connection to be split between the two remaining WANs…
Thus this is something to explore as well.

Greetings Mesquite

Apologies for the delay in response. I made the changes. I ended up losing access to the hex. I couldn’t login using the IP 192.168.88.1. I was able to regain access by using the mac method in the neighbors tab in winbox. I disabled the mangle rules & was able to gain access again using the IP. Narrowed it down to the first set of forward rules that’s blocking the access via IP. Disabled the following first rule set (2 more rules for ISP’s 2 & 3):

add action=mark-connection chain=forward comment=
“mark all new incoming connections” connection-mark=no-mark
connection-state=“” disabled=yes in-interface=ether1 new-connection-mark=
WAN1-conn passthrough=yes

Logged in via mac method in neighbors tab, all mangle rules enabled:
Looking at the routes, there are 2 sets of default routes (for main table) for each ISP. One set that the dhcp-client auto creates & the manual ones I added. The routes are all connected, no routes indicating unreachable. Also, ISP2 isn’t working, no traffic & the config seems to favor ISP3, even after multiple reboots, disabling interfaces and/or dhcp clients etc. ISP3 ends up with most (roughly 90%) of the traffic. Goal is to spread all of the traffic among all 3 ISP’s equally. But if one goes out, to use whichever ISP’s are working.
Screen Shot 2024-02-19 at 8.27.44 PM.png
On the recursive front, I definitely would be interested in that. I have tried to understand it in the past but abandoned it. But I read another thread the other day where you laid it out perfectly. This thread here: http://forum.mikrotik.com/t/dual-dhcp-wan-recursive-failover-w-pcc-load-balancing-and-recursive-ecmp/173691/1 Now a days with fiber becoming more of a standard (which one of my ISP is), the GW will ping even though the connection is down. So I definitely think recursive is the way to go. Enough of my rambling haha

Config:

# 2024-02-19 19:46:46 by RouterOS 7.13.4
# software id = FBAJ-N40M
#
# model = RB750Gr3
# serial number = xxxxxx
/interface bridge
add comment="Lan Bridge" name="Lan Bridge"
/interface ethernet
set [ find default-name=ether1 ] comment="ISP1 - Buckeye - Load Balancing"
set [ find default-name=ether2 ] comment="ISP2 - T-Mobile - Load Balancing"
set [ find default-name=ether3 ] comment="ISP3 - AT&T - Load Balancing"
set [ find default-name=ether4 ] comment="TP-Link Network"
set [ find default-name=ether5 ] comment="Mikrotik Network"
/interface list
add comment=defconf name=WAN
add comment=defconf name=LAN
/ip pool
add comment="Lan Bridge" name=LAN ranges=192.168.88.20-192.168.88.150
/ip dhcp-server
add address-pool=LAN interface="Lan Bridge" name=dhcp1
/routing table
add fib name=to_ISP1
add fib name=to_ISP2
add fib name=to_ISP3
/interface bridge port
add bridge="Lan Bridge" interface=ether4
add bridge="Lan Bridge" interface=ether5
/ip firewall connection tracking
set loose-tcp-tracking=no tcp-established-timeout=12h
/ip settings
set max-neighbor-entries=4096 rp-filter=loose
/ipv6 settings
set disable-ipv6=yes
/interface list member
add interface=ether1 list=WAN
add interface=ether2 list=WAN
add interface=ether3 list=WAN
add interface="Lan Bridge" list=LAN
/ip address
add address=192.168.88.1/24 interface="Lan Bridge" network=192.168.88.0
/ip dhcp-client
add comment="ISP1 - Buckeye - DHCP Client" default-route-distance=255 \
    interface=ether1 script=":if (\$bound=1) do={\r\
    \n:local gw [ /ip dhcp-client get \$\"gateway-address\" ]\r\
    \n/ip route set [ find comment=\"ISP1-MainTable\" gateway!=\$gw ] gateway=\
    \$gw\r\
    \n/ip route set [ find comment=\"ISP1-SpecificTable\" gateway!=\$gw ] gate\
    way=\$gw\r\
    \n}" use-peer-dns=no use-peer-ntp=no
add comment="ISP2 - T-Mobile - DHCP Client" default-route-distance=255 \
    interface=ether2 script=":if (\$bound=1) do={\r\
    \n:local gw [ /ip dhcp-client get \$\"gateway-address\" ]\r\
    \n/ip route set [ find comment=\"ISP2-MainTable\" gateway!=\$gw ] gateway=\
    \$gw\r\
    \n/ip route set [ find comment=\"ISP2-SpecificTable\" gateway!=\$gw ] gate\
    way=\$gw\r\
    \n}" use-peer-dns=no use-peer-ntp=no
add comment="ISP3 - AT&T - DHCP Client" default-route-distance=255 interface=\
    ether3 script=":if (\$bound=1) do={\r\
    \n:local gw [ /ip dhcp-client get \$\"gateway-address\" ]\r\
    \n/ip route set [ find comment=\"ISP3-MainTable\" gateway!=\$gw ] gateway=\
    \$gw\r\
    \n/ip route set [ find comment=\"ISP3-SpecificTable\" gateway!=\$gw ] gate\
    way=\$gw\r\
    \n}" use-peer-dns=no use-peer-ntp=no
/ip dhcp-server network
add address=192.168.88.0/24 comment="Lan Bridge" dns-server=192.168.88.1 \
    gateway=192.168.88.1
/ip dns
set allow-remote-requests=yes servers=1.1.1.1
/ip firewall address-list
add address=192.168.88.200-192.168.88.205 comment="Mikrotik - Admin Devices" list=admin
add address=192.168.88.0/24 comment="Mikrotik hEX Network" list=\
    expected-address-from-LAN
/ip firewall filter
add action=accept chain=input comment=\
    "defconf: accept established,related,untracked" connection-state=\
    established,related,untracked
add action=drop chain=input comment="defconf: drop invalid" connection-state=\
    invalid
add action=accept chain=input comment="defconf: accept ICMP" protocol=icmp
add action=accept chain=input comment="defconf: accept to local loopback" \
    dst-address=127.0.0.1
add action=accept chain=input comment="admin access" in-interface-list=LAN \
    src-address-list=admin
add action=accept chain=input comment="allow LAN DNS queries-TCP" dst-port=53 \
    in-interface-list=LAN protocol=tcp
add action=accept chain=input comment="allow LAN DNS/NTP queries-UDP" \
    dst-port=53,123 in-interface-list=LAN protocol=udp
add action=drop chain=input comment="drop all else"
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" \
    connection-mark=no-mark connection-state=established,related hw-offload=\
    yes
add action=accept chain=forward comment=\
    "defconf: accept established,related,untracked" connection-state=\
    established,related,untracked
add action=drop chain=forward comment="defconf: drop invalid" \
    connection-state=invalid
add action=accept chain=forward comment="internet access" in-interface-list=\
    LAN out-interface-list=WAN
add action=accept chain=forward comment="port forwarding" \
    connection-nat-state=dstnat
add action=drop chain=forward comment="drop all else"
/ip firewall mangle
add action=mark-connection chain=forward comment=\
    "mark all new incoming connections" connection-mark=no-mark \
    connection-state="" disabled=yes in-interface=ether1 new-connection-mark=\
    WAN1-conn passthrough=yes
add action=mark-connection chain=forward connection-mark=no-mark \
    connection-state="" disabled=yes in-interface=ether2 new-connection-mark=\
    WAN2-conn passthrough=yes
add action=mark-connection chain=forward connection-mark=no-mark \
    connection-state="" disabled=yes in-interface=ether3 new-connection-mark=\
    WAN3-conn passthrough=yes
add action=mark-routing chain=prerouting comment="force connection to table" \
    connection-mark=WAN1-conn disabled=yes in-interface-list=LAN \
    new-routing-mark=to_ISP1 passthrough=no
add action=mark-routing chain=prerouting connection-mark=WAN2-conn disabled=\
    yes in-interface-list=LAN new-routing-mark=to_ISP2 passthrough=no
add action=mark-routing chain=prerouting connection-mark=WAN3-conn disabled=\
    yes in-interface-list=LAN new-routing-mark=to_ISP3 passthrough=no
add action=mark-connection chain=forward comment=\
    "divide traffic into three groups" connection-mark=no-mark \
    connection-state="" disabled=yes dst-address-type=!local \
    in-interface-list=LAN new-connection-mark=ISP1_conn passthrough=yes \
    per-connection-classifier=src-address-and-port:3/0
add action=mark-connection chain=forward connection-mark=no-mark \
    connection-state="" disabled=yes dst-address-type=!local \
    in-interface-list=LAN new-connection-mark=ISP2_conn passthrough=yes \
    per-connection-classifier=src-address-and-port:3/1
add action=mark-connection chain=forward connection-mark=no-mark \
    connection-state="" disabled=yes dst-address-type=!local \
    in-interface-list=LAN new-connection-mark=ISP3_conn passthrough=yes \
    per-connection-classifier=src-address-and-port:3/2
add action=mark-routing chain=prerouting comment=\
    "distribute traffic across ISP's" connection-mark=ISP1_conn disabled=yes \
    in-interface-list=LAN new-routing-mark=to_ISP1 passthrough=no
add action=mark-routing chain=prerouting connection-mark=ISP2_conn disabled=\
    yes in-interface-list=LAN new-routing-mark=to_ISP2 passthrough=no
add action=mark-routing chain=prerouting connection-mark=ISP3_conn disabled=\
    yes in-interface-list=LAN new-routing-mark=to_ISP3 passthrough=no
/ip firewall nat
add action=masquerade chain=srcnat comment="ISP1 - Buckeye - Masquerade" \
    out-interface=ether1
add action=masquerade chain=srcnat comment="ISP2 - T-Mobile - Masquerade" \
    out-interface=ether2
add action=masquerade chain=srcnat comment="ISP3 - AT&T - Masquerade" \
    out-interface=ether3
/ip route
add comment=ISP1-MainTable disabled=no distance=1 dst-address=0.0.0.0/0 \
    gateway=ISP1-GW-IP pref-src="" routing-table=main scope=30 \
    suppress-hw-offload=no target-scope=10
add comment=ISP2-MainTable disabled=no distance=2 dst-address=0.0.0.0/0 \
    gateway=ISP2-GW-IP pref-src="" routing-table=main scope=30 \
    suppress-hw-offload=no target-scope=10
add comment=ISP3-MainTable disabled=no distance=3 dst-address=0.0.0.0/0 \
    gateway=ISP3-GW-IP pref-src="" routing-table=main scope=30 \
    suppress-hw-offload=no target-scope=10
add comment=ISP1-SpecificTable disabled=no distance=1 dst-address=0.0.0.0/0 \
    gateway=ISP1-GW-IP pref-src="" routing-table=to_ISP1 scope=30 \
    suppress-hw-offload=no target-scope=10
add comment=ISP2-SpecificTable disabled=no distance=1 dst-address=0.0.0.0/0 \
    gateway=ISP2-GW-IP pref-src="" routing-table=to_ISP2 scope=30 \
    suppress-hw-offload=no target-scope=10
add comment=ISP3-SpecificTable disabled=no distance=1 dst-address=0.0.0.0/0 \
    gateway=ISP3-GW-IP pref-src="" routing-table=to_ISP3 scope=30 \
    suppress-hw-offload=no target-scope=10

Okay, the IP Routes Table is exactly correct.
If one was to follow the main table, traffic would get routed out WAN1 as its primary (and working hence black).
The two farther distance routes wan2 and wan3 are blue because they are not being used in the main table at the moment ( on-standby)
The specific tables and routes for wan1,2,3 are black hence connected and will be used for traffic through those tables. All good!!

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

What I dont understand is why you have disabled all the mangling??
THe mangle rules should not interfere with accessing the router itself etc. but let me think about why it could…

Okay upon review, I erred in the first half of second set of mangle rules…
The initial PCC rules…
FROM:
add action=mark-connection chain=forward comment=
“divide traffic into three groups” connection-mark=no-mark
connection-state=“” disabled=yes dst-address-type=!local
in-interface-list=LAN new-connection-mark=ISP1_conn passthrough=yes
per-connection-classifier=src-address-and-port:3/0
add action=mark-connection chain=forward connection-mark=no-mark
connection-state=“” disabled=yes dst-address-type=!local
in-interface-list=LAN new-connection-mark=ISP2_conn passthrough=yes
per-connection-classifier=src-address-and-port:3/1
add action=mark-connection chain=forward connection-mark=no-mark
connection-state=“” disabled=yes dst-address-type=!local
in-interface-list=LAN new-connection-mark=ISP3_conn passthrough=yes
per-connection-classifier=src-address-and-port:3/2

TO:
add action=mark-connection chain=prerouting comment=
“divide traffic into three groups” connection-mark=no-mark
connection-state=“” disabled=yes dst-address-type=!local
in-interface-list=LAN new-connection-mark=ISP1_conn passthrough=yes
per-connection-classifier=src-address-and-port:3/0
add action=mark-connection chain=prerouting connection-mark=no-mark
connection-state=“” disabled=yes dst-address-type=!local
in-interface-list=LAN new-connection-mark=ISP2_conn passthrough=yes
per-connection-classifier=src-address-and-port:3/1
add action=mark-connection chain=prerouting connection-mark=no-mark
connection-state=“” disabled=yes dst-address-type=!local
in-interface-list=LAN new-connection-mark=ISP3_conn passthrough=yes
per-connection-classifier=src-address-and-port:3/2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
See if that solves the problem. If not then next step is to put this mangle rule as the first mangle rule in the order of mangle rules.

/ip firewall mangle
add chain=prerouting action=accept src-address-list=192.168.88.0/24 dst-address-type=local

Greeting Mesquite

That worked! Changing the chain to prerouting vs forward. I can access via IP. All ISP’s have equal amounts of traffic shown in interfaces. But, the counters in the mangles rules are at 0 for the first 2 sets of rules. Everything seems to be working though.

Does it matter is the connection marks are different from the first 2 sets of rules vs the last 2 sets of rules?
First 2 sets connection mark: WAN1-conn
Last 2 sets connection marks: ISP1_conn
Screen Shot 2024-02-19 at 11.22.21 PM.png

No it makes little difference, perhaps more items for the CPU to keep track of. I personally like the differentiation as its really different traffic we are marking, the similarity is we push that traffic to the same routes, via using the same table.

So the PCC is working, great news!! As for mangle rule counters?? Think that was for any external traffic to the routers… has that been exercised or tested??

Hello Mesquite

You were right! I put the hex in a live environment & the counters in the first 2 sets of mangle rules are now working.

I personally like the differentiation as its really different traffic we are marking, the similarity is we push that traffic to the same routes, via using the same table.

I like the way you think. Perfect!

One small thing, the gateway IP’s are not updating in the manually created routes. The default route that the DHCP-client creates is updated with the new IP, but the manual routes don’t update with the script in the dhcp-client. I disabled/enabled interface, dhcp-client & also rebooted. Neither has updated the manual routes. Script below:
:if ($bound=1) do={
:local gw [ /ip dhcp-client get $“gateway-address” ]
/ip route set [ find comment=“ISP3-MainTable” gateway!=$gw ] gateway=$gw
/ip route set [ find comment=“ISP3-SpecificTable” gateway!=$gw ] gateway=$gw
}

Can you poste your IP ROUTES protecting the actual WANIPs of course.
Im looking for the line with distance of 255 especially, should be three of them in blue ( possibly withe Dd as the first entry column)

I printed the routes. When I export using “export verbose file=” or “export file=”, the defaults created by dhcp-client don’t show up. Only the manually created routes do. Let me know if there’s a way to print it properly. If not, if you’d like, I can create the command similar to the other routes

D d 0.0.0.0/0 xxx.xxx.xx.x 255
D d 0.0.0.0/0 xxx.xxx.xx.x 255
D d 0.0.0.0/0 xxx.xxx.xx.x 255

All are the same but here is ISP3:
add distance=255 dst-address=0.0.0.0/0 gateway=ISP3-GW-IP pref-src=“” routing-table=main scope=30 target-scope=10 suppress-hw-offload=no vrf-interface=ether3

Okay will have to sort out proper syntax… its like working through mud!!
I am assuming that you are using the letters instead of the actual number showing correct to keep wan information private???
gateway=ISP3-GW-IP

Correct. I’ll put it back to test that way you’ll see the full config, along with the IP info. Allow me some time to do this. I’m not in front of it at the moment. I’ll provide the full unedited config later tonight. Is there a certain way you want me to export the config? Or is the standard “export file=” ok to provide?

standard export is fine…i use notepad++

Sounds good. I’ll reply back in a few hours with the full config. Thank you Mesquite

Try this iteration… for the three scripts… should work.

:if ($bound=1) do={
:local gw $“gateway-address”
/ip route set [ find comment=“ISP1-MainTable” gateway!=$gw ] gateway=$gw
/ip route set [ find comment=“ISP1-SpecificTable” gateway!=$gw ] gateway=$gw
}

Genius! That worked, but only after a reboot. I waited a few minutes & it didn’t update. After the reboot, both manually created routes updated for ISP3 (only one that I tested). Once I get home, I’ll try it again after changing the GW & will report back. Do you still want the full config when I post?