Lab 6: L3VPN
Lab 6: L3VPN
Introduction
Learning Objectives:
Upon completion of this lab, you will be able to:
- Use Cisco Network Services Orchestrator (NSO) to create, deploy and test a service package (L3VPN)
- Understand the brownfield service deployment challenges.
- Discover and reconcile pre-existing L3VPN services manually
- Create an action to discover and reconcile the pre-existing L3VPN services automatically.
Pre-requisite
- Basic understanding of network orchestration, NETCONF/Yang
- Basic knowledge of Cisco Network Services Orchestrator (NSO)
Overview
As an industry leading orchestration platform, NSO is widely used to provide service lifecycle orchestration for hybrid networks. While new services are deployed using NSO service packages, service providers normally have brownfield network, in which there are pre-existing configuration in the network orchestrated by legacy tools. For brownfield network, NSO needs to discover and reconcile pre-existing services.
In this lab, you will create a simple L3VPN service package to configure L3VPN using OSPF as PE-CE protocol.
Diagram 1 illustrates the network topology. The network is composed of ASR devices with Cisco IOS-XR. You will create L3VPN services using OSPF ad your CE-PE Protocol. This lab focuses on PE configuration. To simulate the brownfield network, the CE devices are pre-configured.

Task 1: Create L3VPN Service Package
Requirements of the service package:
A service provider needs to have an orchestration tool to auto-configure L3VPN. The network is shown in Diagram 1. We need to create a service package for the job. After finalizing the requirements, we have Table 1 that lists the parameters of the service package and Table 2 lists the CLI’s to be configured.
Our job is to create the service package. As shown in Table 1 and Table 2, the service gets a list of Pes where customer sites are terminated. For each PE, it needs to create a Layer 3 VPN (with OSPF as PE-CE Protocol) service where the interface and Port number is to identify the CE-PE link termination. Customer Name will be used as VRF-ID and service-ID. Customer number and AS Number will be used for Route-Distinguisher and Route-Targets.
Table: 1
Service Attributes of L2VPN | Type | Note |
---|---|---|
PE Nodes | List | A list of PE devices |
Customer-Interface | String | ThePort number of each PE that connects to the CE |
Router-Distinguisher | Integer | Usedas RD for L3VPN |
Router-Target-Import | Integer | Usedas RT Import for L3VPN |
Router-Target-Export | Integer | Usedas RT Export for L3VPN |
Customer-Name | String | CustomerName is used as VRF Name and service ID |
Customer-Number | Integer | Willbe used for RD, RT and OSPF Process ID |
AS-Number | String | ServiceProviders Autonomous System Number(ASN) |
Location | String | Definesall locations where customer is present |
devices | String | Devicename for each location where CE is terminated |
GigabitEthernet | String | InterfaceID on which customer is Terminated |
IP-Address & IP-Mask | IPv4 | IPv4address and mask of CE-interface |
Table: 2
CLI’s to be configured on PE for L3VPN Service:
vrf vpna address-family ipv4 unicast import route-target 65000:123 export route-target 65000:1 ! interface GigabitEthernet0/0/0/0 description link to CE vrf vpna ipv4 address 12.0.0.2 255.255.255.0 ! router ospf 123 vrf vpna redistribute bgp 65000 area 0 interface GigabitEthernet0/0/0/0 ! router bgp 65000 vrf vpna rd 65000:1 address-family ipv4 unicast redistribute ospf 123 ! commit end
In this task, you will create a service package skeleton, and a service Yang model to capture the service attributes as in Table 1. You will then create service to device mapping to support the configuration of CLIs as in Table 2. At the end, you will deploy the service package onto your NSO host The service model is illustrated in Diagram 2. As shown in the diagram, L3VPN is modelled as a list of ncs services
Diagram: 2. L3VPN Service Model for this Lab:


