YANG Push is a new IETF standard that allows a client to monitor changes to a YANG datastore with notifications instead of with <get> RPC requests. The old way using <get> is called a "Pull" approach.  The new way using notifications is called the "Pull" approach.


The following YANG Push RFCs are implemented in part or in full:

  • Subscription to YANG Notifications (RFC 8639)
  • Dynamic Subscription to YANG Events and Datastores over NETCONF (RFC 8640)
  • Subscription to YANG Notifications for Datastore Updates (RFC 8641)


YANG Push can be used to monitor configuration or operational datastore changes.


There are 2 kinds of subscriptions:

  1. Event Stream Subscriptions: Existing subscriptions to YANG notifications like <netconf-capability-change>
    SIL or SIL-SA publishes a notification to a specific event stream.  All sessions subscribing to that event stream can get the notification.
  2. Datastore Subscriptions: YANG Push subscriptions
    Server or SIL-SA generates a datastore update that is only sent to specific subscriptions, not to any event stream


There are 2 kinds of Datastore subscriptions:

  1. Periodic subscriptions: The data is sent to the client every interval, even if it did not change.
    This mode is similar a periodic <get> request but the client does not have to send any request.
  2. On-Change Subscriptions: The data is sent to the client only when the data changes. The implementation and the "dampening-period" parameter determine how often the server checks for new changes. This is much more efficient than the Pull approach since there are no wasted polling cycles (i.e., the data received is the same as the previous poll)


There are 3 kinds of On-Change subscriptions in the YumaPro implementation:

  1. Conventional: A YANG Push subscription for configuration data.
    The <datastore> parameter can be set to "candidate" or "running"
  2. Simulated Operational (simop): A YANG Push subscription for operational data.
    The <datastore> parameter is set to"operational".
    The server will use an internal polling interval to check if the data changed. If so, a YANG Push update is generated.
  3. Operational: A YANG Push subscription for operational data.
    The <datastore> parameter is set to"operational".
    The server does not check for changes to the operational data. Instead a SIL-SA subsystem sends internal PUSH updates to the server, which then generates YANG Push updates to send to the client.
    This mode is not yet released. A future release will also allow the SIL-SA subsystem (e.g., a linecard) to send YANG Push updates directly to the client, without requiring the server to process any data.



Configuring YANG Push


There is no CLI parameter to turn YANG Push on or off. Instead, then “bundle” parameter is used.


  • A bundle named “yang-push” is used. 

  • “yang-push” is a reserved library name in the server. 

  • The SIL library (libyang-push.so) contains the RPC operation callbacks for YANG Push.
    The “agt” directory contains the server implementation code.

  • The server does not need to support or enable NMDA to use YANG Push. If the --with-nmda parameter is set to     ‘false’ then the <operational> datastore will consist of config=false data nodes and their ancestor lists, list keys, and     containers.

  • The source code must be built using WITH_YANG_PUSH=1 in order for the YANG Push code to be included in the target binaries.



                

Parameter

            
                

Default

            
                

Description

            
                

bundle "yang-push"

            
                

not                 present

            
                

The bundle parameter is used to enable or disable the entire YANG Push feature

            
                

push-max-operational

            
                

4

            
                

Specifies the maximum number of on-change push subscriptions that can be in  use at once for the <operational> datastore

            
                

push-max-periodic

            
                

16

            
                

Specifies the maximum number of periodic push subscriptions that can be in use at once                 

            
                

push-min-dampening

            
                

100

            
                

Specifies  the minimum value for the 'dampening-period'          parameter that will be accepted for an on-change push subscription.    (centiseconds)

            
                

push-min-period

            
                

100

            
                

Specifies the minimum value for the 'period' parameter that will be accepted for a periodic push subscription. (centiseconds)

            
                

push-simop-enabled

            
                

true

            
                

Specifies if the simulated on-change push subscriptions          should be enabled for the <operational> datastore.

            
                

push-simop-patch-update

            
                

true

            
                

Specifies the notification message that should be used for a simulated on-change push subscription.

            
                

push-simop-period

            
                

500

            
                

Specifies the value for the 'period' parameter that will be used for    simulated operational on-change push subscription.

            




Configuration File Example: netconfd-pro.conf


netconfd-pro {
 bundle yang-push
 push-max-operational 10
 push-max-periodic 30
 push-min-dampening 200
 push-min-period 200
 push-simop-enabled true
 push-simop-period 300
}



YANG Push Filters


YANG Push provides configured filters and inline filters. Both types are fully supported.

There are 2 types of filters defined (subtree and XPath). Both types are supported.

