Wednesday, November 30, 2016

CCIE SPv4 - MPLS L2VPN - VPLS BGP Auto Discovery using BGP signaling with VLANs

Software versions:
IOS XE 15.5
IOS XR 5.3

The topology for this demo:

In this post we will be taking a look at a variation of the VPLS BGP AD with LDP where we simply replace LDP signaling with BGP. The configuration overall is pretty straightforward, there are a few differences obviously but most of it is the same. Now to be clear there are actually 2 different RFCs that are built around this capability, 4761 and 4762. Cisco went with 4762 and Juniper with with 4761. 4761 refers to BGP signalling and 4762 refers to LDP signalling.

RFC 4761
RFC 4762

In the first post, we took a look at VPLS BGP Auto Discovery with LDP signalling in an E-LAN design, meaning that all PEs had reachability to all other PEs, or a MP2MP design, literally like an Ethernet switch where 3 or more devices are plugged into switchports all in the same VLAN. BGP can also be configured this way, which is the point of this post. The other feature that hasn't been covered yet is the E-TREE design. The rooted P2MP design or a hub and spoke. E-LAN leverages the ability to keep the "auto-route-target" command on IOS/XE and the XRv boxes simply import/export all the different RT values available. Where in E-TREE you selectively import/export RT values on IOS and XRv. That will be in another post.

So you might ask yourself, why LDP vs BGP or vice versa? I asked the same question, both get the job done in my opinion, the major difference that I have seen is how they get it done. LDP is the born leader for label distribution, it's only goal in life is to propagate labels to all the participating routers. It is very easy to get up and running and then can be easily manipulated later with MPLS TE. BGP on the other hand, is a bit more involved. There is, in my opinion, more to learn in terms of how BGP signalling works than with LDP. If you have already learned how LDP works, UDP hello's to detect peers, TCP connection between LSRs to exchange label info, not much to it, for the most part anyways. BGP is significantly more involved.

With LDP, you configure it like you would a manual configuration, create the service instance, the l2vpn vfi and then bind them together with a bridge domain and it's pretty much working. With BGP on the other hand, you have to intelligently ID one device from the other, manually; give each device a label range to allocate labels for. There is some "genius" level math that goes on in the background to make sure PE1 and PE2 don't allocate the same labels for those PWs. I'll cover the math in a separate post. One thing that is a little easier with BGP signaling over LDP is the increase in support, meaning you don't have to increase the prefix length information to get the peering up.

One thing to note right away. you can't change the signaling protocol under the VFI while it is up and operational. The IOS parser will actually throw up an error if you try. I ended up just deleting the LDP VFI and rebuilding it with BGP. Almost the same configuration.

IOS
R3
l2vpn vfi context E_TREE
 vpn id 50693
 autodiscovery bgp signaling bgp
  ve id 3
  ve range 11
 address-family l2vpn vpls
  neighbor 192.168.1.15 activate
  neighbor 192.168.1.15 suppress-signaling-protocol ldp

R5
l2vpn vfi context E_TREE
 vpn id 50693
 autodiscovery bgp signaling bgp
  ve id 5
  ve range 11
 address-family l2vpn vpls
  neighbor 192.168.1.15 activate
  neighbor 192.168.1.15 suppress-signaling-protocol ldp

R6
l2vpn vfi context E_TREE
 vpn id 50693
 autodiscovery bgp signaling bgp
  ve id 6
  ve range 11
 address-family l2vpn vpls
  neighbor 192.168.1.15 activate
  neighbor 192.168.1.15 suppress-signaling-protocol ldp

IOS XR
XR1
l2vpn
 bridge group E-LAN
  bridge-domain E_LAN
   interface GigabitEthernet0/0/0/2.100
   !
   vfi E_LAN
    vpn-id 50693
    autodiscovery bgp
     rd 1:50693
     route-target import 1:50693
     route-target export 1:50693
     signaling-protocol bgp
      ve-id 11
      ve-range 11

Now we'll get the bridge domain on IOS setup.

R3
bridge-domain 100
 member GigabitEthernet3 service-instance 100
 member vfi E_TREE

R5
bridge-domain 100
 member GigabitEthernet2 service-instance 100
 member vfi E_TREE

