Back to blog

MikroTik / RouterOS  ·  Routing  ·  July 2026

MikroTik
BGP & Dual-ISP Multihoming

MikroTik is everywhere on the WISP and small-ISP edge, and that edge speaks BGP. RouterOS 7 rewrote BGP from the ground up — new menu, new filter model — so even if you knew v6 BGP, this is worth relearning. Same dual-ISP build as the Cisco twin: two upstreams, path control both directions, automatic failover.

MikroTik RouterOS BGP Multihoming Dual-ISP WISP

BGP is the internet's routing protocol — policy-driven, path-vector, built for peering between networks that don't trust each other. You run it on a MikroTik edge for the same reason as anywhere: two ISPs, your own prefix and ASN, and the need to survive an upstream dying automatically. What's MikroTik-specific is that RouterOS 7 completely replaced the v6 BGP implementation: it's now a single /routing bgp connection object per peer, and all policy lives in /routing filter rule chains rather than the old per-instance settings. Configs and tutorials written for v6 will not paste in.

The jobs are identical to the Cisco twin: bring up both eBGP sessions, filter so you never become accidental transit, steer outbound with local-preference and inbound with AS-path prepend. Only the syntax changes — and this is where a mixed estate benefits from one engineer who reads both.

Prerequisites

01

Two eBGP Connections, Filtered

One /routing bgp connection per ISP, our aggregate advertised via a network entry, and an output filter chain that permits only our own prefix — the same anti-transit rule as Cisco, expressed as a filter chain.

RouterOS 7 — peers + the "advertise only ours" output filter
# The prefix we own and will advertise:
/ip address add address=192.0.2.1/24 interface=lo-aggregate
/routing bgp template set default as=65001 router-id=203.0.113.1

# Output filter: accept ONLY our aggregate, drop everything else
# (so we never re-advertise one ISP's routes to the other).
/routing filter rule
add chain=BGP-OUT rule="if (dst==192.0.2.0/24) { accept }"
add chain=BGP-OUT rule="reject"

# The two eBGP sessions. local.role=ebgp, remote .as per ISP.
/routing bgp connection
add name=ISP-A remote.address=198.51.100.1 remote.as=64500 \
    local.role=ebgp as=65001 output.filter-chain=BGP-OUT \
    output.network=192.0.2.0/24
add name=ISP-B remote.address=203.0.113.9 remote.as=64501 \
    local.role=ebgp as=65001 output.filter-chain=BGP-OUT \
    output.network=192.0.2.0/24
⚠ Gotcha — v7 Is Not v6, and Filters Are Mandatory

Two traps in one. First, if you learned BGP on RouterOS 6 (/routing bgp instance, /routing bgp peer), none of it exists in v7 — it's /routing bgp connection and /routing filter rule now, and the filter syntax is a small scripting language, not a row of columns. Second, exactly like Cisco: with no output filter you re-advertise learned routes and become transit between your ISPs. The BGP-OUT chain permitting only your aggregate is not optional. Add an input max-prefix-limit on each connection as a circuit-breaker.

02

Outbound — Local-Preference on Input

Higher local-pref wins for egress, set on the routes coming in from the preferred ISP. In v7 that's a rule in the connection's input filter chain.

RouterOS 7 — prefer ISP-A outbound
/routing filter rule
add chain=ISP-A-IN rule="set bgp-local-pref 200; accept"
/routing bgp connection
set ISP-A input.filter=ISP-A-IN
# Egress now prefers ISP-A (local-pref 200 > default 100). Drop the
# ISP-A session and its routes withdraw; ISP-B takes over automatically.

03

Inbound — Prepend Toward the Backup

Make the path via ISP-B look longer so the internet prefers coming in via ISP-A. Prepend our own AS on the output toward ISP-B.

RouterOS 7 — AS-path prepend on the ISP-B output
# Reuse a dedicated output chain for ISP-B that prepends before accepting
# our aggregate. (Keep the anti-transit reject at the end.)
/routing filter rule
add chain=ISP-B-OUT rule="if (dst==192.0.2.0/24) \
    { set bgp-path-prepend 3; accept }"
add chain=ISP-B-OUT rule="reject"
/routing bgp connection
set ISP-B output.filter-chain=ISP-B-OUT
# Our prefix now looks 3 hops longer via ISP-B -> inbound favours ISP-A.
💡 Same Asymmetry Lesson as Cisco

Local-preference steers only your egress and never leaves your AS; AS-path prepend rides the advertisement and influences ingress — but it's a hint the rest of the internet may ignore if a remote network sits closer to ISP-B. For real inbound control you set BGP communities your ISP publishes (in v7, set bgp-communities in the output chain). Prepending is the portable default; communities are the scalpel. This is identical across both platforms — see the Cisco twin and the translation guide.

04

Default-Only In, and Verify Safe to Run

A small edge rarely needs the full table. Filter inbound to a default from each ISP, then confirm sessions, best path, and failover.

RouterOS 7 — default-only input + the health walk
# Accept only 0.0.0.0/0 inbound to keep the RIB tiny (add to each IN chain):
/routing filter rule
add chain=ISP-A-IN rule="if (dst==0.0.0.0/0) { set bgp-local-pref 200; accept }"
add chain=ISP-A-IN rule="reject"

# --- Verify ---
/routing bgp session print        # both established, uptime climbing
/ip route print where bgp          # the chosen default (via ISP-A)
/routing bgp advertisements print  # what we're sending each peer
# Failover: /interface disable ISP-A-link, watch the default flip to ISP-B.
SymptomWhere to look
Session not establishedTCP 179 reachability / AS mismatch / role — /routing bgp session print detail.
Pasting v6 config failsYou're on v7 — use connection + /routing filter rule, not instance/peer.
Egress via wrong ISPlocal-pref rule not in the preferred peer's input chain.
Re-advertising ISP routesOutput filter chain missing or its final reject absent.

Takeaways

  1. RouterOS 7 BGP is a clean rewrite/routing bgp connection + /routing filter rule chains. v6 configs don't apply; relearn it.
  2. Filter output to your own aggregate or you become accidental transit between your ISPs — same rule as Cisco, expressed as a chain ending in reject.
  3. Outbound = set bgp-local-pref in the preferred peer's input chain (higher wins, stays inside your AS).
  4. Inbound = set bgp-path-prepend toward the backup — a hint; use bgp-communities for real control.
  5. Default-only input keeps the RIB small; failover is automatic when a session drops.
  6. The policy model is identical to Cisco — only the syntax differs, which is the whole argument for one engineer across a mixed estate.

Running a WISP or multihomed site on RouterOS and unsure your BGP is safe?

NOCTIS builds and audits BGP edges on MikroTik and Cisco across Crete — v7-correct filters, real path control, and no accidental-transit surprises — for WISPs, multi-site businesses, and anyone with two upstreams.

Book a Discovery Call →