You just finished reading about the iBGP full mesh problem. You understand the math. You know why full mesh doesn’t scale.
Route reflectors are the solution most networks actually use. They’re not complicated once you understand what problem they’re solving and how the loop prevention works. But implement them without understanding those two things and you’ll spend a long afternoon staring at routes that should be there and aren’t.
The Core Idea

The iBGP split horizon rule says a route learned from an iBGP peer cannot be re-advertised to another iBGP peer. Route reflectors break that rule. They do it with loop prevention built in, but they break it.
A route reflector (RR) is an iBGP router that can re-advertise routes from iBGP clients to other iBGP clients. The clients are just regular routers that peer with the route reflector instead of with each other.
In a route reflector topology:
All non-RR routers (clients) peer only with the route reflector.
The route reflector peers with all clients.
The route reflector re-advertises routes between clients, which normally the split horizon rule would prevent. Instead of n(n-1)/2 sessions for a full mesh, each client just needs one session to the RR. A 50-router network goes from 1,225 sessions to 50.
The Loop Prevention Problem
The split horizon rule exists for good reason. Without it, iBGP creates routing loops. Route reflectors bypass the split horizon rule, so they need their own loop prevention mechanism.
That mechanism is the CLUSTER_LIST attribute.
When a route reflector reflects a route to its clients, it adds its cluster ID to the CLUSTER_LIST attribute in the update. The cluster ID is typically the router-id of the route reflector, though you can configure it explicitly.
When a router receives a BGP update, it checks the CLUSTER_LIST. If its own cluster ID appears in that list, it means the route has already passed through its RR cluster. It discards the update. Loop prevented.
There’s also the ORIGINATOR_ID attribute. When an RR reflects a route, it adds the BGP router-id of the original route source as the ORIGINATOR_ID. If a router receives a route with an ORIGINATOR_ID that matches its own router-id, it discards the update.
Configuration
The configuration change happens on the route reflector. From the RR’s perspective, it adds one command per client neighbor:
router bgp 65001
neighbor 10.0.0.1 remote-as 65001
neighbor 10.0.0.2 remote-as 65001
neighbor 10.0.0.3 remote-as 65001
!
address-family ipv4 unicast
neighbor 10.0.0.1 activate
neighbor 10.0.0.1 route-reflector-client
neighbor 10.0.0.2 activate
neighbor 10.0.0.2 route-reflector-client
neighbor 10.0.0.3 activate
neighbor 10.0.0.3 route-reflector-client
exit-address-family
That’s it on the RR side. The clients don’t need any special configuration. They just run standard iBGP sessions pointing to the RR. They have no idea they’re clients. The RR handles everything.
If you have multiple route reflectors for redundancy, configure each client with sessions to both RRs. The clients get routes from both RRs and pick the best path normally.
Cluster IDs for Redundant Route Reflectors
When you have two route reflectors for the same set of clients, both RRs are part of the same cluster. Configure both with the same cluster ID so their loop prevention works correctly:
router bgp 65001
bgp cluster-id 1.1.1.1
Use the same cluster ID on both RRs. Without this, they each have different cluster IDs, and the CLUSTER_LIST loop prevention can cause one RR to reject routes that the other RR reflected, resulting in missing routes in certain failure scenarios.
Route Reflector Placement Matters
This is where route reflector designs go wrong. Route reflectors need to sit in the path of traffic logically, not just topologically.
A route reflector placed at the edge of a topology will reflect routes accurately, but the next-hop for those reflected routes still points to the original external peers. This is why you still have to set next-hop-self on all of the peers on the route-reflector. If the internal routers have to cross the route reflector to reach the next-hop, you might get asymmetric or suboptimal routing.
Put route reflectors in the core of your topology. In a spine-leaf fabric, the spines are the natural route reflectors. In a traditional WAN topology, the hub routers are the natural choice. Anywhere the RR is logically central to the network is a better choice than anywhere it’s at the edge.
Two route reflectors is the minimum for redundancy. Some large designs run four. Putting them in geographically separate locations is good practice if your network spans multiple sites.
Non-Client iBGP Peers
Route reflectors can also have non-client iBGP peers. These are iBGP sessions to other routers in the AS that are not route reflector clients.
The typical use case is route reflector to route reflector peering. If you have multiple RR clusters in your AS, the RRs peer with each other as non-client iBGP peers. They don’t reflect routes to each other, but they do share routing information across clusters.
Routes reflected to clients follow the normal RR loop prevention rules. Routes exchanged between non-client peers follow standard iBGP split horizon.This is why you need to configure a full mesh between the RRs themselves. Standard iBGP split horizon still applies between non-client peers.
Verification
There are several ways to check which neighbors are configured as route reflector clients:
R4#show bgp ipv4 unicast neighbors 3.3.3.3 policy
Neighbor: 3.3.3.3, Address-Family: IPv4 Unicast
Locally configured policies:
route-reflector-client
----
R4#show run | inc route-reflector-client
neighbor 1.1.1.1 route-reflector-client
neighbor 2.2.2.2 route-reflector-client
neighbor 3.3.3.3 route-reflector-client
Verify that routes are being reflected by checking the CLUSTER_LIST attribute:
show bgp ipv4 unicast 10.3.0.0/24
BGP routing table entry for 10.3.0.0/24, version 7
Paths: (1 available, best #1, table default)
Flag: 0x100
Not advertised to any peer
Refresh Epoch 1
Local
3.3.3.3 (metric 11) from 4.4.4.4 (4.4.4.4)
Origin incomplete, localpref 100, valid, internal, best
Originator: 3.3.3.3, Cluster list: 44.44.44.44
rx pathid: 0, tx pathid: 0x0
Updated on Jul 13 2026 20:50:20 UTC
If the route has been reflected, you’ll see the Cluster list: field populated with the cluster ID of the route reflector that reflected it.
On the client side, verify it’s receiving routes from the RR and that the ORIGINATOR_ID points to the originating router, not the RR:
show bgp ipv4 unicast 10.3.0.0/24
BGP routing table entry for 10.3.0.0/24, version 7
Paths: (1 available, best #1, table default)
Flag: 0x100
Not advertised to any peer
Refresh Epoch 1
Local
3.3.3.3 (metric 11) from 4.4.4.4 (4.4.4.4)
Origin incomplete, localpref 100, valid, internal, best
Originator: 3.3.3.3, Cluster list: 44.44.44.44
rx pathid: 0, tx pathid: 0x0
Updated on Jul 13 2026 20:50:20 UTC
The Originator: field should show the router-id of the router that originally advertised the route, not the RR.
The Design Mistake to Avoid
The most common route reflector design mistake is creating a topology where a client peers with only one RR and that RR has a suboptimal position in the network. When the client needs to reach a destination that came from a different cluster, the traffic path goes through the RR unnecessarily.
Design your RR topology so that the RRs see the full picture. Position them centrally enough that reflected routes don’t create hairpin traffic paths. Test this in a lab before deploying in production.