R6
bridge-domain 100
 member GigabitEthernet2 service-instance 100
 member vfi E_TREE

There is no separate "bridge" configuration on XRv. It all is configured under the "l2vpn" configuration section.

Now we'll get the BGP part up and running. IOS for starters.

R3, R5 and R6
router bgp 1
 bgp log-neighbor-changes
 no bgp default ipv4-unicast
 neighbor 192.168.1.15 remote-as 1
 neighbor 192.168.1.15 transport connection-mode active
 neighbor 192.168.1.15 update-source Loopback0
 !
 address-family ipv4
 exit-address-family
 !
 address-family l2vpn vpls
  neighbor 192.168.1.15 activate
  neighbor 192.168.1.15 suppress-signaling-protocol ldp
 exit-address-family

XR1
router bgp 1
 address-family l2vpn vpls-vpws
 !
 neighbor 192.168.1.15
  remote-as 1
  update-source Loopback0
  session-open-mode active-only
  address-family l2vpn vpls-vpws
   Signalling ldp disable

OK, so now that we have that in place. Let's first verify the BGP configuration is working.

R3, R5 and R6, there will be slight differences in the output, unique to each router, but they are not worth highlighting.

sh bgp l2vpn vpls all
BGP table version is 12, local router ID is 192.168.1.3
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
              x best-external, a additional-path, c RIB-compressed,
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found

     Network          Next Hop            Metric LocPrf Weight Path
Route Distinguisher: 1:50693
 *>  1:50693:VEID-3:Blk-1/136
                       0.0.0.0                            32768 ?
 *>i 1:50693:VEID-5:Blk-1/136
                       192.168.1.5              0    100      0 ?
 *>i 1:50693:VEID-6:Blk-1/136
                       192.168.1.6              0    100      0 ?
 *>i 1:50693:VEID-11:Blk-1/136
                       192.168.1.11                  100      0 i
 *>i 1:50693:VEID-11:Blk-10/136
                       192.168.1.11                  100      0 i


RP/0/0/CPU0:XR1#sh bgp l2vpn vpls sum
Process       RcvTblVer   bRIB/RIB   LabelVer  ImportVer  SendTblVer  StandbyVer
Speaker              24         24         24         24          24           0

Neighbor        Spk    AS MsgRcvd MsgSent   TblVer  InQ OutQ  Up/Down  St/PfxRcd
192.168.1.15      0     1    8691    8643       24    0    0    5d23h          3


RP/0/0/CPU0:XR1#sh bgp l2vpn vpls
Status codes: s suppressed, d damped, h history, * valid, > best
              i - internal, r RIB-failure, S stale, N Nexthop-discard
Origin codes: i - IGP, e - EGP, ? - incomplete
   Network            Next Hop        Rcvd Label      Local Label
Route Distinguisher: 1:50693 (default for vrf E-LAN:E_LAN)
*>i3:1/32             192.168.1.3     300             nolabel
*>i5:1/32             192.168.1.5     506             nolabel
*>i6:1/32             192.168.1.6     42              nolabel
*> 11:1/32            0.0.0.0         nolabel         24130
*> 11:10/32           0.0.0.0         nolabel         24115

One thing to highlight, the "nolabel" in the output, that is an indication that the data plane is not functioning. However the control plane is, which is why we received information.

Now let's go check the bridge domain information and break that down.

R3#sh bridge-domain
Bridge-domain 100 (4 ports in all)
State: UP                    Mac learning: Enabled
Aging-Timer: 300 second(s)
    GigabitEthernet3 service instance 100
    vfi E_TREE neighbor 192.168.1.5 50693
    vfi E_TREE neighbor 192.168.1.6 50693
    vfi E_TREE neighbor 192.168.1.11 50693
   AED MAC address    Policy  Tag       Age  Pseudoport
   0   000C.29BB.45EF forward dynamic   299  E_TREE.1004012
   1   FFFF.FFFF.FFFF flood   static    0    OLIST_PTR:0xe7ef8c00
   0   000C.29C9.1F5C forward dynamic   299  GigabitEthernet3.EFP100
   0   000C.2994.B818 forward dynamic   291  E_TREE.1004013

