Border Gateway Protocol (BGP) is the routing protocol that powers the Internet's inter-domain routing system. Announcing IPv6 prefixes via BGP allows your network to be globally reachable over IPv6. This guide provides a comprehensive technical walkthrough of the configuration steps, best practices, and security measures required to successfully announce IPv6 prefixes.
Before you can announce IPv6 prefixes in BGP, you must have the following in place:
You need a Provider Independent (PI) or Provider Aggregatable (PA) IPv6 address block allocated from one of the Regional Internet Registries (RIRs):
Most organizations receive a /32 or /48 allocation. The /48 prefix is the recommended minimum size for global BGP routing announcements.
You must have your own ASN, either:
Your ASN uniquely identifies your network in the global routing system and is required for originating BGP announcements.
Your network requires at least one router or routing platform that supports:
Common platforms include Cisco IOS/IOS-XE/IOS-XR, Juniper Junos, Arista EOS, Nokia SR OS, and open-source solutions like FRRouting (FRR) and BIRD.
Your router must have native IPv6 connectivity to your upstream provider(s) or Internet Exchange Point (IXP) peers. This typically requires:
BGP treats IPv4 and IPv6 as separate address families within the same protocol. Here's how to configure IPv6 BGP announcements on major platforms:
! Configure BGP with your ASN
router bgp 64500
! Configure BGP router ID (uses IPv4 format)
bgp router-id 203.0.113.1
! Enable BGP neighbor using IPv6 address
neighbor 2001:db8:100::1 remote-as 64501
neighbor 2001:db8:100::1 description Upstream-Provider
! Enter IPv6 unicast address family
address-family ipv6 unicast
! Activate the neighbor for IPv6
neighbor 2001:db8:100::1 activate
! Announce your IPv6 prefix
network 2001:db8::/32
! Apply outbound prefix filter (recommended)
neighbor 2001:db8:100::1 prefix-list IPV6-OUT out
! Apply inbound prefix filter
neighbor 2001:db8:100::1 prefix-list IPV6-IN in
exit-address-family
!
! Define prefix list for outbound announcements
ipv6 prefix-list IPV6-OUT seq 5 permit 2001:db8::/32
! Define prefix list for inbound filtering
ipv6 prefix-list IPV6-IN seq 5 deny ::/0
ipv6 prefix-list IPV6-IN seq 10 deny ::/0 ge 49
ipv6 prefix-list IPV6-IN seq 15 permit ::/0 le 48
# Configure BGP group and neighbor
set protocols bgp group upstream-provider type external
set protocols bgp group upstream-provider peer-as 64501
set protocols bgp group upstream-provider neighbor 2001:db8:100::1
# Configure IPv6 unicast family
set protocols bgp group upstream-provider family inet6 unicast
# Announce your IPv6 prefix with route policy
set policy-options policy-statement announce-ipv6 term export-prefix from route-filter 2001:db8::/32 exact
set policy-options policy-statement announce-ipv6 term export-prefix then accept
set policy-options policy-statement announce-ipv6 term reject-all then reject
# Apply export policy
set protocols bgp group upstream-provider export announce-ipv6
# Configure static route to null0 (best practice)
set routing-options rib inet6.0 static route 2001:db8::/32 discard
router bgp 64500
bgp router-id 203.0.113.1
neighbor 2001:db8:100::1 remote-as 64501
neighbor 2001:db8:100::1 description Upstream-Provider
address-family ipv6 unicast
network 2001:db8::/32
neighbor 2001:db8:100::1 activate
neighbor 2001:db8:100::1 prefix-list ipv6-out out
neighbor 2001:db8:100::1 prefix-list ipv6-in in
exit-address-family
!
ipv6 prefix-list ipv6-out seq 5 permit 2001:db8::/32
ipv6 prefix-list ipv6-in seq 5 deny ::/0
ipv6 prefix-list ipv6-in seq 10 deny ::/0 ge 49
ipv6 prefix-list ipv6-in seq 15 permit ::/0 le 48
The network statement tells BGP which prefixes to announce. For the prefix to be advertised, it must exist in the router's routing table (RIB). Best practice is to create a static route to null0/discard:
! Cisco IOS
ipv6 route 2001:db8::/32 Null0
! Juniper Junos
set routing-options rib inet6.0 static route 2001:db8::/32 discard
! FRR
ipv6 route 2001:db8::/32 Null0
This ensures the prefix is always present in the routing table even if more specific routes are not yet configured.
Outbound Filtering - Only announce prefixes you own:
! Explicitly permit only your allocated prefixes
ipv6 prefix-list IPV6-OUT seq 5 permit 2001:db8::/32
ipv6 prefix-list IPV6-OUT seq 10 deny ::/0 le 128
Inbound Filtering - Protect against bogus announcements:
! Deny default route
ipv6 prefix-list IPV6-IN seq 5 deny ::/0
! Deny documentation prefix
ipv6 prefix-list IPV6-IN seq 10 deny 2001:db8::/32
! Deny unique local addresses
ipv6 prefix-list IPV6-IN seq 15 deny fc00::/7 le 128
! Deny link-local
ipv6 prefix-list IPV6-IN seq 20 deny fe80::/10 le 128
! Deny 6to4
ipv6 prefix-list IPV6-IN seq 25 deny 2002::/16 le 128
! Deny prefixes longer than /48
ipv6 prefix-list IPV6-IN seq 30 deny ::/0 ge 49
! Accept everything else up to /48
ipv6 prefix-list IPV6-IN seq 35 permit ::/0 le 48
Route aggregation reduces the size of the global BGP routing table and improves routing efficiency. The RIPE Routing Working Group (RIPE-532) provides specific recommendations for IPv6 aggregation:
Cisco IOS with aggregate-address:
router bgp 64500
address-family ipv6 unicast
! Create aggregate (suppresses more specific routes)
aggregate-address 2001:db8::/32 summary-only
! Or create aggregate while advertising specifics
aggregate-address 2001:db8::/32 as-set
exit-address-family
Juniper Junos with aggregate route:
set routing-options aggregate route 2001:db8::/32
set policy-options policy-statement announce-aggregate term 1 from protocol aggregate
set policy-options policy-statement announce-aggregate term 1 from route-filter 2001:db8::/32 exact
set policy-options policy-statement announce-aggregate term 1 then accept
Only announce prefixes more specific than your aggregate when:
In these cases, always use BGP communities to control propagation and prevent unnecessary global visibility.
Configure maximum prefix length filtering to reject overly specific routes:
This protects against:
Always filter reserved and special-use IPv6 prefixes:
| Prefix | Purpose | Action |
|---|---|---|
::/0 |
Default route | Deny (unless from upstream) |
::/8 |
Reserved | Deny |
::1/128 |
Loopback | Deny |
::ffff:0:0/96 |
IPv4-mapped | Deny |
2001:db8::/32 |
Documentation | Deny |
fc00::/7 |
Unique Local Addresses | Deny |
fe80::/10 |
Link-local | Deny |
ff00::/8 |
Multicast | Deny |
2002::/16 |
6to4 | Deny |
Configure per-neighbor maximum prefix limits to protect against routing table overflow attacks or misconfigurations:
router bgp 64500
address-family ipv6 unicast
neighbor 2001:db8:100::1 maximum-prefix 200000 90 restart 30
exit-address-family
This example warns at 90% (180,000 prefixes) and tears down the session with 30-minute automatic restart if 200,000 prefixes are received.
ROA is a cryptographically signed object that authorizes a specific AS to originate an IP prefix. It's part of the Resource Public Key Infrastructure (RPKI) framework.
Create ROAs through your RIR's web portal:
Important: Avoid liberal use of maxLength. Setting maxLength longer than your actual announcements exposes you to forged-origin sub-prefix hijacking. Per RFC 9319, only set maxLength when you actually plan to announce more specific prefixes.
For prefix 2001:db8::/32 originated by AS64500:
ROA:
Prefix: 2001:db8::/32
Max Length: /48
Origin AS: 64500
This ROA authorizes AS64500 to announce 2001:db8::/32 and any more specific prefix up to /48 (e.g., 2001:db8:1::/48, 2001:db8:2::/48).
RPKI validation allows routers to verify that BGP announcements match published ROAs, preventing prefix hijacking and route leaks.
Cisco IOS-XE with RTR Protocol:
! Configure RPKI cache server
router bgp 64500
bgp rpki server tcp 2001:db8:rpki::1 port 8282 refresh 600
! Create route-map to validate RPKI
route-map RPKI-VALIDATE permit 10
match rpki valid
set local-preference 200
route-map RPKI-VALIDATE permit 20
match rpki not-found
set local-preference 100
route-map RPKI-VALIDATE permit 30
match rpki invalid
set local-preference 50
! Apply to neighbor
router bgp 64500
address-family ipv6 unicast
neighbor 2001:db8:100::1 route-map RPKI-VALIDATE in
exit-address-family
FRRouting with RPKI:
rpki
rpki cache 2001:db8:rpki::1 8282 preference 1
exit
!
router bgp 64500
address-family ipv6 unicast
neighbor 2001:db8:100::1 route-map rpki-validate in
exit-address-family
!
route-map rpki-validate permit 10
match rpki valid
set local-preference 200
!
route-map rpki-validate permit 20
match rpki notfound
set local-preference 100
!
route-map rpki-validate permit 30
match rpki invalid
set local-preference 50
Best practice is to prefer valid routes, accept not-found routes with lower preference, and either reject or significantly deprioritize invalid routes.
Cisco IOS:
show bgp ipv6 unicast summary
show bgp ipv6 unicast neighbors 2001:db8:100::1
Juniper Junos:
show bgp summary
show bgp neighbor 2001:db8:100::1
FRRouting:
show bgp ipv6 summary
show bgp ipv6 neighbor 2001:db8:100::1
Check that your prefix is being advertised:
show bgp ipv6 unicast 2001:db8::/32
show bgp ipv6 unicast neighbors 2001:db8:100::1 advertised-routes
After configuration, verify global reachability using external tools:
The test-ipv6.run connectivity testing tool is particularly useful for validating that your IPv6 announcement results in working end-to-end connectivity. It tests dual-stack behavior, IPv6-only connectivity, and protocol preference from a user's browser.
Implement monitoring for:
Tools like Prometheus with BGP exporters, Grafana dashboards, or commercial BGP monitoring services can provide comprehensive visibility.
Announcing IPv6 prefixes in BGP requires careful configuration of routing protocol settings, security measures, and validation mechanisms. Key takeaways:
Following these best practices ensures your IPv6 network is secure, efficient, and properly integrated into the global Internet routing system.