idnits 2.17.1 draft-head-rift-auto-evpn-01.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The document seems to lack an IANA Considerations section. (See Section 2.2 of https://www.ietf.org/id-info/checklist for how to handle the case when there are no actions for IANA.) ** There are 73 instances of too long lines in the document, the longest one being 58 characters in excess of 72. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year == Line 894 has weird spacing: '...cIDType defa...' == Line 903 has weird spacing: '...equired comm...' == Line 904 has weird spacing: '...equired comm...' == Line 905 has weird spacing: '...equired comm...' == Line 910 has weird spacing: '...equired set<...' == (26 more instances...) -- The document date (9 July 2021) is 1015 days in the past. Is this intentional? -- Found something which looks like a code comment -- if you have code sections in the document, please surround them with '' and '' lines. Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Looks like a reference, but probably isn't: '0' on line 1532 -- Looks like a reference, but probably isn't: '1' on line 1533 -- Looks like a reference, but probably isn't: '2' on line 1534 -- Looks like a reference, but probably isn't: '3' on line 1532 -- Looks like a reference, but probably isn't: '4' on line 1533 -- Looks like a reference, but probably isn't: '5' on line 1534 -- Looks like a reference, but probably isn't: '6' on line 1535 -- Looks like a reference, but probably isn't: '7' on line 1536 == Outdated reference: A later version (-21) exists of draft-ietf-rift-rift-13 Summary: 2 errors (**), 0 flaws (~~), 8 warnings (==), 10 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 RIFT J. Head, Ed. 3 Internet-Draft T. Przygienda 4 Intended status: Standards Track W. Lin 5 Expires: 10 January 2022 Juniper Networks 6 9 July 2021 8 RIFT Auto-EVPN 9 draft-head-rift-auto-evpn-01 11 Abstract 13 This document specifies procedures that allow an EVPN overlay to be 14 fully and automatically provisioned when using RIFT as underlay by 15 leveraging RIFT's no-touch ZTP architecture. 17 Status of This Memo 19 This Internet-Draft is submitted in full conformance with the 20 provisions of BCP 78 and BCP 79. 22 Internet-Drafts are working documents of the Internet Engineering 23 Task Force (IETF). Note that other groups may also distribute 24 working documents as Internet-Drafts. The list of current Internet- 25 Drafts is at https://datatracker.ietf.org/drafts/current/. 27 Internet-Drafts are draft documents valid for a maximum of six months 28 and may be updated, replaced, or obsoleted by other documents at any 29 time. It is inappropriate to use Internet-Drafts as reference 30 material or to cite them other than as "work in progress." 32 This Internet-Draft will expire on 10 January 2022. 34 Copyright Notice 36 Copyright (c) 2021 IETF Trust and the persons identified as the 37 document authors. All rights reserved. 39 This document is subject to BCP 78 and the IETF Trust's Legal 40 Provisions Relating to IETF Documents (https://trustee.ietf.org/ 41 license-info) in effect on the date of publication of this document. 42 Please review these documents carefully, as they describe your rights 43 and restrictions with respect to this document. Code Components 44 extracted from this document must include Simplified BSD License text 45 as described in Section 4.e of the Trust Legal Provisions and are 46 provided without warranty as described in the Simplified BSD License. 48 Table of Contents 50 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 51 1.1. Requirements Language . . . . . . . . . . . . . . . . . . 3 52 2. Design Considerations . . . . . . . . . . . . . . . . . . . . 3 53 3. System ID . . . . . . . . . . . . . . . . . . . . . . . . . . 4 54 4. Fabric ID . . . . . . . . . . . . . . . . . . . . . . . . . . 4 55 5. Auto-EVPN Device Roles . . . . . . . . . . . . . . . . . . . 5 56 5.1. All Participating Nodes . . . . . . . . . . . . . . . . . 5 57 5.2. ToF Nodes as Route Reflectors . . . . . . . . . . . . . . 5 58 5.3. Leaf Nodes . . . . . . . . . . . . . . . . . . . . . . . 6 59 6. Auto-EVPN Variable Derivation . . . . . . . . . . . . . . . . 7 60 6.1. Auto-EVPN Version . . . . . . . . . . . . . . . . . . . . 8 61 6.2. MAC-VRF ID . . . . . . . . . . . . . . . . . . . . . . . 8 62 6.3. Loopback Address . . . . . . . . . . . . . . . . . . . . 8 63 6.3.1. Leaf Nodes as Gateways . . . . . . . . . . . . . . . 8 64 6.3.2. ToF Nodes as Route Reflectors . . . . . . . . . . . . 9 65 6.3.2.1. Route Reflector Election Procedures . . . . . . . 9 66 6.4. Autonomous System Number . . . . . . . . . . . . . . . . 10 67 6.5. Router ID . . . . . . . . . . . . . . . . . . . . . . . . 10 68 6.6. Cluster ID . . . . . . . . . . . . . . . . . . . . . . . 10 69 6.7. Route Target . . . . . . . . . . . . . . . . . . . . . . 10 70 6.8. Route Distinguisher . . . . . . . . . . . . . . . . . . . 10 71 6.9. EVPN MAC-VRF Services . . . . . . . . . . . . . . . . . . 11 72 6.9.1. Untagged Traffic in Multiple Fabrics . . . . . . . . 11 73 6.9.1.1. VLAN . . . . . . . . . . . . . . . . . . . . . . 11 74 6.9.1.2. VNI . . . . . . . . . . . . . . . . . . . . . . . 11 75 6.9.1.3. MAC Address . . . . . . . . . . . . . . . . . . . 11 76 6.9.1.4. IPv6 IRB Gateway Address . . . . . . . . . . . . 12 77 6.9.1.5. IPv4 IRB Gateway Address . . . . . . . . . . . . 12 78 6.9.2. Tagged Traffic in Multiple Fabrics . . . . . . . . . 12 79 6.9.2.1. VLAN . . . . . . . . . . . . . . . . . . . . . . 12 80 6.9.2.2. VNI . . . . . . . . . . . . . . . . . . . . . . . 12 81 6.9.2.3. MAC Address . . . . . . . . . . . . . . . . . . . 13 82 6.9.2.4. IPv6 IRB Gateway Address . . . . . . . . . . . . 13 83 6.9.2.5. IPv4 IRB Gateway Address . . . . . . . . . . . . 13 84 6.9.3. Tagged Traffic in a Single Fabric . . . . . . . . . . 13 85 6.9.3.1. VLAN . . . . . . . . . . . . . . . . . . . . . . 13 86 6.9.3.2. VNI . . . . . . . . . . . . . . . . . . . . . . . 14 87 6.9.3.3. MAC Address . . . . . . . . . . . . . . . . . . . 14 88 6.9.3.4. IPv6 IRB Gateway Address . . . . . . . . . . . . 14 89 6.9.3.5. IPv4 IRB Gateway Address . . . . . . . . . . . . 14 90 6.9.4. Traffic Routed to External Destinations . . . . . . . 14 91 6.9.4.1. Route Distinguisher . . . . . . . . . . . . . . . 15 92 6.9.4.2. Route Target . . . . . . . . . . . . . . . . . . 15 93 6.10. Auto-EVPN Analytics . . . . . . . . . . . . . . . . . . . 15 94 6.10.1. Auto-EVPN Global Analytics Key Type . . . . . . . . 16 95 6.10.2. Auto-EVPN MAC-VRF Key Type . . . . . . . . . . . . . 16 97 7. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 18 98 8. Security Considerations . . . . . . . . . . . . . . . . . . . 18 99 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 18 100 9.1. Normative References . . . . . . . . . . . . . . . . . . 18 101 Appendix A. Thrift Models . . . . . . . . . . . . . . . . . . . 19 102 A.1. RIFT LIE Schema . . . . . . . . . . . . . . . . . . . . . 19 103 A.1.1. Auto-EVPN Version . . . . . . . . . . . . . . . . . . 19 104 A.1.2. Fabric ID . . . . . . . . . . . . . . . . . . . . . . 19 105 A.2. RIFT Node-TIE Schema . . . . . . . . . . . . . . . . . . 19 106 A.2.1. Auto-EVPN Version . . . . . . . . . . . . . . . . . . 19 107 A.2.2. Fabric ID . . . . . . . . . . . . . . . . . . . . . . 19 108 A.3. common_evpn.thrift . . . . . . . . . . . . . . . . . . . 19 109 A.4. auto_evpn_kv.thrift . . . . . . . . . . . . . . . . . . . 22 110 Appendix B. Auto-EVPN Variable Derivation . . . . . . . . . . . 24 111 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 36 113 1. Introduction 115 RIFT is a protocol that focuses heavily on operational simplicity. 116 [RIFT] natively supports Zero Touch Provisioning (ZTP) functionality 117 that allows each node in an underlay network to automatically derive 118 its place in the topology and configure itself accordingly when 119 properly cabled. RIFT can also disseminate Key-Value information 120 contained in Key-Value Topology Information Elements (KV-TIEs) 121 [RIFT-KV]. These KV-TIEs can contain any information and therefore 122 be used for any purpose. Leveraging RIFT to provision EVPN overlays 123 without any need for configuration and leveraging KV capabilities to 124 easily validate correct operation of such overlay without a single 125 point of failure would provide significant benefit to operators in 126 terms of simplicity and robustness of such a solution. 128 1.1. Requirements Language 130 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 131 "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this 132 document are to be interpreted as described in RFC 2119 [RFC2119]. 134 2. Design Considerations 136 EVPN supports various service models, this document defines a method 137 for the VLAN-Aware service model defined in [RFC7432]. Other service 138 models may be considered in future revisions of this document. 140 Each model has its own set of requirements for deployment. For 141 example, a functional BGP overlay is necessary to exchange EVPN NLRI 142 regardless of the service model. Furthermore, the requirements are 143 made up of individual variables, such as each node's loopback address 144 and AS number for the BGP session. Some of these variables may be 145 coordinated across each node in a network, but are ultimately locally 146 significant (e.g. route distinguishers). Similarly, calculation of 147 some variables will be local only to each device. RIFT contains 148 currently enough topology information in each node to calculate all 149 those necessary variables automatically. 151 Once the EVPN overlay is configured and becomes operational, RIFT 152 Key-Value TIEs can be used to distribute state information to allow 153 for validation of basic operational correctness without the need for 154 further tooling. 156 3. System ID 158 The 64-bit RIFT System ID that uniquely identifies a node as defined 159 in RIFT [RIFT]. 161 4. Fabric ID 163 RIFT operates on variants of Clos substrate which are commonly called 164 an IP Fabric. Since EVPN VLANs can be either contained within one 165 fabric or span them, Auto-EVPN introduces the concept of a Fabric ID 166 into RIFT. 168 This section describes an optional extension to LIE packet schema in 169 the form of a 16-bit Fabric ID that identifies a nodes membership 170 within a particular fabric. Auto-EVPN capable nodes MUST support 171 this extension but MAY not advertise it when not participating in 172 Auto-EVPN. A non-present Fabric ID and value of 0 is reserved as 173 ANY_FABRIC and MUST NOT be used for any other purpose. 175 Fabric ID MUST be considered in existing adjacency FSM rules so nodes 176 that support Auto-EVPN can interoperate with nodes that do not. The 177 LIE validation is extended with following clause and if it is not 178 met, miscabling should be declared: 180 (if fabric_id is not advertised by either node OR 181 if fabric_id is identical on both nodes) 182 AND 183 (if auto_evpn_version is not advertised by either node OR 184 if auto_evpn_version is identical on both nodes) 186 The appendix details LIE (Appendix A.1.2) and Node-TIE 187 (Appendix A.2.2) schema changes. 189 5. Auto-EVPN Device Roles 191 Auto-EVPN requires that each node understand its given role within 192 the scope of the EVPN implementation so each node derives the 193 necessary variables and provides the necessary overlay configuration. 194 For example, a leaf node performing VXLAN gateway functions does not 195 need to derive its own Cluster ID or learn one from the route 196 reflector that it peers with. 198 5.1. All Participating Nodes 200 Not all nodes have to participate in Auto-EVPN, however if a node 201 does assume an Auto-EVPN role, it MUST derive the following 202 variables: 204 *IPv6 Loopback Address* 205 Unique IPv6 loopback address used in BGP sessions. 207 *Router ID* 208 The BGP Router ID. 210 *Autonomous System Number* 211 The ASN for IBGP sessions. 213 *Cluster ID* 214 The Cluster ID for Top-of-Fabric IBGP route reflection. 216 5.2. ToF Nodes as Route Reflectors 218 This section defines an Auto-EVPN role whereby some Top-of-Fabric 219 nodes act as EVPN route reflectors. It is expected that route 220 reflectors would establish IBGP sessions with leaf nodes in the same 221 fabric. The typical route reflector requirements do not change, 222 however determining which specific values to use requires further 223 consideration. ToF nodes performing route reflector functionality 224 MUST derive the following variables: 226 *IPv6 RR Loopback Address* 227 The source address for IBGP sessions with leaf nodes in case 228 ToF won election for one of the route reflectors in the fabric. 230 *IPv6 RR Acceptable Prefix Range* 231 Range of addresses acceptable by the route reflector to form a 232 IBGP session. This range covers ALL possible IPv6 Loopback 233 Addresses derived by other Auto EVPN nodes in the current 234 fabric and other Auto-EVPN RRs addresses. 236 5.3. Leaf Nodes 238 Leaf nodes derive their role from realizing they are at the bottom of 239 the fabric, i.e. not having any southbound adjacencies. Alternately, 240 a node can assume a leaf node if it has only southbound adjacencies 241 to nodes with explicit LEAF_LEVEL to allow for scenarios where RIFT 242 leaves do NOT participate in Auto-EVPN. 244 Leaf nodes MUST derive the following variables: 246 *IPv6 RR Loopback Addresses* 247 Addresses of the RRs present in the fabric. Those addresses 248 are used to build BGP sessions to the RR. 250 *EVIs* 251 Leaf node derives all the necessary variables to instantiate 252 EVIs with layer-2 and optionally layer-3 functionality. 254 If a leaf node is required to perform layer-2 VXLAN gateway 255 functions, it MUST be capable of deriving the following types of 256 variables: 258 *Route Distinguisher* 259 The route distinguisher corresponding to a MAC-VRF that 260 uniquely identifies each node. 262 *Route Target* 263 The route target that corresponds to a MAC-VRF. 265 *MAC VRF Name* 266 This is an optional variable to provide a common MAC VRF name 267 across all leaves. 269 *Set of VLANs* 270 Those are VLANs provisioned either within the fabric or 271 allowing to stretch across fabrics. 273 For each VLAN derived in an EVI the following variables MUST be 274 derived: 276 *VLAN* 277 The VLAN ID. 279 *Name* 280 This is an optional variable to provide a common VLAN name 281 across all leaves. 283 *VNI* 284 The VNI that corresponds to the VLAN ID. This will contribute 285 to the EVPN Type-2 route. 287 *IRB* 288 Optional variables of the IRB for the VLAN if the leaf performs 289 layer-3 gateway function. 291 If a leaf node is required to perform layer-3 VXLAN gateway 292 functions, it MUST additionally be capable of deriving the following 293 types of variables: 295 *IP Gateway MAC Address* 296 The MAC address associated with IP gateway. 298 *IP Gateway Subnetted Address* 299 The IPv4 and/or IPv6 gateway address including its subnet 300 length. 302 Type-5 EVPN IP Prefix with ToFs performing gateway functionality can 303 also be derived and will be described in a future version of this 304 document. 306 6. Auto-EVPN Variable Derivation 308 As previously mentioned, not all nodes are required to derive all 309 variables in a given network (e.g. a transit spine node may not need 310 to derive any or participate in Auto-EVPN). Additionally, all 311 derived variables are derived from RIFT's FSM or ZTP mechanism so no 312 additional flooding beside RIFT flooding is necessary for the 313 functionality. 315 It is also important to mention that all variable derivation is in 316 some way based on combinations of System ID, MAC-VRF ID, Fabric ID, 317 EVI and VLAN and MUST comply precisely with calculation methods 318 specified in the Auto-EVPN Variable Derivation section to allow 319 interoperability between different implementations. All foundational 320 code elements such as imports, constants, etc. are also mentioned 321 there. 323 6.1. Auto-EVPN Version 325 This section describes extensions to both the RIFT LIE packet and 326 Node-TIE schemas in the form of a 16-bit value that identifies the 327 Auto-EVPN Version. Auto-EVPN capable nodes MUST support this 328 extension, but MAY choose not to advertise it in LIEs and Node-TIEs 329 when Auto-EVPN is not being utilized. The appendix describes LIE 330 (Appendix A.1.1) and Node-TIE (Appendix A.2.1) schema changes in 331 detail. 333 6.2. MAC-VRF ID 335 This section describes a variable MAC-VRF ID that uniquely identifies 336 an instance of EVPN instance (EVI) and is used in variable derivation 337 procedures. Each EVPN EVI MUST be associated with a unique MAC-VRF 338 ID, this document does not specify a method for making that 339 association or ensuring that they are coordinated properly across 340 fabric(s). 342 6.3. Loopback Address 344 First and foremost, RIFT does not advertise anything more specific 345 than the fabric default route in the southbound direction by default. 346 However, Auto-EVPN nodes MUST advertise specific loopback addresses 347 southbound to all other Auto-EVPN nodes so to establish MP-BGP 348 reachability correctly in all scenarios. 350 Auto-EVPN nodes MUST derive a ULA-scoped IPv6 loopback address to be 351 used as both the IBGP source address, as well as the VTEP source when 352 VXLAN gateways are required. Calculation is done using the 6-bytes 353 of reserved ULA space, the 2-byte Fabric ID, and the node's 8-byte 354 System ID. Derivation of the System ID varies slightly depending 355 upon the node's location/role in the fabric and will be described in 356 subsequent sections. 358 6.3.1. Leaf Nodes as Gateways 360 Calculation is done using the 6-bytes of reserved ULA space, the 361 2-byte Fabric ID, and the node's 8-byte System ID. 363 In order for leaf nodes to derive IPv6 loopback addresses, algorithms 364 shown in both auto_evpn_fidsidv6loopback (Figure 24) and 365 auto_evpn_v6prefixfidsid2loopback (Figure 9) are required. 367 IPv4 addresses MAY be supported, but it should be noted that they 368 have a higher likelihood of collision. The appendix contains the 369 required auto_evpn_fidsid2v4loopback (Figure 23) algorithm to support 370 IPv4 loopback derivation. 372 6.3.2. ToF Nodes as Route Reflectors 374 ToF nodes acting as route reflectors MUST derive their loopback 375 address according to the specific section describing the algorithm. 376 Calculation is done using the 6-bytes of reserved ULA space, the 377 2-byte Fabric ID, and the 8-byte System ID of each elected route 378 reflector. 380 In order for the ToF nodes to derive IPv6 loopbacks, the algorithms 381 shown in both auto_evpn_fidsidv6loopback (Figure 24) and 382 auto_evpn_fidrrpref2rrloopback (Figure 10) are required. 384 In order for the ToF derive the necessary prefix range to facilitate 385 peering requests from any leaf, the algorithm shown in 386 "auto_evpn_fid2fabric_prefixes" (Figure 8) is required. 388 6.3.2.1. Route Reflector Election Procedures 390 Four Top-of-Fabric nodes MUST be elected as an IBGP route reflector. 391 Each ToF performs the election independently based on system IDs of 392 other ToFs in the fabric obtained via southbound reflection. The 393 route reflector election procedures are defined as follows: 395 1. ToF node with the highest System ID. 397 2. ToF node with the lowest System ID. 399 3. ToF node with the 2nd highest System ID. 401 4. ToF node with the 2nd lowest System ID. 403 This ordering is necessary to prevent a single node with either the 404 highest or lowest System ID from triggering changes to route 405 reflector loopback addresses as it would result in all BGP sessions 406 dropping. 408 For example, if two nodes, ToF01 and ToF02 with System IDs 409 002c6af5a281c000 and 002c6bf5788fc000 respectively, ToF02 would be 410 elected due to it having the highest System ID of the ToFs 411 (002c6bf5788fc000). If a ToF determines that it is elected as route 412 reflector, it uses the knowledge of its position in the list to 413 derive route reflector v6 loopback address. 415 The algorithm shown in "auto_evpn_sids2rrs" (Figure 6) is required to 416 accomplish this. 418 Considerations for multiplane route reflector elections will be 419 included in future revisions. 421 6.4. Autonomous System Number 423 Nodes in each fabric MUST derive a private autonomous system number 424 based on its Fabric ID so that it is unique across the fabric. 426 The algorithm shown in auto_evpn_fid2private_AS (Figure 25) is 427 required to derive the private ASN. 429 6.5. Router ID 431 Nodes MUST drive a Router ID that is based on both its System ID and 432 Fabric ID so that it is unique to both. 434 The algorithm shown in auto_evpn_sidfid2bgpid (Figure 11) is required 435 to derive the BGP Router ID. 437 6.6. Cluster ID 439 Route reflector nodes in each fabric MUST derive a cluster ID that is 440 based on its Fabric ID so that it is unique across the fabric. 442 The algorithm shown in auto_evpn_fid2clusterid (Figure 26) is 443 required to derive the BGP Cluster ID. 445 6.7. Route Target 447 Nodes hosting EVPN EVIs MUST derive a route target extended community 448 based on the MAC-VRF ID for each EVI so that it is unique across the 449 network. Route targets MUST be of type 0 as per RFC4360. 451 For example, if given a MAC-VRF ID of 1, the derived route target 452 would be "target:1" 454 The algorithm shown in auto_evpn_evi2rt (Figure 12) is required to 455 derive the Route Target community. 457 6.8. Route Distinguisher 459 Nodes hosting EVPN EVIs MUST derive a type-0 route distinguisher 460 based on its System ID and Fabric ID so that it is unique per MAC-VRF 461 and per node. 463 The algorithm shown in auto_evpn_sidfid2rd (Figure 18) is required to 464 derive the Route Distinguisher. 466 6.9. EVPN MAC-VRF Services 468 It's obvious that applications utilizing Auto-EVPN overlay services 469 may require a variety of layer-2 and/or layer-3 traffic 470 considerations. Variables supporting these services are also derived 471 based on some combination of MAC-VRF ID, Fabric ID, and other 472 constant values. Integrated Routing and Bridging (IRB) gateway 473 address derivation also leverages a set of constant RANDOMSEEDS 474 (Figure 5) values that MUST be used to provide additional entropy. 476 In order to ensure that VLAN ID's don't collide, a single deployment 477 SHOULD NOT exceed 3 fabrics with 3 EVIs where each EVI terminate 15 478 VLANs. The algorithms shown in auto_evpn_fidevivlansvlans2desc 479 (Figure 16) and auto_evpn_vlan_description_table (Figure 15) are 480 required to derive VLANs accordingly. An implementation MAY exceed 481 this, but MUST indicate methods to ensure collision-free derivation 482 and describe which VLANs are stretched across fabrics. 484 6.9.1. Untagged Traffic in Multiple Fabrics 486 This section defines methods to derive unique VLAN, VNI, MAC, and 487 gateway address values for deployments where untagged traffic is 488 stretched across multiple fabrics. 490 6.9.1.1. VLAN 492 Untagged traffic stretched across multiple fabrics MUST derive VLAN 493 tags based on MAC-VRF ID in conjunction with a constant value of 1 494 (i.e. MAC-VRF ID + 1). 496 6.9.1.2. VNI 498 Untagged traffic stretched across multiple fabrics MUST derive VNIs 499 based on MAC-VRF ID and Fabric ID in conjunction with a constant 500 value. These VNIs MUST correspond to EVPN Type-2 routes. 502 The algorithm shown in auto_evpn_fidevivid2vni (Figure 14) is 503 required to derive VNIs for Type-2 EVPN routes. 505 6.9.1.3. MAC Address 507 The MAC address MUST be a unicast address and also MUST be identical 508 for any IRB gateways that belong to an individual bridge-domain 509 across fabrics. The last 5-bytes MUST be a hash of the MAC-VRF ID 510 and a constant value of 1 that is calculated using the previously 511 mentioned random seed values. 513 The algorithm shown in auto_evpn_fidevividsid2mac (Figure 22) is 514 required to derive MAC addresses. 516 6.9.1.4. IPv6 IRB Gateway Address 518 The derived IPv6 gateway address MUST be from a ULA-scoped range that 519 will account for the first 6-bytes. The next 5-bytes MUST be the 520 last bytes of the derived MAC address. Finally, the remaining 521 7-bytes MUST be ::0001. 523 The algorithm shown in auto_evpn_fidevividsid2v6subnet (Figure 21) is 524 required to derive the IPv6 gateway address. 526 6.9.1.5. IPv4 IRB Gateway Address 528 The derived IPv4 gateway address MUST be from a RFC1918 range, which 529 accounts for the first octet. The next octet MUST a hash of the MAC- 530 VRF ID and a constant value of 1 that is calculated using the 531 previously mentioned random seed values. Finally, the remaining 2 532 octets MUST be 0 and 1 respectively. 534 The algorithm shown in auto_evpn_v4prefixfidevividsid2v4subnet 535 (Figure 19) is required to derive the IPv4 gateway address. It 536 should be noted that there is a higher likelihood of address 537 collisions when deriving IPv4 addresses. 539 6.9.2. Tagged Traffic in Multiple Fabrics 541 This section defines methods to derive unique VLAN, VNI, MAC, and 542 gateway address values for deployments where tagged traffic is 543 stretched across multiple fabrics. 545 6.9.2.1. VLAN 547 Tagged traffic stretched across multiple fabrics MUST derive VLAN 548 tags based on MAC-VRF ID in conjunction with a constant value of 16 549 (i.e. MAC-VRF ID + 16). 551 6.9.2.2. VNI 553 Tagged traffic stretched across multiple fabrics MUST derive VNIs 554 based on MAC-VRF ID and Fabric ID in conjunction with a constant 555 value. These VNIs MUST correspond to EVPN Type-2 routes. 557 The algorithm shown in auto_evpn_fidevivid2vni (Figure 14) is 558 required to derive VNIs for Type-2 EVPN routes. 560 6.9.2.3. MAC Address 562 The MAC address MUST be a unicast address and also MUST be identical 563 for any IRB gateways that belong to an individual bridge-domain 564 across fabrics. The last 5-bytes MUST be a hash of the MAC-VRF ID 565 and a constant value of 1 that is calculated using the previously 566 mentioned random seed values. 568 The algorithm shown in auto_evpn_fidevividsid2mac (Figure 22) is 569 required to derive MAC addresses. 571 6.9.2.4. IPv6 IRB Gateway Address 573 The derived IPv6 gateway address MUST be from a ULA-scoped range that 574 will account for the first 6-bytes. The next 5-bytes MUST be the 575 last bytes of the derived MAC address. Finally, the remaining 576 7-bytes MUST be ::0001. 578 The algorithm shown in auto_evpn_fidevividsid2v6subnet (Figure 21) is 579 required to derive the IPv6 gateway address. 581 6.9.2.5. IPv4 IRB Gateway Address 583 The derived IPv4 gateway address MUST be from a RFC1918 range, which 584 accounts for the first octet. The next octet MUST a hash of the MAC- 585 VRF ID and a constant value of 16 that is calculated using the 586 previously mentioned random seed values. Finally, the remaining 2 587 octets MUST be 0 and 1 respectively. 589 The algorithm shown in auto_evpn_v4prefixfidevividsid2v4subnet 590 (Figure 19) is required to derive the IPv4 gateway address. It 591 should be noted that there is a higher likelihood of address 592 collisions when deriving IPv4 addresses. 594 6.9.3. Tagged Traffic in a Single Fabric 596 This section defines a method to derive unique VLAN, VNI, MAC, and 597 gateway address values for deployments where untagged traffic is 598 contained within a single fabric. 600 6.9.3.1. VLAN 602 Tagged traffic contained to a single fabric MUST derive VLAN tags 603 based on MAC-VRF ID and Fabric ID in conjunction with a constant 604 value of 17 (i.e. MAC-VRF ID + Fabric ID + 17). 606 6.9.3.2. VNI 608 Tagged traffic contained to a single fabric MUST derive VNIs based on 609 MAC-VRF ID and Fabric ID in conjunction with a constant value. These 610 VNIs MUST correspond to EVPN Type-2 routes. 612 The algorithm shown in auto_evpn_fidevivid2vni (Figure 14) is 613 required to derive VNIs for Type-2 EVPN routes. 615 6.9.3.3. MAC Address 617 The MAC address MUST be a unicast address and also MUST be identical 618 for any IRB gateways that belong to an individual bridge-domain 619 across fabrics. The last 5-bytes MUST be a hash of the MAC-VRF ID 620 and a constant value of 1 that is calculated using the previously 621 mentioned random seed values. 623 The algorithm shown in auto_evpn_fidevividsid2mac (Figure 22) is 624 required to derive MAC addresses. 626 6.9.3.4. IPv6 IRB Gateway Address 628 The derived IPv6 gateway address MUST be from a ULA-scoped range, 629 which accounts for the first 6-bytes. The next 5-bytes MUST be the 630 last bytes of the derived MAC address. Finally, the remaining 631 7-bytes MUST be ::0001. 633 The algorithm shown in auto_evpn_fidevividsid2v6subnet (Figure 21) is 634 required to derive the IPv6 gateway address. 636 6.9.3.5. IPv4 IRB Gateway Address 638 The derived IPv4 gateway address MUST be from a RFC1918 range, which 639 accounts for the first octet. The next octet MUST a hash of the MAC- 640 VRF ID and a constant value of 17 that is calculated using the 641 previously mentioned random seed values. Finally, the remaining 2 642 octets MUST be 0 and 1 respectively. 644 The algorithm shown in auto_evpn_v4prefixfidevividsid2v4subnet 645 (Figure 19) is required to derive the IPv4 gateway address. It 646 should be noted that there is a higher likelihood of address 647 collisions when deriving IPv4 addresses. 649 6.9.4. Traffic Routed to External Destinations 650 6.9.4.1. Route Distinguisher 652 Nodes hosting IP Prefix routes MUST derive a type-0 route 653 distinguisher based on its System ID and Fabric ID so that it is 654 unique per IP-VRF and per node. 656 The algorithm shown in auto_evpn_sidfid2rd (Figure 18) is required to 657 derive the Route Target. 659 6.9.4.2. Route Target 661 Nodes hosting IP prefix routes MUST derive a route target extended 662 community based on the MAC-VRF ID for each IP-VRF so that it is 663 unique across the network. Route targets MUST be of type 0. 665 The algorithm shown in auto_evpn_evi2rt (Figure 12) is required to 666 derive the Route Target community. 668 6.10. Auto-EVPN Analytics 670 Leaf nodes MAY optionally advertise analytics information about the 671 Auto-EVPN fabric to ToF nodes using RIFT Key-Value TIEs. This may be 672 advantageous in that overlay validation and troubleshooting 673 activities can be performed on the ToF nodes. 675 This section requests suggested values from the RIFT Well-Known Key- 676 Type Registry and describes their use for Auto-EVPN. 678 +===================+=======+====================================+ 679 | Name | Value | Description | 680 +===================+=======+====================================+ 681 | Auto-EVPN | 3 | Analytics describing a MAC-VRF on | 682 | Analytics MAC-VRF | | a particular node within a fabric. | 683 +-------------------+-------+------------------------------------+ 684 | Auto-EVPN | 4 | Analytics describing an Auto-EVPN | 685 | Analytics Global | | node within a fabric. | 686 +-------------------+-------+------------------------------------+ 688 Table 1: Requested RIFT Key Registry Values 690 The normative Thrift schema can be found in the appendix 691 (Appendix A.4). 693 6.10.1. Auto-EVPN Global Analytics Key Type 695 This Key Type describes node level information within the context of 696 the Auto-EVPN fabric. The System ID of the advertising leaf node 697 MUST be used to differentiate the node among other nodes in the 698 fabric. 700 The Auto-EVPN Global Key Type MUST be advertised with the RIFT Fabric 701 ID encoded into the 3rd and 4th bytes of the Key Identifier. 703 0 1 2 3 704 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 705 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 706 | Well-Known | Auto-EVPN (Global) | 707 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 708 | (Auto-EVPN Role, | 709 | Established BGP Peer Count, | 710 | Total BGP Peer Count,) | 711 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 713 Figure 1: Auto-EVPN Global Key-Value TIE 715 where: 717 Auto-EVPN Role: 718 The value indicating the node's Auto-EVPN role within the 719 fabric. 721 0: Illegal value, MUST NOT be used. 723 1: Auto-EVPN Leaf Gateway 725 2: Auto-EVPN Top-of-Fabric Gateway 727 Established BGP Session Count: 728 A 16-bit integer indicating the number of BGP sessions in the 729 Established state. 731 Total BGP Peer Count: 732 A 16-bit integer indicating the total number of possible BGP 733 sessions on the local node, regardless of state. 735 6.10.2. Auto-EVPN MAC-VRF Key Type 737 This Key-Value structure contains information about a specific MAC- 738 VRF within the Auto-EVPN fabric. 740 The Auto-EVPN MAC-VRF Key Type MUST be advertised with the Auto-EVPN 741 MAC-VRF ID encoded into the 3rd and 4th bytes of the Key Identifier. 743 All values advertised in a MAC-VRF Key-Value TIE MUST represent only 744 state of the local node. 746 0 1 2 3 747 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 748 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 749 | Well-Known | Auto-EVPN (MAC-VRF) | 750 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 751 | (Operational CE Interface Count, | 752 | Total CE Interface Count, | 753 | Operational IRB Interface Count, | 754 | Total IRB Interface Count, | 755 | EVPN Type-2 MAC Route Count, | 756 | EVPN Type-2 MAC/IP Route Count, | 757 | Configured VLAN Count, | 758 | MAC-VRF Name, | 759 | MAC-VRF Description,) | 760 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 762 Figure 2: Auto-EVPN MAC-VRF Key-Value TIE 764 where: 766 Operational Customer Edge Interface Count: 767 A 16-bit integer indicating the number of CE interfaces 768 associated with the MAC-VRF where both administrative and 769 operational status are "up". 771 Total Customer Edge Interface Count: 772 A 16-bit integer indicating the total number of CE interfaces 773 associated with the MAC-VRF regardless of interface status. 775 Operational IRB Interface Count: 776 A 16-bit integer indicating the number of IRB interfaces 777 associated with the MAC-VRF where both administrative and 778 operational status are "up". 780 Total IRB Interface Count: 781 A 16-bit integer indicating the total number of IRB interfaces 782 associated with the MAC-VRF regardless of interface status. 784 EVPN Type-2 MAC Route Count: 785 A 32-bit integer indicating the total number of EVPN Type-2 MAC 786 routes. 788 EVPN Type-2 MAC/IP Route Count: 789 A 32-bit integer indicating the total number of EVPN Type-2 790 MAC/IP routes. 792 VLAN Count: 793 A 16-bit integer indicating the total number configured VLANs. 795 MAC-VRF Name: 796 A string used to indicate the name of the MAC-VRF on the node. 798 MAC-VRF Description: 799 A string used to describe the MAC-VRF on the node, similar to 800 that of an interface description. 802 7. Acknowledgements 804 The authors would like to thank Olivier Vandezande, Matthew Jones, 805 and Michal Styszynski for their contributions. 807 8. Security Considerations 809 This document introduces no new security concerns to RIFT or other 810 specifications referenced in this document. 812 9. References 814 9.1. Normative References 816 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 817 Requirement Levels", BCP 14, RFC 2119, 818 DOI 10.17487/RFC2119, March 1997, 819 . 821 [RFC7432] Sajassi, A., Aggarwal, R., Bitar, N., Isaac, A., Uttaro, 822 J., Drake, J., and W. Henderickx, "BGP MPLS-Based Ethernet 823 VPN", February 2015, 824 . 826 [RIFT] Przygienda, T., Sharma, A., Thubert, P., Rijsman, B., and 827 D. Afanasiev, "RIFT: Routing in Fat Trees", Work in 828 Progress, draft-ietf-rift-rift-13, July 2021. 830 [RIFT-KV] Head, J. and T. Przygienda, "RIFT Keys Structure and Well- 831 Known Registry in Key Value TIE", Work in Progress, draft- 832 head-rift-kv-registry-01, July 2021. 834 Appendix A. Thrift Models 836 This section contains the normative Thrift models required to support 837 Auto-EVPN. Per the main RIFT [RIFT] specification, all signed values 838 MUST be interpreted as unsigned values. 840 A.1. RIFT LIE Schema 842 A.1.1. Auto-EVPN Version 844 struct LIEPacket { 845 ... 846 /** It provides optional version of EVPN ZTP as 256 * MAJOR + MINOR */ 847 26: optional i16 auto_evpn_version; 848 ... 850 A.1.2. Fabric ID 852 struct LIEPacket { 853 ... 854 /** It provides the optional ID of the configured fabric */ 855 25: optional common.FabricIDType fabric_id; 856 ... 858 A.2. RIFT Node-TIE Schema 860 A.2.1. Auto-EVPN Version 862 struct NodeTIEElement { 863 ... 864 /** It provides optional version of EVPN ZTP as 256 * MAJOR + MINOR */ 865 13: optional i16 auto_evpn_version; 866 ... 868 A.2.2. Fabric ID 870 struct NodeTIEElement { 871 ... 872 /** It provides the optional ID of the Fabric configured */ 873 12: optional common.FabricIDType fabric_id; 874 ... 876 A.3. common_evpn.thrift 878 This section contains the normative Auto-EVPN Thrift schema. 880 /** 881 Thrift file for common AUTO EVPN definitions for RIFT 883 Copyright (c) Juniper Networks, Inc., 2016- 884 All rights reserved. 885 */ 887 namespace py common_evpn 888 namespace rs models 890 include "common.thrift" 891 include "encoding.thrift" 892 include "statistics.thrift" 894 const common.FabricIDType default_fabric_id = 1 895 const i8 default_evis = 3 896 const i8 default_vlans_per_evi = 7 898 typedef i32 RouterIDType 899 typedef i32 ASType 900 typedef i32 ClusterIDType 902 struct EVPNAnyRole { 903 1: required common.IPv6Address v6_loopback, 904 2: required common.IPv6Address type5_v6_loopback, 905 3: required common.IPv4Address type5_v4_loopback, 906 4: required RouterIDType bgp_router_id, 907 5: required ASType autonomous_system, 908 6: required ClusterIDType cluster_id, 909 /** prefixes to be redistributed north */ 910 7: required set redistribute_north, 911 /** prefixes to be redistributed south */ 912 8: required set redistribute_south, 913 /** group name for evpn auto overlay */ 914 9: required string bgp_group_name, 915 /** fabric prefixes to be advertised in rift instead of default */ 916 10: required set fabric_prefixes, 917 } 919 struct PartialEVPNEVI { 920 // route target per RFC4360 921 1: required CommunityType rt_target, 922 2: required RTDistinguisherType rt_distinguisher, 923 3: required RTDistinguisherType rt_type5_distinguisher, 924 5: required string mac_vrf_name, 925 6: required VNIType type5_vni, 926 } 927 struct EVPNRRRole { 928 2: required common.IPv6Address v6_rr_addr_loopback, 929 3: required common.IPv6PrefixType v6_peers_allowed_range, 930 4: required map evis, 931 } 933 typedef i64 RTDistinguisherType 934 typedef i64 RTTargetType 935 typedef i16 MACVRFNumberType 937 typedef i16 VLANIDType 938 typedef binary MACType 940 typedef i16 UnitType 942 struct IRBType { 943 1: required string name, 944 2: required UnitType unit, 945 /// constant 946 3: required MACType mac, 947 /// contains address of the gateway as well 948 4: optional common.IPv6PrefixType v6_subnet, 949 /// contains address of the gateway as well 950 5: optional common.IPv4PrefixType v4_prefix, 951 } 953 typedef i32 VNIType 955 struct VLANType { 956 1: optional VLANIDType id, 957 2: required string name, 958 3: optional IRBType irb, 959 5: optional bool stretched = false, 960 6: optional bool is_native = false, 961 } 963 struct CEInterfaceType { 964 2: optional common.IEEE802_1ASTimeStampType moved_to_ce, 965 // we may not be able to obtain it in case of internal errors 966 3: optional string platform_interface_name, 967 } 969 typedef i64 CommunityType 971 struct EVPNEVI { 972 // route target per RFC4360 973 1: required CommunityType rt_target, 974 2: required RTDistinguisherType rt_distinguisher, 975 3: required RTDistinguisherType rt_type5_distinguisher, 976 4: required string mac_vrf_name, 977 // fabric unique 24 bits VNI on non-stretch, otherwise unique across fabrics 978 5: required map vlans, 979 6: required VNIType type5_vni, 980 } 982 struct EVPNLeafRole { 983 1: required set rrs, 984 2: required map evis, 985 3: optional map ce_interfaces, 988 5: optional binary leaf_unique_lacp_system_id, 989 6: optional binary fabric_unique_lacp_system_id, 990 } 992 /// structure to indicate EVPN roles assumed and their variables for 993 /// external platform to configure itself accordingly. Presence of 994 /// according structure indicates that the role is assumed. 995 struct EVPNRoles { 996 1: required EVPNAnyRole generic, 997 2: optional EVPNRRRole route_reflector, 998 3: optional EVPNLeafRole leaf, 999 } 1001 const common.TimeIntervalInSecType default_leaf_delay = 120 1002 const common.TimeIntervalInSecType default_interface_ce_delay = 180 1003 /// default delay before EVPNZTP FSM starts to compute anything 1004 const common.TimeIntervalInSecType default_evpnztp_startup_delay = 60 1006 A.4. auto_evpn_kv.thrift 1008 This section contains the normative Auto-EVPN Analytics Thrift 1009 schema. 1011 include "common.thrift" 1013 namespace py auto_evpn_kv 1014 namespace rs models 1016 /** We don't need the full role structure, only an indication of the node's basic role */ 1017 enum AutoEVPNRole { 1018 ILLEGAL = 0, 1019 auto_evpn_leaf_erb = 1, 1020 auto_evpn_tof_gw = 2, 1021 } 1022 enum KVTypes { 1023 OUI = 1, 1024 WellKnown = 2, 1025 } 1027 const i8 AutoEVPNWellKnownKeyType = 1 1028 typedef i32 AutoEVPNKeyIdentifier 1029 typedef i16 AutoEVPNCounterType 1030 typedef i32 AutoEVPNLongCounterType 1032 const i8 GlobalAutoEVPNTelemetryKV = 4 1033 const i8 AutoEVPNTelemetryKV = 3 1035 /** Per the according RIFT draft the key comes from the well known space. 1036 Part of the key is used as Fabric-ID. 1038 1st byte MUST be = "Well-Known" 1039 2nd byte MUST be = "Global Auto-EVPN Telemetry KV", 1040 3rd/4th bytes MUST be = FabricIDType 1041 */ 1042 struct AutoEVPNTelemetryGlobalKV { 1043 /** Only values that the ToF cannot derive itself should be flooded. */ 1044 1: required set auto_evpn_roles, 1046 /** Established BGP peer count (for Auto-EVPN) 1047 2: optional AutoEVPNCounterType established_bgp_peer_count, 1049 /** Total BGP peer count (for Auto-EVPN) 1050 3: optional AutoEVPNCounterType total_bgp_peer_count, 1051 } 1053 /** Per the according RIFT draft the key comes from the well known space. 1054 Part of the key is used as MAC-VRF number. 1056 1st byte MUST be = "Well-Known" 1057 2nd byte MUST be = indicates "Auto-EVPN Telemetry KV", 1058 3rd/4th bytes MUST be = MACVRFNumberType 1059 */ 1060 struct AutoEVPNTelemetryMACVRFKV { 1061 /** Active CE interface count (up/up) 1062 1: optional AutoEVPNCounterType active_ce_interfaces, 1064 /** Total CE interface count 1065 2: optional AutoEVPNCounterType total_ce_interfaces, 1067 /** Active IRB interface count (up/up) 1068 3: optional AutoEVPNCounterType active_irb_interfaces, 1069 /** Total IRB interface count 1070 4: optional AutoEVPNCounterType total_irb_interfaces, 1072 /** Local EVPN Type-2 MAC route count 1073 5: optional AutoEVPNLongCounterType local_evpn_type2_mac_routes, 1075 /** Local EVPN Type-2 MAC/IP route count 1076 6: optional AutoEVPNLongCounterType local_evpn_type2_mac_ip_routes, 1078 /** number of configured VLANs */ 1079 7: optional i16 configured_vlans, 1081 /** optional human readable name */ 1082 8: optional string name, 1084 /** optional human readable string describing the MAC-VRF */ 1085 9: optional string description, 1086 } 1088 Figure 3: Auto-EVPN Key-Value Thrift Schema 1090 Appendix B. Auto-EVPN Variable Derivation 1091 use std::cell::{RefCell, RefMut}; 1092 use std::cmp::{max, min}; 1093 use std::collections::{BTreeMap, BTreeSet, HashMap}; 1094 use std::fmt::Debug; 1095 use std::net::{Ipv4Addr, Ipv6Addr}; 1096 use std::str::FromStr; 1097 use itertools::interleave; 1098 use itertools::Itertools; 1099 use rayon::slice::ParallelSliceMut; 1101 use foundation::models::common::{FabricIDType, IPv6PrefixType}; 1102 use foundation::models::common::LevelType; 1103 use foundation::models::common::HierarchyIndications; 1104 use foundation::models::common::IPPrefixType; 1105 use foundation::models::common::IPv4Address; 1106 use foundation::models::common::IPv4PrefixType; 1107 use foundation::models::common::IPv6Address; 1108 use foundation::models::common::LEAF_LEVEL; 1109 use foundation::models::common_services::ServiceErrorType; 1110 use foundation::models::common_evpn::{DEFAULT_EVIS, DEFAULT_VLANS_PER_EVI, 1111 DEFAULT_EVPNZTP_STARTUP_DELAY, DEFAULT_FABRIC_ID, DEFAULT_INTERFACE_CE_DELAY, 1112 DEFAULT_LEAF_DELAY, EVPNAnyRole, EVPNLeafRole, 1113 EVPNRoles, EVPNRRRole, UnitType}; 1114 use foundation::models::common_evpn::CEInterfaceType; 1115 use foundation::models::common_evpn::CommunityType; 1116 use foundation::models::common_evpn::EVPNEVI; 1117 use foundation::models::common_evpn::IRBType; 1118 use foundation::models::common_evpn::MACVRFNumberType; 1119 use foundation::models::common_evpn::PartialEVPNEVI; 1120 use foundation::models::common_evpn::RTDistinguisherType; 1121 use foundation::models::common_evpn::VLANIDType; 1122 use foundation::models::common_evpn::VLANType; 1123 use foundation::models::common_evpn::VNIType; 1124 use ILLEGAL_SYSTEM_I_D; 1125 use NodeCapabilities; 1126 use UnsignedSystemID; 1128 Figure 4: auto_evpn_imports 1130 /// indicates how many RRs we're computing in EVPN ZTP 1131 pub const MAX_AUTO_EVPN_RRS: usize = 3; 1132 /// indicates the fabric has no ID, used in computations to omit effects of fabric ID 1133 pub const NO_FABRIC_ID: FabricIDType = 0; 1134 /// invalid MACVRF number, MACVRFs start from 1 1135 pub const NO_MACVRF: MACVRFNumberType = 0; 1137 /// unique v6 prefix for all nodes starts with this 1138 pub const AUTO_EVPN_V6PREF: &str = "FD00:A1"; 1139 /// how many bytes in a v6pref for RRs 1140 pub const AUTO_EVPN_V6PREFLEN: usize = 8 * 3; 1141 /// unique v6 prefix for route reflector purposes starts like this 1142 pub const AUTO_EVPN_V6RRPREF: &str = "FD00:A2"; 1143 /// unique v6 prefix for type-5 purposes starts like this 1144 pub const AUTO_EVPN_V6T5PREF: &str = "FD00:A3"; 1145 /// unique v6 prefix for IRB prefix purposes 1146 pub const AUTO_EVPN_V6IRBPREF: &str = "FD00"; 1147 /// unique v6 prefix first byte for v6 IRB prefix purposes 1148 pub const AUTO_EVPN_V6IRBPREFFIRSTBYTE: u8 = 0xA4; 1149 /// unique v4 prefix for IRB purposes 1150 pub const AUTO_EVPN_V4IRBPREF: &str = "10"; 1151 /// 3 bytes of prefix type and then we have fabric ID after that 1152 pub const AUTO_EVPN_V6_FABPREFIXLEN: usize = 8 + 8 + 8 + 16; 1154 /// per RFC magic 1155 const RT_TARGET_HIGH: CommunityType = 0; 1156 const RT_TARGET_LOW: CommunityType = 0; 1158 /// first available VLAN number 1159 pub const FIRST_VLAN: VLANIDType = 1; 1160 // maximum vlan number one less than maximum to use as bitmask 1161 pub const MAX_VLAN: VLANIDType = 4095; 1162 /// constant VLAN shift 1163 pub const FIRST_VLAN_SHIFT: VLANIDType = 16; 1164 /// NATIVE VLAN number 1165 pub const NATIVE_VLAN: VLANIDType = 1; 1167 /// abstract description of VLAN properties for a derived VLAN 1168 pub struct VLANDescription { 1169 pub vlan_id: VLANIDType, 1170 pub name: String, 1171 /// can this VLAN be stretched across multiple fabrics 1172 pub stretchable: bool, 1173 pub native: bool, 1174 } 1176 /// maximum number of VLANs per MACVRF 1177 pub const MAX_VLANS_PER_EVI: usize = 15; 1179 pub type VLANStretchableType = bool; 1180 pub type VLANNativeType = bool; 1182 pub const EXTRATYPE5_RD_DISTINGUISHER: u32 = 0xffff_ffff; 1184 /// high bits of type 5 VNI 1185 const TYPE5VNIHIGH: VNIType = 0x0080_0000; 1186 /// bitmask for type 2 VNI 1187 const TYPE2VNIMASK: VNIType = 0x00ff_ffff ^ TYPE5VNIHIGH; 1189 /// random seeds used in several algorithms to increase entropy 1190 pub const RANDOMSEEDS: [u64; 4] = [ 1191 27008318799u64, 1192 67438371571, 1193 37087353685, 1194 88675895388, 1195 ]; 1197 Figure 5: auto_evpn_const_structs_type 1199 pub(crate) fn auto_evpn_sids2rrs(mut v: Vec) -> Vec { 1200 v.par_sort_unstable(); 1201 let r = if v.len() > 2 { 1202 let mut s = v.split_off(v.len() / 2); 1203 s.reverse(); 1204 interleave(v.into_iter(), s.into_iter()).collect() 1205 } else { 1206 v 1207 }; 1209 r 1210 } 1212 Figure 6: auto_evpn_sids2rrs 1214 pub(crate) fn auto_evpn_v62octets(a: Ipv6Addr) -> Vec { 1215 a.octets().iter().cloned().collect() 1216 } 1218 Figure 7: auto_evpn_v62octets 1220 /// fabric prefixes derived instead of advertising default on the fabric to allow 1221 /// for default route on ToF or leaves 1222 pub fn auto_evpn_fid2fabric_prefixes(fid: FabricIDType) -> Result, ServiceErrorType> { 1223 vec![ 1224 (auto_evpn_fidsidv6loopback(fid, ILLEGAL_SYSTEM_I_D as _), AUTO_EVPN_V6PREFLEN), 1225 (auto_evpn_fidrrpref2rrloopback(fid, ILLEGAL_SYSTEM_I_D as _), AUTO_EVPN_V6PREFLEN), 1226 ] 1227 .into_iter() 1228 .map(|(p, _)| 1229 match p { 1230 Ok(_) => Ok( 1231 IPPrefixType::Ipv6prefix( 1232 IPv6PrefixType { 1233 address: auto_evpn_v62octets(p?), 1234 prefixlen: AUTO_EVPN_V6PREFLEN as _, 1235 })), 1236 Err(e) => Err(e), 1237 } 1238 ) 1239 .collect::, _>>() 1240 } 1242 Figure 8: auto_evpn_fid2fabric_prefixes 1244 /// local address with encoded fabric ID and system ID for collision free identifiers. Basis 1245 /// for several different prefixes. 1246 pub fn auto_evpn_v6prefixfidsid2loopback(v6pref: &str, fid: FabricIDType, 1247 sid: UnsignedSystemID) -> Result { 1248 assert!(fid != 0); 1249 let a = format!("{}{:02X}::{}", 1250 v6pref, 1251 fid as u16, 1252 sid.to_ne_bytes() 1253 .iter() 1254 .chunks(2) 1255 .into_iter() 1256 .map(|chunk| 1257 chunk.fold(0u16, |v, n| (v << 8) | *n as u16)) 1258 .map(|v| format!("{:04X}", v)) 1259 .collect::>() 1260 .into_iter() 1261 .join(":") 1262 ); 1264 Ipv6Addr::from_str(&a) 1265 .map_err(|_| ServiceErrorType::INTERNALRIFTERROR) 1266 } 1267 Figure 9: auto_evpn_v6prefixfidsid2loopback 1269 /// auto evpn V6 loopback for RRs 1270 pub fn auto_evpn_fidrrpref2rrloopback(fid: FabricIDType, 1271 preference: u8) -> Result { 1272 auto_evpn_v6prefixfidsid2loopback(AUTO_EVPN_V6RRPREF, fid, (1 + preference) as _) 1273 } 1275 Figure 10: auto_evpn_fidrrpref2rrloopback 1277 /// auto evpn BGP router ID 1278 pub fn auto_evpn_sidfid2bgpid(fid: FabricIDType, sid: UnsignedSystemID) -> u32 { 1279 assert!(fid != 0); 1280 let hs: u32 = ((sid & 0xffff_ffff_0000_0000) >> 32) as _; 1281 let mut ls: u32 = (sid & 0xffff_ffff) as _; 1282 ls = ls.rotate_right(7) ^ (fid as u32).rotate_right(13); 1283 max(1, hs ^ ls) // never a 0 1284 } 1286 Figure 11: auto_evpn_sidfid2bgpid 1288 /// route target bytes are type0/0 and then add EVI 1289 pub fn auto_evpn_evi2rt(evi: MACVRFNumberType) -> CommunityType { 1290 let wideevi = (evi + 1) as CommunityType; 1292 (RT_TARGET_HIGH << (64 - 8)) | (RT_TARGET_LOW << 64 - 16) | 1293 ((wideevi) << 17) | 1294 ((wideevi)) 1295 } 1297 Figure 12: auto_evpn_evi2rt 1299 /// type-5 VNI for an EVI 1300 pub fn auto_evpn_fidevi2type5vni(fid: FabricIDType, evi: MACVRFNumberType) -> VNIType { 1301 TYPE5VNIHIGH | auto_evpn_fidevivid2vni(fid, evi, 0) 1302 } 1304 Figure 13: auto-evpn_fidevi2type5vni 1306 /// type-2 VNI for a specific VLAN 1307 pub fn auto_evpn_fidevivid2vni(fid: FabricIDType, evi: MACVRFNumberType, vlanid: VLANIDType) -> VNIType { 1308 let rfid = fid as i32; 1309 let revi = evi as i32; 1310 let rvlan = vlanid as i32; 1311 // mask out high bits, VNI is only 24 bits 1312 TYPE2VNIMASK & 1313 ( 1314 rfid.rotate_left(16) ^ 1315 revi.rotate_left(12) ^ 1316 rvlan 1317 ) 1318 } 1320 Figure 14: auto_evpn_fidevivid2vni 1322 /// maximum VLANs per EVI supported by auto evpn when deriving 1323 pub fn auto_evpn_vlan_description_table<'a>(vlans: usize) 1324 -> Result<&'a [(VLANIDType, VLANStretchableType, VLANNativeType)], ServiceErrorType> { 1325 // up to 15 vlans can be activated 1326 const VLANSARRAY: [(i16, bool, bool); MAX_VLANS_PER_EVI] = [ 1327 (NATIVE_VLAN, true, true, ), 1328 (FIRST_VLAN_SHIFT, true, false, ), 1329 (FIRST_VLAN_SHIFT + 1, true, false, ), 1330 (FIRST_VLAN_SHIFT + 2, true, false, ), 1331 (FIRST_VLAN_SHIFT + 3, false, false, ), 1332 (FIRST_VLAN_SHIFT + 4, false, false, ), 1333 (FIRST_VLAN_SHIFT + 5, false, false, ), 1334 (FIRST_VLAN_SHIFT + 6, false, false, ), 1335 (FIRST_VLAN_SHIFT + 7, false, false, ), 1336 (FIRST_VLAN_SHIFT + 8, false, false, ), 1337 (FIRST_VLAN_SHIFT + 9, false, false, ), 1338 (FIRST_VLAN_SHIFT +10, false, false, ), 1339 (FIRST_VLAN_SHIFT +11, false, false, ), 1340 (FIRST_VLAN_SHIFT +12, false, false, ), 1341 (FIRST_VLAN_SHIFT +13, false, false, ), 1342 ]; 1344 if vlans > VLANSARRAY.len() { 1345 return Err(ServiceErrorType::INVALIDPARAMETERVALUE) 1346 } 1348 Ok(&VLANSARRAY[..vlans]) 1349 } 1351 Figure 15: auto_evpn_vlan_description_table 1353 /// delivers the vlan description that can be used to generate vlans for a 1354 /// specific fabric ID and a MACVRF number 1355 pub fn auto_evpn_fidevivlansvlans2desc(fid: FabricIDType, macvrf: MACVRFNumberType, 1356 vlans: usize) -> Vec { 1358 assert!(NO_MACVRF != macvrf); 1360 // abstract description of derived VLANs 1361 let vlan_table = auto_evpn_vlan_description_table(vlans) 1362 .expect("vlan table in AUTO EVPN incorrect"); 1364 let vlanshift = vlan_table 1365 .iter() 1366 .map(|(vl, _, _)| *vl as usize) 1367 .max() 1368 .expect("vlan table in AUTO EVPN incorrect") 1369 .checked_next_power_of_two() 1370 .expect("vlan table in AUTO EVPN incorrect"); 1372 assert!(vlan_table.len() < FIRST_VLAN_SHIFT as _); 1374 vlan_table 1375 .iter() 1376 .map(move |(vid, stretch, native_)| { 1377 let stretchedfid = if !stretch { 1378 fid 1379 } else { 1380 NO_FABRIC_ID 1381 }; 1383 let mut vlan_id = *vid ^ stretchedfid 1384 .rotate_left(max(16, vlanshift as u32 + 8)) as VLANIDType; 1385 // leave space for VLANs in the encoding 1386 vlan_id ^= macvrf.rotate_left(vlanshift as _) as VLANIDType; 1388 vlan_id %= MAX_VLAN; 1389 vlan_id = max(1, vlan_id); 1391 VLANDescription { 1392 vlan_id: vlan_id as _, 1393 name: format!("V{}", vlan_id), 1394 stretchable: *stretch, 1395 native: *native_, 1396 } 1397 }) 1398 .collect() 1399 } 1400 Figure 16: auto_evpn_fidevivlansvlans2desc 1402 /// IRB interface number. 1403 /// fid/evi combination shifted up to not interfere with the VLAN-ID 1404 /// and then add the VLAN-ID 1405 pub fn auto_evpn_fidevivid2irb(fid: FabricIDType, evi: MACVRFNumberType, vid: VLANIDType) -> UnitType { 1407 assert!(NO_MACVRF != evi); 1409 let mut v = (fid as UnitType ^ evi.rotate_left(4) as UnitType) << (16 - FIRST_VLAN.leading_zeros()); 1411 v = 1 + v.wrapping_add(vid) % MAX_VLAN; 1412 v % (UnitType::MAX - 1) 1413 } 1415 Figure 17: auto_evpn_fidevivid2irb 1417 /// route distinguisher derivation 1418 pub fn auto_evpn_sidfid2rd(sid: UnsignedSystemID, fid: FabricIDType, extra: u32) -> RTDistinguisherType { 1419 // generate type 0 route distinguisher, first 2 bytes 0 and then 6 bytes 1420 assert!(fid != NO_FABRIC_ID); 1421 // shift the 2 bytes we loose 1422 let convsid = sid as RTDistinguisherType; 1423 let hs = ((sid & 0xffff_0000_0000_0000) >> 32) as RTDistinguisherType; 1424 let mut ls: RTDistinguisherType = convsid & 0x0000_ffff_ffff_ffff; 1425 ls ^= hs; 1426 ls ^= (fid as RTDistinguisherType).rotate_left(16); 1427 ls ^= extra as RTDistinguisherType; 1428 ls 1429 } 1431 Figure 18: auto_evpn_sidfid2rd 1433 /// v4 subnet derivation 1434 pub fn auto_evpn_v4prefixfidevividsid2v4subnet(v4pref: &str, fid: FabricIDType, 1435 evi: MACVRFNumberType, vid: VLANIDType, 1436 sid: UnsignedSystemID) -> Result { 1438 assert!(NO_MACVRF != evi); 1440 // fid can be 0 for stretched v4subnets 1441 let mut sub = evi.to_ne_bytes().iter() 1442 .fold((RANDOMSEEDS[0] & 0xff) as u8, |r, e| r.rotate_left(1) ^ e.rotate_right(1)); 1443 sub ^= fid.to_ne_bytes().iter() 1444 .fold((RANDOMSEEDS[1] & 0xff) as u8, |r, e| r.rotate_left(2) ^ e.rotate_right(1)); 1445 sub ^= vid.to_ne_bytes().iter() 1446 .fold((RANDOMSEEDS[2] & 0xff) as u8, |r, e| r.rotate_left(3) ^ e.rotate_right(1)); 1448 let subnet = sub % 254; // make sure we don't show multicast subnet 1450 let _host = sid.to_ne_bytes().iter() 1451 .fold(0u16, |r, e| r.rotate_left(3) ^ e.rotate_right(3) as u16); 1453 let a = format!("{}.{}.{}.{}", 1454 v4pref, 1455 subnet, 1456 0, 1457 1, 1458 ); 1460 Ok( 1461 IPv4PrefixType { 1462 address: Ipv4Addr::from_str(&a) 1463 .map_err(|_| { 1464 ServiceErrorType::INTERNALRIFTERROR 1465 })? 1466 .octets() 1467 .iter() 1468 .fold(0u32, |v, nv| v << 8 | (*nv as u32)) as IPv4Address 1469 , 1470 prefixlen: 16, 1471 } 1472 ) 1473 } 1475 Figure 19: auto_evpn_v4prefixfidevividsid2v4subnet 1477 /// generic v6 bytes derivation used for different purposes 1478 pub fn auto_evpn_v6hash(fid: FabricIDType, evi: MACVRFNumberType, vid: VLANIDType, sid: UnsignedSystemID) 1479 -> [u8; 8] { 1481 let mut sub = evi.to_ne_bytes().iter() 1482 .fold(RANDOMSEEDS[3], |r, e| r.rotate_left(6) ^ e.rotate_right(4) as u64); 1483 sub ^= fid.to_ne_bytes().iter() 1484 .fold(RANDOMSEEDS[0], |r, e| r.rotate_left(6) ^ e.rotate_right(4) as u64); 1485 sub ^= vid as u64; 1486 sub ^= sid; 1488 sub.to_ne_bytes() 1489 } 1491 Figure 20: auto_evpn_v6hash 1493 pub fn auto_evpn_fidevividsid2v6subnet(fid: FabricIDType, evi: MACVRFNumberType, 1494 vid: VLANIDType, 1495 sid: UnsignedSystemID) -> Result { 1497 assert!(NO_MACVRF != evi); 1499 let sb = auto_evpn_v6hash(fid, evi, vid, sid); 1501 let a = format!("{}:{:02X}{:02X}:{:02X}{:02X}:{:02X}{:02X}::1", 1502 AUTO_EVPN_V6IRBPREF, 1503 AUTO_EVPN_V6IRBPREFFIRSTBYTE, 1504 sb[3] ^ sb[0], 1505 sb[4] ^ sb[1], 1506 sb[5] ^ sb[2], 1507 sb[6], 1508 sb[7], 1509 ); 1511 Ok(IPv6PrefixType { 1512 address: Ipv6Addr::from_str( 1513 &a) 1514 .map_err(|_| { 1515 ServiceErrorType::INTERNALRIFTERROR 1516 })? 1517 .octets() 1518 .to_vec(), 1519 prefixlen: 64, 1520 }) 1521 } 1523 Figure 21: auto_evpn_fidevividsid2v6subnet 1525 /// MAC address derivation for IRB 1526 pub fn auto_evpn_fidevividsid2mac(fid: FabricIDType, evi: MACVRFNumberType, 1527 vid: VLANIDType, sid: UnsignedSystemID) -> Vec { 1529 let sb = auto_evpn_v6hash(fid, evi, vid, sid); 1531 vec![0x02, 1532 sb[3] ^ sb[0], 1533 sb[4] ^ sb[1], 1534 sb[5] ^ sb[2], 1535 sb[6], 1536 sb[7], 1537 ] 1538 } 1540 Figure 22: auto_evpn_fidevividsid2mac 1542 /// v4 loopback address derivation for every node in auto-evpn 1543 pub fn auto_evpn_fidsid2v4loopback(fid: FabricIDType, sid: UnsignedSystemID) -> IPv4Address { 1544 let mut derived = sid.to_ne_bytes().iter() 1545 .fold(0 as IPv4Address, |p, e| (p << 4) ^ (*e as IPv4Address)); 1546 derived ^= fid as IPv4Address; 1547 // use the byte we loose for entropy 1548 derived ^= derived >> 24; 1549 // and sanitize for loopback range 1550 derived &= 0x00ff_ffff; 1552 let m = ((127 as IPv4Address) << 24) | derived; 1553 m as _ 1554 } 1556 Figure 23: auto_evpn_fidsid2v4loopback 1558 /// V6 loopback derivation for every node in auto-evpn 1559 pub fn auto_evpn_fidsidv6loopback(fid: FabricIDType, 1560 sid: UnsignedSystemID) -> Result { 1561 auto_evpn_v6prefixfidsid2loopback(AUTO_EVPN_V6PREF, fid, sid) 1562 } 1564 Figure 24: auto_evpn_fidsidv6loopback 1566 #[allow(non_snake_case)] 1567 pub fn auto_evpn_fid2private_AS(fid: FabricIDType) -> u32 { 1568 assert!(fid != NO_FABRIC_ID); 1569 // range 4200000000-4294967294 1570 const DIFF: u32 = 4_294_967_294 - 4_200_000_000; 1571 64496 + ((fid as u32) << 3) % DIFF 1572 } 1573 Figure 25: auto_evpn_fid2private_AS 1575 pub fn auto_evpn_fid2clusterid(fid: FabricIDType) -> u32 { 1576 auto_evpn_fid2private_AS(fid) 1577 } 1579 Figure 26: auto_evpn_fid2clusterid 1581 Authors' Addresses 1583 Jordan Head (editor) 1584 Juniper Networks 1585 1137 Innovation Way 1586 Sunnyvale, CA 1587 United States of America 1589 Email: jhead@juniper.net 1591 Tony Przygienda 1592 Juniper Networks 1593 1137 Innovation Way 1594 Sunnyvale, CA 1595 United States of America 1597 Email: prz@juniper.net 1599 Wen Lin 1600 Juniper Networks 1601 10 Technology Park Drive 1602 Westford, MA 1603 United States of America 1605 Email: wlin@juniper.net