R5#sh bridge-domain
Bridge-domain 100 (4 ports in all)
State: UP                    Mac learning: Enabled
Aging-Timer: 300 second(s)
    GigabitEthernet2 service instance 100
    vfi E_TREE neighbor 192.168.1.3 50693
    vfi E_TREE neighbor 192.168.1.6 50693
    vfi E_TREE neighbor 192.168.1.11 50693
   AED MAC address    Policy  Tag       Age  Pseudoport
   0   000C.29BB.45EF forward dynamic   297  GigabitEthernet2.EFP100
   1   FFFF.FFFF.FFFF flood   static    0    OLIST_PTR:0xe7f06c20
   0   000C.29C9.1F5C forward dynamic   298  E_TREE.1004023
   0   000C.2994.B818 forward dynamic   290  E_TREE.1004021


R6#sh bridge-domain
Bridge-domain 100 (4 ports in all)
State: UP                    Mac learning: Enabled
Aging-Timer: 300 second(s)
    GigabitEthernet2 service instance 100
    vfi E_TREE neighbor 192.168.1.3 50693
    vfi E_TREE neighbor 192.168.1.5 50693
    vfi E_TREE neighbor 192.168.1.11 50693
   AED MAC address    Policy  Tag       Age  Pseudoport
   0   000C.29BB.45EF forward dynamic   293  E_TREE.1004017
   1   FFFF.FFFF.FFFF flood   static    0    OLIST_PTR:0xe7fce020
   0   000C.29C9.1F5C forward dynamic   294  E_TREE.1004019
   0   000C.2994.B818 forward dynamic   296  GigabitEthernet2.EFP100

You will notice that on each router, the MAC for the EFP100 interface will change, this is indicative of the CE MAC being learned and propagated to the other PE routers.

R6 Provisioning of the PWs. ***I know it says "E_TREE" in the output, that is the name of the VFI, not the design***

XR1
XC VFI VC[E_TREE/pw100011]: Processing provision of vfi-pw (0.0.0.11, 50693)
XC VFI VC[E_TREE/pw100011]: Setting up circuit
XC VFI VC[E_TREE/pw100011]: Provision vfi-pw switch
XC VFI VC[E_TREE/pw100011]: Sending update message to client
XC VFI VC[E_TREE/pw100011]: Circuit attributes to client:
XC VFI VC[E_TREE/pw100011]:  i/f: 4002
XC VFI VC[E_TREE/pw100011]:  Status: UP (0x1)
XC VFI VC[E_TREE/pw100011]:  Circuit directive: Go Active
XC VFI VC[E_TREE/pw100011]:  Payload encap: Ethernet
XC VFI VC[E_TREE/pw100011]:  Circuit Encap: VFI
XC VFI VC[E_TREE/pw100011]:  Interworking type: none
XC VFI VC[E_TREE/pw100011]:  Segment type: VFI
XC VFI VC[E_TREE/pw100011]:  Switch handle: 16413
XC VFI VC[E_TREE/pw100011]:  MTU: 1500
XC VFI VC[E_TREE/pw100011]:  I/F Str: pw100003
XC VFI VC[E_TREE/pw100011]:  Circuit string: vfi

R3
XC VFI VC[E_TREE/pw100010]: Processing provision of vfi-pw (0.0.0.3, 50693)
XC VFI VC[E_TREE/pw100010]: Setting up circuit
XC VFI VC[E_TREE/pw100010]: Provision vfi-pw switch
XC VFI VC[E_TREE/pw100010]: Sending update message to client
XC VFI VC[E_TREE/pw100010]: Circuit attributes to client:
XC VFI VC[E_TREE/pw100010]:  i/f: 4002
XC VFI VC[E_TREE/pw100010]:  Status: UP (0x1)
XC VFI VC[E_TREE/pw100010]:  Circuit directive: Go Active
XC VFI VC[E_TREE/pw100010]:  Payload encap: Ethernet
XC VFI VC[E_TREE/pw100010]:  Circuit Encap: VFI
XC VFI VC[E_TREE/pw100010]:  Interworking type: none
XC VFI VC[E_TREE/pw100010]:  Segment type: VFI
XC VFI VC[E_TREE/pw100010]:  Switch handle: 20511
XC VFI VC[E_TREE/pw100010]:  MTU: 1500
XC VFI VC[E_TREE/pw100010]:  I/F Str: pw100003
XC VFI VC[E_TREE/pw100010]:  Circuit string: vfi

