BGP Route Reflector cluster-id: Configuration Guide - 夜莺博客

BGP Route Reflector cluster-id: Configuration Guide

Inside an autonomous system, iBGP's split-horizon rule forbids a router from re-advertising routes learned from one iBGP peer to another iBGP peer. That rule prevents routing loops but forces a full mesh of N(N-1)/2 sessions as the AS grows. BGP route reflectors (RRs) break the full-mesh requirement: clients peer only with the reflector, which reflects routes between them. The catch is loop prevention - and that is exactly what the cluster and cluster-id mechanism handles. This guide explains route reflector roles, why two redundant reflectors in the same cluster must share one cluster-id, and how ORIGINATOR_ID plus CLUSTER_LIST stop reflected routes from looping.

The numbers make the case for reflectors on their own. Ten routers in a full mesh need 45 iBGP sessions; fifty need 1225; a hundred need 4950. Every one of those sessions is configuration, memory and a potential flap. With a pair of route reflectors, the same hundred routers need 200 client sessions plus one reflector-to-reflector session - and the topology stops growing quadratically.

Route Reflector Roles: Client, Non-Client, Cluster

A route reflector re-advertises iBGP routes between its clients and to non-client iBGP peers. The rules:

  • Routes from a client are reflected to other clients and to non-clients.
  • Routes from a non-client are reflected to clients only.
  • A client does not need any special configuration - the RR marks the relationship unilaterally.

A cluster is a group of RRs and their clients that behaves as one logical reflector. An AS can contain many clusters, and multiple RRs inside one cluster exist for redundancy. The reflector-to-reflector sessions are ordinary iBGP sessions between non-clients, which is why they must not be configured with route-reflector-client on either side.

Two additional rules matter in practice. First, a route that a reflector receives from a client is reflected to all other clients and to all non-clients; a route received from a non-client is reflected only to clients, never back into the non-client set. Second, the client does not have to be a direct neighbour in the topology - it only has to be an iBGP peer of the reflector - so a single RR can serve clients many hops away as long as IP reachability exists.

Configuring a Route Reflector on Cisco IOS

On the reflector, define each client with the route-reflector-client neighbor command under the address family:

router bgp 65001
 bgp router-id 10.255.0.1
 neighbor 10.0.0.1 remote-as 65001
 neighbor 10.0.0.1 update-source Loopback0
 neighbor 10.0.0.2 remote-as 65001
 neighbor 10.0.0.2 update-source Loopback0
 address-family ipv4 unicast
  neighbor 10.0.0.1 route-reflector-client
  neighbor 10.0.0.2 route-reflector-client
 exit-address-family

The same command applies per address family, so an RR serving both IPv4 unicast and EVPN needs it under each:

router bgp 65001
 bgp router-id 10.255.0.1
 neighbor 10.0.0.1 remote-as 65001
 neighbor 10.0.0.1 update-source Loopback0
 address-family ipv4 unicast
  neighbor 10.0.0.1 route-reflector-client
 address-family l2vpn evpn
  neighbor 10.0.0.1 route-reflector-client
  neighbor 10.0.0.1 send-community extended
 exit-address-family

On the client side there is nothing to configure for reflector purposes - the client is simply a normal iBGP neighbour of both reflectors. What the client does need is reachability to the reflector loopback, which normally means the loopback is redistributed or advertised by the IGP.

Why Redundant RRs Need the Same cluster-id

By default the cluster-id equals the RR's router-id. If you deploy two reflectors for redundancy and leave that default, each reflector forms its own cluster and the reflected routes look as if they come from separate clusters - which can cause loops during transient states. Set the same explicit cluster-id on both reflectors of a redundant pair so they act as one logical cluster:

! Configure on both RR1 and RR2 in the same cluster
router bgp 65001
 bgp cluster-id 1.1.1.1

Loop prevention then works through the CLUSTER_LIST attribute: a reflector that receives a route whose CLUSTER_LIST already contains its own cluster-id discards the route. ORIGINATOR_ID carries the identity of the original advertiser, so the route never bounces between reflectors.