Note that event stream filters and datastore filters appear to be the same but they are very different.
An event stream filter is applied to a <notification> message and a datastore filter is applied to YANG data nodes.


Some YANG Push usage modes have limited filtering capability:


Periodic No restrictions: Any subtree or XPath filter is allowed
ConventionalEither no filter at all is allowed or a filter that represents a data node identifier (i.e., all instances of a single object) Object must be a container or a list.
Simulated Operational (simop)No restrictions: Any subtree or XPath filter is allowed
OperationalA filter that represents a data node identifier (i.e., all instances of the target object) Object must be a container or a list. All ancestor keys must be provided.




Event Stream Filter Example: A subtree filter named "filter2" for a <netconf-session-start> event.


<filters xmlns="urn:ietf:params:xml:ns:yang:ietf-subscribed-notifications">
  <stream-filter>
    <name>filter2</name>
    <stream-xpath-filter
        xmlns:n="urn:ietf:params:xml:ns:yang:ietf-netconf-notifications"
        >/n:netconf-session-start</stream-xpath-filter>
  </stream-filter>
</filters>




Datastore Filter Example: A subtree filter named "filter2" for a datastore that selects the /nacm/groups subtree.


<filters xmlns="urn:ietf:params:xml:ns:yang:ietf-subscribed-notifications">
  <selection-filter xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push">
    <filter-id>filter2</filter-id>
    <datastore-subtree-filter>
       <nacm xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-acm">
         <groups />
       </nacm>
    </datastore-subtree-filter>
  </selection-filter>
</filters>



YANG Push Periodic Subscriptions


  • The <establish-subscription> RPC is used to start a YANG Push subscription.
  • Multiple subscriptions are allowed on the same session.
  • These subscriptions are controlled by the --push-max-periodic parameter.
    •  If set to zero then this type of subscription is disabled.
  • The <periodic> container must be present and the <period> parameter must be present.
  • The <period> parameter must have a value greater or equal to the value of the --push-min-period parameter



Periodic Subscription Example: Retrieve the /interfaces-state/interface entry for interface “lo” every 30 seconds.


The client might send this <establish-subscription> request:

<?xml version="1.0" encoding="UTF-8"?>
<rpc message-id="2"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <establish-subscription 
      xmlns="urn:ietf:params:xml:ns:yang:ietf-subscribed-notifications">
  <datastore xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push"
           xmlns:ds="urn:ietf:params:xml:ns:yang:ietf-datastores"
        >ds:operational</datastore>
  <datastore-subtree-filter xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push">
    <interfaces-state xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
      <interface>
         <name>lo</name>
      </interface>
    </interfaces-state>
  </datastore-subtree-filter>
  <periodic xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push">
   <period>3000</period>
  </periodic>
 </establish-subscription>
</rpc>


The server will respond with an <rpc-reply> that contains an "id" element if the subscription request was granted:


<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply message-id="2"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <id xmlns="urn:ietf:params:xml:ns:yang:ietf-subscribed-notifications">1</id>
</rpc-reply>


The server will send an initial “push-update” notification right away, and then periodically every 30 seconds


<?xml version="1.0" encoding="UTF-8"?>
<notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
 <eventTime>2020-10-11T19:02:59Z</eventTime>
 <push-update xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push">
  <id>1</id>
  <datastore-contents>
   <interfaces-state xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
    <interface>
     <name>lo</name>
     <type
      xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type"
        >ianaift:softwareLoopback</type>
     <admin-status>up</admin-status>
     <oper-status>up</oper-status>
     <if-index>1</if-index>
     <phys-address>00:00:00:00:00:00</phys-address>
     <speed>0</speed>
     <statistics>
      <in-octets>163797125</in-octets>
      <in-unicast-pkts>866265</in-unicast-pkts>
      <in-multicast-pkts>0</in-multicast-pkts>
      <in-discards>0</in-discards>
      <in-errors>0</in-errors>
      <out-octets>163797125</out-octets>
      <out-unicast-pkts>866265</out-unicast-pkts>
      <out-discards>0</out-discards>
      <out-errors>0</out-errors>
     </statistics>
    </interface>
   </interfaces-state>
  </datastore-contents>
 </push-update>
</notification>



