E-Line (EVPN VPWS) Multi-Homed

EVPN VPWS gives us the ability to multihome the CE on a p2p connection natively within the protocol. This gives us active/active layer 2 multihoming to two separate PEs without needing an MLAG between the PEs. It is also incredibly easy to configure with EVPN.

In the single-homed EVPN VPWS lab, the ESI was all zeros. ESI (Ethernet Segment Identifier) is used to identify a group of links that go to the same CE. A single-homed device has an ESI of zeros. But now that we are multi-homed, the ESI value is important, and we will discuss how this works.

ESI essentially identifies an EVPN LAG (link aggregation group). The ESI identifies a multi-homed segment. The segment in this case is two or more links. The term “segment” can be slightly confusing because we are used to thinking of a single link as a segment, but just remember that the set of links is an Ethernet segment. In EVPN, an ethernet segment means a group of links that should be treated as a single LAG.

The CE which is multihomed will see these two links as a port-channel. This means you can use two diverse physical circuits, terminating on two different PEs, to act as a single L2 port-channel. Usually, you would think that each PE needs to run some sort of multi-chassis aggregation protocol, in order for the CE’s LACP process to believe that each PE is actually the same system. But in EVPN we don’t need to have any sort of interchassis link between the PEs. The PEs will statically define the lacp system mac on the interface, but that’s it. This “tricks” the CE’s LACP process into thinking it is connected to the same system on both links. The PEs know about each other because they see each other’s ESI for this AC, which is the same, using EVPN type-1 and type-4 routes.

We’ll be using XR9000v for this demo, because I cannot find support for EPVN multihoming in CSR1000v.

Lab

In this lab, CE1 is multihomed to PE1 and PE2. CE2 is multihomed to PE3 and PE4. Each CE has a single port-channel. The two CEs believe they are connected back-to-back on these port-channels.

OSPF, MPLS/LDP and IPs have been configured in the MPLS core already. Be aware that this is all configured using XR9000v in the core, which uses IOS-XR, not IOS-XE. The CEs are IOSvL2. P5 can be XRv or XR9000v.

PE1#
hostname PE1
!
interface Loopback0
 ipv4 address 1.1.1.1 255.255.255.255
!
interface GigabitEthernet0/0/0/0
 ipv4 address 10.1.5.1 255.255.255.0
!
router ospf 1
 area 0
  interface Loopback0
  !
  interface GigabitEthernet0/0/0/0
   network point-to-point
!
mpls ldp
 interface GigabitEthernet0/0/0/0

PE2#
hostname PE2
!
interface Loopback0
 ipv4 address 2.2.2.2 255.255.255.255
!
interface GigabitEthernet0/0/0/0
 ipv4 address 10.2.5.2 255.255.255.0
!
router ospf 1
 area 0
  interface Loopback0
  !
  interface GigabitEthernet0/0/0/0
   network point-to-point
!
mpls ldp
 interface GigabitEthernet0/0/0/0

PE3#
hostname PE3
!
interface Loopback0
 ipv4 address 3.3.3.3 255.255.255.255
!
interface GigabitEthernet0/0/0/0
 ipv4 address 10.3.5.3 255.255.255.0
!
router ospf 1
 area 0
  interface Loopback0
  !       
  interface GigabitEthernet0/0/0/0
   network point-to-point
!
mpls ldp
 interface GigabitEthernet0/0/0/0

PE4#
hostname PE4
!
interface Loopback0
 ipv4 address 4.4.4.4 255.255.255.255
!
interface GigabitEthernet0/0/0/0
 ipv4 address 10.4.5.4 255.255.255.0
!
router ospf 1
 area 0
  interface Loopback0
  !       
  interface GigabitEthernet0/0/0/0
   network point-to-point
!
mpls ldp
 interface GigabitEthernet0/0/0/0

P5#
hostname P5
!
interface Loopback0
 ipv4 address 5.5.5.5 255.255.255.255
!
interface GigabitEthernet0/0/0/1
 ipv4 address 10.1.5.5 255.255.255.0
