cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1088
Views
0
Helpful
4
Replies

XRv9K NETCONF 1.1

horseinthesky
Level 1
Level 1

Hello.
I'm experimenting with ydk-examples from https://github.com/CiscoDevNet/ydk-py-samples and got stuck in something.


I'm trying to deploy this config on XRv9K 

import logging

from ydk.services import CodecService, CRUDService
from ydk.providers import CodecServiceProvider, NetconfServiceProvider
from ydk.models.openconfig import openconfig_bgp as oc_bgp
from ydk.models.openconfig import openconfig_bgp_types as oc_bgp_types
from ydk.filters import YFilter

logger = logging.getLogger('ydk')
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
formatter = logging.Formatter(("%(asctime)s - %(name)s - "
                               "%(levelname)s - %(message)s"))
handler.setFormatter(formatter)
logger.addHandler(handler)

DEVICES = {
    'junos': {
        'ip': '10.10.30.4',
        'pass': 'Juniper'
    },
    'xr': {
        'ip': '10.10.30.5',
        'pass': 'admin'
    },
    'xe': {
        'ip': '10.10.30.6',
        'pass': 'admin'
    }
}


def config_bgp(bgp):
    """Add config data to bgp object."""
    # global configuration
    bgp.global_.config.as_ = 65001
    afi_safi = bgp.global_.afi_safis.AfiSafi()
    afi_safi.afi_safi_name = oc_bgp_types.IPV6UNICAST()
    afi_safi.config.afi_safi_name = oc_bgp_types.IPV6UNICAST()
    afi_safi.config.enabled = True
    bgp.global_.afi_safis.afi_safi.append(afi_safi)

    # configure IBGP peer group
    peer_group = bgp.peer_groups.PeerGroup()
    peer_group.peer_group_name = "EBGP"
    peer_group.config.peer_group_name = "EBGP"
    peer_group.config.peer_as = 65002
    peer_group.transport.config.local_address = "Loopback0"
    afi_safi = peer_group.afi_safis.AfiSafi()
    afi_safi.afi_safi_name = oc_bgp_types.IPV6UNICAST()
    afi_safi.config.afi_safi_name = oc_bgp_types.IPV6UNICAST()
    afi_safi.config.enabled = True
    # afi_safi.apply_policy.config.import_policy.append("POLICY3")
    # afi_safi.apply_policy.config.export_policy.append("POLICY1")
    peer_group.afi_safis.afi_safi.append(afi_safi)
    bgp.peer_groups.peer_group.append(peer_group)

    # configure IBGP neighbor
    neighbor = bgp.neighbors.Neighbor()
    neighbor.neighbor_address = '2001:db8:e:1::1'
    neighbor.config.neighbor_address = '2001:db8:e:1::1'
    neighbor.config.peer_group = "EBGP"
    bgp.neighbors.neighbor.append(neighbor)


if __name__ == '__main__':
    # provider = CodecServiceProvider(type='xml')
    # codec = CodecService()

    bgp = oc_bgp.Bgp()
    bgp.yfilter = YFilter.replace
    config_bgp(bgp)

    # print(codec.encode(provider, native))

    device = DEVICES['xe']

    provider = NetconfServiceProvider(
        address=device['ip'],
        port=830,
        username='admin',
        password=device['pass'],
        protocol='ssh'
    )
    crud = CRUDService()
    crud.create(provider, bgp)


I get this:

2019-12-06 17:40:48,225 - ydk - INFO - Path where models are to be downloaded: /home/horseinthesky/.ydk/10.10.30.5
2019-12-06 17:40:48,234 - ydk - INFO - Connected to 10.10.30.5 on port 830 using ssh with timeout of -1
2019-12-06 17:40:48,234 - ydk - INFO - Executing CRUD create operation on [openconfig-bgp:bgp]
2019-12-06 17:40:48,234 - ydk - INFO - Executing 'edit-config' RPC on [openconfig-bgp:bgp]
2019-12-06 17:40:48,285 - ydk - INFO - ============= Sending RPC to device =============
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <target>
    <candidate/>
  </target>
  <config><bgp xmlns="http://openconfig.net/yang/bgp" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="replace">
  <global>
    <config>
      <as>65001</as>
    </config>
    <afi-safis>
      <afi-safi>
        <afi-safi-name xmlns:oc-bgp-types="http://openconfig.net/yang/bgp-types">oc-bgp-types:IPV6_UNICAST</afi-safi-name>
        <config>
          <afi-safi-name xmlns:oc-bgp-types="http://openconfig.net/yang/bgp-types">oc-bgp-types:IPV6_UNICAST</afi-safi-name>
          <enabled>true</enabled>
        </config>
      </afi-safi>
    </afi-safis>
  </global>
  <neighbors>
    <neighbor>
      <neighbor-address>2001:db8:e:1::1</neighbor-address>
      <config>
        <peer-group>EBGP</peer-group>
        <neighbor-address>2001:db8:e:1::1</neighbor-address>
      </config>
    </neighbor>
  </neighbors>
  <peer-groups>
    <peer-group>
      <peer-group-name>EBGP</peer-group-name>
      <config>
        <peer-group-name>EBGP</peer-group-name>
        <peer-as>65002</peer-as>
      </config>
      <transport>
        <config>
          <local-address>Loopback0</local-address>
        </config>
      </transport>
      <afi-safis>
        <afi-safi>
          <afi-safi-name xmlns:oc-bgp-types="http://openconfig.net/yang/bgp-types">oc-bgp-types:IPV6_UNICAST</afi-safi-name>
          <config>
            <afi-safi-name xmlns:oc-bgp-types="http://openconfig.net/yang/bgp-types">oc-bgp-types:IPV6_UNICAST</afi-safi-name>
            <enabled>true</enabled>
          </config>
        </afi-safi>
      </afi-safis>
    </peer-group>
  </peer-groups>
</bgp>
</config>
</edit-config>
</rpc>
2019-12-06 17:40:48,468 - ydk - INFO - ============= Received RPC from device =============
<?xml version="1.0"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="1">
  <rpc-error>
    <error-type>protocol</error-type>
    <error-tag>unknown-namespace</error-tag>
    <error-severity>error</error-severity>
    <error-info>
      <bad-element>bgp</bad-element>
      <bad-namespace>http://openconfig.net/yang/bgp</bad-namespace>
    </error-info>
  </rpc-error>
</rpc-reply>

2019-12-06 17:40:48,469 - ydk - ERROR - RPC error occurred:
<?xml version="1.0"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="1">
  <rpc-error>
    <error-type>protocol</error-type>
    <error-tag>unknown-namespace</error-tag>
    <error-severity>error</error-severity>
    <error-info>
      <bad-element>bgp</bad-element>
      <bad-namespace>http://openconfig.net/yang/bgp</bad-namespace>
    </error-info>
  </rpc-error>
</rpc-reply>