The failure mode without a shared cluster-id is subtle and worth spelling out. With two reflectors in different clusters, RR1 receives a route from a client, reflects it to RR2 with CLUSTER_LIST containing the cluster-id of RR1. RR2 - in its own cluster - reflects it back to RR1 with its own cluster-id prepended. RR1 sees its own cluster-id is absent from CLUSTER_LIST (because RR2 stripped nothing and the list now holds RR2's id followed by RR1's id), and it reflects again. In a stable network the ORIGINATOR_ID check usually terminates the loop at the originating client, but during a transient state - one reflector losing its client session while the other still has it - you can get a reflected route that survives longer than it should and produces a routing loop for the duration.

cluster-id Formats and Defaults

The command accepts either a 32-bit AS number or a dotted-quad IPv4 address:

router bgp 65001
 ! Dotted-quad form - readable, and the usual choice
 bgp cluster-id 1.1.1.1
 !
 ! 32-bit integer form - equivalent to the above
 bgp cluster-id 16843009

Both encode the same 32-bit value. Most engineers use the dotted-quad form with a value that is obviously not a router-id in the AS (for example 1.1.1.1 or 0.0.0.1) so that it can never be confused with a real device. Read the effective value back with:

show bgp ipv4 unicast summary
show ip bgp
! The cluster-id appears in the extended attributes of reflected routes

If you leave it unset, the cluster-id is the RR's BGP router-id. That default is why the shared-cluster-id requirement is so easy to miss: the configuration looks identical between a correct deployment and a broken one, because the "correct" version looks like an unnecessary extra line.

CLUSTER_LIST and ORIGINATOR_ID: A Packet Walk

Say client R3 (router-id 3.3.3.3) originates the prefix 192.0.2.0/24 and peers with RR1 and RR2, both in cluster 1.1.1.1.

  1. R3 sends the UPDATE to RR1 and RR2. At this point the route has no ORIGINATOR_ID and no CLUSTER_LIST - the client is not a reflector.
  2. RR1 receives the route from a client. Before reflecting, it adds ORIGINATOR_ID 3.3.3.3 (the router-id of the client that injected it) and CLUSTER_LIST 1.1.1.1 (its own cluster-id).
  3. RR1 reflects the route to every other client and to all non-clients, including RR2.
  4. RR2 receives the route from a non-client. It is not the originator (its router-id is not 3.3.3.3) and its cluster-id 1.1.1.1 is not in CLUSTER_LIST, so it reflects the route to its clients. When reflecting a route received from a non-client to a client, RR2 does not prepend its cluster-id - the attribute already records that this cluster has seen the route.
  5. If RR2 sends the route back to RR1, RR1 checks CLUSTER_LIST, finds 1.1.1.1, and discards it. The loop is broken.
  6. Any other router that receives the route with ORIGINATOR_ID 3.3.3.3 equal to its own router-id drops it, which prevents a route from being reflected back to its originator.

Those two attributes are the complete loop-prevention mechanism, and both are invisible in normal operation. The practical consequence: if you ever disable or filter them - for example with an outbound route-map that strips attributes - you break loop prevention and will not find out until a transient failure produces a forwarding loop.

Common Mistakes

  • Deploying redundant RRs without an explicit shared cluster-id.
  • Making one RR a client of another RR - reflectors should peer with each other as regular non-client iBGP.
  • Adding a new iBGP router but forgetting to configure it as a client on the RR.
  • Forgetting that clients still need a full mesh among themselves only if they are non-clients.
  • Configuring route-reflector-client under only one address family, so EVPN or IPv6 routes silently fail to reflect.
  • Filtering inbound routes with an ACL that also blocks the ORIGINATOR_ID or CLUSTER_LIST attributes, or using a BGP policy that rewrites them.
  • Deploying a third reflector in the same cluster with a different cluster-id, which reintroduces the multi-cluster loop risk.
  • Pointing a client at only one RR, so a reflector reload takes the client's routes with it.

Verifying Route Reflection

router# show ip bgp summary
router# show ip bgp neighbors 10.0.0.1
router# show bgp ipv4 unicast 172.16.0.0/24

The interesting output is in the path attributes. A route that arrived through reflection shows both ORIGINATOR_ID and CLUSTER_LIST; compare the view on a client against the view on a non-client to prove the reflection is happening as designed:

! On a client - the prefix should be present with ORIGINATOR_ID set
router# show bgp ipv4 unicast 172.16.0.0/24

