<?xml version='1.0'?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!ENTITY rfc2119 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY rfc6020 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6020.xml">
<!ENTITY rfc6241 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6241.xml">
]>


<?rfc toc="yes"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes" ?>
<?rfc compact="no"?>
<?rfc subcompact="no"?>
<?rfc linkmailto="no" ?>
<?rfc editing="no" ?>
<?rfc comments="yes" ?>
<?rfc inline="yes"?>
<?rfc rfcedstyle="yes"?>
<?rfc-ext allow-markup-in-artwork="yes" ?>
<?rfc-ext include-index="no" ?>
<!--<?rfc strict="no"?> -->

<rfc category="std"
     ipr="trust200902"
     docName="draft-kwatsen-netmod-opstate-01">
  <front>
    <title abbrev="Op-State Enhancements">Operational State Enhancements for YANG, NETCONF, and RESTCONF</title>
      <author initials="K.W." surname="Watsen" fullname="Kent Watsen">
        <organization>Juniper Networks</organization>
         <address>
           <email>kwatsen@juniper.net</email>
         </address>
      </author>
      <author initials="A.B." surname="Bierman" fullname="Andy Bierman">
        <organization>Yumaworks</organization>
         <address>
           <email>andy@yumaworks.com</email>
         </address>
      </author>
      <author initials="M.B." surname="Bjorklund" fullname="Martin Bjorklund">
        <organization>Tail-f Systems</organization>
         <address>
           <email>mbj@tail-f.com</email>
         </address>
      </author>
      <author initials="J.S." surname="Schoenwaelder" fullname="Juergen Schoenwaelder">
        <organization>Jacobs University Bremen</organization>
        <address>
          <email>j.schoenwaelder@jacobs-university.de</email>
        </address>
      </author>
      <date/>
      <area>Operations</area>
      <workgroup>NETMOD Working Group</workgroup>
      <abstract>
        <t>This document presents enhancements to YANG, NETCONF, and RESTCONF 
        satisfying the requirements set forth in Terminology and Requirements
        for Enhanced Handling of Operational State.</t>
      </abstract>
    </front>

    <middle>

      <section title="Introduction" anchor="intro">
        <t>This document presents enhancements to YANG <xref target="RFC6020"/>, NETCONF
        <xref target="RFC6241"/>, and RESTCONF <xref target="draft-ietf-netconf-restconf"/>
        satisfying the requirements set forth in Terminology and Requirements for Enhanced
        Handling of Operational State <xref target="draft-ietf-netmod-opstate-reqs-03"/>.</t>
        <t>A traceability matrix illustrating how each requirement is satisfied is provided
        in <xref target="traceability-matrix"/>.</t>
      </section>

      <section title="Terminology" anchor="terms">
        <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL",
        "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY",
        and "OPTIONAL" in this document are to be interpreted as
        described in RFC 2119 <xref target="RFC2119"/>.</t>
        <t>The following terms are defined in <xref target="RFC6241"/>:
          <list style="symbols">
            <t>client</t>
            <t>datastore</t>
            <t>server</t>
          </list>
        </t>
        <t>The following terms are defined in <xref target="draft-ietf-netmod-opstate-reqs-03"/>:
          <list style="symbols">
            <t>applied configuration</t>
            <t>asynchronous configuration operation</t>
            <t>derived state</t>
            <t>intended configuration</t>
            <t>operational state</t>
            <t>synchronous configuration operation</t>
          </list>
        </t>
      </section>

      <section title="Conceptual Model" anchor="model">
        <t>The following diagram illustrates the conceptual model presented
        in this document:</t>
        <figure>
          <artwork><![CDATA[
                                     +                   
                       intended      |    operational    
                        state        |       state       
                                     |                   
                     +----------+    |    +---------+    
  config true        | intended |    |    | applied |    
  YANG nodes         |  config  |    |    | config  |    
                     +----------+    |    +---------+    
                                     |                   
+-------------------------------------------------------+
                                     |                   
                                     |    +---------+    
  config false                       |    | derived |    
  YANG nodes                         |    |  state  |    
                                     |    +---------+    
                                     |                   
                                     +                   
          ]]></artwork>
        </figure>
        <t>Key aspects illustrated in the above diagram include:
          <list style="symbols">
            <t>The horizontal line partitions what is defined by config true and
            config false nodes.  Above the line are data models defined by config
            true nodes and below the line are data models defined by config false
            nodes.  Notably, it illustrates that the same config true nodes define
            the data model for both the intended configuration and the applied
            configuration, consistent with requirement 1-C in <xref
            target="draft-ietf-netmod-opstate-reqs-03"/>.</t>
            <t>The vertical line partitions the types of data models in a server.
            Left of the line is data that represents the intended state
            of the server and right of the line data that represents
            the operational state of the server.  Notably, the intended state of
            the server consists only of config true nodes, whereas the operational
            state consists of both config true and config false nodes.  This
            diagram illustrates that operational state is composed of both applied
            config and derived state, consistent with its terminology definition
            in <xref target="draft-ietf-netmod-opstate-reqs-03"/>.</t>
          </list>
        </t>
      </section>

      <section title="Enhancements to YANG" anchor="yang">

        <t>To support the opstate requirements, one modification to YANG is 
        necessary.  This modification can be introduced as a YANG extension,
        as described next.</t>

        <section title="The related-state Statement" anchor="related-state">

          <t>The "related-state" statement designates where related
          derived state nodes for a config true node can be found.
          This association is not needed for any descendant config
          false nodes, as they are already implicitly associated
          to the parent config true node.</t>

          <t>The "related-state" statement takes as an argument a
          string that is used to specify the path to a config false node
          holding the associated operational state.  The format of the
          argument is the same as for the leafref's "path" statement,
          Section 9.9.2 in <xref target="RFC6020"/>.</t>

          <section title="Usage Example" toc="exclude">
            <t>The following example illustrates the related-state statement in use:</t>
            <figure>
              <artwork><![CDATA[
module ex-interfaces {
  namespace "http://example.com/interfaces";
  prefix xif;

  import ietf-yang-related-state {
    prefix yrs;
  }

  container interfaces {
    list interface {
      key name;
      yrs:related-state
        "/interfaces-state/interface[name=current()/name]";
      leaf name { type string }
      leaf mtu { type uint16; }
      ...
    }
  }

  container interfaces-state {
    config false;
    list interface {
      key name;
      leaf name { type string; }
      ...
    }
  }
}

]]></artwork>
            </figure>
          </section>  <!-- end usage example -->
        </section>  <!-- end related-state -->
 
        <section title="YANG Module">
          <t>Note: there is no tree diagram for this YANG module
          since it does not contain any protocol accessible nodes.</t>
          <figure>
            <artwork><![CDATA[

<CODE BEGINS> file "ietf-yang-related-state@2016-02-02.yang"

module ietf-yang-related-state {
  namespace urn:ietf:params:xml:ns:yang:ietf-yang-related-state;
  prefix yrs;

  organization
    "IETF NETMOD (NETCONF Data Modeling Language) Working Group";

  contact
    "WG Web:   <http://tools.ietf.org/wg/netmod/>
     WG List:  <netmod@ietf.org>
     WG Chair: Tom Nadeau
               <tnadeau@brocade.com>
     WG Chair: Kent Watsen
               <kwatsen@juniper.net>
     WG Chair: Juergen Schoenwaelder
               <j.schoenwaelder@jacobs-university.de>";

  description
    "This YANG module defines the YANG statement 'related-state'.";

  revision 2016-02-02 {
    description
      "Initial revision";
    reference
      "RFC XXXXX: Terminology and Requirements for Enhanced Handling
       of Operational State";
  }

  extension related-state {
    argument path;
    description
      "The related-state statement is used to identify a node that
       contains additional operational state associated for a config
       true node.

       The format of the argument is the same as for a leafref's
       'path' statement.

       The related-state statement can be specified in the following
       YANG statements:

         o  leaf
         o  leaf-list
         o  container
         o  list

       The related-state statement allows the following YANG
       substatements:

         o  description

       Multiple related-state statements can be given in a
       specific node.";
  }

}

<CODE ENDS>
]]></artwork>
          </figure>
        </section>
      </section>  <!-- end enhancments to yang -->


      <section title="Enhancements to NETCONF" anchor="netconf">

        <t>The following sections describe enhancements to NETCONF provided by
        the "ietf-netconf-opstate" YANG module.</t>

        <section title="The 'applied' &lt;source&gt; Value" anchor="applied">

          <t>The "ietf-netconf-opstate" YANG module enables NETCONF clients
          to access the contents of the applied configuration datastore by
          passing the value 'applied' for the &lt;source&gt; parameter in 
          the &lt;get-config&gt; and &lt;copy-config&gt; operations.</t>

          <section title="Usage Example" toc="exclude">
            <t>To retrieve the "/interfaces" subtree from the applied
            configuration datastore:</t>
            <figure>
              <artwork><![CDATA[
<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <get-config>
    <source>
      <applied xmlns="urn:example:ietf-netconf-applied-config"/>
    </source>
    <filter type="subtree">
      <interfaces xmlns="http://example.com/example-app"/>
    </filter>
  </get-config>
</rpc>
              ]]></artwork>
            </figure>
          </section>
        </section>

        <section title="The &lt;sync-behavior&gt; Parameter" anchor="sync-behavior">

          <t>The "ietf-netconf-opstate" YANG module enables NETCONF clients
          to control if operations that effect the intended configuration
          are executed synchronously or asynchronously.  The operations that
          support this ability include:
          <list style="symbols">
            <t>&lt;edit-config&gt;   // only when target is "running"</t>
            <t>&lt;copy-config&gt;   // only when target is "running"</t>
            <t>&lt;commit&gt;</t>
          </list>
          </t>
          <t>In order to control how an operation is executed, clients
          must pass the &lt;sync-behavior&gt; parameter with a value
          'sync' or 'async', for synchronous or asynchronous execution
          respectively.</t>
          <t>When synchronous execution is requested (i.e., 'sync' is
          passed), the &lt;rpc-reply&gt; will not return until the
          server has fully attempted to update both the intended and
          applied configurations.  When no errors or warnings are
          generated, the &lt;rpc-reply&gt; will only contain &lt;ok&gt;.
          When only warnings are generated, the &lt;rpc-reply&gt; will 
          contain &lt;ok&gt; and also the &lt;apply-warnings&gt; flag.
          If any errors are generated, the &lt;rpc-reply&gt; will
          contain the standard &lt;rpc-error&gt;.</t>
          <t>When asynchronous execution is requested (i.e., 'async' is
          passed), the &lt;rpc-reply&gt; will return immediately, and
          contain an additional &lt;sync-id&gt; value that clients can
          use to correlate a subsequent 'sync-complete' notification
          (<xref target="sync-complete"/>) to determine when the
          asynchronous request has completed and with what result.</t>
          <t>For either synchronous or asynchronous requests, any processing
          semantics associated with the operation are preserved and
          extended to also include applying the configuration to internal
          server components.  Notably are the &lt;edit-config&gt; 
          operation's &lt;error-option &gt; parameter and the &lt;commit&gt;
          operation's atomic update semantic.  Any rollback that may
          occur will restore both the intended and the applied
          configurations to their previous states.</t>
          <t>In order to implement the rollback behavior, for &lt;edit-config&gt;
          or &lt;commit&gt;, it is necessary for the server to maintain a
          global lock until the processing is complete.  That is, either a 'sync' request
          returns or an 'async' request's 'sync-complete' notification has been
          sent.  Any attempts to read or write either intended or applied
          configuration will be blocked until the request completes.</t>

          <section title="Usage Example" toc="exclude">
            <t>To edit the "/interfaces" subtree from the applied
            configuration datastore:</t>
            <figure>
              <artwork><![CDATA[
<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <edit-config>
    <sync-behavior>async</sync-behavior>
    <target>
      <running/>
    </target>
    <config>
      <top xmlns="http://example.com/schema/1.2/config">
        <interface>
          <name>Ethernet0/0</name>
          <mtu>1500</mtu>
        </interface>
      </top>
    </config>
  </edit-config>
</rpc>

<rpc-reply message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <ok/>
  <sync-id>4123</sync-id>
</rpc-reply>
              ]]></artwork>
            </figure>
          </section>
        </section>

        <section title="The &lt;get-diff&gt; Operation" anchor="get-diff">
          <t>The "ietf-netconf-opstate" YANG module enables NETCONF clients
          to request a server to return the difference between datastores
          (running, startup, candidate, and applied).</t>
          <t>The &lt;get-diff&gt; RPC takes two 'source' parameters as input
          and, based on the value of the 'format' paramter,  returns either
          an &lt;edit-config&gt; document (Section 7.2 in <xref target="RFC6241"/>)
          or a YANG-patch document (<xref target="draft-ietf-netconf-yang-patch"/>),
          that transforms the first datastore into the second datastore.</t>

          <section title="Usage Example" toc="exclude">
            <t>This example assumes a YANG module has a data model like:</t>
            <figure>
              <artwork><![CDATA[
module example-module {
  namespace "http://example.com/ns/example-module";
  container system {
    leaf hostname {
      type string;
    }
  }
}
]]></artwork>
            </figure>
            <t>With a value in the candidate datastore of 'us-east-dc-fw-1'
            and value in the running datastore 'us-eass-dc-fw-1' (notice
            the typo):</t>
            <figure>
              <artwork><![CDATA[
<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <get-diff>
    <format>yang-patch</format>
    <source1>candidate</source1>
    <source2>running</source2>
</rpc>

<rpc-reply message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <yang-patch xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-patch">
    <patch-id>202</patch-id>
    <edit>
      <edit-id>edit1</edit-id>
      <operation>replace</operation>
      <target>/example-module:system/hostname</target>
      <value>
        <hostname xmlns="http://example.com/ns/example-module">
          us-east-dc-fw-1
        </hostname>
      </value>
    </edit>
  </yang-patch>
</rpc-reply>
              ]]></artwork>
            </figure>
          </section>
        </section>

        <section title="The &lt;get-state&gt; Operation" anchor="get-state">
          <t>The "ietf-netconf-opstate" YANG module enables NETCONF clients
          to request a server to return operational state data.  This RPC
          is similar to the &lt;get-config&gt; RPC (Section 7.1 in
          <xref target="RFC6241"/>), but for operational state instead of
          configuration.</t>
          <t>The &lt;get-state&gt; RPC takes two optional parameters.  The
          first parameter is a choice between the values &lt;applied/&gt;
          and &lt;derived/&gt;, which selects if only these types of nodes
          should be returned.  The second parameter is a filter just like
          the one used by the &lt;get-config&gt; RPC, including the optional
          support for XPath expressions.</t>

          <section title="Usage Example" toc="exclude">
            <t>The following example depicts a request that returns all
            the derived state (i.e. config false) nodes under the "users"
            subtree.</t> 
            <figure>
              <artwork><![CDATA[
<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <get-state>
    <derived/>
    <filter type="subtree">
      <top xmlns="http://example.com/schema/1.2/config">
        <users/>
      </top>
    </filter>
  </get-state>
</rpc>
]]></artwork>
            </figure>
          </section>
        </section>

        <section title="The &lt;sync-complete&gt; Notification" anchor="sync-complete">
          <t>The </t>
          <section title="Usage Example" toc="exclude">
            <t>The following example depicts a notification for a that returns all
            the derived state (i.e. config false) nodes under the "users" subtree.</t> 
            <figure>
              <artwork><![CDATA[
<notification
  xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
   <eventTime>2007-07-08T00:02:00Z</eventTime>
   <sync-complete
      xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-opstate">
      <sync-id>4123</sync-id>
      <rpc-warning/>
   </sync-complete>
</notification>
]]></artwork>
            </figure>
          </section>
        </section>

        <section title="YANG Module">
          <t>The tree diagram for the "ietf-netconf-opstate" YANG module:</t>
          <figure>
            <artwork><![CDATA[
module: ietf-netconf-opstate
augment /nc:get-config/nc:input/nc:source/nc:config-source:
   +--rw applied?   empty
augment /nc:copy-config/nc:input/nc:source/nc:config-source:
   +--rw applied?   empty
augment /nc:edit-config/nc:input:
   +---- sync-behavior?   enumeration
augment /nc:edit-config/nc:output:
   +---- (request-type)?
      +--:(sync)
      |  +---- apply-warning?   empty
      +--:(async)
         +---- sync-id?         string
augment /nc:copy-config/nc:input:
   +---- sync-behavior?   enumeration
augment /nc:copy-config/nc:output:
   +---- (request-type)?
      +--:(sync)
      |  +---- apply-warning?   empty
      +--:(async)
         +---- sync-id?         string
augment /nc:commit/nc:input:
   +---- sync-behavior?   enumeration
augment /nc:commit/nc:output:
   +---- (request-type)?
      +--:(sync)
      |  +---- apply-warning?   empty
      +--:(async)
         +---- sync-id?         string
rpcs:
   +---x get-diff
   |  +---w input
   |  |  +---w format?    enumeration
   |  |  +---w source1
   |  |  |  +---w (config-source)
   |  |  |     +--:(candidate)
   |  |  |     |  +---w candidate?   empty {nc:candidate}?
   |  |  |     +--:(running)
   |  |  |     |  +---w running?     empty
   |  |  |     +--:(startup)
   |  |  |     |  +---w startup?     empty {nc:startup}?
   |  |  |     +--:(applied)
   |  |  |        +---w applied?     empty
   |  |  +---w source2
   |  |     +---w (config-source)
   |  |        +--:(candidate)
   |  |        |  +---w candidate?   empty {nc:candidate}?
   |  |        +--:(running)
   |  |        |  +---w running?     empty
   |  |        +--:(startup)
   |  |        |  +---w startup?     empty {nc:startup}?
   |  |        +--:(applied)
   |  |           +---w applied?     empty
   |  +--ro output
   |     +--ro (format)?
   |        +--:(edit-config)
   |        |  +--ro data
   |        +--:(yang-patch)
   |           +--ro yang-patch
   |              +--ro patch-id?   string
   |              +--ro comment?    string
   |              +--ro edit* [edit-id]
   |                 +--ro edit-id      string
   |                 +--ro operation    enumeration
   |                 +--ro target       target-resource-offset
   |                 +--ro point?       target-resource-offset
   |                 +--ro where?       enumeration
   |                 +--ro value
   +---x get-state
      +---w input
      |  +---w (type)?
      |  |  +--:(applied)
      |  |  |  +---w applied?   empty
      |  |  +--:(derived)
      |  |     +---w derived?   empty
      |  +---w filter
      +--ro output
         +--ro data
notifications:
   +---n sync-complete
      +--ro sync-id          string
      +--ro (response)
         +--:(ok)
         |  +--ro ok?              empty
         +--:(apply-warning)
         |  +--ro apply-warning?   empty
         +--:(rpc-error)
            +--ro rpc-error
               +--ro error-type        enumeration
               +--ro error-tag         nc:error-tag-type
               +--ro error-severity    nc:error-severity-type
               +--ro error-app-tag?    string
               +--ro error-path?       string
               +--ro error-message?    string
               +--ro error-info
                  +--ro session-id?      uint32
                  +--ro bad-attribute?   string
                  +--ro bad-element?     string
                  +--ro ok-element?      string
                  +--ro err-element?     string
                  +--ro noop-element?    string
                  +--ro bad-namespace?   string
]]></artwork>
          </figure>
          <t>The "ietf-netconf-opstate" YANG module:</t>
          <figure>
            <artwork><![CDATA[

<CODE BEGINS> file "ietf-netconf-opstate@2016-02-02.yang"

module ietf-netconf-opstate {
  yang-version 1.1;
  namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-opstate";
  prefix ncos;
  import ietf-netconf {       // RFC 6241
    prefix nc;
  }
  import ietf-yang-patch {    // RFC YYYY
    prefix yp;
  }
  organization
    "IETF NETMOD (NETCONF Data Modeling Language) Working Group";

  contact
    "WG Web:   <http://tools.ietf.org/wg/netmod/>
     WG List:  <netmod@ietf.org>
     WG Chair: Tom Nadeau
               <tnadeau@brocade.com>
     WG Chair: Kent Watsen
               <kwatsen@juniper.net>
     WG Chair: Juergen Schoenwaelder
               <j.schoenwaelder@jacobs-university.de>";

  description
   "This YANG module does the following:

      - enables get-config and copy-config to access applied datastore
      - enables edit-config, copy-config, and commit to be executed
        either synchronously or asynchronously 
      - defines 'get-diff' operation to diff datastores
      - defines 'get-state' operation to return just state data
      - defines 'sync-complete' notification for async requests";

  revision 2016-02-02 {
    description
      "Initial revision";
    reference
      "RFC XXXXX: Terminology and Requirements for Enhanced Handling
       of Operational State";
  }

  // features

  feature sync {
    description
      "Indicates the server supports the 'sync' value for the
       <sync-behavior> parameter in the operations <edit-config>,
       <copy-config>, and <commit>.";
  }

  feature async {
    description
      "Indicates the server supports the 'async' value for the
       <sync-behavior> parameter in the operations <edit-config>,
       <copy-config>, and <commit>.";
  }


  // The following two augmentations enable 'applied' to be passed as a 
  // <source> argument in the <get-config> and <copy-config> operations.

  augment /nc:get-config/nc:input/nc:source/nc:config-source {
    description
     "Allows 'applied' to be passed in <get-config>";
    leaf applied {
       type empty;
       description
         "Indicates that the applied configuration should be returned";
    }
  }

  augment /nc:copy-config/nc:input/nc:source/nc:config-source {
    description
     "Allows 'applied' to be passed in <copy-config>";
    leaf applied {
       type empty;
       description
        "Indicates that the applied configuration should be returned";
    }
  }

  // The following two groupings define input and output parameters that
  // are subsequently augmented into the edit-config, copy-config, and
  // commit operations.

  grouping sync-behavior-input {
    description
     "This grouping is augmented into the edit-config, copy-config,
      and commit operations";
    leaf sync-behavior {
      type enumeration {
        enum "sync" {
          if-feature sync;
          description
            "Request the server to not return a response until both the
             intended and applied configurations have been updated.";
        }
        enum "async" {
          if-feature async;
          description
            "Request the server to not wait for the configuration to be
             applied before returning a response.  The response will
             contain the 'sync-id' leaf.  Later, after both the intended
             and applied configurations have been updated, the server
             will send the 'sync-complete' notification using the same
             sync-id value.";
        }
      }
      description
        "This value specifies whether the server should process the
         request synchronously or asynchronously.";
    }
  }

  grouping sync-behavior-output {
    description
     "This grouping is augmented into the edit-config, copy-config,
      and commit operations.  The additional output is only returned
      when 'sync-behavior' is specified, and thus does not alter
      legacy behavior.";
    choice request-type {
      description
        "This choice makes it explicit which content is possibly
         returned for the two 'sync-behavior' values.";
      case sync {
        leaf apply-warning {
          type empty;
          description
           "Indicates that a warning was generated when applying the
            intended configuration to internal server components
            (e.g., due to missing hardware) and hence the applied
            configuration differs from the intended configuration.";
        }
      }
      case async {
        leaf sync-id {
          type string;
          description
           "A server-specified value to identify the asynchronous
            request.  This value is returned whenever 'async' is
            passed in the request.  The server must ensure that it
            is a unique value over some reasonable amount of time.";
        }
      }
    }
  }

  // The following six augmentations are used to insert the 
  // sync-behavior-input and sync-behavior-output nodes into
  // the edit-config, copy-config, and commit operations.

  augment /nc:edit-config/nc:input {
    description
     "Allows 'sync-behavior' to be passed in <edit-config>.
      When specified, the 'error-option' value is interpreted
      as spanning both the updating of the intended and
      applied configurations.  Notably, when rollback-on-error
      is set, both the intended and applied configurations
      are restored to their initial states on error.";
    uses sync-behavior-input {
      when "nc:target/nc:running" {
        description "only available when target is 'running'";
      }
    }
  }

  augment /nc:edit-config/nc:output {
    description 
     "Allows 'apply-warning' and 'sync-id' to be returned 
      for <edit-config> operations.";
    uses sync-behavior-output;
  }

  augment /nc:copy-config/nc:input {
    description
     "Allows 'sync-behavior' to be passed in <copy-config>";
    uses sync-behavior-input {
      when "nc:target/nc:running" {
        description "only available when target is 'running'";
      }
    }
  }

  augment /nc:copy-config/nc:output {
    description
     "Allows 'apply-warning' and 'sync-id' to be returned 
      for <copy-config> operations.";
    uses sync-behavior-output;
  }

  augment /nc:commit/nc:input {
    description
      "Allows 'sync-behavior' to be passed in the <commit>
       operation.  The <commit> operation's atomic behavior
       is extended to include both the updating of the
       intended and applied configurations.";
    uses sync-behavior-input;
  }

  augment /nc:commit/nc:output {
    description
     "Allows 'apply-warning' and 'sync-id' to be returned 
      for <commit> operations.";
    uses sync-behavior-output;
  }

  // The following grouping is used by the get-diff RPC

  grouping get-diff-source {
    description
     "This grouping is used by the 'get-diff' RPC's two 
      input parameters.";
    choice config-source {
      mandatory true;
      description
        "The configuration datastore to use as a source.";
      leaf candidate {
        if-feature nc:candidate;
        type empty;
        description
          "The candidate configuration is the config source.";
      }
      leaf running {
        type empty;
        description
          "The running configuration is the config source.";
      }
      leaf startup {
        if-feature nc:startup;
        type empty;
        description
          "The startup configuration is the config source.";
      }
      leaf applied {
        type empty;
        description
          "The applied configuration is the config source.";
      }
    }
  }

  // The following RPC returns the diff between two datastores

  rpc get-diff {
    description
     "Get the difference between two datastores in the form
      of a YANG Patch (see RFC YYYY) that transforms 'source1'
      into 'source2'.  Specifying the same datastore for both
      sources always returns an empty diff.";
    input {
      leaf format {
        type enumeration {
          enum edit-config { description ""; }
          enum yang-patch { description ""; }
        }
        description "Selects output format";
      }
      container source1 {
        description "the first of two datastores to compare";
        uses get-diff-source;
      }
      container source2 {
        description "the second of two datastores to compare";
        uses get-diff-source;
      }
    }
    output {
      choice format {
        case edit-config {
          anyxml data {description "";}
        }
        case yang-patch {
          uses yp:yang-patch;
        }
        description "";
      }
    }
  }

  // The following RPC returns just operational state nodes from
  // the server.

  rpc get-state {
    description
     "Retrieve operational state from the server. Operational state
      is composed of both applied configuration and derived state.
      Applied configuration is the subset of config true nodes that
      is operational.  Derived state is composed of just the config
      false nodes.";
    reference "RFC 6241, Section 7.7";
    input {
      choice type {
        description
         "An optional parameter to select if only applied configuration
          or derived state nodes should be returned.  If not specified,
          then all node types are returned.";
        leaf applied {
          type empty;
          description
           "Only return matching applied configuration nodes";
        }
        leaf derived {
          type empty;
          description
           "Only return matching derived state nodes";
        }
      }
      anyxml filter {
        mandatory true;
        description
          "This parameter specifies the portion of the applied
           configuration and derived state data to retrieve.
           ";
        nc:get-filter-element-attributes;
      }
    }
    output {
      anyxml data {
        description
          "Copy of the running datastore subset and/or state
           data that matched the filter criteria (if any).
           An empty data container indicates that the request
           did not produce any results.";
      }
    }
  }

  // This following notification is used to alert clients when
  // an asynchronous operation request has completed.  

  notification sync-complete {
    description
      "Sent by the server when an asynchronous operation
       request has completed.";
    leaf sync-id {
      type string;
      mandatory true;
      description
        "The server-specified unique identifier returned
         to the client that requested the asynchronous
         operation.";
    }
    choice response {
      mandatory true;
      leaf ok {
        type empty;
        description
         "Indicates that the request processed successfully.";
      }
      leaf apply-warning {
        type empty;
        description
         "Indicates that a warning was generated when applying the
          intended configuration to internal server components
          (e.g., due to missing hardware) and hence the applied
          configuration differs from the intended configuration.";
      }
      container rpc-error {
        leaf error-type {
          type enumeration {
            enum transport { description "transport"; }
            enum rpc { description "rpc"; }
            enum protocol { description "protocol"; }
            enum application { description "application"; }
          }
          mandatory true;
          description "error-type";
        }
        leaf error-tag {
          type nc:error-tag-type;
          mandatory true;
          description "error-tag";
        }
        leaf error-severity {
          type nc:error-severity-type;
          mandatory true;
          description "error-severity";
        }
        leaf error-app-tag {
          type string;
          description "error-app-tag";
        }
        leaf error-path {
          type string;
          description "error-path";
        }
        leaf error-message {
          type string;
          description "error-message";
        }
        container error-info {
          leaf session-id {
            type uint32;
            description "session-id";
          }
          leaf bad-attribute {
            type string;
            description "bad-attribute";
          }
          leaf bad-element {
            type string;
            description "bad-element";
          }
          leaf ok-element {
            type string;
            description "ok-element";
          }
          leaf err-element {
            type string;
            description "err-element";
          }
          leaf noop-element {
            type string;
            description "noop-element";
          }
          leaf bad-namespace {
            type string;
            description "bad-namespace";
          }
          description "error-info";
        }
        description "rpc-error";
      }
      description "response";
    }
  }
}


<CODE ENDS>
]]></artwork>
          </figure>
        </section>
      </section>

      <section title="Enhancements to RESTCONF" anchor="restconf">
        <t>TBD</t>
      </section>

      <section title="Security Considerations" anchor="sec-con">
        <t>TBD</t>
      </section>

      <section title="IANA Considerations" anchor="iana-con">
        <t>TBD</t>
      </section>

      <section title="Acknowledgements">
        <t>TBD</t>
      </section>

    </middle>

    <back>
      <references title="Normative References">

        &rfc2119;
        &rfc6241;
        &rfc6020;

        <reference anchor="draft-ietf-netconf-restconf" target="https://tools.ietf.org/html/draft-ietf-netconf-restconf">
          <front>
            <title>
              RESTCONF Protocol
            </title>
            <author initials='A.B.' surname='Bierman' fullname='Andy Bierman'>
              <organization>YumaWorks</organization>
            </author>
            <author initials='M.B.' surname='Bjorklund' fullname='Martin Bjorklund'>
              <organization>Tail-f Systems</organization>
            </author>
            <author initials='K.W.' surname='Watsen' fullname='Kent Watsen'>
              <organization>Juniper Networks</organization>
            </author>
            <date year='2014' />
          </front>
          <seriesInfo name='Internet-Draft' value='draft-ieft-netconf-restconf-04' />
        </reference>
        <reference anchor="draft-ietf-netconf-yang-patch" target="https://tools.ietf.org/html/draft-ietf-netconf-yang-patch">
          <front>
            <title>
              YANG Patch Media Type
            </title>
            <author initials='A.B.' surname='Bierman' fullname='Andy Bierman'>
              <organization>YumaWorks</organization>
            </author>
            <author initials='M.B.' surname='Bjorklund' fullname='Martin Bjorklund'>
              <organization>Tail-f Systems</organization>
            </author>
            <author initials='K.W.' surname='Watsen' fullname='Kent Watsen'>
              <organization>Juniper Networks</organization>
            </author>
            <date year='2014' />
          </front>
          <seriesInfo name='Internet-Draft' value='draft-ieft-netconf-yang-patch-07' />
        </reference>
      </references>

      <references title="Informative References">
        <reference anchor="draft-ietf-netmod-opstate-reqs-03" target="https://tools.ietf.org/html/draft-ietf-netmod-opstate-reqs-03">
          <front>
            <title>Terminology and Requirements for Operational State and Model Structure</title>
            <author initials="K.W." surname="Watsen" fullname="Kent Watsen"/>
            <author initials="A.B." surname="Bierman" fullname="Andy Bierman"/>
            <author initials="M.B." surname="Bjorklund" fullname="Martin Bjorklund"/>
            <author initials="J.S." surname="Schoenwaelder" fullname="Juergen Schoenwaelder"/>
            <date month="January" year="2016"/>
          </front>
          <seriesInfo name='Internet-Draft' value='draft-ietf-opstate-reqs-03' />
        </reference>
      </references>

      <section title="Traceabilty Matrix" anchor="traceability-matrix">
        <t>This section explains how the requirements specified in 
        <xref target="draft-ietf-netmod-opstate-reqs-03"/> are satisfied by the solution 
        presented in this document.</t>

        <t>The following outline mimics the outline in the requirements draft:</t>

        <t>
          <list style="numbers">
            <t>Ability to interact with both intended and applied configuration
              <list style="letters">
                <t>A NETCONF client can ask the operational components of a server
                   (e.g., line cards) for the configuration that they are currently
                   using either by using the &lt;get-config&gt; RPC with the
                   &lt;source&gt; value "applied", or by using the &lt;get-state&gt;
                   RPC with the &lt;applied&gt; parameter.</t>
                <t>A NETCONF client is only able to read applied configuration.
                   Neither the &lt;get-config&gt; nor &lt;get-state&gt; RPCs
                   enable modification and no other RPC targets the applied
                   datastore directly.</t>
                <t>The data model for the intended and applied configurations are
                   identical.  A fundamental aspect of the solution defined in 
                   this document is that config true nodes simultaneously define both</t>
                <t>Ensuring that the applied configuration values match the intended
                   configuration values is the responsibility of an implementation
                   more so than the solution presented in this document.</t>
              </list>
            </t>
            <t>Support for both synchronous and asynchronous configuration
            operations (see terms)
              <list style="letters">
                <t>A server may only support synchronous configuration
                operations by only advertising the 'sync' feature.
                A server may only support asynchronous configuration
                operations by only advertising the 'async' feature.
                A server may support both synchronous and asynchronous configuration
                operations by advertising both the 'sync' and 'async' features.
                A NETCONF client may select on a per-operation basis if a request
                should be processed synchronously and asynchronously using the
                &lt;sync-behavior&gt; parameter.</t>
                <t>NETCONF clients can use the &lt;get-diff&gt; RPC to determine the
                difference between the intended and applied configurations.</t>
                <t>This solution handles errors by extending existing semantics for
                the &lt;edit-config&gt;, &lt;get-config&gt;, and &lt;commit&gt;
                operations to include also the application of the configuration to
                the operational components of the system.  For synchronous operations,
                errors or warnings are returned in the &lt;rpc-reply&gt;, whereas for
                asynchronous operations, errors or warnings are returned in the
                &lt;sync-complete&gt; notification.  This solution supports the
                rollback-on-error semantics in &lt;edit-config&gt; (for servers that
                support the :rollback capability) and in &lt;commit&gt; (for servers 
                that support the :candidate capability).</t>
              </list>
            </t>
            <t>Separation of the applied configuration and derived state aspects of operational
            state; ability to retrieve them independently and together
              <list style="letters">
                <t>A NETCONF client can retrieve only the applied configuration of operational state
                either by using the "applied" source target in the &lt;get-config&gt; operation or by
                using the 'applied' argument in the &lt;get-state&gt; operation.</t>
                <t>A NETCONF client can retrieve only the derived state aspects of operational state
                by using the 'derived' argument in the &lt;get-state&gt; operation.</t>
                <t>A NETCONF client may retrieve both the applied configuration and derived state
                aspects of operational state together by not passing either the 'applied' or 'derived'
                arguments in the &lt;get-state&gt; operation.</t>
              </list>
            </t>
            <t>Ability to relate configuration with its corresponding operational state
              <list style="letters">
                <t>Mapping intended config nodes to corresponding applied config nodes is automatic,
                as the same paths are used to access the same nodes in both trees.</t>
                <t>The ability to relate intended config nodes to associated derived state nodes
                is provided by the "related-state" YANG statement (<xref target="related-state"/>).</t>
                <t>The "related-state" statement is programmatically consumable, being defined
                using a YANG statement.</t> 
              </list>
            </t>
            <t>Backwards compatibility
              <list style="letters">
                <t>NETCONF and RESTCONF servers can be upgraded to one that supports this solution
                without breaking backwards compatibility as all the changes made to NETCONF and
                RESTCONF require a client to explicitly opt into it, by passing some new input
                parameter in the requests that it may send to a server.</t>
                <t>NETCONF and RESTCONF clients coded to support this solution can differentiate
                servers that support opstate from those that don't, by examining if the servers
                support the ietf-netconf-opstate or ietf-restconf-opstate modules.</t>
              </list>
            </t>
          </list>
        </t>
      </section>

    </back>

</rfc>

