NSO Lab 6: L3VPN (Layer 3 Virtual Private Networks)
Layer 3 Virtual Private Networks (L3VPN)
In Lab 6: L3VPN, participants typically delve into the configuration and management of Layer 3 Virtual Private Networks (L3VPNs) using the Cisco Network Services Orchestrator (NSO). This lab involves tasks such as defining VPN parameters, specifying routing policies, and orchestrating the deployment of L3VPNs across network devices. Participants may utilize NSO's capabilities to automate the provisioning and modification of L3VPN services, ensuring consistency and efficiency in large-scale network environments. The lab aims to provide hands-on experience in leveraging NSO for the seamless orchestration of Layer 3 VPN services, showcasing the platform's ability to streamline complex networking tasks. Successful completion of NSO Lab 6 equips participants with practical skills in deploying and managing L3VPNs using NSO, contributing to the optimization of network operations and services.
Lab:
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
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#