R3
XC VFI VC[E_TREE/pw100008]: Processing provision of vfi-pw (0.0.0.5, 50693)
XC VFI VC[E_TREE/pw100008]: Setting up circuit
XC VFI VC[E_TREE/pw100008]: Provision vfi-pw switch
XC VFI VC[E_TREE/pw100008]: Sending update message to client
XC VFI VC[E_TREE/pw100008]: Circuit attributes to client:
XC VFI VC[E_TREE/pw100008]:  i/f: 4002
XC VFI VC[E_TREE/pw100008]:  Status: UP (0x1)
XC VFI VC[E_TREE/pw100008]:  Circuit directive: Go Active
XC VFI VC[E_TREE/pw100008]:  Payload encap: Ethernet
XC VFI VC[E_TREE/pw100008]:  Circuit Encap: VFI
XC VFI VC[E_TREE/pw100008]:  Interworking type: none
XC VFI VC[E_TREE/pw100008]:  Segment type: VFI
XC VFI VC[E_TREE/pw100008]:  Switch handle: 24609
XC VFI VC[E_TREE/pw100008]:  MTU: 1500
XC VFI VC[E_TREE/pw100008]:  I/F Str: pw100003
XC VFI VC[E_TREE/pw100008]:  Circuit string: vfi


Bringing up the PWs
XR1
XC VFI VC[E_TREE/pw100011]: Processing client Update message
XC VFI VC[E_TREE/pw100011]: Circuit attributes from client:
XC VFI VC[E_TREE/pw100011]:  i/f: 4005
XC VFI VC[E_TREE/pw100011]:  Status: UP (0x1)
XC VFI VC[E_TREE/pw100011]:  Payload encap: Undefined
XC VFI VC[E_TREE/pw100011]:  Circuit Encap: Undefined
XC VFI VC[E_TREE/pw100011]:  Segment type: AToM
XC VFI VC[E_TREE/pw100011]:  Static VC: yes
XC VFI VC[E_TREE/pw100011]:  Control Word: no
XC VFI VC[E_TREE/pw100011]:  Fast Switchover: no
XC VFI VC[E_TREE/pw100011]:  I/F Str: pw100011
XC VFI VC[E_TREE/pw100011]:  Circuit string: 0.0.0.11:50693

R3
XC VFI VC[E_TREE/pw100011]: client update received for bd_id 64 all_up 0 pw up count 1
XC VFI VC[E_TREE/pw100011]: First pw up, starting the pw actv timer
XC VFI VC[E_TREE/pw100010]: Processing client Update message
XC VFI VC[E_TREE/pw100010]: Circuit attributes from client:
XC VFI VC[E_TREE/pw100010]:  i/f: 4003
XC VFI VC[E_TREE/pw100010]:  Status: UP (0x1)
XC VFI VC[E_TREE/pw100010]:  Payload encap: Undefined
XC VFI VC[E_TREE/pw100010]:  Circuit Encap: Undefined
XC VFI VC[E_TREE/pw100010]:  Segment type: AToM
XC VFI VC[E_TREE/pw100010]:  Static VC: yes
XC VFI VC[E_TREE/pw100010]:  Control Word: no
XC VFI VC[E_TREE/pw100010]:  Fast Switchover: no
XC VFI VC[E_TREE/pw100010]:  I/F Str: pw100010
XC VFI VC[E_TREE/pw100010]:  Circuit string: 0.0.0.3:50693

R5
XC VFI VC[E_TREE/pw100008]: Processing client Update message
XC VFI VC[E_TREE/pw100008]: Circuit attributes from client:
XC VFI VC[E_TREE/pw100008]:  i/f: 4004
XC VFI VC[E_TREE/pw100008]:  Status: UP (0x1)
XC VFI VC[E_TREE/pw100008]:  Payload encap: Undefined
XC VFI VC[E_TREE/pw100008]:  Circuit Encap: Undefined
XC VFI VC[E_TREE/pw100008]:  Segment type: AToM
XC VFI VC[E_TREE/pw100008]:  Static VC: yes
XC VFI VC[E_TREE/pw100008]:  Control Word: no
XC VFI VC[E_TREE/pw100008]:  Fast Switchover: no
XC VFI VC[E_TREE/pw100008]:  I/F Str: pw100008
XC VFI VC[E_TREE/pw100008]:  Circuit string: 0.0.0.5:50693