YANG Push Conventional On-Change Subscriptions


  • A conventional on-change subscription request that is granted will cause the specified data to be pushed when the data has changed.
  • The “candidate” and “running” datastores can be monitored.  
  • There is no internal overhead such as polling to support this subscription type. 
  • The server will check these subscriptions when a successful commit to the target datastore has been completed.
  • Error operations are not reported to the subscription.
  • If the sync-on-start option is selected then a <push-update> will be sent when the subscription starts.
  • After that, only <push-change-update> events will usually be sent.  
  • The resync-subscription operation will cause a new <push-update> notification to be generated as soon as possible.
  • The “on-change” presence container must be provided, and a “dampening-period” parameter must be provided. This must be greater or equal to the --push-min-dampening CLI parameter value.
  • The filter parameter is restricted. Two modes of operation are provided:
    • object monitoring mode: The filter must represent one configuration data node. 
      All instances of that one object will be monitored.
    • datastore replication mode:  No filter at all is used


Object Monitoring Mode Example: Retrieve the /nacm/groups/group entry from <running> if any group is edited



Assume the client has created a named filter called “nacm-group”


<config>
  <filters xmlns="urn:ietf:params:xml:ns:yang:ietf-subscribed-notifications">
   <selection-filter xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push">
    <filter-id>nacm-group</filter-id>
    <datastore-xpath-filter
        xmlns:n="urn:ietf:params:xml:ns:yang:ietf-netconf-acm"
      >/n:nacm/n:groups/n:group</datastore-xpath-filter>
   </selection-filter>
  </filters>
 </config>


The client might send this request using a “selection-filter-ref” instead of an inline filter:

The dampening period is set to 10 seconds in this example.


<rpc message-id="5"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <establish-subscription
     xmlns="urn:ietf:params:xml:ns:yang:ietf-subscribed-notifications">
   <datastore xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push"
           xmlns:ds="urn:ietf:params:xml:ns:yang:ietf-datastores"
       >ds:running</datastore>
   <selection-filter-ref
     xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push"
       >nacm-group</selection-filter-ref>
   <on-change xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push">
     <dampening-period>1000</dampening-period>
    <excluded-change>move</excluded-change>
     <sync-on-start>true</sync-on-start>
   </on-change>
 </establish-subscription>


Assume the server sent an <id> response with a value of “1” like the example above.

If the “sync-on-start” parameter is set to “true” (the default) then the server will send a <push-update> notification as soon as the subscription starts:

<notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
 <eventTime>2020-10-11T19:39:21Z</eventTime>
 <push-update xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push">
  <id>1</id>
  <datastore-contents>
   <nacm xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-acm">
    <groups>
     <group>
      <name>test1</name>
     </group>
    </groups>
   </nacm>
  </datastore-contents>
 </push-update>
</notification>


The server will send a <push-change-update> notification when the targeted entry is changed


<?xml version="1.0" encoding="UTF-8"?>
<notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
 <eventTime>2020-10-11T19:42:01Z</eventTime>
 <push-change-update xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push">
  <id>1</id>
  <datastore-changes>
   <yang-patch xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push">
    <patch-id>0</patch-id>
    <edit>
     <edit-id>E1</edit-id>
     <operation>create</operation>
     <target>/ietf-netconf-acm:nacm/groups/group=monitor</target>
     <value>
      <group xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-acm">
       <name>monitor</name>
       <user-name>admin1</user-name>
       <user-name>admin2</user-name>
      </group>
     </value>
    </edit>
   </yang-patch>
  </datastore-changes>
 </push-change-update>
</notification>





YANG Push Simulated Operational On-Change Subscriptions


  • This mode is called "simulated" because the server maintains an internal polling cycle
    • This mode allows existing YANG instrumentation to be used with YANG Push without requiring any code changes
    • The server does not store GET2 callback responses in memory. It uses an efficient internal algorithm to determine if the last GET2 response was the same as the current response
  • A simulated operational on-change subscription request that is granted will cause the specified data to be pushed when the data has changed.
  • The “operational” datastore can be monitored. 
  • These subscriptions are only allowed if the --push-simop-enabled parameter is set to ‘true’.
  • There is an internal polling and processing overhead required o support this subscription type.  The server will check these subscriptions when the --push-simop-periodinterval expires. 
    • If the “dampening-period” parameter is provided then the maximum of these two parameters is used for the internal polling interval, when dampening is required.
  • If the sync-on-start option is selected then a <push-update> will be sent when the subscription starts. After that, only <push-change-update> events will usually be sent.  
    • Set --push-simop-patch-update=false to receive only<push-update> notifications instead of
      <push-change-update> notifications. The standard specifies the <push-change-update> format but this YANG Patch format is much more complex for the subscriber to filter and use. The <push-update> message is simple and has the same format every time.
  • The resync-subscription operation will cause a new <push-update> notification to be generated as soon as possible.
  • The “on-change” presence container must be provided, and a “dampening-period” parameter must be provided.
    • This must be greater or equal to the --push-min-dampening CLI parameter value.
  • There are no filter restrictions for a simulated operational subscription.  Any filter that is allowed for a <get> operation may be used for a simulated operational subscription. 
  • If a named filter is used then it can be modified while a  subscription is active. The subscription output will be updated as soon as possible after a filter reference in use is modified.


