YANG & RESTCONF
Configuring BGP on IOS-XE with openconfig-network-instance over RESTCONF
In this module we will explore configuring the CSR1kv using Openconfig BGP YANG models over RESTCONF. To learn more about RESTCONF on IOS-XE, check out the RESTCONF Programmable Interface guide for IOS-XE.
Configuring the IOS-XE Device
In this excercise, we will configure one EBGP peer on our CSRv device using YANG, RESTCONF, and the openconfig-network-instance YANG model.
The openconfig-network-instance model is a superset of many route/switch concepts and was created to address some of the
limitations of working with individual openconfig-* protocol specific models.
To inspect the openconfig-network-instance model, go here.
To learn more about the history and how openconfig-network-instance ties in many route/switch concepts a unified fashion,
refer to this IETF slide deck.
Create New Python File
Return to Visual Studio Code and create a new Python file called
restconf_xe_bgp_conf.py
. You can copy this file name below for ease.
restconf_xe_bgp_conf.py
Imports Required and Setup
Since we are performing our YANG modeling operations of RESTCONF, we will naturally use Python's requests library. The HTTPBasicAuth is imported to allow us to specify a username and password. The disable_warnings() call tells requests' underlying urllib3 to not warn about unsigned SSL certificates.
# Using python request library for REST operations
from requests.auth import HTTPBasicAuth
import requests
# disable warnings from SSL/TLS certificates
requests.packages.urllib3.disable_warnings()
Check RESTCONF Capabilities
Similar to how ncclient can be used to check device capabilities, RESTCONF can be queried to return the list of YANG model capabilities that the device supports.
response = requests.get(
f"https://10.2.100.11/restconf/data/ietf-yang-library:modules-state",
auth=HTTPBasicAuth('admin', 'cisco.123'),
#headers=headers,
verify=False)
# Print out device capabilities.
print(response.text)
Construct the REST Payload
Now that we have confirmed RESTCONF connectivity for getting data, let's build the Payload that we intend to use to configure BGP and add the neighbor.
# RPC call that defines global level and neighbor level BGP peering information.
rest_data = '''
<network-instances>
<network-instance>
<name>default</name>
<protocols>
<protocol>
<identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:BGP</identifier>
<name>65001</name>
<config>
<identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:BGP</identifier>
<name>65001</name>
</config>
<bgp>
<global>
<config>
<as>65001</as>
<router-id>1.1.1.1</router-id>
</config>
</global>
<neighbors>
<neighbor>
<neighbor-address>10.1.1.2</neighbor-address>
<config>
<neighbor-address>10.1.1.2</neighbor-address>
<peer-as>65002</peer-as>
</config>
<ebgp-multihop>
<config>
<enabled>false</enabled>
</config>
</ebgp-multihop>
</neighbor>
</neighbors>
</bgp>
</protocol>
</protocols>
</network-instance>
</network-instances>
'''
Sending the RESTCONF Payload
With the RESTCONF payload defined, we now need to send this data to the device using requests libraries patch() function. Note how we provide HTTPBasic auth headers.
response = requests.patch(
f"https://10.2.100.11/restconf/data/openconfig-network-instance:network-instances",
auth=HTTPBasicAuth('admin', 'cisco.123'),
verify=False,
data=rest_data)
The Full Script
At this point, your script should look as follows:
# Using python request library for REST operations
from requests.auth import HTTPBasicAuth
import requests
# disable warnings from SSL/TLS certificates
requests.packages.urllib3.disable_warnings()
response = requests.get(
f"https://10.2.100.11/restconf/data/ietf-yang-library:modules-state",
auth=HTTPBasicAuth('admin', 'cisco.123'),
#headers=headers,
verify=False)
# Print out device capabilities.
print(response.text)
# RPC call that defines global level and neighbor level BGP peering information.
rest_data = '''
<network-instances>
<network-instance>
<name>default</name>
<protocols>
<protocol>
<identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:BGP</identifier>
<name>65001</name>
<config>
<identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:BGP</identifier>
<name>65001</name>
</config>
<bgp>
<global>
<config>
<as>65001</as>
<router-id>1.1.1.1</router-id>
</config>
</global>
<neighbors>
<neighbor>
<neighbor-address>10.1.1.2</neighbor-address>
<config>
<neighbor-address>10.1.1.2</neighbor-address>
<peer-as>65002</peer-as>
</config>
<ebgp-multihop>
<config>
<enabled>false</enabled>
</config>
</ebgp-multihop>
</neighbor>
</neighbors>
</bgp>
</protocol>
</protocols>
</network-instance>
</network-instances>
'''
# Patch openconfig-network-instance with the updated BGP configuration.
response = requests.patch(
f"https://10.2.100.11/restconf/data/openconfig-network-instance:network-instances",
auth=HTTPBasicAuth('admin', 'cisco.123'),
verify=False,
data=rest_data)
Execute Python Script
python3.6 restconf_xe_bgp_conf.py
Verify Configuration on CSRv
Your CSR's BGP configuration should look as follows:
Pod03-CSRv#show run | sec bgp
router bgp 65001
bgp router-id 1.1.1.1
bgp log-neighbor-changes
bgp bestpath compare-routerid
neighbor 10.1.1.2 remote-as 65002
neighbor 10.1.1.2 transport path-mtu-discovery disable
neighbor 10.1.1.2 transport connection-mode active
neighbor 10.1.1.2 log-neighbor-changes
neighbor 10.1.1.2 timers 30 90
Pod03-CSRv#
Use CURL to Query RESTCONF
To visually inspect that the configuration was applied, you can also use the unix tool curl to Query the openconfig-network-instance model.
curl -v -k -u admin:cisco.123 https://10.2.100.11/restconf/data/openconfig-network-instance:network-instances/
You should observe something similar to the following:
<network-instances xmlns="http://openconfig.net/yang/network-instance" xmlns:oc-netinst="http://openconfig.net/yang/network-instance">
<network-instance>
<name>management</name>
<config>
<name>management</name>
<type xmlns:oc-ni-types="http://openconfig.net/yang/network-instance-types">oc-ni-types:L3VRF</type>
<enabled-address-families xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</enabled-address-families>
</config>
<state>
<name>management</name>
<type xmlns:oc-ni-types="http://openconfig.net/yang/network-instance-types">oc-ni-types:L3VRF</type>
<enabled-address-families xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</enabled-address-families>
</state>
<interfaces>
<interface>
<id>GigabitEthernet1</id>
<config>
<id>GigabitEthernet1</id>
<interface>GigabitEthernet1</interface>
</config>
<state>
<id>GigabitEthernet1</id>
<interface>GigabitEthernet1</interface>
<associated-address-families xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</associated-address-families>
</state>
</interface>
</interfaces>
<tables>
<table>
<protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</protocol>
<address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family>
<config>
<protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</protocol>
<address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family>
</config>
<state>
<protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</protocol>
<address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family>
</state>
</table>
<table>
<protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</protocol>
<address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family>
<config>
<protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</protocol>
<address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family>
</config>
<state>
<protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</protocol>
<address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family>
</state>
</table>
</tables>
<protocols>
<protocol>
<identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:BGP</identifier>
<name>65001</name>
<config>
<identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:BGP</identifier>
<name>65001</name>
</config>
<bgp>
<global>
<state>
<as>65001</as>
</state>
<graceful-restart>
<config>
<enabled>false</enabled>
</config>
<state>
<enabled>false</enabled>
</state>
</graceful-restart>
<route-selection-options>
<config>
<always-compare-med>false</always-compare-med>
</config>
<state>
<always-compare-med>false</always-compare-med>
</state>
</route-selection-options>
</global>
</bgp>
</protocol>
<protocol>
<identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</identifier>
<name>DEFAULT</name>
<config>
<identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</identifier>
<name>DEFAULT</name>
</config>
<static-routes>
<static>
<prefix>0.0.0.0/0</prefix>
<config>
<prefix>0.0.0.0/0</prefix>
</config>
<state>
<prefix>0.0.0.0/0</prefix>
</state>
<next-hops>
<next-hop>
<index>10.0.249.1</index>
<config>
<index>10.0.249.1</index>
<next-hop>10.0.249.1</next-hop>
</config>
<state>
<index>10.0.249.1</index>
<next-hop>10.0.249.1</next-hop>
</state>
</next-hop>
</next-hops>
</static>
</static-routes>
</protocol>
<protocol>
<identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</identifier>
<name>DEFAULT</name>
<config>
<identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</identifier>
<name>DEFAULT</name>
</config>
</protocol>
</protocols>
</network-instance>
<network-instance>
<name>default</name>
<config>
<name>default</name>
<type xmlns:oc-ni-types="http://openconfig.net/yang/network-instance-types">oc-ni-types:DEFAULT_INSTANCE</type>
<description>default-vrf [read-only]</description>
</config>
<state>
<name>default</name>
<type xmlns:oc-ni-types="http://openconfig.net/yang/network-instance-types">oc-ni-types:DEFAULT_INSTANCE</type>
<description>default-vrf [read-only]</description>
</state>
<tables>
<table>
<protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</protocol>
<address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family>
<config>
<protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</protocol>
<address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family>
</config>
<state>
<protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</protocol>
<address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family>
</state>
</table>
<table>
<protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</protocol>
<address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV6</address-family>
<config>
<protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</protocol>
<address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV6</address-family>
</config>
<state>
<protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</protocol>
<address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV6</address-family>
</state>
</table>
<table>
<protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:OSPF</protocol>
<address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family>
<config>
<protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:OSPF</protocol>
<address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family>
</config>
<state>
<protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:OSPF</protocol>
<address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family>
</state>
</table>
<table>
<protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</protocol>
<address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family>
<config>
<protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</protocol>
<address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family>
</config>
<state>
<protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</protocol>
<address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family>
</state>
</table>
<table>
<protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</protocol>
<address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV6</address-family>
<config>
<protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</protocol>
<address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV6</address-family>
</config>
<state>
<protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</protocol>
<address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV6</address-family>
</state>
</table>
</tables>
<protocols>
<protocol>
<identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:BGP</identifier>
<name>65001</name>
<config>
<identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:BGP</identifier>
<name>65001</name>
</config>
<bgp>
<global>
<config>
<as>65001</as>
<router-id>1.1.1.1</router-id>
</config>
<state>
<as>65001</as>
<router-id>1.1.1.1</router-id>
</state>
<graceful-restart>
<config>
<enabled>false</enabled>
</config>
<state>
<enabled>false</enabled>
</state>
</graceful-restart>
<route-selection-options>
<config>
<always-compare-med>false</always-compare-med>
<external-compare-router-id>true</external-compare-router-id>
</config>
<state>
<always-compare-med>false</always-compare-med>
<external-compare-router-id>true</external-compare-router-id>
</state>
</route-selection-options>
</global>
<neighbors>
<neighbor>
<neighbor-address>10.1.1.2</neighbor-address>
<config>
<neighbor-address>10.1.1.2</neighbor-address>
<peer-as>65002</peer-as>
</config>
<state>
<neighbor-address>10.1.1.2</neighbor-address>
<peer-as>65002</peer-as>
<peer-type>EXTERNAL</peer-type>
<messages>
<sent>
<UPDATE>0</UPDATE>
<NOTIFICATION>0</NOTIFICATION>
</sent>
<received>
<UPDATE>0</UPDATE>
<NOTIFICATION>0</NOTIFICATION>
</received>
</messages>
<queues>
<input>0</input>
<output>0</output>
</queues>
</state>
<timers>
<config>
<hold-time>90.0</hold-time>
<keepalive-interval>30.0</keepalive-interval>
<minimum-advertisement-interval>30.0</minimum-advertisement-interval>
</config>
<state>
<hold-time>90.0</hold-time>
<keepalive-interval>30.0</keepalive-interval>
<minimum-advertisement-interval>30.0</minimum-advertisement-interval>
</state>
</timers>
<transport>
<config>
<mtu-discovery>false</mtu-discovery>
<passive-mode>false</passive-mode>
</config>
<state>
<mtu-discovery>false</mtu-discovery>
<passive-mode>false</passive-mode>
<local-port>0</local-port>
<remote-port>0</remote-port>
</state>
</transport>
<error-handling>
<state>
<treat-as-withdraw>true</treat-as-withdraw>
</state>
</error-handling>
<logging-options>
<config>
<log-neighbor-state-changes>true</log-neighbor-state-changes>
</config>
<state>
<log-neighbor-state-changes>true</log-neighbor-state-changes>
</state>
</logging-options>
<ebgp-multihop>
<config>
<enabled>false</enabled>
</config>
<state>
<enabled>false</enabled>
</state>
</ebgp-multihop>
<route-reflector>
<config>
<route-reflector-client>false</route-reflector-client>
</config>
</route-reflector>
<as-path-options>
<config>
<replace-peer-as>false</replace-peer-as>
</config>
</as-path-options>
<add-paths>
<config>
<receive>false</receive>
</config>
</add-paths>
</neighbor>
</neighbors>
</bgp>
</protocol>
<protocol>
<identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:OSPF</identifier>
<name>100</name>
<config>
<identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:OSPF</identifier>
<name>100</name>
</config>
</protocol>
<protocol>
<identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</identifier>
<name>DEFAULT</name>
<config>
<identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:STATIC</identifier>
<name>DEFAULT</name>
</config>
<static-routes>
<static>
<prefix>10.0.249.0/24</prefix>
<config>
<prefix>10.0.249.0/24</prefix>
</config>
<state>
<prefix>10.0.249.0/24</prefix>
</state>
<next-hops>
<next-hop>
<index>GigabitEthernet1_10.0.249.1</index>
<config>
<index>GigabitEthernet1_10.0.249.1</index>
<next-hop>10.0.249.1</next-hop>
</config>
<state>
<index>GigabitEthernet1_10.0.249.1</index>
<next-hop>10.0.249.1</next-hop>
</state>
<interface-ref>
<config>
<interface>GigabitEthernet1</interface>
</config>
<state>
<interface>GigabitEthernet1</interface>
</state>
</interface-ref>
</next-hop>
</next-hops>
</static>
</static-routes>
</protocol>
<protocol>
<identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</identifier>
<name>DEFAULT</name>
<config>
<identifier xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</identifier>
<name>DEFAULT</name>
</config>
</protocol>
</protocols>
</network-instance>
</network-instances>
Let's wrap-up the Python/Openconfig/YANG sections and move on to verifying the entire BGP topology and ensure all BGP peers are Established.