Final verification that the configurations between PEs are correctly negotiated

XR1
XC VFI VC[E_TREE/pw100011]: Processing client Update message
XC VFI VC[E_TREE/pw100011]: Circuit attributes from client:
XC VFI VC[E_TREE/pw100011]:  Payload encap: Ethernet
XC VFI VC[E_TREE/pw100011]:  Circuit Encap: Ethernet
XC VFI VC[E_TREE/pw100011]:  Segment type: AToM
XC VFI VC[E_TREE/pw100011]:  VLAN ID: 0
XC VFI VC[E_TREE/pw100011]: Update VC type not needed

R3
XC VFI VC[E_TREE/pw100010]: Processing client Update message
XC VFI VC[E_TREE/pw100010]: Circuit attributes from client:
XC VFI VC[E_TREE/pw100010]:  Payload encap: Ethernet
XC VFI VC[E_TREE/pw100010]:  Circuit Encap: Ethernet
XC VFI VC[E_TREE/pw100010]:  Segment type: AToM
XC VFI VC[E_TREE/pw100010]:  VLAN ID: 0
XC VFI VC[E_TREE/pw100010]: Update VC type not needed

R5
XC VFI VC[E_TREE/pw100008]: Processing client Update message
XC VFI VC[E_TREE/pw100008]: Circuit attributes from client:
XC VFI VC[E_TREE/pw100008]:  Payload encap: Ethernet
XC VFI VC[E_TREE/pw100008]:  Circuit Encap: Ethernet
XC VFI VC[E_TREE/pw100008]:  Segment type: AToM
XC VFI VC[E_TREE/pw100008]:  VLAN ID: 0
XC VFI VC[E_TREE/pw100008]: Update VC type not needed

Now that the PWs are built between the PWs, we need to propagate the BGP NLRI between them.

%BGP-5-ADJCHANGE: neighbor 192.168.1.15 Up

Initial updates received from peers
XR1
BGP(9): 192.168.1.15 rcvd UPDATE w/ attr: nexthop 192.168.1.11, origin i, localpref 100, originator 192.168.1.11, clusterlist 192.168.1.15, extended community RT:1:50693 L2VPN L2:0x0:MTU-1500
BGP(9): 192.168.1.15 rcvd 1:50693:VEID-11:Blk-1:VBS-9:LB-24130/136
BGP(9): bump net 1:50693:VEID-11:Blk-1:VBS-9:LB-24130/136, non bpath  added
BGP(9): 192.168.1.15 rcvd 1:50693:VEID-11:Blk-10:VBS-11:LB-24115/136
BGP(9): bump net 1:50693:VEID-11:Blk-10:VBS-11:LB-24115/136, non bpath  added

R3
BGP(9): 192.168.1.15 rcvd UPDATE w/ attr: nexthop 192.168.1.3, origin ?, localpref 100, metric 0, originator 192.168.1.3, clusterlist 192.168.1.15, extended community RT:1:50693 L2VPN L2:0x0:MTU-1500
BGP(9): 192.168.1.15 rcvd 1:50693:VEID-3:Blk-1:VBS-11:LB-300/136
BGP(9): bump net 1:50693:VEID-3:Blk-1:VBS-11:LB-300/136, non bpath  added

R5
BGP(9): 192.168.1.15 rcvd UPDATE w/ attr: nexthop 192.168.1.5, origin ?, localpref 100, metric 0, originator 192.168.1.5, clusterlist 192.168.1.15, extended community RT:1:50693 L2VPN L2:0x0:MTU-1500
BGP(9): 192.168.1.15 rcvd 1:50693:VEID-5:Blk-1:VBS-11:LB-506/136
BGP(9): bump net 1:50693:VEID-5:Blk-1:VBS-11:LB-506/136, non bpath  added




