BGP — The Routing Protocol of the Internet
Border Gateway Protocol is what stitches the Internet together. Every Autonomous System (AS) at the edge of the global routing table runs BGP with its neighbors; every multi-homed enterprise that wants to control its inbound and outbound traffic flows runs BGP. Unlike OSPF or EIGRP — which find the shortest path according to a metric — BGP is a policy-driven path-vector protocol. It picks routes based on attributes you can manipulate, not just the lowest cost.
This article covers BGP on Cisco IOS: peering establishment, the major attributes, the decision process, route manipulation with route-maps, peer groups, and the verification commands.
iBGP vs eBGP — Two Different Behaviors
BGP changes its rules based on whether the neighbor is in the same AS:
- External BGP (eBGP) — neighbors in different AS numbers. Default TTL of 1 (peers must be directly connected). Administrative distance 20.
- Internal BGP (iBGP) — neighbors in the same AS number. TTL is whatever you set (often 255 internally). AD 200. Iterations of routes between iBGP peers DO NOT propagate — iBGP requires a full mesh, or a route reflector to break the rule.
The full-mesh requirement at scale is what motivates route reflectors and confederations — but those are CCNP/CCIE topics. For most enterprise multi-homing scenarios you have a couple of edge routers running eBGP to ISPs and iBGP between themselves, with the iBGP “mesh” being two routers.
Basic Peering
BGP establishes neighbors via TCP port 179. Each side configures the other as a neighbor with their AS number:
! On the local edge router (AS 65001):
Router(config)# router bgp 65001
Router(config-router)# neighbor 198.51.100.1 remote-as 65002
Router(config-router)# neighbor 198.51.100.1 description ISP-A peer
Router(config-router)# network 203.0.113.0 mask 255.255.255.0
That second line gives the peer a friendly name (use it — future-you reading show ip bgp summary will thank you). The network statement tells BGP which prefixes to originate — only matching prefixes that exist in your local routing table get advertised.
Loopback peering for iBGP
iBGP peerings are typically built between loopback addresses, not physical interfaces, so the session survives a single link failure between routers. Two extra commands:
Router(config-router)# neighbor 10.255.0.2 remote-as 65001
Router(config-router)# neighbor 10.255.0.2 update-source Loopback0
Router(config-router)# neighbor 10.255.0.2 next-hop-self
update-source Loopback0 tells BGP to source the TCP session from the loopback IP. next-hop-self tells the local router to rewrite the BGP next-hop attribute to its own loopback when readvertising eBGP-learned routes to its iBGP peers — otherwise the iBGP peers see the eBGP-learned next-hop, which they may not have a route to.
eBGP between loopbacks
If for some reason your eBGP peering is between loopbacks (rare, but happens with private peering setups), eBGP’s default TTL of 1 prevents it. Open it up:
Router(config-router)# neighbor 198.51.100.1 ebgp-multihop 2
The Path-Selection Process
For each prefix, BGP may have multiple candidate paths in its BGP table. It picks the best one by walking through these attributes in order, stopping at the first one that’s decisive:
| Step | Attribute | Rule |
|---|---|---|
| 1 | Weight (Cisco-only, local) | Highest wins |
| 2 | Local Preference | Highest wins (default 100) |
| 3 | Locally originated? | Yes wins (network statement / aggregate / redistribute) |
| 4 | AS-Path length | Shortest wins |
| 5 | Origin | IGP < EGP < Incomplete |
| 6 | MED | Lowest wins (default 0) |
| 7 | eBGP vs iBGP | eBGP wins |
| 8 | IGP cost to next hop | Lowest wins |
| 9 | Router ID tiebreaker | Lowest wins |
Knowing this order is what BGP policy is built on. To favor one path, manipulate the highest-priority attribute that’s easy to set — usually local preference for outbound preference (which exit do we use) and AS-Path prepending for inbound preference (which entry path do peers prefer).
The Four Most-Used Path Manipulations
1. Local Preference — control which exit your AS uses
Local-pref is propagated within an AS, so all routers in your AS will agree on the preferred exit. Higher = preferred. Default is 100.
Router(config)# route-map PREFER-ISP-A permit 10
Router(config-route-map)# set local-preference 200
Router(config)# router bgp 65001
Router(config-router)# neighbor 198.51.100.1 route-map PREFER-ISP-A in
Result: every prefix learned from ISP-A gets local-pref 200. Prefixes from other peers stay at the default 100. iBGP peers see local-pref 200 and prefer those routes too.
2. AS-Path Prepending — deprefer your inbound
You can’t set local-pref on remote ASes — they ignore yours. To make remote ASes prefer one of your ISPs over another, lengthen the AS-Path on the path you want them to deprefer:
Router(config)# route-map DEPREF-ISP-B permit 10
Router(config-route-map)# set as-path prepend 65001 65001
Router(config-router)# neighbor 198.51.100.5 route-map DEPREF-ISP-B out
Now ISP-B sees a 3-AS path to your prefix (65001 65001 65001) instead of 1, and most paths through ISP-B will lose to alternative paths through ISP-A on AS-path length.
3. MED — suggest entry path within a peer’s AS
If you have two links to the same ISP, MED tells them which entry to prefer. Lower MED is better.
Router(config-route-map)# set metric 50
MED only applies between ASes with multiple links and is widely ignored or stripped by ISPs. Verify the peer honors it before relying on it.
4. Communities — tags that travel with routes
Communities are tags you attach to prefixes. Peer ISPs publish “community values” that, when set on routes you send them, alter their behavior — e.g. ISP community 65002:100 might mean “don’t advertise to other peers,” while 65002:200 means “prepend three times in your AS.” This is how serious traffic engineering happens.
Router(config-route-map)# set community 65002:100
! Send communities to peers (off by default!):
Router(config-router)# neighbor 198.51.100.1 send-community
Filtering with Prefix Lists
The cleanest way to filter what you send and receive. Prefix lists describe ranges of prefixes; route-maps reference them.
Router(config)# ip prefix-list MYPREFIXES permit 203.0.113.0/24
Router(config)# route-map ANNOUNCE-MINE permit 10
Router(config-route-map)# match ip address prefix-list MYPREFIXES
Router(config-router)# neighbor 198.51.100.1 prefix-list MYPREFIXES out
That ensures you only advertise 203.0.113.0/24 to ISP-A — you won’t accidentally leak the full Internet table back to your provider, which is the failure mode that takes networks down.
Peer Groups (and Peer Templates)
Configuring 20 ISPs by hand and copying the same options to each is error-prone. Peer groups let you define one template and assign neighbors to it:
Router(config-router)# neighbor ISP-PEERS peer-group
Router(config-router)# neighbor ISP-PEERS remote-as 65002
Router(config-router)# neighbor ISP-PEERS prefix-list MYPREFIXES out
Router(config-router)# neighbor ISP-PEERS send-community
Router(config-router)# neighbor 198.51.100.1 peer-group ISP-PEERS
Router(config-router)# neighbor 198.51.100.5 peer-group ISP-PEERS
Peer-templates (newer syntax) let you split session vs policy templates, but peer groups are still common in production.
Resetting BGP After Policy Changes
Changing inbound policy doesn’t apply retroactively to routes already in the table. You need to reset the session or do a soft refresh:
! Hard reset (drops the session):
Router# clear ip bgp 198.51.100.1
! Soft reset inbound (re-applies inbound policy, no session drop):
Router# clear ip bgp 198.51.100.1 soft in
! Soft reset outbound (re-applies outbound policy):
Router# clear ip bgp 198.51.100.1 soft out
For soft inbound to work without storing all received routes, both peers must support route-refresh capability (every modern peer does). Verify with show ip bgp neighbors.
Verifying BGP
| Command | Shows |
|---|---|
show ip bgp summary |
Neighbor list, state, prefix counts, uptime |
show ip bgp |
Full BGP table with attributes per route |
show ip bgp neighbors |
Detailed per-neighbor state, capabilities, counters |
show ip bgp neighbors X.X.X.X advertised-routes |
What we’re sending to that peer |
show ip bgp neighbors X.X.X.X routes |
What we’ve accepted from that peer (post-inbound-policy) |
show ip route bgp |
BGP routes installed in the IP routing table |
The state machine in show ip bgp summary matters. Established means the session is up. Active means the local router is trying to bring it up but hasn’t succeeded. Idle means the session is administratively down or the router has given up retrying.
Common Pitfalls
- Missing the route in your routing table. The
networkstatement only originates a prefix if it exists in the IP routing table. If you’re trying to advertise203.0.113.0/24but the router only has203.0.113.0/26connected, BGP won’t originate the /24. - iBGP next-hop unreachable. An eBGP route’s next-hop is the eBGP peer’s IP. Without
next-hop-selfon the eBGP-learning router, iBGP peers receive a next-hop they can’t resolve. - iBGP not propagating. iBGP peers don’t pass routes between themselves. Either build a full mesh or use a route reflector.
- No soft reset after policy change. Inbound policy changes don’t apply until you trigger soft refresh. The route stays as it was originally accepted.
- Outbound prefix-list missing. The day you forget to filter your outbound advertisement is the day you become a transit AS for the entire Internet routing table for ten minutes.
- Communities not sent.
send-communityis off by default per neighbor. If your route-map sets a community and the peer never sees it, you forgot this.
Conclusion
BGP is policy plumbing more than it is a routing protocol. The metric model is alien to anyone coming from OSPF/EIGRP — instead of one number that says “best path,” you have nine attributes evaluated in a specific order, any of which you can rewrite with a route-map.
Five habits that make BGP manageable:
- Always use prefix-lists out, on every neighbor. Default is “announce everything you know.”
- Set
next-hop-selfon edge routers when readvertising eBGP routes into iBGP. - Name peers with
description—show ip bgp summarybecomes self-documenting. - Use peer groups for any setup with more than two similar peers.
- Soft-reset after policy changes; don’t hard-reset unless you have to. Hard resets drop sessions and the BGP table for those neighbors gets rebuilt from scratch.
BGP’s reputation as the “hardest” routing protocol comes from its policy surface, not its mechanics. The TCP-based session is straightforward; the path attribute system is just a list with a deterministic comparison order. Once that clicks, the rest of BGP becomes about choosing where to apply the levers.