Traceback (most recent call last):
  File "openconfig_bgp.py", line 86, in <module>
    crud.create(provider, bgp)
  File "/usr/local/lib/python3.6/dist-packages/ydk/errors/error_handler.py", line 112, in helper
    return func(self, provider, entity, *args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/ydk/services/crud_service.py", line 49, in create
    return _crud_update(provider, entity, self._crud.create)
  File "/usr/local/lib/python3.6/dist-packages/ydk/services/crud_service.py", line 70, in _crud_update
    return crud_call(provider, entity)
  File "/usr/lib/python3.6/contextlib.py", line 99, in __exit__
    self.gen.throw(type, value, traceback)
  File "/usr/local/lib/python3.6/dist-packages/ydk/errors/error_handler.py", line 82, in handle_runtime_error
    _raise(_exc)
  File "/usr/local/lib/python3.6/dist-packages/ydk/errors/error_handler.py", line 54, in _raise
    exec("raise exc from None")
  File "<string>", line 1, in <module>
ydk.errors.YServiceProviderError:  RPC error occurred; check log file for details
2019-12-06 17:40:48,536 - ydk - INFO - Disconnected from device

 

 

If I set logging level to DEBUG I see that YDK is sending both base 1.0 and base 1.1 capabilities:

<?xml version="1.0" encoding="UTF-8"?>
<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <capabilities>
    <capability>urn:ietf:params:netconf:base:1.0</capability>
    <capability>urn:ietf:params:netconf:base:1.1</capability>
    <capability>urn:ietf:params:netconf:capability:writable-running:1.0</capability>
    <capability>urn:ietf:params:netconf:capability:candidate:1.0</capability>
    <capability>urn:ietf:params:netconf:capability:startup:1.0</capability>
    <capability>urn:ietf:params:netconf:capability:rollback-on-error:1.0</capability>
  </capabilities>
</hello>


XRv9K sending only base 1.1 capability:

 <capabilities>
  <capability>urn:ietf:params:netconf:base:1.1</capability>
  <capability>urn:ietf:params:netconf:capability:candidate:1.0</capability>
  <capability>urn:ietf:params:netconf:capability:rollback-on-error:1.0</capability>
  <capability>urn:ietf:params:netconf:capability:validate:1.1</capability>
  <capability>urn:ietf:params:netconf:capability:confirmed-commit:1.1</capability>
  <capability>urn:ietf:params:netconf:capability:notification:1.0</capability>
  <capability>urn:ietf:params:netconf:capability:interleave:1.0</capability>

 

 

So it is supposed that only 1.1 framing format is possible.
But in the output above I can see that YDK is sending edit-config RPC with base 1.0 namespace:

<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">

 How can I fix that?

4 Replies 4

yangorelik
Spotlight
Spotlight

The issue is not related to YANG-1.1 support. Look at the error message:

ydk.errors.YServiceProviderError:  RPC error occurred; check log file for details

And details in the log:

2019-12-06 17:40:48,468 - ydk - INFO - ============= Received RPC from device =============
<?xml version="1.0"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="1">
  <rpc-error>
    <error-type>protocol</error-type>
    <error-tag>unknown-namespace</error-tag>
    <error-severity>error</error-severity>
    <error-info>
      <bad-element>bgp</bad-element>
      <bad-namespace>http://openconfig.net/yang/bgp</bad-namespace>
    </error-info>
  </rpc-error>
</rpc-reply>

This means that Netconf does not know how to translate 'bgp' node to router configuration commands.

I think that BGP on Cisco routers can be configured only by using Cisco proprietary YANG models. The Cisco routers do not support openconfig models for device configuration; these models can be used only for reading configuration.

Yan Gorelik
YDK Solutions

I'll try to send the same RPC by hand tomorrow but for now, I am pretty confused about why YDK uses Netconf 1.0 framing to send RPC when the device said that it only capable of 1.0?!

As I understand the Netconf 1.0 and 1.1 uses the same framing; the version 1.1 just has some additional capabilities. More info about differences you can find here. Please do not confuse Netconf version and IETF YANG model namespaces. The last all have '*:base:1.0' namespaces defined in RFC 6241.

The CRUD and Netconf Services implementation in YDK currently use only Netconf 1.0 capabilities. However, the Netconf client, which is implemented in C and C++ code, does implement both 1.0 and 1.1 versions, meaning that the RPCs compliant with version 1.1 still can be successfully processed.

The YDK also includes Executor Service, which allows to build and execute RPCs based on ietf_netconf.yang model. That means, you can include into RPC any constructs defined in the model. You can find multiple examples of how to use Executor Service in unit tests included in ydk-gen repository.

Yan Gorelik
YDK Solutions

Actually if I try to send RPC with ]]>]]> at the end XRv9k will close the session because of wrong framing.

The right way to do it in 1.1 is the following:

#85
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="4">
<commit/>
</rpc>
##

But any way it doesn't work I guess because XRv9K doesn't support openconfig-bgp model for the config =(