Back to blog

Cisco / IOS  ·  Routing  ·  July 2026

Cisco IOS
BGP & Dual-ISP Multihoming

The whole series stops at OSPF, which runs your inside. BGP runs the outside — the protocol that glues the internet together and the one you reach for the day a single default route out one ISP isn't good enough. This builds a real dual-ISP edge: two upstreams, sane inbound and outbound path control, and failover that just happens when a session drops.

Cisco IOS BGP Multihoming Dual-ISP Routing CCNP

OSPF is an interior gateway protocol — it trusts every router in your domain and shares full topology. BGP is the opposite: a path-vector, policy-driven protocol built for the internet, where you don't trust anyone and you advertise reachability, not topology. You run it the moment you have two ISPs and your own address space (a PI /24 and an ASN), and want to survive one upstream dying without a phone call.

The three jobs of a multihomed edge: bring up eBGP sessions to both ISPs, control outbound path selection (which upstream your traffic leaves by) and inbound (which upstream the internet uses to reach you), and make failover automatic. Outbound you steer with local-preference; inbound you nudge with AS-path prepending — you can't command the internet, only hint. This is the bridge from the OSPF post to how the edge actually talks to the world, and it has a MikroTik twin in RouterOS BGP.

Prerequisites

01

Bring Up Both eBGP Sessions

A neighbour statement per ISP, your prefix advertised, and — non-negotiable at the edge — filters so you never leak a route you shouldn't. An unfiltered multihomed router can accidentally become a transit provider between two Tier-1s.

IOS — two eBGP peers, advertise our /24, filter hard
R1(config)# router bgp 65001
R1(config-router)# bgp router-id 203.0.113.1
R1(config-router)# no bgp default ipv4-unicast       # explicit is safer

# ISP-A and ISP-B, each an external AS
R1(config-router)# neighbor 198.51.100.1 remote-as 64500
R1(config-router)# neighbor 203.0.113.9 remote-as 64501

R1(config-router)# address-family ipv4 unicast
R1(config-router-af)# neighbor 198.51.100.1 activate
R1(config-router-af)# neighbor 203.0.113.9 activate
# Advertise ONLY our own aggregate.
R1(config-router-af)# network 192.0.2.0 mask 255.255.255.0
# Never re-advertise one ISP's routes to the other — filter outbound.
R1(config-router-af)# neighbor 198.51.100.1 prefix-list OUR-NETS out
R1(config-router-af)# neighbor 203.0.113.9 prefix-list OUR-NETS out
R1(config)# ip prefix-list OUR-NETS permit 192.0.2.0/24
⚠ Gotcha — An Unfiltered Edge Becomes Accidental Transit

Without that outbound filter, your router will happily advertise routes learned from ISP-A back to ISP-B. Both upstreams then think they can reach the whole internet through your little edge router, and your uplinks melt under transit traffic you never intended to carry. An outbound prefix-list that permits only your own aggregate is mandatory on every multihomed edge — it's the difference between multihoming and a bad afternoon. Optionally cap the damage with neighbor … maximum-prefix.

02

Outbound — Local-Preference Picks the Exit

Local-preference is the highest-weight knob you fully control, and it decides which upstream your traffic leaves by. Higher wins. Set it inbound from the preferred ISP.

IOS — prefer ISP-A outbound via local-preference
# Tag everything learned from ISP-A with a higher local-pref (default 100).
R1(config)# route-map PREFER-A-IN permit 10
R1(config-route-map)# set local-preference 200
R1(config)# router bgp 65001
R1(config-router-af)# neighbor 198.51.100.1 route-map PREFER-A-IN in
# Now all outbound traffic prefers ISP-A; ISP-B is hot standby.
# If the ISP-A session drops, those routes vanish and ISP-B takes over.
R1# show ip bgp | include 0.0.0.0|200

03

Inbound — AS-Path Prepend (You Can Only Hint)

You don't control how the internet reaches you — remote networks pick the shortest AS-path to your prefix. To make ISP-B the backup for inbound, make your path through it look longer by prepending your own AS a few times.

IOS — make ISP-B the less-preferred inbound path
# Advertise to ISP-B with our AS prepended 3x -> longer path -> less
# preferred by the rest of the internet. ISP-A carries inbound.
R1(config)# route-map PREPEND-B-OUT permit 10
R1(config-route-map)# set as-path prepend 65001 65001 65001
R1(config)# router bgp 65001
R1(config-router-af)# neighbor 203.0.113.9 route-map PREPEND-B-OUT out
💡 The Asymmetry That Trips Everyone

Outbound and inbound are separate problems with separate knobs, and forgetting one gives you asymmetric routing that mostly works until it doesn't. Local-preference is a local decision — it never leaves your AS — so it only steers your egress. AS-path prepend travels with the advertisement, so it's the tool for ingress — but it's a hint, not a command; a network close to ISP-B may still come in that way. For true inbound control you'd use BGP communities the ISP honours (e.g. "set local-pref low on your side"). Prepending is the portable 80% solution.

04

Default-Only vs Full Tables, and Verify Safe to Run

Most edges don't need 950k+ internet routes. Taking a default route from each ISP keeps memory low and failover simple; take full tables only when you need per-destination path optimisation.

IOS — accept default-only inbound, then the health walk
# Ask each ISP to send us only a default (or filter to 0.0.0.0/0 inbound).
R1(config-router-af)# neighbor 198.51.100.1 prefix-list DEFAULT-ONLY in
R1(config)# ip prefix-list DEFAULT-ONLY permit 0.0.0.0/0

# --- Verify ---
R1# show ip bgp summary            # both neighbours in Established, prefixes > 0
R1# show ip bgp 0.0.0.0            # best path = ISP-A (local-pref 200)
R1# show ip route bgp              # the chosen default in the RIB
# Failover test: shut the ISP-A interface, watch BGP reconverge to ISP-B.
SymptomWhere to look
Neighbour stuck in Active/IdleNo TCP 179 reachability or AS mismatch — show ip bgp neighbors.
Session up, no routesMissing activate in the address-family, or inbound filter too tight.
Traffic leaves wrong ISPlocal-preference not applied inbound from the preferred peer.
Inbound still favours backupPrepend too weak, or a remote net is simply closer to ISP-B — use communities.

Takeaways

  1. BGP runs the edge, OSPF runs the inside. You reach for it when you have two ISPs and your own address space and want to survive one dying.
  2. Filter outbound, always. An unfiltered multihomed edge becomes accidental transit between your two ISPs — advertise only your own aggregate.
  3. Outbound = local-preference (higher wins, set inbound from the preferred ISP). It never leaves your AS, so it only steers your egress.
  4. Inbound = AS-path prepend — a hint, not a command. Make the backup path look longer; use ISP communities when you need real control.
  5. Outbound and inbound are separate problems. Solve both or accept asymmetric routing.
  6. Default-only is enough for most edges. Take full tables only when you need per-destination optimisation; failover is automatic when a session drops.

Two ISPs but only one of them ever actually used?

NOCTIS designs multihomed BGP edges on Cisco and MikroTik across Crete — real inbound/outbound path control and failover that reconverges on its own, not a floating static and a prayer.

Book a Discovery Call →