!
interface GigabitEthernet0/0/0/2
 ipv4 address 10.2.5.5 255.255.255.0
!
interface GigabitEthernet0/0/0/3
 ipv4 address 10.3.5.5 255.255.255.0
!
interface GigabitEthernet0/0/0/4
 ipv4 address 10.4.5.5 255.255.255.0
!
router ospf 1
 area 0
  interface Loopback0
  !
  interface GigabitEthernet0/0/0/1
   network point-to-point
  !
  interface GigabitEthernet0/0/0/2
   network point-to-point
  !
  interface GigabitEthernet0/0/0/3
   network point-to-point
  !
  interface GigabitEthernet0/0/0/4
   network point-to-point
!
mpls ldp
 interface GigabitEthernet0/0/0/1
 !
 interface GigabitEthernet0/0/0/2
 !
 interface GigabitEthernet0/0/0/3
 !
 interface GigabitEthernet0/0/0/4

First we’ll enable BGP, using P5 as the RR. We’ll need to active the l2vpn/evpn address-family as before.

PE1,PE2,PE3,PE4#
router bgp 65000
 address-family l2vpn evpn
 !
 neighbor 5.5.5.5
  remote-as 65000
  update-source Loopback0
  address-family l2vpn evpn

P5#
router bgp 65000
 address-family l2vpn evpn
 !
 neighbor-group IBGP
  remote-as 65000
  update-source Loopback0
  address-family l2vpn evpn
   route-reflector-client
  !
 !
 neighbor 1.1.1.1
  use neighbor-group IBGP
 !
 neighbor 2.2.2.2
  use neighbor-group IBGP
 !
 neighbor 3.3.3.3
  use neighbor-group IBGP
 !
 neighbor 4.4.4.4
  use neighbor-group IBGP

EVPN VPWS configuration on IOS-XR is fairly similar to IOS-XE as we saw in the previous article. We’ll configure the EVPN VPWS on PE1, PE2, PE3, and PE4. We’ll use the service IDs of 101 and 301 like before. So far there is no multihoming specific configuration yet. (Other than the fact that PE1/PE2 and PE3/PE4 share the same xconnect config).

PE1,PE2#
l2vpn
 xconnect group EVPN_VPWS
  p2p CUSTOMER
   interface Bundle-Ether1
   neighbor evpn evi 1 target 301 source 101

PE3,PE4#
l2vpn
 xconnect group EVPN_VPWS
  p2p CUSTOMER
   interface Bundle-Ether1
   neighbor evpn evi 1 target 101 source 301

On all PEs we’ll configure BE1 (which is like Po1 in IOS-XE) to face the CE. BE stands for bundle ethernet. There will only be a single interface in the bundle on each PE and we want two PEs to act as a single LACP system. To do this, we must configure the same LACP system MAC on each pair of PEs (PE1/PE2 and PE3/PE4).

PE1,PE2#
lacp system mac 1111.1111.1111
!
interface Bundle-Ether1
 l2transport
!
interface GigabitEthernet0/0/0/1
 bundle id 1 mode active

PE3,PE4#
lacp system mac 2222.2222.2222
!
interface Bundle-Ether1
 l2transport
!
interface GigabitEthernet0/0/0/1
 bundle id 1 mode active

Here’s the interesting part. We configure the ESI under the evpn config section.

PE1,2#
evpn
 interface Bundle-Ether1
  ethernet-segment
   identifier type 0 00.01.00.00.00.00.00.00.01

PE3,4#
evpn
 interface Bundle-Ether1
  ethernet-segment
   identifier type 0 00.02.00.00.00.00.00.00.02

PE1/PE2 and PE3/PE4 configure their BE1 to have the same ESI. This is the secret ingredient to achieving a multihomed p2p service.

Let’s configure the CEs, verify the service works, and then dig deeper into the inner workings of EVPN. LACP was not working on CSR1000v for me in CML, so I used IOSvL2 instead. (Port-channels do not work on IOSv).

CE1#
hostname CE1
!
line con 0
 logging sync