BGP routing table entry for 172.16.0.0/24, version 42
Paths: (1 available, best #1, table default)
  Advertised to update-groups:
     3
  Refresh Epoch 1
  Local
    10.0.0.1 from 10.0.0.1 (10.255.0.1)
      Origin IGP, metric 0, localpref 100, valid, internal, best
      Originator: 3.3.3.3, Cluster list: 1.1.1.1

! Confirm the RR is reflecting to all expected clients
router# show bgp ipv4 unicast neighbors 10.0.0.1 advertised-routes
router# show bgp ipv4 unicast neighbors 10.0.0.2 advertised-routes

! Check that the shared cluster-id is actually in effect
router# show run | section router bgp
router# show bgp ipv4 unicast summary | include cluster

A quick sanity check on the whole design: count what each client should receive and compare it against what it does receive. If a client is missing prefixes that other clients have, the usual cause is that one of its peers on the reflector was never marked as a client, or that route-reflector-client was applied under the wrong address family.

Scale, Redundancy and Design Patterns

Route reflector design has settled into a small number of proven patterns.

  • Two RRs per cluster, shared cluster-id, every client peering with both. This is the default and correct pattern for nearly every enterprise AS. It gives resilience to a single reflector failure with no reconvergence penalty.
  • Multiple clusters for geographic or administrative separation. Each cluster needs its own cluster-id; the reflectors of different clusters peer with each other as non-clients. Use this when propagation scope or policy differs by region.
  • Hierarchical reflectors - a top layer of RRs peering with a lower layer of RRs to reduce session count further. Two tiers is a common practical limit; more tiers add latency and complexity for little gain.
  • Reflectors inside a single vendor/role boundary. Do not mix route-reflector clients with a completely different policy set unless you intend the policy to be reflected too - an RR reflects what it receives, and a badly filtered client can inject routes everywhere.

Place the reflectors on the routing-relevant devices wherever possible - core routers, border routers, or the spine layer of a data centre fabric - so that the reflected path stays close to the shortest IGP path. A reflector that is logically central but physically remote adds latency to every converged route and can become an unintended traffic magnet if next-hop-self is misconfigured.

A checklist before going live:

  1. The same explicit cluster-id on every RR in the cluster, and different ids across clusters.
  2. ORIGINATOR_ID and CLUSTER_LIST never stripped by inbound or outbound policy.
  3. Every client configured as a client on every one of its reflectors, in every address family it uses.
  4. Reflectors peering with each other as non-clients, with no client marking on those sessions.
  5. Loopback-based peering and IGP reachability to every reflector loopback.
  6. Inbound filters on client sessions that only permit the prefixes the client is supposed to originate.
  7. A documented count of expected prefixes per client, checked after every change.

FAQ

Can a route reflector be its own client? No. The reflector must peer with other reflectors as non-client iBGP neighbours; marking a reflector-to-reflector session as a client-to-client relationship breaks the intended propagation rules and can create loops.

Do clients need to peer with each other? No. The whole point of reflection is that clients peer only with the reflectors. If clients still peer with each other they are behaving as non-clients and you have neither simplified the topology nor removed the session count.

Why does my reflected route show no CLUSTER_LIST? Because the route was learned from a client, not reflected. A route injected locally or learned from an eBGP peer that is then advertised into the cluster carries no cluster attributes until a reflector reflects it.

How many clusters should an AS have? As few as possible. One cluster with a redundant pair of reflectors handles most enterprise ASes; add clusters only for regional policy or scale reasons, and remember that more clusters mean more inter-cluster sessions to manage.

Does the cluster-id have to be unique inside the AS? Yes. Two different clusters must not share a cluster-id, or a reflector in one cluster will discard legitimate routes from the other as a loop.

What happens if I change the cluster-id on a live pair? Expect a brief reconvergence as peers re-evaluate reflected routes. Change both reflectors in the same maintenance window, starting with the standby.

Deepen your BGP knowledge with our BGP route flap damping explained, prefix-list and route-map BGP filtering, and BGP communities configuration examples. For troubleshooting the sessions themselves, see BGP session stuck in Idle or Active, BGP best-external and Add-Path advertisement, and Junos traceoptions for BGP troubleshooting.

原文链接:https://packetmentor.com/topics/bgp-route-reflectors