BGP Deep Dive Part 10: Multiprotocol BGP, or How One Session Learned to Carry Everything
Every attribute covered so far in this series, from ORIGIN through the communities in Part 7, was defined against one assumption: the thing BGP is advertising is an IPv4 unicast prefix. That assumption was true of BGP-4 as specified in 1994’s RFC 1654 and RFC 1771. It stopped being true in 2007, when RFC 4760 defined Multiprotocol Extensions for BGP-4 and turned BGP from an IPv4-routing protocol into a generic reachability-advertisement transport that happens to carry IPv4 unicast routes as its original, default case.
This part covers what changed, why it changed the way it did, and the two concrete uses of it that show up most in production: IPv6 and MPLS L3VPN. It closes with a shorter look at EVPN, because Part 4 of the Container Networking Deep Dive series already did the VXLAN encapsulation legwork this needs.
The problem RFC 4760 solved
Before RFC 4760, adding a new thing for BGP to route meant either overloading the existing NLRI field (fragile, ambiguous) or defining an entirely new protocol with its own session type, its own FSM, its own peering relationships to manage. Neither is a good answer. Operators already had BGP sessions established, with policy, with authentication, with years of operational trust built into them. The obviously right design was to keep the session and extend what could travel inside it.
RFC 4760’s answer was two new path attributes: MP_REACH_NLRI (type code 14) and MP_UNREACH_NLRI (type code 15). Both are optional non-transitive, per the attribute taxonomy from Part 3 — a router that doesn’t understand them is allowed to ignore them, and it should never propagate them further than it understands. That’s a deliberate compatibility design: a BGP-4 speaker from 1996 and a dual-stack speaker from 2026 can peer with each other. The old speaker sees only the IPv4 unicast NLRI it already understands and silently drops the multiprotocol attributes it doesn’t. Nothing breaks.
MP_REACH_NLRI carries three things: an Address Family Identifier (AFI), a Subsequent Address Family Identifier (SAFI), and the NLRI itself, now decoupled from the fixed IPv4-prefix format the base UPDATE message assumes. AFI 1 is IPv4, AFI 2 is IPv6. SAFI 1 means unicast, SAFI 2 means multicast, SAFI 128 means MPLS-labeled VPN. The AFI/SAFI pair is the thing that tells a receiving router what kind of reachability information it’s looking at and how to parse the NLRI that follows. MP_UNREACH_NLRI does the same job in reverse, withdrawing routes for a given AFI/SAFI rather than announcing them.
Capability negotiation decides what actually gets used
None of this happens automatically just because both routers run code that supports it. Part 2 covered the OPEN message’s Capabilities optional parameter (RFC 5492) as the mechanism 4-byte ASNs get negotiated through. Multiprotocol support uses the exact same mechanism. Each AFI/SAFI combination a router wants to exchange gets advertised as its own capability (code 1) in the OPEN message, and the session only carries that address family if both sides advertise it.
This is why a Cisco IOS-XE router with address-family ipv4 unicast and address-family vpnv4 both configured under the same neighbor statement is running one TCP session, one FSM, one set of KEEPALIVEs, but potentially several independent sets of capability-negotiated NLRI exchange layered on top. The neighbor relationship is singular. What travels over it is not.
IPv6: the simplest case
IPv6 unicast is AFI 2, SAFI 1. Structurally, nothing about best path selection, attribute handling, or the FSM changes. LOCAL_PREF still works the way Part 4 described it. AS_PATH loop prevention is identical. The only genuinely new wrinkle is the NEXT_HOP attribute, which in the base IPv4 case is a single 4-byte address. For IPv6, MP_REACH_NLRI’s next hop field can carry a 16-byte global address, or a 32-byte pair consisting of both a global and a link-local address, since some IPv6 deployments still route on-link decisions off the link-local address even when the route itself carries a global next hop.
Sessions themselves can run over either transport independently of which address families they carry. A BGP session can be established over IPv4 TCP and still carry IPv6 NLRI inside it via MP_REACH_NLRI, which is exactly what happens in most dual-stack deployments that haven’t fully moved their infrastructure addressing to IPv6 yet. The session transport and the routes it carries are two separate decisions.
MPLS L3VPN: AFI 1, SAFI 128, and the Route Distinguisher
This is the multiprotocol use case with the most machinery behind it, and it’s worth understanding because it’s the direct ancestor of every “how do I keep Customer A’s 10.0.0.0/8 separate from Customer B’s 10.0.0.0/8 on the same provider core” problem, which is the same shape of problem VDOMs solve on FortiGate (see the VDOM deep dive) at the box level rather than the provider-core level.
RFC 4364 defines VPNv4, AFI 1 SAFI 128, as a 12-byte address: an 8-byte Route Distinguisher prepended to an ordinary 4-byte IPv4 prefix. The RD’s only job is to make otherwise-colliding customer prefixes globally unique inside the provider’s BGP table. Customer A’s 10.0.0.0/8 tagged with RD 65000:100 and Customer B’s 10.0.0.0/8 tagged with RD 65000:200 are, as far as BGP’s best path algorithm is concerned, two completely different prefixes that happen to share an IPv4 suffix. The RD solves the uniqueness problem and nothing else. It has no role in controlling which PE routers actually receive which routes.
That role belongs to Route Targets, which are BGP extended communities (RFC 4360, covered alongside standard communities in Part 7) attached to each VPNv4 route as an export policy and read by each PE as an import policy. A PE exports a customer’s routes tagged with an export RT, and every other PE configured to import that RT pulls the route into its own VRF for that customer. Simple hub-and-spoke topologies use one RT. Extranets, shared-services VPNs, and anything more complex than strict any-to-any connectivity get built by controlling which RTs each PE imports, entirely independent of the RD uniqueness mechanism sitting underneath it.
The forwarding plane carries two MPLS labels stacked on top of each packet: an outer transport label that gets the packet from ingress PE to egress PE across the provider core (via LDP or RSVP-TE, not BGP), and an inner VPN label, assigned per-route by the egress PE and distributed via the same MP-BGP session, that tells the egress PE which VRF and which outgoing interface the packet belongs to once the transport label has been popped. BGP’s role in all of this is entirely about the control plane: reachability and label distribution. It never touches the actual MPLS forwarding of a single packet.
EVPN, briefly
BGP EVPN (RFC 7432, AFI 25 SAFI 70) applies the same RD/RT machinery from L3VPN to something structurally different: MAC and ARP/ND reachability rather than IP prefix reachability, distributed as a new NLRI type carried inside the same MP_REACH_NLRI attribute this whole part has been describing. Container Networking Part 4 covered VXLAN’s data-plane encapsulation, a MAC-in-UDP tunnel with a flood-and-learn control plane by default. EVPN replaces that flood-and-learn behavior with BGP doing what BGP already does well, advertising reachability, applying import/export policy via route targets, and converging on topology changes without waiting for a flood to teach every VTEP the same thing. It’s the same multiprotocol pattern covered in this part, applied to a spine-leaf data center fabric rather than an MPLS provider core. Genuinely production-grade EVPN-VXLAN design is its own series, not a subsection of this one, but the mechanism connecting it to everything else in this part is the same: a new AFI/SAFI, a new NLRI encoding, carried inside a session and a capability-negotiation model that hasn’t changed since RFC 4760.
What one session can carry at once
Put together, a single modern BGP session between two PE routers might negotiate IPv4 unicast, IPv6 unicast, VPNv4 unicast, and EVPN capabilities simultaneously, each independently negotiated in the OPEN message, each with its own NLRI encoding inside MP_REACH_NLRI, each subject to the same best path algorithm from Part 4 running independently per address family. This is the payoff of the RFC 4760 design: one session, one set of operational trust and authentication and monitoring already built around it, carrying an open-ended set of address families that has grown for over two decades without ever requiring a new base protocol.
The next part turns to what keeps all of this converging reliably and at scale: route flap dampening, BFD, graceful restart, and ADD-PATH.