Companion posts. This is the hands-on lab — real NX-OSv configs, the tests I ran, and where they broke. For the high-level summary see Anycast Inside the Data Center; for the deeper protocol write-up (overlay index, recursive resolution, why pure-IP fabrics lose per-host ECMP) see Anycast in EVPN/VXLAN Fabrics: The IPv6 Unnumbered and RFC 5549 Problem.
Why#
Anycast is used for horizontal scaling and for better failure response. With modern orchestration and virtualization, a new instance of a service can be spawned on demand — by an engineer or by the system itself.
Anycast is a good option for network-level services such as DNS or load balancers, but whether it works end-to-end depends on the features available in the protocols you run in the fabric.
The Idea#
In a modern data center, a service or VM can be spawned on any host. That dynamic placement requires dynamic routing all the way down to the server: we need a routing session between the fabric and the servers. BGP is the most practical choice here, with the most flexible deployment options for anycast.
A natural design is to run BGP between hosts and leaves over RFC 5549 — Advertising IPv4 NLRI with an IPv6 Next Hop (now obsoleted by RFC 8950). RFC 5549 is a point-to-point technique: it uses ICMPv6 RA/NA messages to discover the remote router, so neighbor discovery is based on IPv6 link-local addresses, and you may not even need IPv4 enabled on those links.
sequenceDiagram
participant L as Leaf (IPv6 LL)
participant H as Host (IPv6 LL)
L->>H: ICMPv6 Router Solicitation / Advertisement
H->>L: ICMPv6 Neighbor Advertisement
Note over L,H: BGP session forms over IPv6 link-local
H->>L: Advertise IPv4 prefix with IPv6 next hop (RFC 5549)
Because discovery is point-to-point over link-local, you can only build point-to-point relationships. We can use RFC 5549 both between the hosts and the leaves and for building the underlay. The type of underlay affects route distribution / BGP address families and introduces some knobs — which is where the trouble starts.
Let’s analyse RFC 5549 between host and leaf for the fabric below.
flowchart TB
subgraph Spine
S1["F1-S1<br/>AS 65201"]
end
subgraph Leaves
L1["Leaf-1<br/>AS 65001<br/>VRF BLUE_TENANT"]
L2["Leaf-2<br/>AS 65002<br/>VRF BLUE_TENANT"]
L3["Leaf-3<br/>AS 65003<br/>VRF BLUE_TENANT"]
end
S1 --- L1
S1 --- L2
S1 --- L3
L1 --- H1["Hosts AS 20 / AS 10<br/>advertise VIP prefix A"]
L2 --- H2["Hosts AS 10<br/>advertise VIP prefix A"]
L3 --- H3["Server<br/>advertise prefix A"]
The Type-5 Encapsulation Problem#
In an EVPN/VXLAN fabric, the routes learned from the hosts over eBGP are carried as EVPN route-type 5 (IP Prefix routes). The question is how those routes get encapsulated into RT-5.
Normally the gateway IP field of the RT-5 route is all zeros. Even if we use IPv6 to advertise the IPv4 next hop (RFC 5549), this does not change anything from the EVPN perspective — the gateway IP is still all zeros, same mechanism.
The problem arises when we advertise a VIP (Virtual IP) from the hosts — a load balancer, DNS, or any virtual network service. VIPs require ECMP in the fabric. For an EVPN/VXLAN underlay using distributed routing and symmetric IRB, you generally need a VRF for the edge networks, so let’s focus on the ECMP problem inside that VRF’s routing table.
Take Leaf-3: it has a local server advertising prefix A, while remote servers behind Leaf-1 and Leaf-2 advertise the same prefix. Leaf-1 and Leaf-2 each have multiple servers advertising it, and they must advertise all of those paths into EVPN. The leaves with multiple servers must install every path into their routing table. That requires:
- Multiple paths (
maximum-paths) so each leaf installs all the local paths. - AS-path handling —
bestpath as-path ignore, or relaxing it, depending on how the hosts use AS numbers. - Advertise all paths, not just best, via RT-5. If every path has the same AS and the same VRF, the routes look identical and only one is advertised. The only field left to differentiate them is the gateway IP, which is all zeros by default. Setting it to the remote BGP peer address of each host gives us distinct BGP paths for the same prefix even when AS and VRF are identical.
- Per-vendor tuning — local-preference for selecting local routes, etc.
Otherwise Leaf-3 ends up with only 2 remote routes instead of the 5 it should have (3 from Leaf-1, 2 from Leaf-2).
Leaf-3 must install all remote routes and the local routes. You may need to ignore AS-path, because local paths have a shorter AS-path. On my tests with Cisco Nexus NX-OSv 9.3(11), the local leaf (e.g. Leaf-3) chose the remote prefixes as best path and advertised them back toward the spine, where they were dropped as an AS loop. NX-OSv seems to use the best path’s attributes — including AS-path — when constructing the multipaths with all-same-AS. From the remote leaves, all the local routes then look the same. I worked around it by setting the local-preference of the local routes so the local paths win best-path.
Leaf-1 also has a host advertising the VIP with a different AS (AS 20), and chose that local path as best. On the remote leaves, all Leaf-1 routes appear to come from AS 20.
Setting the Gateway IP — and Where RFC 5549 Breaks#
The gateway IP is set with export gateway-ip on Cisco NX-OS. But because we are using IPv6 for the eBGP session with the hosts, the next hop is an IPv6 address. How does the switch encode that IPv6 address into the IPv4 gateway field of an RT-5 route?
It can’t, in any useful way. There is no solution for this. This means you cannot use RFC 5549 / RFC 8950 to advertise an IPv4 VIP through the data center: all the local routes on a single leaf end up with the same gateway IP, so only one of them is advertised into EVPN — and the receiving leaf may then drop the route because the gateway is invalid.
For example, configuring several host sessions on a leaf gives 6 local paths, 2 of them via IPv6 next hops. Looking at the route detail, the gateway IP for those is clearly wrong:
Test 1 — Leaf-1: four VIP paths, gateway-ip export with IPv6 next hops#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
| router bgp 65001
router-id 10.34.0.1
log-neighbor-changes
address-family ipv4 unicast
redistribute direct route-map d2bgp
address-family l2vpn evpn
maximum-paths 64
additional-paths send
additional-paths receive
additional-paths selection route-map pass_all
neighbor 10.33.1.1
remote-as 65201
description spine
address-family ipv4 unicast
send-community
send-community extended
address-family l2vpn evpn
send-community extended
neighbor 10.101.5.1
remote-as 20
description HOST
address-family ipv4 unicast
neighbor 10.101.0.0/16
remote-as 10
description HOST
address-family ipv4 unicast
neighbor Ethernet1/1
remote-as 65201
description spine
address-family ipv4 unicast
address-family l2vpn evpn
send-community extended
vrf BLUE_TENANT
bestpath as-path ignore
address-family ipv4 unicast
redistribute direct route-map permit_all
export-gateway-ip
maximum-paths mixed 64
additional-paths receive
additional-paths selection route-map pass_all
neighbor 10.101.5.1
remote-as 20
description HOST
address-family ipv4 unicast
neighbor 10.101.0.0/16
remote-as 10
description HOST
address-family ipv4 unicast
|
Test 2 — Leaf-2: RFC 5549 toward the spine invalidates the route#
With RFC 5549 configured on the Leaf-2 ↔ spine session, Leaf-2 invalidates the route with an “invalid rnh resolve” error:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
| router bgp 65002
router-id 10.34.0.2
log-neighbor-changes
address-family ipv4 unicast
redistribute direct route-map d2bgp
address-family l2vpn evpn
maximum-paths 64
additional-paths send
additional-paths receive
additional-paths selection route-map pass_all
neighbor 10.33.2.1
remote-as 65201
description spine
shutdown
address-family ipv4 unicast
send-community
send-community extended
address-family l2vpn evpn
send-community extended
neighbor 10.102.0.0/16
remote-as 10
description HOST
address-family ipv4 unicast
neighbor Ethernet1/1
remote-as 65201
description spine
address-family ipv4 unicast
address-family l2vpn evpn
send-community extended
vrf BLUE_TENANT
address-family ipv4 unicast
redistribute direct route-map permit_all
export-gateway-ip
additional-paths receive
neighbor 10.102.0.0/16
remote-as 10
description HOST
address-family ipv4 unicast
|
When I changed the Leaf-2 ↔ spine session from RFC 5549 back to normal IPv4, Leaf-2 validated the route (note the shutdown moves to the Ethernet1/1 unnumbered session instead):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
| router bgp 65002
router-id 10.34.0.2
log-neighbor-changes
address-family ipv4 unicast
redistribute direct route-map d2bgp
address-family l2vpn evpn
maximum-paths 64
additional-paths send
additional-paths receive
additional-paths selection route-map pass_all
neighbor 10.33.2.1
remote-as 65201
description spine
address-family ipv4 unicast
send-community
send-community extended
address-family l2vpn evpn
send-community extended
neighbor 10.102.0.0/16
remote-as 10
description HOST
address-family ipv4 unicast
neighbor Ethernet1/1
remote-as 65201
description spine
shutdown
address-family ipv4 unicast
address-family l2vpn evpn
send-community extended
vrf BLUE_TENANT
address-family ipv4 unicast
redistribute direct route-map permit_all
export-gateway-ip
additional-paths receive
neighbor 10.102.0.0/16
remote-as 10
description HOST
address-family ipv4 unicast
|
What this means#
- We cannot use RFC 5549 for the host sessions when we need the gateway-IP trick. I could not find any way to make the leaf resolve the next hop when using
export gateway-ip. I even tried advertising the next-hop /32 from Leaf-1 (network nh/32 under BGP) — it did not help. - We cannot use RFC 5549 for the underlay together with
export-gateway-ip either.
The Working Solution: EVPN with IPv4 Host Sessions#
Dropping RFC 5549 in favour of normal IPv4 eBGP sessions to the hosts, the anycast/ECMP design works. Full configs below; the inline annotations mark the knobs that matter.
Leaf config (Leaf-1; the other leaves are similar):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
| F1-R1-L1# sh run
nv overlay evpn
feature bgp
feature isis
feature interface-vlan
feature vn-segment-vlan-based
feature nv overlay
fabric forwarding anycast-gateway-mac 0000.2222.3333
vlan 1,10,1010
vlan 10
vn-segment 900010
vlan 1010
vn-segment 800010
ip prefix-list d2bgp seq 5 permit 10.34.0.1/32
ip prefix-list d2bgp seq 10 permit 10.35.0.1/32
route-map d2bgp permit 10
match ip address prefix-list d2bgp
route-map d2bgp deny 100
route-map pass_all permit 10
set path-selection all advertise
route-map test_in permit 10
set local-preference 250
! ^ required for selecting local prefixes as best, used to construct the
! multipath attributes. Mostly an NX-OS specific.
vrf context BLUE_TENANT
vni 800010
rd auto
address-family ipv4 unicast
route-target both auto
route-target both auto evpn
route-target import 65000:800010
route-target import 65000:800010 evpn
route-target export 65000:800010
route-target export 65000:800010 evpn
vrf context management
ip route 0.0.0.0/0 192.168.122.1
interface Vlan1
interface Vlan10
no shutdown
vrf member BLUE_TENANT
ip address 10.10.10.1/24
fabric forwarding mode anycast-gateway
interface Vlan1010
no shutdown
vrf member BLUE_TENANT
ip forward
interface nve1
no shutdown
host-reachability protocol bgp
source-interface loopback1
member vni 800010 associate-vrf
member vni 900010
ingress-replication protocol bgp
interface Ethernet1/1
no switchport
ip address 10.33.1.0/31
ipv6 link-local use-bia
isis network point-to-point
isis circuit-type level-2
ip router isis underlay
no shutdown
interface Ethernet1/2
interface Ethernet1/3
interface Ethernet1/4
interface Ethernet1/5
no switchport
vrf member BLUE_TENANT
ip address 10.101.5.0/31
ipv6 link-local use-bia
no shutdown
interface Ethernet1/6
no switchport
vrf member BLUE_TENANT
ip address 10.101.6.0/31
no shutdown
interface Ethernet1/7
no switchport
vrf member BLUE_TENANT
ip address 10.101.7.0/31
no shutdown
interface Ethernet1/8
no switchport
vrf member BLUE_TENANT
ip address 10.101.8.0/31
ipv6 link-local use-bia
no shutdown
interface loopback0
ip address 10.34.0.1/32
isis network point-to-point
isis circuit-type level-2
ip router isis underlay
interface loopback1
ip address 10.35.0.1/32
isis network point-to-point
isis circuit-type level-2
ip router isis underlay
router isis underlay
net 49.0000.0000.0001.00
is-type level-2
router bgp 65001
router-id 10.34.0.1
address-family ipv4 unicast
redistribute direct route-map d2bgp
maximum-paths 64
additional-paths send
additional-paths receive
additional-paths selection route-map pass_all
address-family l2vpn evpn
maximum-paths 64 ! required for installing multiple EVPN routes
additional-paths send ! required for sending multiple EVPN routes
additional-paths receive ! required for receiving multiple EVPN routes
additional-paths selection route-map pass_all ! select multiple EVPN routes to advertise
template peer-policy host
route-map test_in in
template peer-session host
remote-as 10
neighbor 10.33.1.1
remote-as 65201
address-family ipv4 unicast
disable-peer-as-check
soft-reconfiguration inbound always
address-family l2vpn evpn
disable-peer-as-check
send-community extended
vrf BLUE_TENANT
bestpath as-path ignore ! remote-leaf and local routes have different AS-path lengths
address-family ipv4 unicast
redistribute direct route-map pass_all ! with export-gateway-ip our routes use the remote
! BGP peer address as next hop, so advertise those peer IPs
export-gateway-ip ! differentiate local routes when building the EVPN NLRI
maximum-paths mixed 64 ! mix local and remote prefixes for multipath
additional-paths send ! send multipath into EVPN
additional-paths receive ! receive multipath from hosts
additional-paths selection route-map pass_all
neighbor 10.101.5.1
remote-as 20
address-family ipv4 unicast
route-map test_in in
neighbor 10.101.0.0/16
inherit peer-session host
address-family ipv4 unicast
inherit peer-policy host 1
neighbor Ethernet1/5
remote-as 20
address-family ipv4 unicast
route-map test_in in
neighbor Ethernet1/8
inherit peer-session host
address-family ipv4 unicast
inherit peer-policy host 1
evpn
vni 900010 l2
route-target import auto
route-target export auto
logging monitor 7
|
Spine config:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| F1-S1# sh run
router isis underlay
net 49.0000.0000.0201.00
is-type level-2
router bgp 65201
router-id 10.34.0.201
bestpath as-path ignore ! or relax the AS-path; at this level all routes come from
! leaves and share the same AS-path length
address-family ipv4 unicast
maximum-paths 64
retain route-target all
additional-paths send
additional-paths receive
additional-paths selection route-map add_select ! select prefixes for additional-path
neighbor 10.33.1.0
remote-as 65001
address-family ipv4 unicast
soft-reconfiguration inbound always
address-family l2vpn evpn
send-community extended
neighbor 10.33.2.0
remote-as 65002
address-family ipv4 unicast
address-family l2vpn evpn
send-community extended
neighbor 10.33.5.0
remote-as 65003
address-family ipv4 unicast
address-family l2vpn evpn
send-community extended
|
Conclusion#
It is not yet feasible to use BGP unnumbered (RFC 5549 / RFC 8950) — either toward the hosts or for the underlay — for VNF/anycast services that depend on the Type-5 gateway-IP trick: the IPv6 next hop has nowhere to live in the IPv4 gateway field, the local routes collapse to a single gateway, and receiving leaves drop them as unresolvable. The same design works fine with normal IPv4-based eBGP sessions to the hosts, combined with export-gateway-ip, maximum-paths, and additional-paths on both the IPv4-unicast and L2VPN-EVPN address families.
References#
The content of this post was created by the author; AI was used for editing and restructuring.