The routing table forwards by destination — that's its whole job. But sometimes you need to route by who sent it, not where it's going: guest VLAN out the cheap ISP, staff out the good one; VoIP out the low-latency link. Policy-Based Routing overrides the routing table for traffic you choose. The twin of MikroTik's routing-rules-and-mangle approach.
Normal routing is destination-based and identical for everyone: a packet to 8.8.8.8 takes the same path whether it came from the CEO's laptop or the lobby TV. Policy-Based Routing (PBR) breaks that symmetry — it lets you match traffic on source, protocol, port, or size and set a different next-hop before the routing table gets a vote. It's how you implement "guests leave via the backup ISP so they never touch the expensive metered link," or "send this one subnet down the VPN and everything else out normally."
PBR is a route-map applied inbound on an interface: match clauses pick the traffic (usually via an ACL), set clauses choose the next-hop. It runs on the router receiving the traffic, before the FIB lookup. This pairs naturally with the dual-ISP edge and the IP SLA failover post, and its RouterOS counterpart is routing rules & mangle.
01
Classify with an ACL, then a route-map that sets the next-hop for matches and falls through to normal routing for everything else. Apply it inbound on the interface where that traffic arrives.
# 1. Classify: which traffic gets special treatment? R1(config)# ip access-list extended GUEST-OUT R1(config-ext-nacl)# permit ip 10.10.20.0 0.0.0.255 any # 2. The policy: match the ACL, set the ISP-B next-hop. R1(config)# route-map PBR-GUEST permit 10 R1(config-route-map)# match ip address GUEST-OUT R1(config-route-map)# set ip next-hop 203.0.113.9 # ISP-B gateway # A permit clause with no set = "route these normally" (explicit passthrough). R1(config)# route-map PBR-GUEST permit 20 # 3. Apply INBOUND on the interface the guest traffic arrives on. R1(config)# interface Vlan20 R1(config-if)# ip policy route-map PBR-GUEST
PBR is applied with ip policy on the interface where the traffic enters the router, not where it leaves. New engineers reflexively put it on the WAN interface and nothing happens. Also mind direction: the route-map only affects transit traffic arriving on that interface — for traffic the router itself originates (pings, management), you need ip local policy route-map separately. Match the interface to where the interesting traffic shows up.
02
There are several set verbs and they differ in when they win against the routing table. Pick the wrong one and PBR either overrides too aggressively or not at all.
set clause | Behaviour |
|---|---|
| set ip next-hop X | Force next-hop X — overrides the routing table. Blackholes if X is down. |
| set ip next-hop verify-availability | Same, but skip if X is unreachable (uses CDP/tracking) — safer. |
| set interface Tunnel0 | Force out an interface (good for point-to-point / tunnels). |
| set ip default next-hop X | Use X only if the routing table has no specific route — a gentle nudge. |
A bare set ip next-hop blackholes matched traffic the moment that next-hop dies — PBR doesn't consult reachability by default. Combine it with an IP SLA track and set ip next-hop verify-availability <nh> <seq> track <n> so the policy steps aside when the path is down and the packet falls through to normal routing (or the next set clause). Policy routing without a health check is a self-inflicted outage waiting for the backup link to be needed.
03
PBR's power is that the match can be anything an ACL expresses — protocol, port, DSCP, even packet length. That's how you route by application, not just by subnet.
# Match by DSCP (VoIP marked EF) or port, then steer to the good link. R1(config)# ip access-list extended VOICE R1(config-ext-nacl)# permit ip any any dscp ef R1(config)# route-map PBR-APP permit 10 R1(config-route-map)# match ip address VOICE R1(config-route-map)# set ip next-hop verify-availability 198.51.100.1 1 track 1 # match ip address with a length ACL, or match length, is also valid — # e.g. push big backups out the metered link, keep interactive on fibre.
04
PBR failures are silent — traffic just routes normally. Confirm the policy is attached, matching, and its counters are climbing.
R1# show ip policy # which interfaces have a route-map R1# show route-map PBR-GUEST # "policy routing matches: N packets" # Trace the decision for a specific flow: R1# debug ip policy # (carefully, on a lab / low traffic) # From a guest host, a traceroute should now exit via ISP-B's gateway.
Takeaways
ip policy — not on the exit, and router-originated traffic needs ip local policy.set: next-hop overrides the table (and blackholes if down); default next-hop only fills a gap; verify-availability adds a safety check.show ip policy and the route-map match counters.NOCTIS designs policy-routed dual-WAN edges on Cisco and MikroTik across Crete — the right traffic on the right link, with health checks so a dead path never becomes a black hole.
Book a Discovery Call →