Simulated Operational On-Change Subscription Example:  Retrieve the /netconf-state/backup-files subtree if it changes


  • In this example the <datastore-xpath-filter> does not use any prefixes.
    • The server will accept this filter and find the correct data nodes even if the prefixes are missing.
  • In this example the dampening period is 1 second.


<?xml version="1.0" encoding="UTF-8"?>
<rpc message-id="9"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <establish-subscription xmlns="urn:ietf:params:xml:ns:yang:ietf-subscribed-notifications"> 
  <datastore xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push"
            xmlns:ds="urn:ietf:params:xml:ns:yang:ietf-datastores">ds:operational</datastore>
  <datastore-xpath-filter xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push"
     >/netconf-state/backup-files</datastore-xpath-filter>
  <on-change xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push">
   <dampening-period>100</dampening-period>
  </on-change>
 </establish-subscription>
</rpc>


The server will send a <push-update> notification right away for this filter:


<notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
 <eventTime>2020-10-11T20:20:21Z</eventTime>
 <push-update xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push">
  <id>4</id>
  <datastore-contents>
       <netconf-state xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">
        <backup-files xmlns="http://yumaworks.com/ns/yumaworks-system">
          <backup-file>
            <name>push1.xml</name>
            <backup-time>2020-08-29T20:10:23Z</backup-time>
          </backup-file>
          <backup-file>
            <name>push2.xml</name>
            <backup-time>2020-08-29T20:50:35Z</backup-time>
          </backup-file>
        </backup-files>
       </netconf-state>
  </datastore-contents>
 </push-update>
</notification>


If any backup file changes then the entire <backup-files> container is returned in the <push-change-update> notification:

Note that the operation will always be “replace” for a simulated operational on-change subscription.


<?xml version="1.0" encoding="UTF-8"?>
<notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
 <eventTime>2020-10-11T20:25:35Z</eventTime>
 <push-change-update xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push">
  <id>4</id>
  <datastore-changes>
   <yang-patch xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push">
    <patch-id>0</patch-id>
    <comment>simop</comment>
    <edit>
     <edit-id>E1</edit-id>
     <operation>replace</operation>
     <target>/</target>
     <value>
      <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <netconf-state xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">
        <backup-files xmlns="http://yumaworks.com/ns/yumaworks-system">
          <backup-file>
            <name>push1.xml</name>
            <backup-time>2020-08-29T20:10:23Z</backup-time>
          </backup-file>
          <backup-file>
            <name>push2.xml</name>
            <backup-time>2020-08-29T20:50:35Z</backup-time>
          </backup-file>
          <backup-file>
            <name>test-snap.xml</name>
            <backup-time>2020-10-11T20:25:34Z</backup-time>
          </backup-file>
        </backup-files>
       </netconf-state>
      </data>
     </value>
    </edit>
   </yang-patch>
  </datastore-changes>
 </push-change-update>
</notification>




YANG Push Usage Restrictions


The following usage restrictions are implementation-specific, and subject to change at anytime.


  • The "yang-push" bundle and all YANG Push functionality is only available in the 20.10 release train
  • There are multiple ways to do the same thing in YANG Push, so not all of it is implemented at once.
  • The “dynamic subscriptions” functionality is implemented in phase 1.
  • The “configured subscriptions” functionality is not needed or relevant for subscriptions that use NETCONF sessions. It is intended for a binary push protocol that is expected to be standardized in the near future.  This is planned for a future release.


Supported RFCs;

  • RFC 8639: Subscription to YANG Notifications

    • YANG Module: ietf-subscribed-notifications@2019-09-09.yang       

    • Supported Features  

      • encode-xml

      • replay

      • subtree

      • xpath 

    • Unsupported Features

      • configured     

      • dscp 

      • encode-json

      • interface-designation

      • qos

      • supports-vrf

                
  • RFC 8640:  Dynamic Subscription to YANG Events and Datastores over NETCONF

    • No restrictions


  • RFC 8641: Subscription to YANG Notifications for Datastore Updates      

    • YANG Module: ietf-yang-push@2019-09-09.yang

    • Supported Features   

      • on-change 

    • Unsupported Objects (yumapro-yangpush-dev.yang)

      • /subscriptions data node not             available for NMDA access to <operational> values of dynamic             subscriptions 

      • anchor-time parameter is not implemented yet