BGP Peering: eBGP and iBGP Configuration
BGP Peering: eBGP and iBGP Configuration
Section titled “BGP Peering: eBGP and iBGP Configuration”This guide covers RouterOS 7 BGP configuration: establishing eBGP and iBGP peering sessions, advertising and filtering routes, and influencing path selection with BGP attributes.
RouterOS 7 replaces the v6 flat /routing bgp peer model with a three-object design: template (protocol parameters and policy), connection (transport endpoint), and session (runtime state). All examples on this page use RouterOS 7 syntax.
Overview
Section titled “Overview”BGP (Border Gateway Protocol) is a path-vector protocol designed for inter-domain routing between autonomous systems (ASes). Unlike IGPs (OSPF, IS-IS), BGP is policy-driven: which routes to accept, which to advertise, and which path to prefer are all explicitly controlled.
Use BGP when:
- Connecting to one or more ISPs (multihoming)
- Operating as a transit or peering AS
- Exchanging routes between internal network segments with distinct policies
Do not use BGP when static routes or an IGP (OSPF, RIP) are sufficient. BGP has high configuration overhead and requires careful policy design to avoid routing loops and path leaks.
eBGP vs iBGP
Section titled “eBGP vs iBGP”| eBGP | iBGP | |
|---|---|---|
| ASN relationship | Different ASes | Same AS |
| AS_PATH handling | Prepends own AS on send | Does not modify AS_PATH |
| Next-hop behavior | Next-hop set to self by default | Next-hop preserved (requires IGP reachability) |
| Route propagation | Freely propagated to any peer | Not re-advertised between iBGP peers (split-horizon) |
| TTL default | 1 (direct link) | 255 |
iBGP split-horizon means routes learned from one iBGP peer are not forwarded to another iBGP peer. This requires either a full-mesh of iBGP sessions or a route reflector design.
Prerequisites
Section titled “Prerequisites”- RouterOS 7.x with the
routingpackage installed (included by default on most images; check/system/package/print) - Each BGP router requires a unique router-id (typically a loopback address)
- eBGP peers must be directly reachable at the configured
remote.address(or multihop configured for indirect peers) - For iBGP, all routers need IGP reachability to peer loopback addresses
RouterOS 7 BGP Architecture
Section titled “RouterOS 7 BGP Architecture”RouterOS 7 BGP uses three objects:
| Object | Menu | Purpose |
|---|---|---|
| Template | /routing/bgp/template | Protocol defaults: AS number, router-id, timers, filters, redistribution |
| Connection | /routing/bgp/connection | Per-peer transport: remote address, role, template binding |
| Session | /routing/bgp/session | Runtime state (read-only): established prefixes, uptime, state |
A template defines shared behavior. A connection references a template and adds the peer-specific transport details. Multiple connections can share one template.
# View runtime session state/routing bgp session print/routing bgp session print detaileBGP Configuration
Section titled “eBGP Configuration”Basic eBGP Peer
Section titled “Basic eBGP Peer”# Step 1: Create a template with your AS number and router-id/routing bgp templateadd name=default as=65001 router-id=192.0.2.1
# Step 2: Create a connection for the eBGP peer/routing bgp connectionadd name=to-isp \ remote.address=203.0.113.1 \ remote.as=64500 \ local.role=ebgp \ templates=defaultlocal.role=ebgp is required for eBGP connections. RouterOS uses the role to apply correct AS_PATH and next-hop rules.
Outbound Route Advertisement
Section titled “Outbound Route Advertisement”Routes are not advertised automatically. Enable redistribution on the template and attach an output filter chain:
# Enable redistribution of connected and static routes/routing bgp templateset default output.redistribute=connected,static
# Output filter: advertise only your assigned prefix/routing filter ruleadd chain=bgp-out rule="if (dst == 198.51.100.0/24) { accept }"add chain=bgp-out rule="reject"
# Attach filter to the connection/routing bgp connectionset to-isp output.filter-chain=bgp-outThe filter chain is evaluated top-to-bottom. Routes not matched by any accept rule are rejected. The final explicit reject rule documents intent but is redundant since unmatched routes are rejected by default.
Inbound Route Filtering
Section titled “Inbound Route Filtering”Always filter inbound routes to prevent route leaks:
# Accept only default route and reject everything else/routing filter ruleadd chain=bgp-in rule="if (dst == 0.0.0.0/0) { accept }"add chain=bgp-in rule="reject"
/routing bgp connectionset to-isp input.filter-chain=bgp-inAuthentication
Section titled “Authentication”Use TCP MD5 to authenticate BGP sessions:
/routing bgp connectionset to-isp tcp-md5-key="secretpassword"Both sides must configure the same key.
Multihop eBGP
Section titled “Multihop eBGP”When the eBGP peer is not directly connected (e.g., peering over a loopback or through intermediate hops), increase the TTL:
/routing bgp connectionset to-isp multihop=yesEnsure the remote peer address is reachable via a static route or IGP.
Passive Mode
Section titled “Passive Mode”A passive connection does not initiate the TCP session — it only accepts incoming connections:
/routing bgp connectionset to-isp passive=yesUse passive mode when the remote peer always initiates, or to prevent TCP collisions on simultaneous open.
iBGP Configuration
Section titled “iBGP Configuration”Full Mesh
Section titled “Full Mesh”iBGP requires that every router receive all BGP routes. The simplest design is a full mesh: every iBGP router sessions to every other. With n routers this creates n(n-1)/2 sessions — practical only for small networks (3–5 routers).
# On router R1 (AS 65000, router-id 10.255.0.1)/routing bgp templateadd name=ibgp-default as=65000 router-id=10.255.0.1
/routing bgp connectionadd name=to-r2 remote.address=10.255.0.2 remote.as=65000 \ local.role=ibgp templates=ibgp-defaultadd name=to-r3 remote.address=10.255.0.3 remote.as=65000 \ local.role=ibgp templates=ibgp-defaultThe same AS number is used for all iBGP connections. Peers use loopback addresses for session stability (the session survives as long as the loopback is reachable via IGP, regardless of which physical link is used).
next-hop-self for iBGP
Section titled “next-hop-self for iBGP”When eBGP-learned routes are propagated to iBGP peers, the next-hop is the external peer address. If iBGP clients do not have a route to the external next-hop, force the router to set itself as next-hop:
/routing bgp connectionset to-r2 nexthop-choice=force-selfset to-r3 nexthop-choice=force-selfAlternatively, redistribute the external next-hop addresses via IGP so all iBGP routers can resolve them without next-hop rewriting.
Route Reflectors
Section titled “Route Reflectors”Route reflectors (RR) eliminate the full-mesh requirement. A route reflector re-advertises iBGP-learned routes to its clients. Clients only need to session with the RR, not with each other.
[R1] ─── [RR] ─── [R2] │ [R3]RR and clients are in the same AS. The RR sessions with all clients; clients session only with the RR.
# On the Route Reflector (RR)/routing bgp templateadd name=rr-template as=65000 router-id=10.255.0.254
# Session to each client: local.role=ibgp-rr/routing bgp connectionadd name=to-client1 remote.address=10.255.0.1 remote.as=65000 \ local.role=ibgp-rr templates=rr-templateadd name=to-client2 remote.address=10.255.0.2 remote.as=65000 \ local.role=ibgp-rr templates=rr-templateadd name=to-client3 remote.address=10.255.0.3 remote.as=65000 \ local.role=ibgp-rr templates=rr-template# On each RR Client/routing bgp templateadd name=client-template as=65000 router-id=10.255.0.1
# Session only to the RR: local.role=ibgp-rr-client/routing bgp connectionadd name=to-rr remote.address=10.255.0.254 remote.as=65000 \ local.role=ibgp-rr-client templates=client-templateThe RR automatically adds ORIGINATOR_ID and CLUSTER_LIST attributes to reflected routes to prevent loops.
Route Reflector Redundancy
Section titled “Route Reflector Redundancy”Deploy two RRs per cluster for redundancy. Both RRs should use the same cluster-id so clients see them as equivalent:
# On both RR1 and RR2/routing bgp templateset rr-template cluster-id=10.255.0.0Clients session with both RRs. Each RR reflects independently; clients install routes from whichever RR provides the best path.
Route Advertisement
Section titled “Route Advertisement”Redistribute Connected and Static Routes
Section titled “Redistribute Connected and Static Routes”/routing bgp templateset default output.redistribute=connected,staticSupported output.redistribute values: connected, static, rip, ospf, ospf-ext1, ospf-ext2, bgp.
Always combine redistribution with an output filter chain to prevent advertising unwanted prefixes.
Selective Advertisement with Output Filters
Section titled “Selective Advertisement with Output Filters”# Advertise only specific prefixes/routing filter ruleadd chain=bgp-out rule="if (dst == 192.0.2.0/24) { accept }"add chain=bgp-out rule="if (dst == 192.0.2.128/25) { accept }"add chain=bgp-out rule="reject"
/routing bgp connectionset to-isp output.filter-chain=bgp-outPrefix-Range Filtering
Section titled “Prefix-Range Filtering”To accept a block of prefixes with a length constraint (e.g., customer /24s within a /22):
/routing filter rule# Accept /24s within 203.0.113.0/22, reject more-specifics and summariesadd chain=bgp-out rule="if (dst in 203.0.113.0/22 && dst-len == 24) { accept }"add chain=bgp-out rule="reject"Inbound Filtering with AS-Path
Section titled “Inbound Filtering with AS-Path”Reject routes from specific ASes or with specific AS_PATH patterns:
/routing filter rule# Reject anything with AS 64496 in the path (customer route leak prevention)add chain=bgp-in rule="if (bgp-as-path .= \".*64496.*\") { reject }"# Accept all other routesadd chain=bgp-in rule="accept"Influencing Path Selection
Section titled “Influencing Path Selection”Best Path Order
Section titled “Best Path Order”RouterOS 7 selects the best BGP path in this order (first difference wins):
| Step | Criterion | Prefer |
|---|---|---|
| 1 | Local Preference (bgp-local-pref) | Higher |
| 2 | AS-PATH length | Shorter |
| 3 | Origin code | IGP > EGP > Incomplete |
| 4 | MED | Lower |
| 5 | eBGP over iBGP | eBGP |
| 6 | IGP distance to next-hop | Lower |
| 7 | Router-ID of advertising peer | Lower |
| 8 | Cluster-list length | Shorter |
| 9 | Peer IP address | Lower |
RouterOS does not implement Cisco-style per-neighbor weight. Use local-pref or per-connection filters instead.
Local Preference
Section titled “Local Preference”Local Preference influences path selection within your AS. Higher is preferred. Set it on inbound eBGP routes:
# Prefer ISP-A (local-pref 200) over ISP-B (local-pref 100)/routing filter ruleadd chain=bgp-in-isp-a rule="accept; set bgp-local-pref 200"add chain=bgp-in-isp-b rule="accept; set bgp-local-pref 100"
/routing bgp connectionset to-isp-a input.filter-chain=bgp-in-isp-aset to-isp-b input.filter-chain=bgp-in-isp-bLocal Preference is propagated to all iBGP peers. It is not sent to eBGP neighbors.
MED (Multi-Exit Discriminator)
Section titled “MED (Multi-Exit Discriminator)”MED influences how external peers choose between your entry points. Lower MED is preferred. Set it on outbound announcements:
# Prefer traffic entering via this router for 198.51.100.0/24/routing filter ruleadd chain=bgp-out rule="if (dst == 198.51.100.0/24) { set bgp-med 10; accept }"add chain=bgp-out rule="reject"MED is only compared between routes from the same neighboring AS unless the peer’s BGP implementation is configured otherwise.
AS-Path Prepending
Section titled “AS-Path Prepending”Prepend your AS number multiple times on outbound announcements to make a path appear longer and therefore less preferred by external networks:
# Make traffic prefer the other link for 198.51.100.0/24/routing filter ruleadd chain=bgp-out-secondary rule="if (dst == 198.51.100.0/24) { \ set bgp-path-prepend 3; accept }"add chain=bgp-out-secondary rule="reject"
/routing bgp connectionset to-isp-secondary output.filter-chain=bgp-out-secondaryset bgp-path-prepend 3 prepends your AS three times.
BGP Communities
Section titled “BGP Communities”Communities are tags attached to routes. Use them to implement policy signaling between peers:
# Tag outbound routes with a standard community/routing filter ruleadd chain=bgp-out rule="if (dst == 198.51.100.0/24) { \ append bgp-communities 65000:100; accept }"
# Match incoming community and set local-pref/routing filter ruleadd chain=bgp-in rule="if (bgp-communities includes 65010:200) { \ set bgp-local-pref 250; accept }"add chain=bgp-in rule="accept"RouterOS 7 supports standard communities (65000:100), extended communities, and large communities (65000:1:100).
Full Example: Dual-Homed Router with iBGP
Section titled “Full Example: Dual-Homed Router with iBGP”This example shows a router with two eBGP upstreams and iBGP to a peer router, applying preference policy and advertising an aggregate prefix.
ISP-A (AS64500) ISP-B (AS64501) 203.0.113.1 203.0.113.5 │ │ ether1 .2 ether2 .6 ┌─────────────────────────┐ │ edge-router │ │ router-id 10.255.0.1 │ │ AS 65000 │ └──────────┬──────────────┘ ether3 10.255.0.1 │ (iBGP to core) [core-router 10.255.0.2]# Template/routing bgp templateadd name=edge as=65000 router-id=10.255.0.1 \ output.redistribute=connected,static
# eBGP connections/routing bgp connectionadd name=to-isp-a remote.address=203.0.113.1 remote.as=64500 \ local.role=ebgp templates=edge \ input.filter-chain=bgp-in-isp-a output.filter-chain=bgp-out
add name=to-isp-b remote.address=203.0.113.5 remote.as=64501 \ local.role=ebgp templates=edge \ input.filter-chain=bgp-in-isp-b output.filter-chain=bgp-out
# iBGP to core router (next-hop-self so core can resolve external next-hops)/routing bgp connectionadd name=to-core remote.address=10.255.0.2 remote.as=65000 \ local.role=ibgp templates=edge \ nexthop-choice=force-self
# Outbound: advertise only our /24 aggregate/routing filter ruleadd chain=bgp-out rule="if (dst == 198.51.100.0/24) { accept }"add chain=bgp-out rule="reject"
# Inbound from ISP-A: prefer (local-pref 200)/routing filter ruleadd chain=bgp-in-isp-a rule="if (dst == 0.0.0.0/0) { set bgp-local-pref 200; accept }"add chain=bgp-in-isp-a rule="reject"
# Inbound from ISP-B: fallback (local-pref 100)/routing filter ruleadd chain=bgp-in-isp-b rule="if (dst == 0.0.0.0/0) { set bgp-local-pref 100; accept }"add chain=bgp-in-isp-b rule="reject"Troubleshooting
Section titled “Troubleshooting”Checking Session State
Section titled “Checking Session State”# View all BGP sessions and their current state/routing bgp session print
# Detail view: shows uptime, prefixes received/advertised, hold-time/routing bgp session print detailBGP session states progress through: Idle → Connect → Active → OpenSent → OpenConfirm → Established
| State | Meaning |
|---|---|
Idle | BGP is not attempting to connect (disabled or waiting) |
Connect | TCP connection attempt in progress |
Active | TCP failed; retrying. Usually: wrong peer address, firewall blocking TCP/179, or peer not listening |
OpenSent | TCP established, BGP OPEN sent, waiting for peer OPEN |
OpenConfirm | OPEN received, exchanging KEEPALIVEs |
Established | Session up and routes exchanged |
Session Stuck in Active
Section titled “Session Stuck in Active”A session stuck in Active indicates TCP is not completing. Check:
# Verify the peer address and AS number are correct/routing bgp connection print detail
# Confirm TCP/179 is not blocked/ip firewall filter print where dst-port=179 or src-port=179
# Test reachability to peer/tool/ping 203.0.113.1For multihop eBGP, verify a route exists to the peer address and multihop=yes is set.
Viewing Advertised and Received Prefixes
Section titled “Viewing Advertised and Received Prefixes”# Show routes received from a specific peer/routing bgp advertisements print where session=to-isp
# Show all BGP routes in the routing table/ip route print where bgp~"."
# Show BGP routes not installed (e.g. suboptimal or filtered)/routing bgp session print detailCheck the prefix-count fields in session detail — output-prefixes shows advertised, input-prefixes shows received.
Route Learned but Not Installed
Section titled “Route Learned but Not Installed”A BGP route may be received but not installed in the routing table when:
- A better route exists — check if a static or connected route covers the same prefix with a lower distance
- Output filter rejected it — verify the filter chain with
/routing filter rule print where chain=<name> - BGP distance is too high — BGP administrative distance is 20 (eBGP) or 200 (iBGP) by default
- next-hop unresolvable — the next-hop IP is not reachable; check IGP or add a static route
# Check if a prefix is present in BGP table/routing bgp advertisements print where session=to-isp prefix~"198.51.100"
# Check the routing table for the prefix/ip route print where dst-address~"198.51.100"No Routes Advertised
Section titled “No Routes Advertised”If output-prefixes is 0 after establishing a session:
- Verify
output.redistributeis set on the template - Check the output filter chain is attached and passes the intended routes
- Confirm the routes exist in the routing table (
/ip route print) - Temporarily remove the output filter to confirm redistribution is working:
/routing bgp connection set to-isp output.filter-chain=""# Check output-prefixes in session detail/routing bgp session print detail# Re-attach filter after testing/routing bgp connection set to-isp output.filter-chain=bgp-outSee Also
Section titled “See Also”- OSPF Configuration — Redistributing OSPF routes into BGP and vice versa
- OSPF — OSPF fundamentals for building the IGP underlay required by iBGP
- Route Filters — Complete routing filter rule syntax, matchers, and actions
- WireGuard VPN — Running BGP over VPN tunnels for site interconnects