Step 1: Create Services Skeleton:
1. From NSO application, create a service skeleton package using “ncs-make-package” command, name it l3vpn
cd ~/nso-5.3/packages/neds/nso-instance/packages ncs-make-package --service-skeleton template l3vpn --augment /ncs:services
Note: “ncs-make-package” creates a directory structure (l3vpn), and skeleton of service files.
2. From Inspect the skeleton files, make sure files Makefile, l3vpn.yang and l3vpn.xml are created:
$ cd ~/nso-5.3/packages/neds/nso-instance/packages/l3vpn $ ls src Makefile yang $ ls src/yang l3vpn.yang $ ls templates l3vpn.xml
Step 2: Update the auto-generated l3vpn.yang:
The skeleton of l3vpn.yang file is auto-generated as part of ncs-make-package command. In this step, you will update the auto-generated Yang file, l3vpn.yang to model the l3vpn service as illustrated in Table 1 and Diagram 2.
- Edit ~/nso-5.3/packages/neds/nso-instance/packages/l3vpn/src/yang/l3vpn.yang using text editor or nano
- The auto-generated l3vpn.yang file contains several skeleton blocks. You need to update l3vpn block to add service attributes. Modify the generated Yang file, locate the block starts with “list l3vpn”.
- Your l3vpn.yang file should now look as seen below:
module l3vpn { namespace "http://com/example/l3vpn"; prefix l3vpn; import ietf-inet-types { prefix inet; } import tailf-common { prefix tailf; } import tailf-ncs { prefix ncs; } import tailf-ned-cisco-ios-xr { prefix cisco-ios-xr; } grouping endpoint-grouping { leaf GigabitEthernet { type leafref { path "/ncs:devices/ncs:device[ncs:name=current()/../../device]/ncs:config/cisco-ios-xr:interface/cisco-ios-xr:GigabitEthernet/cisco-ios-xr:id"; } } leaf IP-Address { tailf:info "Local interface address."; type inet:ipv4-address; } leaf IP-Mask { tailf:info "Local interface mask."; type inet:ipv4-address; } } container vpn { list l3vpn { description "Layer3 VPN"; key Customer-Name; leaf Customer-Name { tailf:info "Unique service id"; type string; } leaf Customer-Number { tailf:info "Unique service id"; type uint32; } leaf Route-Distinguisher { tailf:info "ASN:ID"; default "65000:123"; type string; } list Route-Target-Import { description "RT-in"; key Route-Target-Import; leaf Route-Target-Import { tailf:info "Unique service id"; type string; } } list Route-Target-Export { description "RT-out"; key Route-Target-Export; leaf Route-Target-Export { tailf:info "Unique service id"; type string; } } uses ncs:service-data; ncs:servicepoint "l3vpn-template"; list Customer-Locations { key "Location"; leaf Location{ tailf:info "Endpoint identifier"; type string; } leaf AS-Number { description "AS used within all VRF of the VPN"; tailf:info "MPLS VPN AS number."; default 65000; type uint32; } container PE { leaf device { mandatory true; type leafref { path "/ncs:devices/ncs:device/ncs:name"; } } container Customer-Interface { uses endpoint-grouping; } } } } }
- Save the updated l3vpn.yang file
- Define the path for your ned module cisco-iosxr-cli-7.18 used in our yang file. To do this go to the src directory and add following line in file name “Makefile”
YANGPATH += ../../cisco-iosxr-cli-7.18/src/ncsc-out/modules/yang
cd ~/nso-5.3/packages/neds/nso-instance/packages/l3vpn/src nano Makefile and add following line and save the file YANGPATH += ../../cisco-iosxr-cli-7.18/src/ncsc-out/modules/yang
- Compile project L2VPN on your server using following command.
cd ~/nso-5.3/packages/neds/nso-instance/packages/l3vpn/src make
Note: Make sure there is no compilation errors. Following output will be seen is everything is working properly
/home/NSO/ncs-4.3.1/bin/ncsc `ls l3vpn-ann.yang > /dev/null 2>&1 && echo "-a l3vpn-ann.yang"` \ -c -o ../load-dir/l3vpn.fxs yang/L2VPN.yang
Step 3: Complete L3VPN template to map service model to device model
You have created the service model in the previous step. Next, L3VPN service needs to send the proper CLI’s (as in Table 2) to PE devices. In NSO term, this is called service model to device model mapping. In most cases, the service to device mapping can be easily implemented through xml template. You will use this approach for L3VPN. The skeleton of mapping template xml file, l3vpn.xml is auto generated. In this step, you will add the contents.
We start with creating a sample configuration as specified in Table: 2 to a PE through NSO CLI. NSO’s operation “commit dry-run” will have NSO’s cisco-iosxr Ned calculate the device CLI’s. “commit dry-run outformat xml” displays the output in xml format. This output is the starting point of the mapping template.
- In NSO cli mode, configure a the PE1 device using the configuration defined in Table: 2
cd ~/nso-5.3/packages/neds/nso-instance source $HOME/nso-5.3/ncsrc ncs_cli -C -u admin
- You have entered NSO Cli mode, Start configuring the PE device issuing following command.
admin@ncs# config admin@ncs(config)# devices device PE1 admin@ncs(config-device-PE1)# config admin@ncs(config-config)# vrf vpna admin@ncs(config-vrf)# address-family ipv4 unicast admin@ncs(config-vrf-af)# import route-target admin@ncs(config-vrf-import-rt)# 65000:1 admin@ncs(config-vrf-import-rt)# export route-target admin@ncs(config-vrf-export-rt)# 65000:1 admin@ncs(config-vrf-export-rt)# exit admin@ncs(config-vrf-af)# exit admin@ncs(config-vrf)# exit admin@ncs(config-config)# interface GigabitEthernet0/0/0/0 admin@ncs(config-if)# description ACME admin@ncs(config-if)# vrf vpna admin@ncs(config-if)# ipv4 address 12.0.0.2 255.255.255.0 admin@ncs(config-if)# router ospf 100 admin@ncs(config-ospf)# vrf vpna admin@ncs(config-ospf-vrf)# redistribute bgp 65000 admin@ncs(config-ospf-vrf)# area 0 admin@ncs(config-ospf-ar)# interface GigabitEthernet0/0/0/0 admin@ncs(config-ospf-ar-if)# router bgp 65000 admin@ncs(config-bgp)# vrf vpna admin@ncs(config-bgp-vrf)# vrf vpna admin@ncs(config-bgp-vrf)# rd 65000:1 admin@ncs(config-bgp-vrf)# address-family ipv4 unicast admin@ncs(config-bgp-af)# redistribute ospf 100 admin@ncs(config-bgp-af)# exit admin@ncs(config-bgp-vrf)# exit admin@ncs(config-bgp)# exit admin@ncs(config-config)#
- From ncs cli config mode, issue “commit dry run outformat xml”. This command will show the configuration changes to be sent to device as xml format.
admin@ncs(config)# commit dry-run outformat xml result-xml { local-node { data <devices xmlns="http://tail-f.com/ns/ncs"> <device> <name>PE1</name> <config> <vrf xmlns="http://tail-f.com/ned/cisco-ios-xr"> <vrf-list> <name>vpna</name> <address-family> <ipv4> <unicast> <import> <route-target> <address-list> <name>65000:1</name> </address-list> </route-target> </import> <export> <route-target> <address-list> <name>65000:1</name> </address-list> </route-target> </export> </unicast> </ipv4> </address-family> </vrf-list> </vrf> <interface xmlns="http://tail-f.com/ned/cisco-ios-xr"> <GigabitEthernet> <id>0/0/0/0</id> <description>ACME</description> <vrf>vpna</vrf> <ipv4> <address> <ip>12.0.0.2</ip> <mask>255.255.255.0</mask> </address> </ipv4> </GigabitEthernet> </interface> <router xmlns="http://tail-f.com/ned/cisco-ios-xr"> <ospf> <name>100</name> <vrf> <name>vpna</name> <redistribute> <bgp> <id>65000</id> </bgp> </redistribute> <area> <id>0</id> <interface> <name>GigabitEthernet0/0/0/0</name> </interface> <interface> <name>g0/0/0/0</name> </interface> </area> </vrf> </ospf> <bgp> <bgp-no-instance> <id>65000</id> <vrf> <name>vpna</name> <rd>65000:1</rd> <address-family> <ipv4> <unicast> <redistribute> <ospf> <id>100</id> </ospf> </redistribute> </unicast> </ipv4> </address-family> </vrf> </bgp-no-instance> </bgp> </router> </config> </device> </devices> } } admin@ncs(config-config)#
- We don’t want to commit the above changes to devices. Exit from ncs cli without committing:
- Now let’s complete l3vpn template file, l3vpn.xml
- Edit ~/nso-5.3/packages/neds/nso-instance/packages/l3vpn/templates/l3vpn.xml using text editor or nano
- Replace the contents of the block of <config-template xmlns=”http://tailf.com/ns/config/1.0″> With the highlighted output from item 3. Output will look as below
<config-template xmlns="http://tail-f.com/ns/config/1.0" servicepoint="l3vpn-template"> <devices xmlns="http://tail-f.com/ns/ncs"> <?foreach {Customer-Locations/PE}?> <device tags="nocreate"> <name>{device}</name> <config tags="merge"> <!-- PE template for Cisco IOS-XR routers --> <vrf xmlns="http://tail-f.com/ned/cisco-ios-xr"> <vrf-list> <name>{string(/Customer-Name)}</name> <address-family> <ipv4> <unicast> <?set-context-node {..}?> <import> <route-target> <address-list> <name>{string(/Route-Target-Import)}</name> </address-list> </route-target> </import> <export> <route-target> <address-list> <name>{string(/Route-Target-Export)}</name> </address-list> </route-target> </export> </unicast> </ipv4> </address-family> </vrf-list> </vrf> <interface xmlns="http://tail-f.com/ned/cisco-ios-xr" tags="nocreate"> <?foreach {Customer-Interface}?> <GigabitEthernet> <id>{GigabitEthernet}</id> <description tags="merge">link to CE</description> <ipv4 tags="merge"> <address> <ip>{IP-Address}</ip> <mask>{IP-Mask}</mask> </address> </ipv4> <vrf tags="merge">{string(/Customer-Name)}</vrf> </GigabitEthernet> <?end?> </interface> <router xmlns="http://tail-f.com/ned/cisco-ios-xr" tags="merge"> <ospf> <name>{string(/Customer-Number)}</name> <vrf> <name>{string(/Customer-Name)}</name> <redistribute> <bgp> <id>{../AS-Number}</id> </bgp> </redistribute> <area> <id>0</id> <interface> <name>GigabitEthernet{../PE/Customer-Interface/GigabitEthernet}</name> </interface> </area> </vrf> </ospf> <bgp> <bgp-no-instance> <id>{../AS-Number}</id> <vrf tags="merge"> <name>{string(/Customer-Name)}</name> <?set-context-node {..}?> <rd>{/Route-Distinguisher}</rd> <address-family> <ipv4> <unicast> <redistribute> <ospf> <id>{string(/Customer-Number)}</id> </ospf> </redistribute> </unicast> </ipv4> </address-family> </vrf> </bgp-no-instance> </bgp> </router> </config> </device> <?end?> </devices> </config-template>
- Next you need to plant the service attributes to replace the sample parameters. The service attributes are identified as an xpath from service root l3vpn, with proper syntax (inside {}) and context. AS the l3vpn configuration will require configuration on multiple Provider Edge routers hence we need to populate the XML template for multiple PE routers
- The final template file l3vpn.xml should look like the following, note the yellow highlighted parts are replaced with service attributes:
Note: The xml Template below is created for each PE node
<config-template xmlns="http://tail-f.com/ns/config/1.0" servicepoint="l3vpn-template"> <devices xmlns="http://tail-f.com/ns/ncs"> <?foreach {Customer-Locations/PE}?> <device tags="nocreate"> <name>{device}</name> <config tags="merge"> <!-- PE template for Cisco IOS-XR routers --> <vrf xmlns="http://tail-f.com/ned/cisco-ios-xr"> <vrf-list> <name>{string(/Customer-Name)}</name> <address-family> <ipv4> <unicast> <?set-context-node {..}?> <import> <route-target> <address-list> <name>{string(/Route-Target-Import)}</name> </address-list> </route-target> </import> <export> <route-target> <address-list> <name>{string(/Route-Target-Export)}</name> </address-list> </route-target> </export> </unicast> </ipv4> </address-family> </vrf-list> </vrf> <interface xmlns="http://tail-f.com/ned/cisco-ios-xr" tags="nocreate"> <?foreach {Customer-Interface}?> <GigabitEthernet> <id>{GigabitEthernet}</id> <description tags="merge">link to CE</description> <ipv4 tags="merge"> <address> <ip>{IP-Address}</ip> <mask>{IP-Mask}</mask> </address> </ipv4> <vrf tags="merge">{string(/Customer-Name)}</vrf> </GigabitEthernet> <?end?> </interface> <router xmlns="http://tail-f.com/ned/cisco-ios-xr" tags="merge"> <ospf> <name>{string(/Customer-Number)}</name> <vrf> <name>{string(/Customer-Name)}</name> <redistribute> <bgp> <id>{../AS-Number}</id> </bgp> </redistribute> <area> <id>0</id> <interface> <name>GigabitEthernet{../PE/Customer-Interface/GigabitEthernet}</name> </interface> </area> </vrf> </ospf> <bgp> <bgp-no-instance> <id>{../AS-Number}</id> <vrf tags="merge"> <name>{string(/Customer-Name)}</name> <?set-context-node {..}?> <rd>{/Route-Distinguisher}</rd> <address-family> <ipv4> <unicast> <redistribute> <ospf> <id>{string(/Customer-Number)}</id> </ospf> </redistribute> </unicast> </ipv4> </address-family> </vrf> </bgp-no-instance> </bgp> </router> </config> </device> <?end?> </devices> </config-template>
Step 4: Deploy the service package L3VPN
Now you are ready to deploy the service package to NSO application.
- From NSO cli (ncs_cli), reload packages to complete the package deployment process. Make sure the reload result is true.
admin@ncs> packages reload force >>> System upgrade is starting. >>> Sessions in configure mode must exit to operational mode. >>> No configuration changes can be performed until upgrade has completed. reload-result { package l3vpn result true } reload-result { package cisco-iosxr-cli-7.18 result true }
Step 5: PE1, PE2, CE1 and CE2 Routers Initial Config
PE1:
hostname PE1 telnet vrf default ipv4 server max-servers 10 telnet vrf Mgmt-intf ipv4 server max-servers 10 ! interface Loopback0 ipv4 address 1.1.1.1 255.255.255.0 ! interface MgmtEth0/0/CPU0/0 ipv4 address 10.0.0.2 255.255.255.0 no shut ! interface GigabitEthernet0/0/0/0 no shut ! interface GigabitEthernet0/0/0/1 ipv4 address 23.0.0.2 255.255.255.0 no shut ! route-policy passall pass end-policy ! router ospf 1 router-id 1.1.1.1 area 0 interface Loopback0 interface GigabitEthernet0/0/0/1 ! router bgp 65000 address-family ipv4 unicast network 1.1.1.0/24 ! address-family vpnv4 unicast retain route-target all ! neighbor 23.0.0.3 remote-as 65000 address-family ipv4 unicast route-policy passall in route-policy passall out ! address-family vpnv4 unicast ! mpls ldp router-id 1.1.1.1 interface GigabitEthernet0/0/0/1 ! commit
PE2:
hostname PE2 telnet vrf default ipv4 server max-servers 10 telnet vrf Mgmt-intf ipv4 server max-servers 10 ! interface Loopback0 ipv4 address 2.2.2.2 255.255.255.0 ! interface MgmtEth0/0/CPU0/0 ipv4 address 10.0.0.3 255.255.255.0 no shut ! interface GigabitEthernet0/0/0/0 no shut ! interface GigabitEthernet0/0/0/1 ipv4 address 23.0.0.3 255.255.255.0 no shut ! route-policy passall pass end-policy ! router ospf 1 router-id 2.2.2.2 area 0 interface Loopback0 interface GigabitEthernet0/0/0/1 ! router bgp 65000 address-family ipv4 unicast network 2.2.2.0/24 ! address-family vpnv4 unicast retain route-target all ! neighbor 23.0.0.2 remote-as 65000 address-family ipv4 unicast route-policy passall in route-policy passall out ! address-family vpnv4 unicast ! mpls ldp router-id 2.2.2.2 interface GigabitEthernet0/0/0/1 ! Commit
CE1:
hostname CE1 telnet vrf default ipv4 server max-servers 10 telnet vrf Mgmt-intf ipv4 server max-servers 10 ! interface Loopback100 ipv4 address 100.0.0.1 255.255.255.0 ! interface Loopback101 ipv4 address 101.0.0.1 255.255.255.0 ! interface MgmtEth0/0/CPU0/0 ipv4 address 10.0.0.1 255.255.255.0 no shut ! interface GigabitEthernet0/0/0/0 ipv4 address 12.0.0.1 255.255.255.0 ! router ospf 1 area 0 interface Loopback100 interface Loopback101 interface GigabitEthernet0/0/0/0 ! Commit
CE2:
hostname CE2 telnet vrf default ipv4 server max-servers 10 telnet vrf Mgmt-intf ipv4 server max-servers 10 ! interface Loopback100 ipv4 address 200.0.0.1 255.255.255.0 ! interface Loopback101 ipv4 address 201.0.0.1 255.255.255.0 ! interface MgmtEth0/0/CPU0/0 ipv4 address 10.0.0.4 255.255.255.0 no shut ! interface GigabitEthernet0/0/0/0 ipv4 address 34.0.0.4 255.255.255.0 ! router ospf 1 area 0 interface Loopback100 interface Loopback101 interface GigabitEthernet0/0/0/0 ! Commit
Step 6: Deploy the service package to create L3VPN
- Go to WebUI-one -> Service manager and select L3VPN Service, Click on + sign to create service

- Select ACME

- Now Click on Customer-Locations and add Mumbai and Delhi as Locations

- Now Click on Mumbai Location

- Fill all required information for Mumbai Location and then click as seen below:

- Similarly Click on Delhi Location

- Fill all required information for Delhi Location then click on commit manager:
- Now click on commit as seen below:

- Verify on CE1 Router and check if customer remote site routers are learnt:
RP/0/0/CPU0:CE1# show ip route C 10.0.0.0/24 is directly connected, 3d05h, MgmtEth0/0/CPU0/0 L 10.0.0.1/32 is directly connected, 3d05h, MgmtEth0/0/CPU0/0 C 12.0.0.0/24 is directly connected, 3d05h, GigabitEthernet0/0/0/0 L 12.0.0.1/32 is directly connected, 3d05h, GigabitEthernet0/0/0/0 O IA 34.0.0.0/24 [110/2] via 12.0.0.2, 00:04:16, GigabitEthernet0/0/0/0 C 100.0.0.0/24 is directly connected, 3d05h, Loopback100 L 100.0.0.1/32 is directly connected, 3d05h, Loopback100 C 101.0.0.0/24 is directly connected, 3d05h, Loopback101 L 101.0.0.1/32 is directly connected, 3d05h, Loopback101 O IA 200.0.0.1/32 [110/3] via 12.0.0.2, 00:04:16, GigabitEthernet0/0/0/0 O IA 201.0.0.1/32 [110/3] via 12.0.0.2, 00:04:16, GigabitEthernet0/0/0/0 RP/0/0/CPU0:CE1#