!
int range Gi0/0-1
 sw acc vlan 10
 channel-group 1 mode active
!
int vlan10
 ip address 10.1.1.1 255.255.255.0
 no shut
!
router ospf 1
 network 0.0.0.0 255.255.255.255 area 0

CE2#
hostname CE2
!
line con 0
 logging sync
!
int range Gi0/0-1
 sw acc vlan 10
 channel-group 1 mode active
!
int vlan10
 ip address 10.1.1.2 255.255.255.0
 no shut
!
router ospf 1
 network 0.0.0.0 255.255.255.255 area 0

We have an OSPF adjacency up between CE1 and CE2:

CE1#show ip ospf nei

Neighbor ID     Pri   State           Dead Time   Address         Interface
10.1.1.2          1   FULL/BDR        00:00:35    10.1.1.2        Vlan10

You can experiment with shutting down one link at a time, and seeing if your OSPF adjancency stays up

EVPN ESI Behind the Scenes

PE1 and PE2 need a way to discover that they are both connected to the same Ethernet segment in order to determine which PE will forward BUM traffic onto the segment. If both PEs forward BUM traffic, the CE will receive duplicate frames. This is done with the EVPN type 4 route.

The type 4 route advertises the ESI. This route contains an ES-Import RT that ensures only the PEs connected to the same ESI will use this route. This is because the ES-Import RT is derived from the ESI value. I believe the value is the first 6 bytes of the ESI value (which is 10 bytes total).

Here is the type 4 route advertised by PE2:

RP/0/RP0/CPU0:PE1#show bgp l2vpn evpn rd 2.2.2.2:0 [4][0000.0100.0000.0000.0001][32][2.2.2.2]/128
<snip>
  Local
    2.2.2.2 (metric 3) from 5.5.5.5 (2.2.2.2)
      Origin IGP, localpref 100, valid, internal, best, group-best, import-candidate, not-in-vrf
      Received Path ID 0, Local Path ID 1, version 100
      Extended community: EVPN ES Import:0001.0000.0000 DF Election:0:0x0008:0 
      Originator: 2.2.2.2, Cluster list: 5.5.5.5

PE1 will not even accept the type 4 routes from PE3 and PE4 since they have a different EVPN ES Import value:

RP/0/RP0/CPU0:PE1#show bgp l2vpn evpn route-type 4 | beg Network
Wed Oct  5 15:08:10.724 UTC
   Network            Next Hop            Metric LocPrf Weight Path
Route Distinguisher: 1.1.1.1:0 (default for vrf ES:GLOBAL)
*> [4][0000.0100.0000.0000.0001][32][1.1.1.1]/128
                      0.0.0.0                                0 i
*>i[4][0000.0100.0000.0000.0001][32][2.2.2.2]/128
                      2.2.2.2                       100      0 i
Route Distinguisher: 2.2.2.2:0
*>i[4][0000.0100.0000.0000.0001][32][2.2.2.2]/128
                      2.2.2.2                       100      0 i

Processed 3 prefixes, 3 paths
  • Here we see PE1’s route-type 4, PE2’s route-type 4, and the PE2 route that PE1 injected itself using its own RID. The PE3 and PE4 route-type 4 routes are not even accepted into the table.

When a PE sees that another PE connects to the same ESI, the PE will implement split-horizon. If the CE sends a BUM frame to the non-DF PE, and the non-DF PE forwards it to the DF PE, the DF PE shouldn’t send the frame back to the CE.

To implement the split-horizon functionality, the BUM frame has an MPLS label that identifies the ES it came from. This is the ESI label from the ES Label Extended community in the type 1 route. The MPLS label stack is now 3-deep instead of 2-deep. If the PE sees a BUM frame with this label, it does not forward it to the CE. This is not really necessary for VPWS, since all traffic sent from one CE is simply sent to the other CE. But this is important for E-LAN which we will see next.

