(I’m going to throw in some bonus BGP templates because I like templates when I have lots of neighbors to configure, may elaborate in a later post but with any familiarity with BGP at all, their purpose should be self-evident).
By default, old school IOS (not IOS-XR) presumes that any neighbor you configure (regardless of whether you configure the neighbor with an IPv4 address or an IPv6 address) supports the IPv4 address family. This is advertised in the capabilities negotiation during the BGP OPEN phase of neighbor establishment. See also: http://www.cisco.com/en/US/docs/ios/12_3t/ip_route/command/reference/ip2_b1gt.html#wp1078888 for explanation and method for turning this default off. This post describes the default behaviour and recommends a decent, working configuration that keeps things clean and simple.
IOS does not support sending IPv6 NLRI (or “routes,” hehe) by default; it requires configuration under BGP’s “address-family ipv6 unicast” stanza. The effect is that if you just do “neighbor x:x:x:x:x:x:x remote-as xxxxx” as usual (without configuring it for the appropriate address-family), you will establish a TCP connection over IPv6, but send/receive only IPv4 routes. Not very useful. In my own opinion, it would be best to make protocol operation as address-family independent as possible. It would be a good idea (again, in my less-than-humble opinion!) to advertise your IPv4 routes over IPv4-only, and IPv6 routes over IPv6 only.
Editor’s note: As an aside, caveats to this approach include using IS-IS to advertise both address-families, but since IS-IS runs directly on top of the data-link and has no real dependency on IPv4 or IPv6, it’s not really much of a caveat, haha. Anyway, when that magic day comes along where you want to turn down IPv4 processing on a router, you need only turn down the IPv4 BGP sessions, or remove IPv4 address-family capability from IS-IS, or turn off OSPFv2…etc.
If one side of the BGP session is left to defaults, and the other side is configured to support only the IPv6 address family, the adjacency never comes up due to capability mismatch (one side supports IPv6 NLRI only, other side supports only IPv4). For the session to come up, both sides have to support the same NLRI.
IOS provides a simple way to adjust your BGP configuration to handle this: the “no bgp default ipv4-unicast” command under the router bgp process as described in the link above. After entering this command, the configuration is converted to address-family syntax, and neighbors must be explicitly activated to advertise one or more address families (typically IPv4 and IPv6 unicast). This conversion does not affect existing BGP sessions.
After trying to add an IPv6 neighbor under the IPv6 address family, but before disabling the default behaviour of sending IPv4 unicast routes over all BGP sessions on an IOS router, the configuration looks a little like this:
router bgp 65000
!
template peer-policy CORE-POLICY
next-hop-self
soft-reconfiguration inbound
send-community both
exit-peer-policy
!
template peer-session IPV4-SESSION
remote-as 65000
update-source Loopback100
version 4
fall-over
exit-peer-session
!
template peer-session IPV6-SESSION
remote-as 65000
update-source Loopback300
version 4
fall-over
exit-peer-session
!
neighbor 10.0.0.1 remote-as 65000
neighbor 10.0.0.1 inherit peer-session IPv4-SESSION
neighbor 2001:DB8:E53C::2 remote-as 65000
neighbor 2001:DB8:E53C::2 inherit peer-session IPv6-SESSION
!
address-family ipv4
neighbor 10.1.1.2 activate
neighbor 10.1.1.2 inherit peer-policy CORE-POLICY
no neighbor 2001:DB8:E53C::2 activate
exit-address-family
!
address-family ipv6
neighbor 2001:DB8:E53C::2 activate
neighbor 2001:DB8:E53C::2 inherit peer-policy CORE-POLICY
If that IPv6 neighbor isn’t explicitly deactivated under the IPv4 configuration, there is a very good chance that the session may not come up due to parameter mismatch. After disabling the default behaviour of advertising IPv4-unicast routes over all sessions, the configuration begins to make more sense:
router bgp 22995
!
no bgp default ipv4-unicast
!
neighbor 10.0.0.1 inherit peer-session IPv4-SESSION
neighbor 2001:DB8:E53C::2 inherit peer-session IPv6-SESSION
!
address-family ipv4
neighbor 10.0.0.1 activate
neighbor 10.0.0.1 inherit peer-policy CORE-POLICY
exit-address-family
!
address-family ipv6
neighbor 2001:DB8:E53C::2 activate
neighbor 2001:DB8:E53C::2 inherit peer-policy CORE-POLICY
exit-address-family
The end result is a completely separate IPv6-only session to a neighbor, sending/receiving only IPv6 NLRI. This keeps your IPv4 completely separate from IPv6, as far as BGP topology is concerned; and it keeps your configuration clean. Although it’s also perfectly workable to send all NLRI for all address families over a single transport connection (i.e. send all IPv4/IPv6 routes using only IPv6 transport, or only IPv4 transport), I just wouldn’t do it; no sense hitching the IPv6 freight train to the IPv4 wagon.