BGP Deep Dive Part 6: Route Reflectors and Confederations, Two Ways to Break the Full Mesh

Part 5 ended on a hard requirement: every iBGP speaker needs a direct session to every other iBGP speaker in the AS, because the rule that prevents internal loops is a blanket ban on re-advertising an iBGP-learned route to another iBGP peer. A full mesh satisfies that rule by construction, everyone hears everything directly, but it requires n(n-1)/2 sessions among n routers, growing as O(n²), and it stops being practical well before a network gets genuinely large. Two mechanisms exist to relax the rule in a controlled way rather than remove it. This post covers both.

Route reflection: an exception carved into the rule itself

RFC 4456 solves the problem by introducing two new roles: route reflector and client. A route reflector is an ordinary iBGP speaker with one added permission: it’s allowed to re-advertise a route learned from one of its clients to its other clients, and to its non-client iBGP peers, something the plain split-horizon rule from Part 5 would otherwise forbid. Clients, in turn, only need a session to the route reflector, not to every other iBGP speaker in the AS. The full mesh collapses into a hub-and-spoke topology at each reflector, and reflectors themselves still need a mesh, or their own reflection hierarchy, among each other.

The exact reflection rules matter: a route learned from a client is reflected to all other clients and to non-client peers. A route learned from a non-client peer is reflected to clients only, not to other non-clients, which is the split-horizon rule from Part 5 still holding at that boundary. Route reflection isn’t a suspension of the no-iBGP-to-iBGP rule, it’s a narrowly scoped exception granted specifically to the reflector-to-client relationship.

That exception needs its own loop prevention, since the original AS_PATH mechanism still doesn’t apply inside an AS. RFC 4456 adds two new attributes, both optional non-transitive, both deferred from Part 3’s catalog specifically because they only exist for this purpose:

  • ORIGINATOR_ID (attribute type code 9): a 4-octet field carrying the BGP Identifier of the router that originally introduced the route into the AS. A reflector creates it the first time a route gets reflected, and any speaker that sees its own BGP Identifier as the ORIGINATOR_ID on an incoming route discards it, that’s the router the route actually came from, being handed back to itself.
  • CLUSTER_LIST (attribute type code 10): an ordered sequence of CLUSTER_ID values, one appended by every reflector a route passes through. A cluster is a reflector plus its clients, identified by a 4-octet CLUSTER_ID, and a reflector that sees its own cluster ID already present in an incoming CLUSTER_LIST discards the route as a loop.

Multiple reflectors can share the same CLUSTER_ID to act as a redundant pair for the same set of clients, which is also exactly why CLUSTER_LIST checks by cluster rather than by individual router: two reflectors serving the same clients are the same cluster for loop-detection purposes, even though they’re different routers with different BGP Identifiers.

The tradeoff route reflection doesn’t advertise up front: path hiding

Route reflection has one real cost that’s worth naming plainly, since it’s the kind of thing that only shows up once you’re troubleshooting an outcome that looks wrong on paper. A route reflector runs Part 4’s best path algorithm exactly like any other speaker, and it reflects only its own single best path to its clients, not every path it heard. A client whose own best-path calculation might have picked a different path, because it sits at a different point in the network with a different IGP metric to a given NEXT_HOP, never gets the chance: it only ever sees the one path the reflector chose, and has no visibility into the alternatives that got filtered out upstream. This is usually called path hiding, and it’s a direct, structural consequence of collapsing what used to be full visibility, every router hearing every path directly, into a hub that summarizes before passing anything on. It doesn’t make route reflection wrong, the alternative is a full mesh that doesn’t scale, but it’s a real behavioral difference from the pre-reflection topology, not just an implementation detail.

Confederations: splitting the AS itself instead of adding a role

RFC 5065, the current specification (it obsoletes RFC 3065, which itself obsoleted the original RFC 1965), takes a different approach entirely: rather than adding an exception to the full-mesh rule, it splits one large AS into multiple smaller sub-autonomous-systems, each identified by a private AS number, and lets the sub-ASes peer with each other using something that looks like eBGP internally but presents as a single AS to the outside world.

Inside each sub-AS, the normal rules apply in full: a real iBGP full mesh (or its own route reflectors, the two mechanisms aren’t mutually exclusive) is still required among the routers within that sub-AS. What changes is the relationship between sub-ASes. A session between two sub-ASes in the same confederation is a confederation eBGP session: from an AS_PATH perspective it behaves like eBGP, each sub-AS prepends its own number, using a special AS_CONFED_SEQUENCE segment type rather than an ordinary AS_SEQUENCE, so that loop prevention works correctly at the sub-AS level. But unlike genuine eBGP, LOCAL_PREF and other iBGP-only attributes from Part 5 are permitted to cross a confederation eBGP boundary, since the sub-ASes are still, administratively, one AS pretending to be several for the purposes of this one problem.

Before the route ever leaves the confederation to a genuine external peer, every AS_CONFED_SEQUENCE segment is stripped from the AS_PATH. The outside world never learns the confederation has internal structure at all; it just sees the single, real, publicly registered AS number the confederation presents as.

Choosing between them

In practice, route reflection is the far more common choice, and for a straightforward reason: it doesn’t require renumbering anything or introducing an entirely new internal addressing scheme, it’s a role added to existing routers, deployed incrementally, client by client. Confederations ask for more structural commitment: private AS numbers to assign, a real internal AS boundary to design around, and configuration on every sub-AS boundary that’s a step more involved than pointing a client at a reflector. Where confederations earn their complexity is in networks that already have, or want, genuine administrative separation between chunks of what’s nominally one AS, the classic case being two previously separate networks merged after an acquisition, each arriving with its own already-built iBGP mesh that a confederation lets you join without immediately having to unify. Both remain valid RFC-sanctioned answers to the same problem, and both can be, and often are, combined: confederations for the coarse administrative split, route reflection inside each sub-AS for the fine-grained scaling within it.

Part 7 moves to an attribute that has nothing to do with scaling iBGP and everything to do with expressing policy directly: communities, and the well-known values that let one AS signal intent to another without a dedicated attribute for every possible meaning.