PE1/PE2 also need to decide which PE router will forwarding BUM traffic to the CE. Let’s say this is a E-LAN setup. If a CE broadcasts a frame, and both PE1 and PE2 receive it, only one PE should forward the frame onto the Ethernet segment. PE1 and PE2 elect a DF (designated forwarder) using the EVPN route type 4. The DF is the one which forwards BUM traffic onto the segment.

The DF is the PE with the lowest IP address. Each PE builds a list of all other PEs connected to the segment using the type 4 routes that each PE originates.

Type 1

The type 1 route is similar to what we saw in the previous article. There are two type 1 routes, one per ES and one per EVI. The reason behind is this is so that the per ES route can be used for fast withdraw. If a link goes down, instead of withdrawing hundreds of per EVI route type 1s, you can withdraw the single per ES route type and achieve immediate failover. So then what is the purpose of a per EVI route? This allows other routes to load balance traffic between the multihoming PEs.

In our lab we only have a single EVI. Here is the per EVI route type 1 that PE2 advertised:

RP/0/RP0/CPU0:PE1#show bgp l2vpn evpn rd 2.2.2.2:1 [1][0000.0100.0000.0000.0001][101]/120
<snip>
    2.2.2.2 (metric 3) from 5.5.5.5 (2.2.2.2)
      Received Label 24001 
      Origin IGP, localpref 100, valid, internal, best, group-best, import-candidate, not-in-vrf
      Received Path ID 0, Local Path ID 1, version 101
      Extended community: EVPN L2 ATTRS:0x02:1500 RT:65000:1 
      Originator: 2.2.2.2, Cluster list: 5.5.5.5

Here is the per ES route type 1 that PE2 advertised. It uses the MAX EVI value (4294967295)

RP/0/RP0/CPU0:PE1#show bgp l2vpn evpn rd 2.2.2.2:1 [1][2.2.2.2:1][0000.0100.0000.0000.0001][4294967295]/184
<snip>
    2.2.2.2 (metric 3) from 5.5.5.5 (2.2.2.2)
      Received Label 0 
      Origin IGP, localpref 100, valid, internal, best, group-best, import-candidate, not-in-vrf
      Received Path ID 0, Local Path ID 1, version 104
      Extended community: EVPN ESI Label:0x00:24000 RT:65000:1 
      Originator: 2.2.2.2, Cluster list: 5.5.5.5

As you can see, the only difference is essentially the EVI value which is present in the route update name itself, and not seen in the detailed output in the CLI show command.

Let’s imagine that the link from PE1 to CE1 fails. PE1 needs to advertise that this link failed. It does this doing a Withdraw.

CE1#
int Gi0/0
 shut

Wait for PE1 to see the link is no longer sending LACPDUs. This may take 90 seconds if you have the default LACP rate.

First we see the Withdraw for the type 4 and type 1 per ES. This is sent first to initate fast failover on remote PEs.

Next we see the Withdraw for each type 1 per EVI. There is only one for our lab:

Conclusion

EVPN allows for L2 multihoming without MLAG. MLAG is generally proprietary on every vendor device. It can be complicated to setup and requires an inter-chassis connection. We’ve seen that EVPN can provide the same functionality without this complexity and while theoretically being vendor neutral. The only special config is that each PE configures the same ESI value for the segment. EVPN will automatically handle BUM traffic forwarding and split horizon.

So far we have seen two EVPN route types:

  • Type 1 is used to advertise the EVI and also advertise the ESI. When using single-homing VPWS, the type 1 is only used for the EVI itself. When using multi-homing, there is also an ESI route type 1.

  • Type 4 is used by PEs connecting to the same ESI in order to delect a designated forwarder (DF). The DF is the PE which will forware BUM traffic onto the segment. This is similar to the PIM DF role.

Next we will look at the type 2 and type 3 routes with EVPN for E-LAN.

Further Reading

https://www.youtube.com/watch?v=tIf_6ecXWkQ&ab_channel=Apstra

https://www.juniper.net/documentation/us/en/software/junos/evpn-vxlan/topics/concept/evpn-bgp-multihoming-overview.html#evpn-multihoming-overview__d4185e128

https://datatracker.ietf.org/doc/html/rfc7432

Last updated