Label allocation values are reported to the local router from the remote peers.
R3
BGP-L2VPN: set net vbs 11 label base 300
BGP(9): nettable_walker called for 1:50693:VEID-3:Blk-1:VBS-11:LB-300/136
BGP(9): best path[0] 1:50693:VEID-3:Blk-1:VBS-11:LB-300/136 source 192.168.1.6 nh 192.168.1.3 vpls-id: L2VPN L2:0x0:MTU-1500
BGP(9): add XC RIB route 1:50693:VEID-3:Blk-1:VBS-11:LB-300/136 masklen 136 L2VPN L2:0x0:MTU-1500 pathcount: 1 [0] LDP source:192.168.1.6 nexthop:192.168.1.3 RT:1:50693
BGP(9): net was 1:50693:VEID-5:Blk-1:VBS-11:LB-506/136

R5
BGP-L2VPN: set net vbs 11 label base 506
BGP(9): nettable_walker called for 1:50693:VEID-5:Blk-1:VBS-11:LB-506/136
BGP(9): best path[0] 1:50693:VEID-5:Blk-1:VBS-11:LB-506/136 source 192.168.1.6 nh 192.168.1.5 vpls-id: L2VPN L2:0x0:MTU-1500
BGP(9): add XC RIB route 1:50693:VEID-5:Blk-1:VBS-11:LB-506/136 masklen 136 L2VPN L2:0x0:MTU-1500 pathcount: 1 [0] LDP source:192.168.1.6 nexthop:192.168.1.5 RT:1:50693
BGP(9): net was 1:50693:VEID-6:Blk-1:VBS-11:LB-42/136

R6
BGP-L2VPN: set net vbs 11 label base 42
BGP(9): nettable_walker called for 1:50693:VEID-6:Blk-1:VBS-11:LB-42/136
BGP(9): nettable_walker 1:50693:VEID-6:Blk-1:VBS-11:LB-42/136 route sourced locally
BGP(9): net was 1:50693:VEID-11:Blk-1:VBS-9:LB-24130/136

XR1
BGP-L2VPN: set net vbs 9 label base 24130
BGP(9): nettable_walker called for 1:50693:VEID-11:Blk-1:VBS-9:LB-24130/136
BGP(9): best path[0] 1:50693:VEID-11:Blk-1:VBS-9:LB-24130/136 source 192.168.1.6 nh 192.168.1.11 vpls-id: L2VPN L2:0x0:MTU-1500
BGP(9): add XC RIB route 1:50693:VEID-11:Blk-1:VBS-9:LB-24130/136 masklen 136 L2VPN L2:0x0:MTU-1500 pathcount: 1 [0] LDP source:192.168.1.6 nexthop:192.168.1.11 RT:1:50693
BGP(9): net was 1:50693:VEID-11:Blk-10:VBS-11:LB-24115/136



Output from the remote peers informing R6 of the label ranges being allocated.

R3
BGP-L2VPN: modify prefix: LLB 0 LB 300
BGP(9): update modified for 1:50693:VEID-3:Blk-1:VBS-11:LB-300/136 VE ID 3 VBO 1 VBS 11 Label Base 300 /136

R5
BGP-L2VPN: modify prefix: LLB 0 LB 506
BGP(9): update modified for 1:50693:VEID-5:Blk-1:VBS-11:LB-506/136 VE ID 5 VBO 1 VBS 11 Label Base 506 /136

R6
BGP-L2VPN: modify prefix: LLB 0 LB 42
BGP(9): update modified for 1:50693:VEID-6:Blk-1:VBS-11:LB-42/136 VE ID 6 VBO 1 VBS 11 Label Base 42 /136

XR1
BGP-L2VPN: modify prefix: LLB 0 LB 24115
BGP(9): update modified for 1:50693:VEID-11:Blk-10:VBS-11:LB-24115/136 VE ID 11 VBO 10 VBS 11 Label Base 24115 /136



Now we can verify the CEs are able to reach each other.

R8#sh ospfv3 1 nei

          OSPFv3 1 address-family ipv6 (router-id 172.16.8.8)

Neighbor ID     Pri   State           Dead Time   Interface ID    Interface
172.16.9.9        1   FULL/DROTHER    00:00:39    12              GigabitEthernet1.100
172.16.10.10      1   FULL/DR         00:00:38    13              GigabitEthernet1.100

Excellent! This proves that the connectivity works as expected.

Thanks for stopping by!
Rob Riker, CCIE #50693

No comments:

Post a Comment