From 854e20a328270ff980f0a864f72def1cc84e716f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pecka?= <tomas.pecka@cesnet.cz>
Date: Mon, 27 Jan 2025 16:53:33 +0100
Subject: [PATCH 36/44] restconf: introduce internal RPC handling for
 subscribed notifications
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Wires

This commit adds support for establishing subscribed notifications [1,2]
in the URI parser and server processing.

We are going to implement the required RPC handlers for creating
subscribed notifications directly in rousette on the HTTP-level,
i.e., we are not going to pass those RPC calls to sysrepo.

The Netopeer2 project already implements the RPC callbacks for subscribed
notifications RPCs. Sysrepo can handle multiple RPC callbacks, but only
one of them can return data. The other will be executed but the data will
be ignored [4].

It makes no sense to establish subscriptions through NETCONF and then
request the stream via RESTCONF and AFAIK it is even not allowed by RFCs
which states that NETCONF requests are handled by the same NETCONF
session and also, there is no way how to get to those subscriptions via
RESTCONF. RESTCONF provides its own way how to read the streamed
notifications [3,4].

And yes, we want both Netopeer2 and Rousette to be able to run at the
same time on the same machine.

[1] https://datatracker.ietf.org/doc/html/rfc8639
[2] https://datatracker.ietf.org/doc/html/rfc8650
[3] https://datatracker.ietf.org/doc/html/rfc8640
[4] https://github.com/sysrepo/sysrepo/blob/ef93a1253cc97f13671759f6e7790cbf729a5ae9/doc/subs.dox#L78

Change-Id: I207e4d5b0d34eea4477c50019e9cab4f8e81e1a6
Signed-off-by: Mattias Walström <lazzer@gmail.com>
---
 CMakeLists.txt                                |    8 +
 src/restconf/Server.cpp                       |   18 +-
 src/restconf/uri.cpp                          |   15 +-
 src/restconf/uri.h                            |    1 +
 tests/restconf-rpc.cpp                        |    8 +
 tests/uri-parser.cpp                          |   13 +-
 yang/iana-if-type@2014-05-08.yang             | 1523 +++++++++++++++++
 yang/ietf-interfaces@2018-02-20.yang          | 1123 ++++++++++++
 yang/ietf-ip@2018-02-22.yang                  |  876 ++++++++++
 yang/ietf-network-instance@2019-01-21.yang    |  282 +++
 ...f-subscribed-notifications@2019-11-17.yang |   85 +
 ...f-subscribed-notifications@2019-09-09.yang | 1350 +++++++++++++++
 12 files changed, 5298 insertions(+), 4 deletions(-)
 create mode 100644 yang/iana-if-type@2014-05-08.yang
 create mode 100644 yang/ietf-interfaces@2018-02-20.yang
 create mode 100644 yang/ietf-ip@2018-02-22.yang
 create mode 100644 yang/ietf-network-instance@2019-01-21.yang
 create mode 100644 yang/ietf-restconf-subscribed-notifications@2019-11-17.yang
 create mode 100644 yang/ietf-subscribed-notifications@2019-09-09.yang

diff --git a/CMakeLists.txt b/CMakeLists.txt
index bcabe84..2287447 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -146,6 +146,12 @@ install(FILES
     ${CMAKE_SOURCE_DIR}/yang/ietf-restconf@2017-01-26.yang
     ${CMAKE_SOURCE_DIR}/yang/ietf-restconf-monitoring@2017-01-26.yang
     ${CMAKE_SOURCE_DIR}/yang/ietf-yang-patch@2017-02-22.yang
+    ${CMAKE_SOURCE_DIR}/yang/iana-if-type@2014-05-08.yang
+    ${CMAKE_SOURCE_DIR}/yang/ietf-interfaces@2018-02-20.yang
+    ${CMAKE_SOURCE_DIR}/yang/ietf-ip@2018-02-22.yang
+    ${CMAKE_SOURCE_DIR}/yang/ietf-network-instance@2019-01-21.yang
+    ${CMAKE_SOURCE_DIR}/yang/ietf-subscribed-notifications@2019-09-09.yang
+    ${CMAKE_SOURCE_DIR}/yang/ietf-restconf-subscribed-notifications@2019-11-17.yang
     DESTINATION ${CMAKE_INSTALL_PREFIX}/share/yang/modules/rousette)
 
 include(CTest)
@@ -205,6 +211,8 @@ if(BUILD_TESTING)
         --install ${CMAKE_CURRENT_SOURCE_DIR}/yang/ietf-restconf@2017-01-26.yang
         --install ${CMAKE_CURRENT_SOURCE_DIR}/yang/ietf-restconf-monitoring@2017-01-26.yang
         --install ${CMAKE_CURRENT_SOURCE_DIR}/yang/ietf-yang-patch@2017-02-22.yang
+        --install ${CMAKE_CURRENT_SOURCE_DIR}/yang/ietf-subscribed-notifications@2019-09-09.yang
+        --install ${CMAKE_CURRENT_SOURCE_DIR}/yang/ietf-restconf-subscribed-notifications@2019-11-17.yang
         --install ${CMAKE_CURRENT_SOURCE_DIR}/tests/yang/example.yang --enable-feature f1
         --install ${CMAKE_CURRENT_SOURCE_DIR}/tests/yang/example-delete.yang
         --install ${CMAKE_CURRENT_SOURCE_DIR}/tests/yang/example-augment.yang
diff --git a/src/restconf/Server.cpp b/src/restconf/Server.cpp
index c454541..9fd3fa9 100644
--- a/src/restconf/Server.cpp
+++ b/src/restconf/Server.cpp
@@ -430,6 +430,12 @@ libyang::CreatedNodes createEditForPutAndPatch(libyang::Context& ctx, const std:
     return {editNode, replacementNode};
 }
 
+std::optional<libyang::DataNode> processInternalRPC(sysrepo::Session&, const libyang::DataNode&)
+{
+    // TODO: Implement internal RPCs
+    throw ErrorResponse(501, "application", "operation-not-supported", "Internal RPCs are not yet supported.");
+}
+
 void processActionOrRPC(std::shared_ptr<RequestContext> requestCtx, const std::chrono::milliseconds timeout)
 {
     requestCtx->sess.switchDatastore(sysrepo::Datastore::Operational);
@@ -460,7 +466,12 @@ void processActionOrRPC(std::shared_ptr<RequestContext> requestCtx, const std::c
         rpcNode->parseOp(requestCtx->payload, *requestCtx->dataFormat.request, libyang::OperationType::RpcRestconf);
     }
 
-    auto rpcReply = requestCtx->sess.sendRPC(*rpcNode, timeout);
+    std::optional<libyang::DataNode> rpcReply;
+    if (requestCtx->restconfRequest.type == RestconfRequest::Type::Execute) {
+        rpcReply = requestCtx->sess.sendRPC(*rpcNode, timeout);
+    } else if (requestCtx->restconfRequest.type == RestconfRequest::Type::ExecuteInternal) {
+        rpcReply = processInternalRPC(requestCtx->sess, *rpcNode);
+    }
 
     if (!rpcReply || rpcReply->immediateChildren().empty()) {
         requestCtx->res.write_head(204, {CORS});
@@ -833,6 +844,8 @@ Server::Server(sysrepo::Connection conn, const std::string& address, const std::
              {"ietf-netconf", "", {}},
              {"ietf-yang-library", "2019-01-04", {}},
              {"ietf-yang-patch", "2017-02-22", {}},
+             {"ietf-subscribed-notifications", "2019-09-09", {}},
+             {"ietf-restconf-subscribed-notifications", "2019-11-17", {}},
          }) {
         if (auto mod = conn.sessionStart().getContext().getModuleImplemented(module)) {
             for (const auto& feature : features) {
@@ -1120,7 +1133,8 @@ Server::Server(sysrepo::Connection conn, const std::string& address, const std::
                     res.end();
                     break;
 
-                case RestconfRequest::Type::Execute: {
+                case RestconfRequest::Type::Execute:
+                case RestconfRequest::Type::ExecuteInternal: {
                     auto requestCtx = std::make_shared<RequestContext>(req, res, dataFormat, sess, restconfRequest);
 
                     req.on_data([requestCtx, timeout](const uint8_t* data, std::size_t length) {
diff --git a/src/restconf/uri.cpp b/src/restconf/uri.cpp
index e95d70e..956c155 100644
--- a/src/restconf/uri.cpp
+++ b/src/restconf/uri.cpp
@@ -555,6 +555,19 @@ std::vector<PathSegment> asPathSegments(const std::string& uriPath)
     return uri->segments;
 }
 
+/** @brief Checks if the RPC with this schema path should be handled internally by the RESTCONF server */
+constexpr bool isInternalRPCPath(const std::string& schemaPath)
+{
+    std::vector<std::string> arr{
+        "/ietf-subscribed-notifications:establish-subscription",
+        "/ietf-subscribed-notifications:modify-subscription",
+        "/ietf-subscribed-notifications:delete-subscription",
+        "/ietf-subscribed-notifications:kill-subscription",
+    };
+
+    return std::find(arr.begin(), arr.end(), schemaPath) != arr.end();
+}
+
 /** @brief Parse requested URL as a RESTCONF requested
  *
  * The URI path (i.e., a resource identifier) will be parsed into an action that is supposed to be performed,
@@ -601,7 +614,7 @@ RestconfRequest asRestconfRequest(const libyang::Context& ctx, const std::string
     } else if (httpMethod == "DELETE" && schemaNode) {
         type = RestconfRequest::Type::DeleteNode;
     } else if (httpMethod == "POST" && schemaNode && (schemaNode->nodeType() == libyang::NodeType::Action || schemaNode->nodeType() == libyang::NodeType::RPC)) {
-        type = RestconfRequest::Type::Execute;
+        type = isInternalRPCPath(schemaNode->path()) ? RestconfRequest::Type::ExecuteInternal : RestconfRequest::Type::Execute;
     } else if (httpMethod == "POST" && (uri->prefix.resourceType == impl::URIPrefix::Type::BasicRestconfData || uri->prefix.resourceType == impl::URIPrefix::Type::NMDADatastore)) {
         type = RestconfRequest::Type::CreateChildren;
     } else if (httpMethod == "PATCH") {
diff --git a/src/restconf/uri.h b/src/restconf/uri.h
index 6f1f69f..d9dd29f 100644
--- a/src/restconf/uri.h
+++ b/src/restconf/uri.h
@@ -180,6 +180,7 @@ struct RestconfRequest {
         CreateOrReplaceThisNode, ///< PUT on a data resource
         DeleteNode, ///< DELETE on a data resource
         Execute, ///< POST on a operation resource (Execute an RPC or an action)
+        ExecuteInternal, ///< POST on a operation resource (RPC or action) that is not sent to sysrepo but handled in roustte directly
         CreateChildren, ///< POST on a data resource
         YangLibraryVersion, ///< Report ietf-yang-library version
         OptionsQuery, ///< Request for allowed HTTP methods for a path
diff --git a/tests/restconf-rpc.cpp b/tests/restconf-rpc.cpp
index d49b121..a3e9309 100644
--- a/tests/restconf-rpc.cpp
+++ b/tests/restconf-rpc.cpp
@@ -97,6 +97,10 @@ TEST_CASE("invoking actions and rpcs")
       "ietf-system:set-current-datetime": [null],
       "ietf-system:system-restart": [null],
       "ietf-system:system-shutdown": [null],
+      "ietf-subscribed-notifications:establish-subscription": [null],
+      "ietf-subscribed-notifications:modify-subscription": [null],
+      "ietf-subscribed-notifications:delete-subscription": [null],
+      "ietf-subscribed-notifications:kill-subscription": [null],
       "example:test-rpc": [null],
       "example:test-rpc-no-output": [null],
       "example:test-rpc-no-input": [null],
@@ -126,6 +130,10 @@ TEST_CASE("invoking actions and rpcs")
     <set-current-datetime xmlns="urn:ietf:params:xml:ns:yang:ietf-system"/>
     <system-restart xmlns="urn:ietf:params:xml:ns:yang:ietf-system"/>
     <system-shutdown xmlns="urn:ietf:params:xml:ns:yang:ietf-system"/>
+    <establish-subscription xmlns="urn:ietf:params:xml:ns:yang:ietf-subscribed-notifications"/>
+    <modify-subscription xmlns="urn:ietf:params:xml:ns:yang:ietf-subscribed-notifications"/>
+    <delete-subscription xmlns="urn:ietf:params:xml:ns:yang:ietf-subscribed-notifications"/>
+    <kill-subscription xmlns="urn:ietf:params:xml:ns:yang:ietf-subscribed-notifications"/>
     <test-rpc xmlns="http://example.tld/example"/>
     <test-rpc-no-output xmlns="http://example.tld/example"/>
     <test-rpc-no-input xmlns="http://example.tld/example"/>
diff --git a/tests/uri-parser.cpp b/tests/uri-parser.cpp
index 53d1fbb..23c2b79 100644
--- a/tests/uri-parser.cpp
+++ b/tests/uri-parser.cpp
@@ -63,6 +63,8 @@ TEST_CASE("URI path parser")
     auto ctx = libyang::Context{std::filesystem::path{CMAKE_CURRENT_SOURCE_DIR} / "tests" / "yang"};
     ctx.loadModule("example", std::nullopt, {"f1"});
     ctx.loadModule("example-augment");
+    ctx.setSearchDir(std::filesystem::path{CMAKE_CURRENT_SOURCE_DIR} / "yang");
+    ctx.loadModule("ietf-subscribed-notifications");
 
     SECTION("Valid paths")
     {
@@ -398,23 +400,32 @@ TEST_CASE("URI path parser")
             {
                 std::string uri;
                 std::string expectedPath;
+                RestconfRequest::Type expectedRequestType;
 
                 SECTION("RPC")
                 {
                     uri = "/restconf/operations/example:test-rpc";
                     expectedPath = "/example:test-rpc";
+                    expectedRequestType = RestconfRequest::Type::Execute;
                 }
                 SECTION("Action")
                 {
                     uri = "/restconf/data/example:tlc/list=hello-world/example-action";
                     expectedPath = "/example:tlc/list[name='hello-world']/example-action";
+                    expectedRequestType = RestconfRequest::Type::Execute;
+                }
+                SECTION("Internally handled RPC")
+                {
+                    uri = "/restconf/operations/ietf-subscribed-notifications:establish-subscription";
+                    expectedPath = "/ietf-subscribed-notifications:establish-subscription";
+                    expectedRequestType = RestconfRequest::Type::ExecuteInternal;
                 }
 
                 CAPTURE(uri);
                 auto [action, datastore, path, queryParams] = rousette::restconf::asRestconfRequest(ctx, "POST", uri);
                 REQUIRE(path == expectedPath);
                 REQUIRE(datastore == std::nullopt);
-                REQUIRE(action == RestconfRequest::Type::Execute);
+                REQUIRE(action == expectedRequestType);
                 REQUIRE(queryParams.empty());
             }
 
diff --git a/yang/iana-if-type@2014-05-08.yang b/yang/iana-if-type@2014-05-08.yang
new file mode 100644
index 0000000..81b2175
--- /dev/null
+++ b/yang/iana-if-type@2014-05-08.yang
@@ -0,0 +1,1523 @@
+module iana-if-type {
+  namespace "urn:ietf:params:xml:ns:yang:iana-if-type";
+  prefix ianaift;
+
+  import ietf-interfaces {
+    prefix if;
+  }
+
+  organization "IANA";
+  contact
+    "        Internet Assigned Numbers Authority
+
+     Postal: ICANN
+             4676 Admiralty Way, Suite 330
+             Marina del Rey, CA 90292
+
+     Tel:    +1 310 823 9358
+     <mailto:iana@iana.org>";
+  description
+    "This YANG module defines YANG identities for IANA-registered
+     interface types.
+
+     This YANG module is maintained by IANA and reflects the
+     'ifType definitions' registry.
+
+     The latest revision of this YANG module can be obtained from
+     the IANA web site.
+
+     Requests for new values should be made to IANA via
+     email (iana@iana.org).
+
+     Copyright (c) 2014 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD License
+     set forth in Section 4.c of the IETF Trust's Legal Provisions
+     Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     The initial version of this YANG module is part of RFC 7224;
+     see the RFC itself for full legal notices.";
+    reference
+      "IANA 'ifType definitions' registry.
+       <http://www.iana.org/assignments/smi-numbers>";
+
+  revision 2014-05-08 {
+    description
+      "Initial revision.";
+    reference
+      "RFC 7224: IANA Interface Type YANG Module";
+  }
+
+  identity iana-interface-type {
+    base if:interface-type;
+    description
+      "This identity is used as a base for all interface types
+       defined in the 'ifType definitions' registry.";
+  }
+
+  identity other {
+    base iana-interface-type;
+  }
+  identity regular1822 {
+    base iana-interface-type;
+  }
+  identity hdh1822 {
+    base iana-interface-type;
+  }
+  identity ddnX25 {
+    base iana-interface-type;
+  }
+  identity rfc877x25 {
+    base iana-interface-type;
+    reference
+      "RFC 1382 - SNMP MIB Extension for the X.25 Packet Layer";
+  }
+  identity ethernetCsmacd {
+    base iana-interface-type;
+    description
+      "For all Ethernet-like interfaces, regardless of speed,
+       as per RFC 3635.";
+    reference
+      "RFC 3635 - Definitions of Managed Objects for the
+                  Ethernet-like Interface Types";
+  }
+  identity iso88023Csmacd {
+    base iana-interface-type;
+    status deprecated;
+    description
+      "Deprecated via RFC 3635.
+       Use ethernetCsmacd(6) instead.";
+    reference
+      "RFC 3635 - Definitions of Managed Objects for the
+                  Ethernet-like Interface Types";
+  }
+  identity iso88024TokenBus {
+    base iana-interface-type;
+  }
+  identity iso88025TokenRing {
+    base iana-interface-type;
+  }
+  identity iso88026Man {
+    base iana-interface-type;
+  }
+  identity starLan {
+    base iana-interface-type;
+    status deprecated;
+    description
+      "Deprecated via RFC 3635.
+       Use ethernetCsmacd(6) instead.";
+    reference
+      "RFC 3635 - Definitions of Managed Objects for the
+                  Ethernet-like Interface Types";
+  }
+  identity proteon10Mbit {
+    base iana-interface-type;
+  }
+  identity proteon80Mbit {
+    base iana-interface-type;
+  }
+  identity hyperchannel {
+    base iana-interface-type;
+  }
+  identity fddi {
+    base iana-interface-type;
+    reference
+      "RFC 1512 - FDDI Management Information Base";
+  }
+  identity lapb {
+    base iana-interface-type;
+    reference
+      "RFC 1381 - SNMP MIB Extension for X.25 LAPB";
+  }
+  identity sdlc {
+    base iana-interface-type;
+  }
+  identity ds1 {
+    base iana-interface-type;
+    description
+      "DS1-MIB.";
+    reference
+      "RFC 4805 - Definitions of Managed Objects for the
+                  DS1, J1, E1, DS2, and E2 Interface Types";
+  }
+  identity e1 {
+    base iana-interface-type;
+    status obsolete;
+    description
+      "Obsolete; see DS1-MIB.";
+    reference
+      "RFC 4805 - Definitions of Managed Objects for the
+                  DS1, J1, E1, DS2, and E2 Interface Types";
+  }
+
+  identity basicISDN {
+    base iana-interface-type;
+    description
+      "No longer used.  See also RFC 2127.";
+  }
+  identity primaryISDN {
+    base iana-interface-type;
+    description
+      "No longer used.  See also RFC 2127.";
+  }
+  identity propPointToPointSerial {
+    base iana-interface-type;
+    description
+      "Proprietary serial.";
+  }
+  identity ppp {
+    base iana-interface-type;
+  }
+  identity softwareLoopback {
+    base iana-interface-type;
+  }
+  identity eon {
+    base iana-interface-type;
+    description
+      "CLNP over IP.";
+  }
+  identity ethernet3Mbit {
+    base iana-interface-type;
+  }
+  identity nsip {
+    base iana-interface-type;
+    description
+      "XNS over IP.";
+  }
+  identity slip {
+    base iana-interface-type;
+    description
+      "Generic SLIP.";
+  }
+  identity ultra {
+    base iana-interface-type;
+    description
+      "Ultra Technologies.";
+  }
+  identity ds3 {
+    base iana-interface-type;
+    description
+      "DS3-MIB.";
+    reference
+      "RFC 3896 - Definitions of Managed Objects for the
+                  DS3/E3 Interface Type";
+  }
+  identity sip {
+    base iana-interface-type;
+    description
+      "SMDS, coffee.";
+    reference
+      "RFC 1694 - Definitions of Managed Objects for SMDS
+                  Interfaces using SMIv2";
+  }
+  identity frameRelay {
+    base iana-interface-type;
+    description
+      "DTE only.";
+    reference
+      "RFC 2115 - Management Information Base for Frame Relay
+                  DTEs Using SMIv2";
+  }
+  identity rs232 {
+    base iana-interface-type;
+    reference
+      "RFC 1659 - Definitions of Managed Objects for RS-232-like
+                  Hardware Devices using SMIv2";
+  }
+  identity para {
+    base iana-interface-type;
+    description
+      "Parallel-port.";
+    reference
+      "RFC 1660 - Definitions of Managed Objects for
+                  Parallel-printer-like Hardware Devices using
+                  SMIv2";
+  }
+  identity arcnet {
+    base iana-interface-type;
+    description
+      "ARCnet.";
+  }
+  identity arcnetPlus {
+    base iana-interface-type;
+    description
+      "ARCnet Plus.";
+  }
+
+  identity atm {
+    base iana-interface-type;
+    description
+      "ATM cells.";
+  }
+  identity miox25 {
+    base iana-interface-type;
+    reference
+      "RFC 1461 - SNMP MIB extension for Multiprotocol
+                  Interconnect over X.25";
+  }
+  identity sonet {
+    base iana-interface-type;
+    description
+      "SONET or SDH.";
+  }
+  identity x25ple {
+    base iana-interface-type;
+    reference
+      "RFC 2127 - ISDN Management Information Base using SMIv2";
+  }
+  identity iso88022llc {
+    base iana-interface-type;
+  }
+  identity localTalk {
+    base iana-interface-type;
+  }
+  identity smdsDxi {
+    base iana-interface-type;
+  }
+  identity frameRelayService {
+    base iana-interface-type;
+    description
+      "FRNETSERV-MIB.";
+    reference
+      "RFC 2954 - Definitions of Managed Objects for Frame
+                  Relay Service";
+  }
+  identity v35 {
+    base iana-interface-type;
+  }
+  identity hssi {
+    base iana-interface-type;
+  }
+  identity hippi {
+    base iana-interface-type;
+  }
+
+  identity modem {
+    base iana-interface-type;
+    description
+      "Generic modem.";
+  }
+  identity aal5 {
+    base iana-interface-type;
+    description
+      "AAL5 over ATM.";
+  }
+  identity sonetPath {
+    base iana-interface-type;
+  }
+  identity sonetVT {
+    base iana-interface-type;
+  }
+  identity smdsIcip {
+    base iana-interface-type;
+    description
+      "SMDS InterCarrier Interface.";
+  }
+  identity propVirtual {
+    base iana-interface-type;
+    description
+      "Proprietary virtual/internal.";
+    reference
+      "RFC 2863 - The Interfaces Group MIB";
+  }
+  identity propMultiplexor {
+    base iana-interface-type;
+    description
+      "Proprietary multiplexing.";
+    reference
+      "RFC 2863 - The Interfaces Group MIB";
+  }
+  identity ieee80212 {
+    base iana-interface-type;
+    description
+      "100BaseVG.";
+  }
+  identity fibreChannel {
+    base iana-interface-type;
+    description
+      "Fibre Channel.";
+  }
+
+  identity hippiInterface {
+    base iana-interface-type;
+    description
+      "HIPPI interfaces.";
+  }
+  identity frameRelayInterconnect {
+    base iana-interface-type;
+    status obsolete;
+    description
+      "Obsolete; use either
+       frameRelay(32) or frameRelayService(44).";
+  }
+  identity aflane8023 {
+    base iana-interface-type;
+    description
+      "ATM Emulated LAN for 802.3.";
+  }
+  identity aflane8025 {
+    base iana-interface-type;
+    description
+      "ATM Emulated LAN for 802.5.";
+  }
+  identity cctEmul {
+    base iana-interface-type;
+    description
+      "ATM Emulated circuit.";
+  }
+  identity fastEther {
+    base iana-interface-type;
+    status deprecated;
+    description
+      "Obsoleted via RFC 3635.
+       ethernetCsmacd(6) should be used instead.";
+    reference
+      "RFC 3635 - Definitions of Managed Objects for the
+                  Ethernet-like Interface Types";
+  }
+  identity isdn {
+    base iana-interface-type;
+    description
+      "ISDN and X.25.";
+    reference
+      "RFC 1356 - Multiprotocol Interconnect on X.25 and ISDN
+                  in the Packet Mode";
+  }
+
+  identity v11 {
+    base iana-interface-type;
+    description
+      "CCITT V.11/X.21.";
+  }
+  identity v36 {
+    base iana-interface-type;
+    description
+      "CCITT V.36.";
+  }
+  identity g703at64k {
+    base iana-interface-type;
+    description
+      "CCITT G703 at 64Kbps.";
+  }
+  identity g703at2mb {
+    base iana-interface-type;
+    status obsolete;
+    description
+      "Obsolete; see DS1-MIB.";
+  }
+  identity qllc {
+    base iana-interface-type;
+    description
+      "SNA QLLC.";
+  }
+  identity fastEtherFX {
+    base iana-interface-type;
+    status deprecated;
+    description
+      "Obsoleted via RFC 3635.
+       ethernetCsmacd(6) should be used instead.";
+    reference
+      "RFC 3635 - Definitions of Managed Objects for the
+                  Ethernet-like Interface Types";
+  }
+  identity channel {
+    base iana-interface-type;
+    description
+      "Channel.";
+  }
+  identity ieee80211 {
+    base iana-interface-type;
+    description
+      "Radio spread spectrum.";
+  }
+  identity ibm370parChan {
+    base iana-interface-type;
+    description
+      "IBM System 360/370 OEMI Channel.";
+  }
+  identity escon {
+    base iana-interface-type;
+    description
+      "IBM Enterprise Systems Connection.";
+  }
+  identity dlsw {
+    base iana-interface-type;
+    description
+      "Data Link Switching.";
+  }
+  identity isdns {
+    base iana-interface-type;
+    description
+      "ISDN S/T interface.";
+  }
+  identity isdnu {
+    base iana-interface-type;
+    description
+      "ISDN U interface.";
+  }
+  identity lapd {
+    base iana-interface-type;
+    description
+      "Link Access Protocol D.";
+  }
+  identity ipSwitch {
+    base iana-interface-type;
+    description
+      "IP Switching Objects.";
+  }
+  identity rsrb {
+    base iana-interface-type;
+    description
+      "Remote Source Route Bridging.";
+  }
+  identity atmLogical {
+    base iana-interface-type;
+    description
+      "ATM Logical Port.";
+    reference
+      "RFC 3606 - Definitions of Supplemental Managed Objects
+                  for ATM Interface";
+  }
+  identity ds0 {
+    base iana-interface-type;
+    description
+      "Digital Signal Level 0.";
+    reference
+      "RFC 2494 - Definitions of Managed Objects for the DS0
+                  and DS0 Bundle Interface Type";
+  }
+  identity ds0Bundle {
+    base iana-interface-type;
+    description
+      "Group of ds0s on the same ds1.";
+    reference
+      "RFC 2494 - Definitions of Managed Objects for the DS0
+                  and DS0 Bundle Interface Type";
+  }
+  identity bsc {
+    base iana-interface-type;
+    description
+      "Bisynchronous Protocol.";
+  }
+  identity async {
+    base iana-interface-type;
+    description
+      "Asynchronous Protocol.";
+  }
+  identity cnr {
+    base iana-interface-type;
+    description
+      "Combat Net Radio.";
+  }
+  identity iso88025Dtr {
+    base iana-interface-type;
+    description
+      "ISO 802.5r DTR.";
+  }
+  identity eplrs {
+    base iana-interface-type;
+    description
+      "Ext Pos Loc Report Sys.";
+  }
+  identity arap {
+    base iana-interface-type;
+    description
+      "Appletalk Remote Access Protocol.";
+  }
+  identity propCnls {
+    base iana-interface-type;
+    description
+      "Proprietary Connectionless Protocol.";
+  }
+  identity hostPad {
+    base iana-interface-type;
+    description
+      "CCITT-ITU X.29 PAD Protocol.";
+  }
+  identity termPad {
+    base iana-interface-type;
+    description
+      "CCITT-ITU X.3 PAD Facility.";
+  }
+  identity frameRelayMPI {
+    base iana-interface-type;
+    description
+      "Multiproto Interconnect over FR.";
+  }
+  identity x213 {
+    base iana-interface-type;
+    description
+      "CCITT-ITU X213.";
+  }
+  identity adsl {
+    base iana-interface-type;
+    description
+      "Asymmetric Digital Subscriber Loop.";
+  }
+  identity radsl {
+    base iana-interface-type;
+    description
+      "Rate-Adapt. Digital Subscriber Loop.";
+  }
+  identity sdsl {
+    base iana-interface-type;
+    description
+      "Symmetric Digital Subscriber Loop.";
+  }
+  identity vdsl {
+    base iana-interface-type;
+    description
+      "Very H-Speed Digital Subscrib. Loop.";
+  }
+  identity iso88025CRFPInt {
+    base iana-interface-type;
+    description
+      "ISO 802.5 CRFP.";
+  }
+  identity myrinet {
+    base iana-interface-type;
+    description
+      "Myricom Myrinet.";
+  }
+  identity voiceEM {
+    base iana-interface-type;
+    description
+      "Voice recEive and transMit.";
+  }
+  identity voiceFXO {
+    base iana-interface-type;
+    description
+      "Voice Foreign Exchange Office.";
+  }
+  identity voiceFXS {
+    base iana-interface-type;
+    description
+      "Voice Foreign Exchange Station.";
+  }
+  identity voiceEncap {
+    base iana-interface-type;
+    description
+      "Voice encapsulation.";
+  }
+  identity voiceOverIp {
+    base iana-interface-type;
+    description
+      "Voice over IP encapsulation.";
+  }
+  identity atmDxi {
+    base iana-interface-type;
+    description
+      "ATM DXI.";
+  }
+  identity atmFuni {
+    base iana-interface-type;
+    description
+      "ATM FUNI.";
+  }
+  identity atmIma {
+    base iana-interface-type;
+    description
+      "ATM IMA.";
+  }
+  identity pppMultilinkBundle {
+    base iana-interface-type;
+    description
+      "PPP Multilink Bundle.";
+  }
+  identity ipOverCdlc {
+    base iana-interface-type;
+    description
+      "IBM ipOverCdlc.";
+  }
+  identity ipOverClaw {
+    base iana-interface-type;
+    description
+      "IBM Common Link Access to Workstn.";
+  }
+  identity stackToStack {
+    base iana-interface-type;
+    description
+      "IBM stackToStack.";
+  }
+  identity virtualIpAddress {
+    base iana-interface-type;
+    description
+      "IBM VIPA.";
+  }
+  identity mpc {
+    base iana-interface-type;
+    description
+      "IBM multi-protocol channel support.";
+  }
+  identity ipOverAtm {
+    base iana-interface-type;
+    description
+      "IBM ipOverAtm.";
+    reference
+      "RFC 2320 - Definitions of Managed Objects for Classical IP
+                  and ARP Over ATM Using SMIv2 (IPOA-MIB)";
+  }
+  identity iso88025Fiber {
+    base iana-interface-type;
+    description
+      "ISO 802.5j Fiber Token Ring.";
+  }
+  identity tdlc {
+    base iana-interface-type;
+    description
+      "IBM twinaxial data link control.";
+  }
+  identity gigabitEthernet {
+    base iana-interface-type;
+    status deprecated;
+
+    description
+      "Obsoleted via RFC 3635.
+       ethernetCsmacd(6) should be used instead.";
+    reference
+      "RFC 3635 - Definitions of Managed Objects for the
+                  Ethernet-like Interface Types";
+  }
+  identity hdlc {
+    base iana-interface-type;
+    description
+      "HDLC.";
+  }
+  identity lapf {
+    base iana-interface-type;
+    description
+      "LAP F.";
+  }
+  identity v37 {
+    base iana-interface-type;
+    description
+      "V.37.";
+  }
+  identity x25mlp {
+    base iana-interface-type;
+    description
+      "Multi-Link Protocol.";
+  }
+  identity x25huntGroup {
+    base iana-interface-type;
+    description
+      "X25 Hunt Group.";
+  }
+  identity transpHdlc {
+    base iana-interface-type;
+    description
+      "Transp HDLC.";
+  }
+  identity interleave {
+    base iana-interface-type;
+    description
+      "Interleave channel.";
+  }
+  identity fast {
+    base iana-interface-type;
+    description
+      "Fast channel.";
+  }
+
+  identity ip {
+    base iana-interface-type;
+    description
+      "IP (for APPN HPR in IP networks).";
+  }
+  identity docsCableMaclayer {
+    base iana-interface-type;
+    description
+      "CATV Mac Layer.";
+  }
+  identity docsCableDownstream {
+    base iana-interface-type;
+    description
+      "CATV Downstream interface.";
+  }
+  identity docsCableUpstream {
+    base iana-interface-type;
+    description
+      "CATV Upstream interface.";
+  }
+  identity a12MppSwitch {
+    base iana-interface-type;
+    description
+      "Avalon Parallel Processor.";
+  }
+  identity tunnel {
+    base iana-interface-type;
+    description
+      "Encapsulation interface.";
+  }
+  identity coffee {
+    base iana-interface-type;
+    description
+      "Coffee pot.";
+    reference
+      "RFC 2325 - Coffee MIB";
+  }
+  identity ces {
+    base iana-interface-type;
+    description
+      "Circuit Emulation Service.";
+  }
+  identity atmSubInterface {
+    base iana-interface-type;
+    description
+      "ATM Sub Interface.";
+  }
+
+  identity l2vlan {
+    base iana-interface-type;
+    description
+      "Layer 2 Virtual LAN using 802.1Q.";
+  }
+  identity l3ipvlan {
+    base iana-interface-type;
+    description
+      "Layer 3 Virtual LAN using IP.";
+  }
+  identity l3ipxvlan {
+    base iana-interface-type;
+    description
+      "Layer 3 Virtual LAN using IPX.";
+  }
+  identity digitalPowerline {
+    base iana-interface-type;
+    description
+      "IP over Power Lines.";
+  }
+  identity mediaMailOverIp {
+    base iana-interface-type;
+    description
+      "Multimedia Mail over IP.";
+  }
+  identity dtm {
+    base iana-interface-type;
+    description
+      "Dynamic synchronous Transfer Mode.";
+  }
+  identity dcn {
+    base iana-interface-type;
+    description
+      "Data Communications Network.";
+  }
+  identity ipForward {
+    base iana-interface-type;
+    description
+      "IP Forwarding Interface.";
+  }
+  identity msdsl {
+    base iana-interface-type;
+    description
+      "Multi-rate Symmetric DSL.";
+  }
+  identity ieee1394 {
+    base iana-interface-type;
+
+    description
+      "IEEE1394 High Performance Serial Bus.";
+  }
+  identity if-gsn {
+    base iana-interface-type;
+    description
+      "HIPPI-6400.";
+  }
+  identity dvbRccMacLayer {
+    base iana-interface-type;
+    description
+      "DVB-RCC MAC Layer.";
+  }
+  identity dvbRccDownstream {
+    base iana-interface-type;
+    description
+      "DVB-RCC Downstream Channel.";
+  }
+  identity dvbRccUpstream {
+    base iana-interface-type;
+    description
+      "DVB-RCC Upstream Channel.";
+  }
+  identity atmVirtual {
+    base iana-interface-type;
+    description
+      "ATM Virtual Interface.";
+  }
+  identity mplsTunnel {
+    base iana-interface-type;
+    description
+      "MPLS Tunnel Virtual Interface.";
+  }
+  identity srp {
+    base iana-interface-type;
+    description
+      "Spatial Reuse Protocol.";
+  }
+  identity voiceOverAtm {
+    base iana-interface-type;
+    description
+      "Voice over ATM.";
+  }
+  identity voiceOverFrameRelay {
+    base iana-interface-type;
+    description
+      "Voice Over Frame Relay.";
+  }
+  identity idsl {
+    base iana-interface-type;
+    description
+      "Digital Subscriber Loop over ISDN.";
+  }
+  identity compositeLink {
+    base iana-interface-type;
+    description
+      "Avici Composite Link Interface.";
+  }
+  identity ss7SigLink {
+    base iana-interface-type;
+    description
+      "SS7 Signaling Link.";
+  }
+  identity propWirelessP2P {
+    base iana-interface-type;
+    description
+      "Prop. P2P wireless interface.";
+  }
+  identity frForward {
+    base iana-interface-type;
+    description
+      "Frame Forward Interface.";
+  }
+  identity rfc1483 {
+    base iana-interface-type;
+    description
+      "Multiprotocol over ATM AAL5.";
+    reference
+      "RFC 1483 - Multiprotocol Encapsulation over ATM
+                  Adaptation Layer 5";
+  }
+  identity usb {
+    base iana-interface-type;
+    description
+      "USB Interface.";
+  }
+  identity ieee8023adLag {
+    base iana-interface-type;
+    description
+      "IEEE 802.3ad Link Aggregate.";
+  }
+  identity bgppolicyaccounting {
+    base iana-interface-type;
+    description
+      "BGP Policy Accounting.";
+  }
+  identity frf16MfrBundle {
+    base iana-interface-type;
+    description
+      "FRF.16 Multilink Frame Relay.";
+  }
+  identity h323Gatekeeper {
+    base iana-interface-type;
+    description
+      "H323 Gatekeeper.";
+  }
+  identity h323Proxy {
+    base iana-interface-type;
+    description
+      "H323 Voice and Video Proxy.";
+  }
+  identity mpls {
+    base iana-interface-type;
+    description
+      "MPLS.";
+  }
+  identity mfSigLink {
+    base iana-interface-type;
+    description
+      "Multi-frequency signaling link.";
+  }
+  identity hdsl2 {
+    base iana-interface-type;
+    description
+      "High Bit-Rate DSL - 2nd generation.";
+  }
+  identity shdsl {
+    base iana-interface-type;
+    description
+      "Multirate HDSL2.";
+  }
+  identity ds1FDL {
+    base iana-interface-type;
+    description
+      "Facility Data Link (4Kbps) on a DS1.";
+  }
+  identity pos {
+    base iana-interface-type;
+    description
+      "Packet over SONET/SDH Interface.";
+  }
+
+  identity dvbAsiIn {
+    base iana-interface-type;
+    description
+      "DVB-ASI Input.";
+  }
+  identity dvbAsiOut {
+    base iana-interface-type;
+    description
+      "DVB-ASI Output.";
+  }
+  identity plc {
+    base iana-interface-type;
+    description
+      "Power Line Communications.";
+  }
+  identity nfas {
+    base iana-interface-type;
+    description
+      "Non-Facility Associated Signaling.";
+  }
+  identity tr008 {
+    base iana-interface-type;
+    description
+      "TR008.";
+  }
+  identity gr303RDT {
+    base iana-interface-type;
+    description
+      "Remote Digital Terminal.";
+  }
+  identity gr303IDT {
+    base iana-interface-type;
+    description
+      "Integrated Digital Terminal.";
+  }
+  identity isup {
+    base iana-interface-type;
+    description
+      "ISUP.";
+  }
+  identity propDocsWirelessMaclayer {
+    base iana-interface-type;
+    description
+      "Cisco proprietary Maclayer.";
+  }
+
+  identity propDocsWirelessDownstream {
+    base iana-interface-type;
+    description
+      "Cisco proprietary Downstream.";
+  }
+  identity propDocsWirelessUpstream {
+    base iana-interface-type;
+    description
+      "Cisco proprietary Upstream.";
+  }
+  identity hiperlan2 {
+    base iana-interface-type;
+    description
+      "HIPERLAN Type 2 Radio Interface.";
+  }
+  identity propBWAp2Mp {
+    base iana-interface-type;
+    description
+      "PropBroadbandWirelessAccesspt2Multipt (use of this value
+       for IEEE 802.16 WMAN interfaces as per IEEE Std 802.16f
+       is deprecated, and ieee80216WMAN(237) should be used
+       instead).";
+  }
+  identity sonetOverheadChannel {
+    base iana-interface-type;
+    description
+      "SONET Overhead Channel.";
+  }
+  identity digitalWrapperOverheadChannel {
+    base iana-interface-type;
+    description
+      "Digital Wrapper.";
+  }
+  identity aal2 {
+    base iana-interface-type;
+    description
+      "ATM adaptation layer 2.";
+  }
+  identity radioMAC {
+    base iana-interface-type;
+    description
+      "MAC layer over radio links.";
+  }
+  identity atmRadio {
+    base iana-interface-type;
+    description
+      "ATM over radio links.";
+  }
+  identity imt {
+    base iana-interface-type;
+    description
+      "Inter-Machine Trunks.";
+  }
+  identity mvl {
+    base iana-interface-type;
+    description
+      "Multiple Virtual Lines DSL.";
+  }
+  identity reachDSL {
+    base iana-interface-type;
+    description
+      "Long Reach DSL.";
+  }
+  identity frDlciEndPt {
+    base iana-interface-type;
+    description
+      "Frame Relay DLCI End Point.";
+  }
+  identity atmVciEndPt {
+    base iana-interface-type;
+    description
+      "ATM VCI End Point.";
+  }
+  identity opticalChannel {
+    base iana-interface-type;
+    description
+      "Optical Channel.";
+  }
+  identity opticalTransport {
+    base iana-interface-type;
+    description
+      "Optical Transport.";
+  }
+  identity propAtm {
+    base iana-interface-type;
+    description
+      "Proprietary ATM.";
+  }
+  identity voiceOverCable {
+    base iana-interface-type;
+    description
+      "Voice Over Cable Interface.";
+  }
+
+  identity infiniband {
+    base iana-interface-type;
+    description
+      "Infiniband.";
+  }
+  identity teLink {
+    base iana-interface-type;
+    description
+      "TE Link.";
+  }
+  identity q2931 {
+    base iana-interface-type;
+    description
+      "Q.2931.";
+  }
+  identity virtualTg {
+    base iana-interface-type;
+    description
+      "Virtual Trunk Group.";
+  }
+  identity sipTg {
+    base iana-interface-type;
+    description
+      "SIP Trunk Group.";
+  }
+  identity sipSig {
+    base iana-interface-type;
+    description
+      "SIP Signaling.";
+  }
+  identity docsCableUpstreamChannel {
+    base iana-interface-type;
+    description
+      "CATV Upstream Channel.";
+  }
+  identity econet {
+    base iana-interface-type;
+    description
+      "Acorn Econet.";
+  }
+  identity pon155 {
+    base iana-interface-type;
+    description
+      "FSAN 155Mb Symetrical PON interface.";
+  }
+
+  identity pon622 {
+    base iana-interface-type;
+    description
+      "FSAN 622Mb Symetrical PON interface.";
+  }
+  identity bridge {
+    base iana-interface-type;
+    description
+      "Transparent bridge interface.";
+  }
+  identity linegroup {
+    base iana-interface-type;
+    description
+      "Interface common to multiple lines.";
+  }
+  identity voiceEMFGD {
+    base iana-interface-type;
+    description
+      "Voice E&M Feature Group D.";
+  }
+  identity voiceFGDEANA {
+    base iana-interface-type;
+    description
+      "Voice FGD Exchange Access North American.";
+  }
+  identity voiceDID {
+    base iana-interface-type;
+    description
+      "Voice Direct Inward Dialing.";
+  }
+  identity mpegTransport {
+    base iana-interface-type;
+    description
+      "MPEG transport interface.";
+  }
+  identity sixToFour {
+    base iana-interface-type;
+    status deprecated;
+    description
+      "6to4 interface (DEPRECATED).";
+    reference
+      "RFC 4087 - IP Tunnel MIB";
+  }
+  identity gtp {
+    base iana-interface-type;
+    description
+      "GTP (GPRS Tunneling Protocol).";
+  }
+  identity pdnEtherLoop1 {
+    base iana-interface-type;
+    description
+      "Paradyne EtherLoop 1.";
+  }
+  identity pdnEtherLoop2 {
+    base iana-interface-type;
+    description
+      "Paradyne EtherLoop 2.";
+  }
+  identity opticalChannelGroup {
+    base iana-interface-type;
+    description
+      "Optical Channel Group.";
+  }
+  identity homepna {
+    base iana-interface-type;
+    description
+      "HomePNA ITU-T G.989.";
+  }
+  identity gfp {
+    base iana-interface-type;
+    description
+      "Generic Framing Procedure (GFP).";
+  }
+  identity ciscoISLvlan {
+    base iana-interface-type;
+    description
+      "Layer 2 Virtual LAN using Cisco ISL.";
+  }
+  identity actelisMetaLOOP {
+    base iana-interface-type;
+    description
+      "Acteleis proprietary MetaLOOP High Speed Link.";
+  }
+  identity fcipLink {
+    base iana-interface-type;
+    description
+      "FCIP Link.";
+  }
+  identity rpr {
+    base iana-interface-type;
+    description
+      "Resilient Packet Ring Interface Type.";
+  }
+
+  identity qam {
+    base iana-interface-type;
+    description
+      "RF Qam Interface.";
+  }
+  identity lmp {
+    base iana-interface-type;
+    description
+      "Link Management Protocol.";
+    reference
+      "RFC 4327 - Link Management Protocol (LMP) Management
+                  Information Base (MIB)";
+  }
+  identity cblVectaStar {
+    base iana-interface-type;
+    description
+      "Cambridge Broadband Networks Limited VectaStar.";
+  }
+  identity docsCableMCmtsDownstream {
+    base iana-interface-type;
+    description
+      "CATV Modular CMTS Downstream Interface.";
+  }
+  identity adsl2 {
+    base iana-interface-type;
+    status deprecated;
+    description
+      "Asymmetric Digital Subscriber Loop Version 2
+       (DEPRECATED/OBSOLETED - please use adsl2plus(238)
+       instead).";
+    reference
+      "RFC 4706 - Definitions of Managed Objects for Asymmetric
+                  Digital Subscriber Line 2 (ADSL2)";
+  }
+  identity macSecControlledIF {
+    base iana-interface-type;
+    description
+      "MACSecControlled.";
+  }
+  identity macSecUncontrolledIF {
+    base iana-interface-type;
+    description
+      "MACSecUncontrolled.";
+  }
+  identity aviciOpticalEther {
+    base iana-interface-type;
+    description
+      "Avici Optical Ethernet Aggregate.";
+  }
+  identity atmbond {
+    base iana-interface-type;
+    description
+      "atmbond.";
+  }
+  identity voiceFGDOS {
+    base iana-interface-type;
+    description
+      "Voice FGD Operator Services.";
+  }
+  identity mocaVersion1 {
+    base iana-interface-type;
+    description
+      "MultiMedia over Coax Alliance (MoCA) Interface
+       as documented in information provided privately to IANA.";
+  }
+  identity ieee80216WMAN {
+    base iana-interface-type;
+    description
+      "IEEE 802.16 WMAN interface.";
+  }
+  identity adsl2plus {
+    base iana-interface-type;
+    description
+      "Asymmetric Digital Subscriber Loop Version 2 -
+       Version 2 Plus and all variants.";
+  }
+  identity dvbRcsMacLayer {
+    base iana-interface-type;
+    description
+      "DVB-RCS MAC Layer.";
+    reference
+      "RFC 5728 - The SatLabs Group DVB-RCS MIB";
+  }
+  identity dvbTdm {
+    base iana-interface-type;
+    description
+      "DVB Satellite TDM.";
+    reference
+      "RFC 5728 - The SatLabs Group DVB-RCS MIB";
+  }
+  identity dvbRcsTdma {
+    base iana-interface-type;
+    description
+      "DVB-RCS TDMA.";
+    reference
+      "RFC 5728 - The SatLabs Group DVB-RCS MIB";
+  }
+  identity x86Laps {
+    base iana-interface-type;
+    description
+      "LAPS based on ITU-T X.86/Y.1323.";
+  }
+  identity wwanPP {
+    base iana-interface-type;
+    description
+      "3GPP WWAN.";
+  }
+  identity wwanPP2 {
+    base iana-interface-type;
+    description
+      "3GPP2 WWAN.";
+  }
+  identity voiceEBS {
+    base iana-interface-type;
+    description
+      "Voice P-phone EBS physical interface.";
+  }
+  identity ifPwType {
+    base iana-interface-type;
+    description
+      "Pseudowire interface type.";
+    reference
+      "RFC 5601 - Pseudowire (PW) Management Information Base (MIB)";
+  }
+  identity ilan {
+    base iana-interface-type;
+    description
+      "Internal LAN on a bridge per IEEE 802.1ap.";
+  }
+  identity pip {
+    base iana-interface-type;
+    description
+      "Provider Instance Port on a bridge per IEEE 802.1ah PBB.";
+  }
+  identity aluELP {
+    base iana-interface-type;
+    description
+      "Alcatel-Lucent Ethernet Link Protection.";
+  }
+  identity gpon {
+    base iana-interface-type;
+    description
+      "Gigabit-capable passive optical networks (G-PON) as per
+       ITU-T G.948.";
+  }
+  identity vdsl2 {
+    base iana-interface-type;
+    description
+      "Very high speed digital subscriber line Version 2
+       (as per ITU-T Recommendation G.993.2).";
+    reference
+      "RFC 5650 - Definitions of Managed Objects for Very High
+                  Speed Digital Subscriber Line 2 (VDSL2)";
+  }
+  identity capwapDot11Profile {
+    base iana-interface-type;
+    description
+      "WLAN Profile Interface.";
+    reference
+      "RFC 5834 - Control and Provisioning of Wireless Access
+                  Points (CAPWAP) Protocol Binding MIB for
+                  IEEE 802.11";
+  }
+  identity capwapDot11Bss {
+    base iana-interface-type;
+    description
+      "WLAN BSS Interface.";
+    reference
+      "RFC 5834 - Control and Provisioning of Wireless Access
+                  Points (CAPWAP) Protocol Binding MIB for
+                  IEEE 802.11";
+  }
+  identity capwapWtpVirtualRadio {
+    base iana-interface-type;
+    description
+      "WTP Virtual Radio Interface.";
+    reference
+      "RFC 5833 - Control and Provisioning of Wireless Access
+                  Points (CAPWAP) Protocol Base MIB";
+  }
+  identity bits {
+    base iana-interface-type;
+    description
+      "bitsport.";
+  }
+  identity docsCableUpstreamRfPort {
+    base iana-interface-type;
+    description
+      "DOCSIS CATV Upstream RF Port.";
+  }
+
+  identity cableDownstreamRfPort {
+    base iana-interface-type;
+    description
+      "CATV downstream RF Port.";
+  }
+  identity vmwareVirtualNic {
+    base iana-interface-type;
+    description
+      "VMware Virtual Network Interface.";
+  }
+  identity ieee802154 {
+    base iana-interface-type;
+    description
+      "IEEE 802.15.4 WPAN interface.";
+    reference
+      "IEEE 802.15.4-2006";
+  }
+  identity otnOdu {
+    base iana-interface-type;
+    description
+      "OTN Optical Data Unit.";
+  }
+  identity otnOtu {
+    base iana-interface-type;
+    description
+      "OTN Optical channel Transport Unit.";
+  }
+  identity ifVfiType {
+    base iana-interface-type;
+    description
+      "VPLS Forwarding Instance Interface Type.";
+  }
+  identity g9981 {
+    base iana-interface-type;
+    description
+      "G.998.1 bonded interface.";
+  }
+  identity g9982 {
+    base iana-interface-type;
+    description
+      "G.998.2 bonded interface.";
+  }
+  identity g9983 {
+    base iana-interface-type;
+    description
+      "G.998.3 bonded interface.";
+  }
+
+  identity aluEpon {
+    base iana-interface-type;
+    description
+      "Ethernet Passive Optical Networks (E-PON).";
+  }
+  identity aluEponOnu {
+    base iana-interface-type;
+    description
+      "EPON Optical Network Unit.";
+  }
+  identity aluEponPhysicalUni {
+    base iana-interface-type;
+    description
+      "EPON physical User to Network interface.";
+  }
+  identity aluEponLogicalLink {
+    base iana-interface-type;
+    description
+      "The emulation of a point-to-point link over the EPON
+       layer.";
+  }
+  identity aluGponOnu {
+    base iana-interface-type;
+    description
+      "GPON Optical Network Unit.";
+    reference
+      "ITU-T G.984.2";
+  }
+  identity aluGponPhysicalUni {
+    base iana-interface-type;
+    description
+      "GPON physical User to Network interface.";
+    reference
+      "ITU-T G.984.2";
+  }
+  identity vmwareNicTeam {
+    base iana-interface-type;
+    description
+      "VMware NIC Team.";
+  }
+}
diff --git a/yang/ietf-interfaces@2018-02-20.yang b/yang/ietf-interfaces@2018-02-20.yang
new file mode 100644
index 0000000..f66c205
--- /dev/null
+++ b/yang/ietf-interfaces@2018-02-20.yang
@@ -0,0 +1,1123 @@
+module ietf-interfaces {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-interfaces";
+  prefix if;
+
+  import ietf-yang-types {
+    prefix yang;
+  }
+
+  organization
+    "IETF NETMOD (Network Modeling) Working Group";
+
+  contact
+    "WG Web:   <https://datatracker.ietf.org/wg/netmod/>
+     WG List:  <mailto:netmod@ietf.org>
+
+     Editor:   Martin Bjorklund
+               <mailto:mbj@tail-f.com>";
+
+  description
+    "This module contains a collection of YANG definitions for
+     managing network interfaces.
+
+     Copyright (c) 2018 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD License
+     set forth in Section 4.c of the IETF Trust's Legal Provisions
+     Relating to IETF Documents
+     (https://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 8343; see
+     the RFC itself for full legal notices.";
+
+  revision 2018-02-20 {
+    description
+      "Updated to support NMDA.";
+    reference
+      "RFC 8343: A YANG Data Model for Interface Management";
+  }
+
+  revision 2014-05-08 {
+    description
+      "Initial revision.";
+    reference
+      "RFC 7223: A YANG Data Model for Interface Management";
+  }
+
+  /*
+   * Typedefs
+   */
+
+  typedef interface-ref {
+    type leafref {
+      path "/if:interfaces/if:interface/if:name";
+    }
+    description
+      "This type is used by data models that need to reference
+       interfaces.";
+  }
+
+  /*
+   * Identities
+   */
+
+  identity interface-type {
+    description
+      "Base identity from which specific interface types are
+       derived.";
+  }
+
+  /*
+   * Features
+   */
+
+  feature arbitrary-names {
+    description
+      "This feature indicates that the device allows user-controlled
+       interfaces to be named arbitrarily.";
+  }
+  feature pre-provisioning {
+    description
+      "This feature indicates that the device supports
+       pre-provisioning of interface configuration, i.e., it is
+       possible to configure an interface whose physical interface
+       hardware is not present on the device.";
+  }
+  feature if-mib {
+    description
+      "This feature indicates that the device implements
+       the IF-MIB.";
+    reference
+      "RFC 2863: The Interfaces Group MIB";
+  }
+
+  /*
+   * Data nodes
+   */
+
+  container interfaces {
+    description
+      "Interface parameters.";
+
+    list interface {
+      key "name";
+
+      description
+        "The list of interfaces on the device.
+
+         The status of an interface is available in this list in the
+         operational state.  If the configuration of a
+         system-controlled interface cannot be used by the system
+         (e.g., the interface hardware present does not match the
+         interface type), then the configuration is not applied to
+         the system-controlled interface shown in the operational
+         state.  If the configuration of a user-controlled interface
+         cannot be used by the system, the configured interface is
+         not instantiated in the operational state.
+
+         System-controlled interfaces created by the system are
+         always present in this list in the operational state,
+         whether or not they are configured.";
+
+     leaf name {
+        type string;
+        description
+          "The name of the interface.
+
+           A device MAY restrict the allowed values for this leaf,
+           possibly depending on the type of the interface.
+           For system-controlled interfaces, this leaf is the
+           device-specific name of the interface.
+
+           If a client tries to create configuration for a
+           system-controlled interface that is not present in the
+           operational state, the server MAY reject the request if
+           the implementation does not support pre-provisioning of
+           interfaces or if the name refers to an interface that can
+           never exist in the system.  A Network Configuration
+           Protocol (NETCONF) server MUST reply with an rpc-error
+           with the error-tag 'invalid-value' in this case.
+
+           If the device supports pre-provisioning of interface
+           configuration, the 'pre-provisioning' feature is
+           advertised.
+
+           If the device allows arbitrarily named user-controlled
+           interfaces, the 'arbitrary-names' feature is advertised.
+
+           When a configured user-controlled interface is created by
+           the system, it is instantiated with the same name in the
+           operational state.
+
+           A server implementation MAY map this leaf to the ifName
+           MIB object.  Such an implementation needs to use some
+           mechanism to handle the differences in size and characters
+           allowed between this leaf and ifName.  The definition of
+           such a mechanism is outside the scope of this document.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifName";
+      }
+
+      leaf description {
+        type string;
+        description
+          "A textual description of the interface.
+
+           A server implementation MAY map this leaf to the ifAlias
+           MIB object.  Such an implementation needs to use some
+           mechanism to handle the differences in size and characters
+           allowed between this leaf and ifAlias.  The definition of
+           such a mechanism is outside the scope of this document.
+
+           Since ifAlias is defined to be stored in non-volatile
+           storage, the MIB implementation MUST map ifAlias to the
+           value of 'description' in the persistently stored
+           configuration.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifAlias";
+      }
+
+      leaf type {
+        type identityref {
+          base interface-type;
+        }
+        mandatory true;
+        description
+          "The type of the interface.
+
+           When an interface entry is created, a server MAY
+           initialize the type leaf with a valid value, e.g., if it
+           is possible to derive the type from the name of the
+           interface.
+
+           If a client tries to set the type of an interface to a
+           value that can never be used by the system, e.g., if the
+           type is not supported or if the type does not match the
+           name of the interface, the server MUST reject the request.
+           A NETCONF server MUST reply with an rpc-error with the
+           error-tag 'invalid-value' in this case.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifType";
+      }
+
+      leaf enabled {
+        type boolean;
+        default "true";
+        description
+          "This leaf contains the configured, desired state of the
+           interface.
+
+           Systems that implement the IF-MIB use the value of this
+           leaf in the intended configuration to set
+           IF-MIB.ifAdminStatus to 'up' or 'down' after an ifEntry
+           has been initialized, as described in RFC 2863.
+
+           Changes in this leaf in the intended configuration are
+           reflected in ifAdminStatus.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifAdminStatus";
+      }
+
+      leaf link-up-down-trap-enable {
+        if-feature if-mib;
+        type enumeration {
+          enum enabled {
+            value 1;
+            description
+              "The device will generate linkUp/linkDown SNMP
+               notifications for this interface.";
+          }
+          enum disabled {
+            value 2;
+            description
+              "The device will not generate linkUp/linkDown SNMP
+               notifications for this interface.";
+          }
+        }
+        description
+          "Controls whether linkUp/linkDown SNMP notifications
+           should be generated for this interface.
+
+           If this node is not configured, the value 'enabled' is
+           operationally used by the server for interfaces that do
+           not operate on top of any other interface (i.e., there are
+           no 'lower-layer-if' entries), and 'disabled' otherwise.";
+        reference
+          "RFC 2863: The Interfaces Group MIB -
+                     ifLinkUpDownTrapEnable";
+      }
+
+      leaf admin-status {
+        if-feature if-mib;
+        type enumeration {
+          enum up {
+            value 1;
+            description
+              "Ready to pass packets.";
+          }
+          enum down {
+            value 2;
+            description
+              "Not ready to pass packets and not in some test mode.";
+          }
+          enum testing {
+            value 3;
+            description
+              "In some test mode.";
+          }
+        }
+        config false;
+        mandatory true;
+        description
+          "The desired state of the interface.
+
+           This leaf has the same read semantics as ifAdminStatus.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifAdminStatus";
+      }
+
+      leaf oper-status {
+        type enumeration {
+          enum up {
+            value 1;
+            description
+              "Ready to pass packets.";
+          }
+          enum down {
+            value 2;
+
+            description
+              "The interface does not pass any packets.";
+          }
+          enum testing {
+            value 3;
+            description
+              "In some test mode.  No operational packets can
+               be passed.";
+          }
+          enum unknown {
+            value 4;
+            description
+              "Status cannot be determined for some reason.";
+          }
+          enum dormant {
+            value 5;
+            description
+              "Waiting for some external event.";
+          }
+          enum not-present {
+            value 6;
+            description
+              "Some component (typically hardware) is missing.";
+          }
+          enum lower-layer-down {
+            value 7;
+            description
+              "Down due to state of lower-layer interface(s).";
+          }
+        }
+        config false;
+        mandatory true;
+        description
+          "The current operational state of the interface.
+
+           This leaf has the same semantics as ifOperStatus.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifOperStatus";
+      }
+
+      leaf last-change {
+        type yang:date-and-time;
+        config false;
+        description
+          "The time the interface entered its current operational
+           state.  If the current state was entered prior to the
+           last re-initialization of the local network management
+           subsystem, then this node is not present.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifLastChange";
+      }
+
+      leaf if-index {
+        if-feature if-mib;
+        type int32 {
+          range "1..2147483647";
+        }
+        config false;
+        mandatory true;
+        description
+          "The ifIndex value for the ifEntry represented by this
+           interface.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifIndex";
+      }
+
+      leaf phys-address {
+        type yang:phys-address;
+        config false;
+        description
+          "The interface's address at its protocol sub-layer.  For
+           example, for an 802.x interface, this object normally
+           contains a Media Access Control (MAC) address.  The
+           interface's media-specific modules must define the bit
+           and byte ordering and the format of the value of this
+           object.  For interfaces that do not have such an address
+           (e.g., a serial line), this node is not present.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifPhysAddress";
+      }
+
+      leaf-list higher-layer-if {
+        type interface-ref;
+        config false;
+        description
+          "A list of references to interfaces layered on top of this
+           interface.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifStackTable";
+      }
+
+      leaf-list lower-layer-if {
+        type interface-ref;
+        config false;
+
+        description
+          "A list of references to interfaces layered underneath this
+           interface.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifStackTable";
+      }
+
+      leaf speed {
+        type yang:gauge64;
+        units "bits/second";
+        config false;
+        description
+            "An estimate of the interface's current bandwidth in bits
+             per second.  For interfaces that do not vary in
+             bandwidth or for those where no accurate estimation can
+             be made, this node should contain the nominal bandwidth.
+             For interfaces that have no concept of bandwidth, this
+             node is not present.";
+        reference
+          "RFC 2863: The Interfaces Group MIB -
+                     ifSpeed, ifHighSpeed";
+      }
+
+      container statistics {
+        config false;
+        description
+          "A collection of interface-related statistics objects.";
+
+        leaf discontinuity-time {
+          type yang:date-and-time;
+          mandatory true;
+          description
+            "The time on the most recent occasion at which any one or
+             more of this interface's counters suffered a
+             discontinuity.  If no such discontinuities have occurred
+             since the last re-initialization of the local management
+             subsystem, then this node contains the time the local
+             management subsystem re-initialized itself.";
+        }
+
+        leaf in-octets {
+          type yang:counter64;
+          description
+            "The total number of octets received on the interface,
+             including framing characters.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCInOctets";
+        }
+
+        leaf in-unicast-pkts {
+          type yang:counter64;
+          description
+            "The number of packets, delivered by this sub-layer to a
+             higher (sub-)layer, that were not addressed to a
+             multicast or broadcast address at this sub-layer.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCInUcastPkts";
+        }
+
+        leaf in-broadcast-pkts {
+          type yang:counter64;
+          description
+            "The number of packets, delivered by this sub-layer to a
+             higher (sub-)layer, that were addressed to a broadcast
+             address at this sub-layer.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCInBroadcastPkts";
+        }
+
+        leaf in-multicast-pkts {
+          type yang:counter64;
+          description
+            "The number of packets, delivered by this sub-layer to a
+             higher (sub-)layer, that were addressed to a multicast
+             address at this sub-layer.  For a MAC-layer protocol,
+             this includes both Group and Functional addresses.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCInMulticastPkts";
+        }
+
+        leaf in-discards {
+          type yang:counter32;
+          description
+            "The number of inbound packets that were chosen to be
+             discarded even though no errors had been detected to
+             prevent their being deliverable to a higher-layer
+             protocol.  One possible reason for discarding such a
+             packet could be to free up buffer space.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifInDiscards";
+        }
+
+        leaf in-errors {
+          type yang:counter32;
+          description
+            "For packet-oriented interfaces, the number of inbound
+             packets that contained errors preventing them from being
+             deliverable to a higher-layer protocol.  For character-
+             oriented or fixed-length interfaces, the number of
+             inbound transmission units that contained errors
+             preventing them from being deliverable to a higher-layer
+             protocol.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifInErrors";
+        }
+
+        leaf in-unknown-protos {
+          type yang:counter32;
+
+          description
+            "For packet-oriented interfaces, the number of packets
+             received via the interface that were discarded because
+             of an unknown or unsupported protocol.  For
+             character-oriented or fixed-length interfaces that
+             support protocol multiplexing, the number of
+             transmission units received via the interface that were
+             discarded because of an unknown or unsupported protocol.
+             For any interface that does not support protocol
+             multiplexing, this counter is not present.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifInUnknownProtos";
+        }
+
+        leaf out-octets {
+          type yang:counter64;
+          description
+            "The total number of octets transmitted out of the
+             interface, including framing characters.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCOutOctets";
+        }
+
+        leaf out-unicast-pkts {
+          type yang:counter64;
+          description
+            "The total number of packets that higher-level protocols
+             requested be transmitted and that were not addressed
+             to a multicast or broadcast address at this sub-layer,
+             including those that were discarded or not sent.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCOutUcastPkts";
+        }
+
+        leaf out-broadcast-pkts {
+          type yang:counter64;
+          description
+            "The total number of packets that higher-level protocols
+             requested be transmitted and that were addressed to a
+             broadcast address at this sub-layer, including those
+             that were discarded or not sent.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCOutBroadcastPkts";
+        }
+
+        leaf out-multicast-pkts {
+          type yang:counter64;
+          description
+            "The total number of packets that higher-level protocols
+             requested be transmitted and that were addressed to a
+             multicast address at this sub-layer, including those
+             that were discarded or not sent.  For a MAC-layer
+             protocol, this includes both Group and Functional
+             addresses.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCOutMulticastPkts";
+        }
+
+        leaf out-discards {
+          type yang:counter32;
+          description
+            "The number of outbound packets that were chosen to be
+             discarded even though no errors had been detected to
+             prevent their being transmitted.  One possible reason
+             for discarding such a packet could be to free up buffer
+             space.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifOutDiscards";
+        }
+
+        leaf out-errors {
+          type yang:counter32;
+          description
+            "For packet-oriented interfaces, the number of outbound
+             packets that could not be transmitted because of errors.
+             For character-oriented or fixed-length interfaces, the
+             number of outbound transmission units that could not be
+             transmitted because of errors.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifOutErrors";
+        }
+      }
+
+    }
+  }
+
+  /*
+   * Legacy typedefs
+   */
+
+  typedef interface-state-ref {
+    type leafref {
+      path "/if:interfaces-state/if:interface/if:name";
+    }
+    status deprecated;
+    description
+      "This type is used by data models that need to reference
+       the operationally present interfaces.";
+  }
+
+  /*
+   * Legacy operational state data nodes
+   */
+
+  container interfaces-state {
+    config false;
+    status deprecated;
+    description
+      "Data nodes for the operational state of interfaces.";
+
+    list interface {
+      key "name";
+      status deprecated;
+
+      description
+        "The list of interfaces on the device.
+
+         System-controlled interfaces created by the system are
+         always present in this list, whether or not they are
+         configured.";
+
+      leaf name {
+        type string;
+        status deprecated;
+        description
+          "The name of the interface.
+
+           A server implementation MAY map this leaf to the ifName
+           MIB object.  Such an implementation needs to use some
+           mechanism to handle the differences in size and characters
+           allowed between this leaf and ifName.  The definition of
+           such a mechanism is outside the scope of this document.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifName";
+      }
+
+      leaf type {
+        type identityref {
+          base interface-type;
+        }
+        mandatory true;
+        status deprecated;
+        description
+          "The type of the interface.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifType";
+      }
+
+      leaf admin-status {
+        if-feature if-mib;
+        type enumeration {
+          enum up {
+            value 1;
+            description
+              "Ready to pass packets.";
+          }
+          enum down {
+            value 2;
+            description
+              "Not ready to pass packets and not in some test mode.";
+          }
+          enum testing {
+            value 3;
+            description
+              "In some test mode.";
+          }
+        }
+        mandatory true;
+        status deprecated;
+        description
+          "The desired state of the interface.
+
+           This leaf has the same read semantics as ifAdminStatus.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifAdminStatus";
+      }
+
+      leaf oper-status {
+        type enumeration {
+          enum up {
+            value 1;
+            description
+              "Ready to pass packets.";
+          }
+          enum down {
+            value 2;
+            description
+              "The interface does not pass any packets.";
+          }
+          enum testing {
+            value 3;
+            description
+              "In some test mode.  No operational packets can
+               be passed.";
+          }
+          enum unknown {
+            value 4;
+            description
+              "Status cannot be determined for some reason.";
+          }
+          enum dormant {
+            value 5;
+            description
+              "Waiting for some external event.";
+          }
+          enum not-present {
+            value 6;
+            description
+              "Some component (typically hardware) is missing.";
+          }
+          enum lower-layer-down {
+            value 7;
+            description
+              "Down due to state of lower-layer interface(s).";
+          }
+        }
+        mandatory true;
+        status deprecated;
+        description
+          "The current operational state of the interface.
+
+           This leaf has the same semantics as ifOperStatus.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifOperStatus";
+      }
+
+      leaf last-change {
+        type yang:date-and-time;
+        status deprecated;
+        description
+          "The time the interface entered its current operational
+           state.  If the current state was entered prior to the
+           last re-initialization of the local network management
+           subsystem, then this node is not present.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifLastChange";
+      }
+
+      leaf if-index {
+        if-feature if-mib;
+        type int32 {
+          range "1..2147483647";
+        }
+        mandatory true;
+        status deprecated;
+        description
+          "The ifIndex value for the ifEntry represented by this
+           interface.";
+
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifIndex";
+      }
+
+      leaf phys-address {
+        type yang:phys-address;
+        status deprecated;
+        description
+          "The interface's address at its protocol sub-layer.  For
+           example, for an 802.x interface, this object normally
+           contains a Media Access Control (MAC) address.  The
+           interface's media-specific modules must define the bit
+           and byte ordering and the format of the value of this
+           object.  For interfaces that do not have such an address
+           (e.g., a serial line), this node is not present.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifPhysAddress";
+      }
+
+      leaf-list higher-layer-if {
+        type interface-state-ref;
+        status deprecated;
+        description
+          "A list of references to interfaces layered on top of this
+           interface.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifStackTable";
+      }
+
+      leaf-list lower-layer-if {
+        type interface-state-ref;
+        status deprecated;
+        description
+          "A list of references to interfaces layered underneath this
+           interface.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifStackTable";
+      }
+
+      leaf speed {
+        type yang:gauge64;
+        units "bits/second";
+        status deprecated;
+        description
+            "An estimate of the interface's current bandwidth in bits
+             per second.  For interfaces that do not vary in
+             bandwidth or for those where no accurate estimation can
+
+             be made, this node should contain the nominal bandwidth.
+             For interfaces that have no concept of bandwidth, this
+             node is not present.";
+        reference
+          "RFC 2863: The Interfaces Group MIB -
+                     ifSpeed, ifHighSpeed";
+      }
+
+      container statistics {
+        status deprecated;
+        description
+          "A collection of interface-related statistics objects.";
+
+        leaf discontinuity-time {
+          type yang:date-and-time;
+          mandatory true;
+          status deprecated;
+          description
+            "The time on the most recent occasion at which any one or
+             more of this interface's counters suffered a
+             discontinuity.  If no such discontinuities have occurred
+             since the last re-initialization of the local management
+             subsystem, then this node contains the time the local
+             management subsystem re-initialized itself.";
+        }
+
+        leaf in-octets {
+          type yang:counter64;
+          status deprecated;
+          description
+            "The total number of octets received on the interface,
+             including framing characters.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCInOctets";
+        }
+
+        leaf in-unicast-pkts {
+          type yang:counter64;
+          status deprecated;
+          description
+            "The number of packets, delivered by this sub-layer to a
+             higher (sub-)layer, that were not addressed to a
+             multicast or broadcast address at this sub-layer.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCInUcastPkts";
+        }
+
+        leaf in-broadcast-pkts {
+          type yang:counter64;
+          status deprecated;
+          description
+            "The number of packets, delivered by this sub-layer to a
+             higher (sub-)layer, that were addressed to a broadcast
+             address at this sub-layer.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCInBroadcastPkts";
+        }
+
+        leaf in-multicast-pkts {
+          type yang:counter64;
+          status deprecated;
+          description
+            "The number of packets, delivered by this sub-layer to a
+             higher (sub-)layer, that were addressed to a multicast
+             address at this sub-layer.  For a MAC-layer protocol,
+             this includes both Group and Functional addresses.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCInMulticastPkts";
+        }
+
+        leaf in-discards {
+          type yang:counter32;
+          status deprecated;
+
+          description
+            "The number of inbound packets that were chosen to be
+             discarded even though no errors had been detected to
+             prevent their being deliverable to a higher-layer
+             protocol.  One possible reason for discarding such a
+             packet could be to free up buffer space.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifInDiscards";
+        }
+
+        leaf in-errors {
+          type yang:counter32;
+          status deprecated;
+          description
+            "For packet-oriented interfaces, the number of inbound
+             packets that contained errors preventing them from being
+             deliverable to a higher-layer protocol.  For character-
+             oriented or fixed-length interfaces, the number of
+             inbound transmission units that contained errors
+             preventing them from being deliverable to a higher-layer
+             protocol.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifInErrors";
+        }
+
+        leaf in-unknown-protos {
+          type yang:counter32;
+          status deprecated;
+          description
+            "For packet-oriented interfaces, the number of packets
+             received via the interface that were discarded because
+             of an unknown or unsupported protocol.  For
+             character-oriented or fixed-length interfaces that
+             support protocol multiplexing, the number of
+             transmission units received via the interface that were
+             discarded because of an unknown or unsupported protocol.
+             For any interface that does not support protocol
+             multiplexing, this counter is not present.
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifInUnknownProtos";
+        }
+
+        leaf out-octets {
+          type yang:counter64;
+          status deprecated;
+          description
+            "The total number of octets transmitted out of the
+             interface, including framing characters.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCOutOctets";
+        }
+
+        leaf out-unicast-pkts {
+          type yang:counter64;
+          status deprecated;
+          description
+            "The total number of packets that higher-level protocols
+             requested be transmitted and that were not addressed
+             to a multicast or broadcast address at this sub-layer,
+             including those that were discarded or not sent.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCOutUcastPkts";
+        }
+
+        leaf out-broadcast-pkts {
+          type yang:counter64;
+          status deprecated;
+
+          description
+            "The total number of packets that higher-level protocols
+             requested be transmitted and that were addressed to a
+             broadcast address at this sub-layer, including those
+             that were discarded or not sent.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCOutBroadcastPkts";
+        }
+
+        leaf out-multicast-pkts {
+          type yang:counter64;
+          status deprecated;
+          description
+            "The total number of packets that higher-level protocols
+             requested be transmitted and that were addressed to a
+             multicast address at this sub-layer, including those
+             that were discarded or not sent.  For a MAC-layer
+             protocol, this includes both Group and Functional
+             addresses.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCOutMulticastPkts";
+        }
+
+        leaf out-discards {
+          type yang:counter32;
+          status deprecated;
+          description
+            "The number of outbound packets that were chosen to be
+             discarded even though no errors had been detected to
+             prevent their being transmitted.  One possible reason
+             for discarding such a packet could be to free up buffer
+             space.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifOutDiscards";
+        }
+
+        leaf out-errors {
+          type yang:counter32;
+          status deprecated;
+          description
+            "For packet-oriented interfaces, the number of outbound
+             packets that could not be transmitted because of errors.
+             For character-oriented or fixed-length interfaces, the
+             number of outbound transmission units that could not be
+             transmitted because of errors.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifOutErrors";
+        }
+      }
+    }
+  }
+}
diff --git a/yang/ietf-ip@2018-02-22.yang b/yang/ietf-ip@2018-02-22.yang
new file mode 100644
index 0000000..a270f67
--- /dev/null
+++ b/yang/ietf-ip@2018-02-22.yang
@@ -0,0 +1,876 @@
+module ietf-ip {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-ip";
+  prefix ip;
+
+  import ietf-interfaces {
+    prefix if;
+  }
+  import ietf-inet-types {
+    prefix inet;
+  }
+  import ietf-yang-types {
+    prefix yang;
+  }
+
+  organization
+    "IETF NETMOD (Network Modeling) Working Group";
+
+  contact
+    "WG Web:   <https://datatracker.ietf.org/wg/netmod/>
+     WG List:  <mailto:netmod@ietf.org>
+
+     Editor:   Martin Bjorklund
+               <mailto:mbj@tail-f.com>";
+  description
+    "This module contains a collection of YANG definitions for
+     managing IP implementations.
+
+     Copyright (c) 2018 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD License
+     set forth in Section 4.c of the IETF Trust's Legal Provisions
+     Relating to IETF Documents
+     (https://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 8344; see
+     the RFC itself for full legal notices.";
+
+  revision 2018-02-22 {
+    description
+      "Updated to support NMDA.";
+    reference
+      "RFC 8344: A YANG Data Model for IP Management";
+  }
+
+  revision 2014-06-16 {
+    description
+      "Initial revision.";
+    reference
+      "RFC 7277: A YANG Data Model for IP Management";
+  }
+
+  /*
+   * Features
+   */
+
+  feature ipv4-non-contiguous-netmasks {
+    description
+      "Indicates support for configuring non-contiguous
+       subnet masks.";
+  }
+
+  feature ipv6-privacy-autoconf {
+    description
+      "Indicates support for privacy extensions for stateless address
+       autoconfiguration in IPv6.";
+    reference
+      "RFC 4941: Privacy Extensions for Stateless Address
+                 Autoconfiguration in IPv6";
+  }
+
+  /*
+   * Typedefs
+   */
+
+  typedef ip-address-origin {
+    type enumeration {
+      enum other {
+        description
+          "None of the following.";
+      }
+
+      enum static {
+        description
+          "Indicates that the address has been statically
+           configured -- for example, using the Network Configuration
+           Protocol (NETCONF) or a command line interface.";
+      }
+      enum dhcp {
+        description
+          "Indicates an address that has been assigned to this
+           system by a DHCP server.";
+      }
+      enum link-layer {
+        description
+          "Indicates an address created by IPv6 stateless
+           autoconfiguration that embeds a link-layer address in its
+           interface identifier.";
+      }
+      enum random {
+        description
+          "Indicates an address chosen by the system at
+           random, e.g., an IPv4 address within 169.254/16, a
+           temporary address as described in RFC 4941, or a
+           semantically opaque address as described in RFC 7217.";
+        reference
+          "RFC 4941: Privacy Extensions for Stateless Address
+                     Autoconfiguration in IPv6
+           RFC 7217: A Method for Generating Semantically Opaque
+                     Interface Identifiers with IPv6 Stateless
+                     Address Autoconfiguration (SLAAC)";
+      }
+    }
+    description
+      "The origin of an address.";
+  }
+
+  typedef neighbor-origin {
+    type enumeration {
+      enum other {
+        description
+          "None of the following.";
+      }
+      enum static {
+        description
+          "Indicates that the mapping has been statically
+           configured -- for example, using NETCONF or a command line
+           interface.";
+      }
+
+      enum dynamic {
+        description
+          "Indicates that the mapping has been dynamically resolved
+           using, for example, IPv4 ARP or the IPv6 Neighbor
+           Discovery protocol.";
+      }
+    }
+    description
+      "The origin of a neighbor entry.";
+  }
+
+  /*
+   * Data nodes
+   */
+
+  augment "/if:interfaces/if:interface" {
+    description
+      "IP parameters on interfaces.
+
+       If an interface is not capable of running IP, the server
+       must not allow the client to configure these parameters.";
+
+    container ipv4 {
+      presence
+        "Enables IPv4 unless the 'enabled' leaf
+         (which defaults to 'true') is set to 'false'";
+      description
+        "Parameters for the IPv4 address family.";
+
+      leaf enabled {
+        type boolean;
+        default true;
+        description
+          "Controls whether IPv4 is enabled or disabled on this
+           interface.  When IPv4 is enabled, this interface is
+           connected to an IPv4 stack, and the interface can send
+           and receive IPv4 packets.";
+      }
+      leaf forwarding {
+        type boolean;
+        default false;
+        description
+          "Controls IPv4 packet forwarding of datagrams received by,
+           but not addressed to, this interface.  IPv4 routers
+           forward datagrams.  IPv4 hosts do not (except those
+           source-routed via the host).";
+      }
+
+      leaf mtu {
+        type uint16 {
+          range "68..max";
+        }
+        units "octets";
+        description
+          "The size, in octets, of the largest IPv4 packet that the
+           interface will send and receive.
+
+           The server may restrict the allowed values for this leaf,
+           depending on the interface's type.
+
+           If this leaf is not configured, the operationally used MTU
+           depends on the interface's type.";
+        reference
+          "RFC 791: Internet Protocol";
+      }
+      list address {
+        key "ip";
+        description
+          "The list of IPv4 addresses on the interface.";
+
+        leaf ip {
+          type inet:ipv4-address-no-zone;
+          description
+            "The IPv4 address on the interface.";
+        }
+        choice subnet {
+          mandatory true;
+          description
+            "The subnet can be specified as a prefix length or,
+             if the server supports non-contiguous netmasks, as
+             a netmask.";
+          leaf prefix-length {
+            type uint8 {
+              range "0..32";
+            }
+            description
+              "The length of the subnet prefix.";
+          }
+          leaf netmask {
+            if-feature ipv4-non-contiguous-netmasks;
+            type yang:dotted-quad;
+            description
+              "The subnet specified as a netmask.";
+          }
+        }
+
+        leaf origin {
+          type ip-address-origin;
+          config false;
+          description
+            "The origin of this address.";
+        }
+      }
+      list neighbor {
+        key "ip";
+        description
+          "A list of mappings from IPv4 addresses to
+           link-layer addresses.
+
+           Entries in this list in the intended configuration are
+           used as static entries in the ARP Cache.
+
+           In the operational state, this list represents the ARP
+           Cache.";
+        reference
+          "RFC 826: An Ethernet Address Resolution Protocol";
+
+        leaf ip {
+          type inet:ipv4-address-no-zone;
+          description
+            "The IPv4 address of the neighbor node.";
+        }
+        leaf link-layer-address {
+          type yang:phys-address;
+          mandatory true;
+          description
+            "The link-layer address of the neighbor node.";
+        }
+        leaf origin {
+          type neighbor-origin;
+          config false;
+          description
+            "The origin of this neighbor entry.";
+        }
+      }
+    }
+
+    container ipv6 {
+      presence
+        "Enables IPv6 unless the 'enabled' leaf
+         (which defaults to 'true') is set to 'false'";
+      description
+        "Parameters for the IPv6 address family.";
+
+      leaf enabled {
+        type boolean;
+        default true;
+        description
+          "Controls whether IPv6 is enabled or disabled on this
+           interface.  When IPv6 is enabled, this interface is
+           connected to an IPv6 stack, and the interface can send
+           and receive IPv6 packets.";
+      }
+      leaf forwarding {
+        type boolean;
+        default false;
+        description
+          "Controls IPv6 packet forwarding of datagrams received by,
+           but not addressed to, this interface.  IPv6 routers
+           forward datagrams.  IPv6 hosts do not (except those
+           source-routed via the host).";
+        reference
+          "RFC 4861: Neighbor Discovery for IP version 6 (IPv6)
+                     Section 6.2.1, IsRouter";
+      }
+      leaf mtu {
+        type uint32 {
+          range "1280..max";
+        }
+        units "octets";
+        description
+          "The size, in octets, of the largest IPv6 packet that the
+           interface will send and receive.
+
+           The server may restrict the allowed values for this leaf,
+           depending on the interface's type.
+
+           If this leaf is not configured, the operationally used MTU
+           depends on the interface's type.";
+        reference
+          "RFC 8200: Internet Protocol, Version 6 (IPv6)
+                     Specification
+                     Section 5";
+      }
+
+      list address {
+        key "ip";
+        description
+          "The list of IPv6 addresses on the interface.";
+
+        leaf ip {
+          type inet:ipv6-address-no-zone;
+          description
+            "The IPv6 address on the interface.";
+        }
+        leaf prefix-length {
+          type uint8 {
+            range "0..128";
+          }
+          mandatory true;
+          description
+            "The length of the subnet prefix.";
+        }
+        leaf origin {
+          type ip-address-origin;
+          config false;
+          description
+            "The origin of this address.";
+        }
+        leaf status {
+          type enumeration {
+            enum preferred {
+              description
+                "This is a valid address that can appear as the
+                 destination or source address of a packet.";
+            }
+            enum deprecated {
+              description
+                "This is a valid but deprecated address that should
+                 no longer be used as a source address in new
+                 communications, but packets addressed to such an
+                 address are processed as expected.";
+            }
+            enum invalid {
+              description
+                "This isn't a valid address, and it shouldn't appear
+                 as the destination or source address of a packet.";
+            }
+
+            enum inaccessible {
+              description
+                "The address is not accessible because the interface
+                 to which this address is assigned is not
+                 operational.";
+            }
+            enum unknown {
+              description
+                "The status cannot be determined for some reason.";
+            }
+            enum tentative {
+              description
+                "The uniqueness of the address on the link is being
+                 verified.  Addresses in this state should not be
+                 used for general communication and should only be
+                 used to determine the uniqueness of the address.";
+            }
+            enum duplicate {
+              description
+                "The address has been determined to be non-unique on
+                 the link and so must not be used.";
+            }
+            enum optimistic {
+              description
+                "The address is available for use, subject to
+                 restrictions, while its uniqueness on a link is
+                 being verified.";
+            }
+          }
+          config false;
+          description
+            "The status of an address.  Most of the states correspond
+             to states from the IPv6 Stateless Address
+             Autoconfiguration protocol.";
+          reference
+            "RFC 4293: Management Information Base for the
+                       Internet Protocol (IP)
+                       - IpAddressStatusTC
+             RFC 4862: IPv6 Stateless Address Autoconfiguration";
+        }
+      }
+
+      list neighbor {
+        key "ip";
+        description
+          "A list of mappings from IPv6 addresses to
+           link-layer addresses.
+
+           Entries in this list in the intended configuration are
+           used as static entries in the Neighbor Cache.
+
+           In the operational state, this list represents the
+           Neighbor Cache.";
+        reference
+          "RFC 4861: Neighbor Discovery for IP version 6 (IPv6)";
+
+        leaf ip {
+          type inet:ipv6-address-no-zone;
+          description
+            "The IPv6 address of the neighbor node.";
+        }
+        leaf link-layer-address {
+          type yang:phys-address;
+          mandatory true;
+          description
+            "The link-layer address of the neighbor node.
+
+             In the operational state, if the neighbor's 'state' leaf
+             is 'incomplete', this leaf is not instantiated.";
+        }
+        leaf origin {
+          type neighbor-origin;
+          config false;
+          description
+            "The origin of this neighbor entry.";
+        }
+        leaf is-router {
+          type empty;
+          config false;
+          description
+            "Indicates that the neighbor node acts as a router.";
+        }
+
+        leaf state {
+          type enumeration {
+            enum incomplete {
+              description
+                "Address resolution is in progress, and the
+                 link-layer address of the neighbor has not yet been
+                 determined.";
+            }
+            enum reachable {
+              description
+                "Roughly speaking, the neighbor is known to have been
+                 reachable recently (within tens of seconds ago).";
+            }
+            enum stale {
+              description
+                "The neighbor is no longer known to be reachable, but
+                 until traffic is sent to the neighbor no attempt
+                 should be made to verify its reachability.";
+            }
+            enum delay {
+              description
+                "The neighbor is no longer known to be reachable, and
+                 traffic has recently been sent to the neighbor.
+                 Rather than probe the neighbor immediately, however,
+                 delay sending probes for a short while in order to
+                 give upper-layer protocols a chance to provide
+                 reachability confirmation.";
+            }
+            enum probe {
+              description
+                "The neighbor is no longer known to be reachable, and
+                 unicast Neighbor Solicitation probes are being sent
+                 to verify reachability.";
+            }
+          }
+          config false;
+          description
+            "The Neighbor Unreachability Detection state of this
+             entry.";
+          reference
+            "RFC 4861: Neighbor Discovery for IP version 6 (IPv6)
+                       Section 7.3.2";
+        }
+      }
+
+      leaf dup-addr-detect-transmits {
+        type uint32;
+        default 1;
+        description
+          "The number of consecutive Neighbor Solicitation messages
+           sent while performing Duplicate Address Detection on a
+           tentative address.  A value of zero indicates that
+           Duplicate Address Detection is not performed on
+           tentative addresses.  A value of one indicates a single
+           transmission with no follow-up retransmissions.";
+        reference
+          "RFC 4862: IPv6 Stateless Address Autoconfiguration";
+      }
+      container autoconf {
+        description
+          "Parameters to control the autoconfiguration of IPv6
+           addresses, as described in RFC 4862.";
+        reference
+          "RFC 4862: IPv6 Stateless Address Autoconfiguration";
+
+        leaf create-global-addresses {
+          type boolean;
+          default true;
+          description
+            "If enabled, the host creates global addresses as
+             described in RFC 4862.";
+          reference
+            "RFC 4862: IPv6 Stateless Address Autoconfiguration
+                       Section 5.5";
+        }
+        leaf create-temporary-addresses {
+          if-feature ipv6-privacy-autoconf;
+          type boolean;
+          default false;
+          description
+            "If enabled, the host creates temporary addresses as
+             described in RFC 4941.";
+          reference
+            "RFC 4941: Privacy Extensions for Stateless Address
+                       Autoconfiguration in IPv6";
+        }
+
+        leaf temporary-valid-lifetime {
+          if-feature ipv6-privacy-autoconf;
+          type uint32;
+          units "seconds";
+          default 604800;
+          description
+            "The time period during which the temporary address
+             is valid.";
+          reference
+            "RFC 4941: Privacy Extensions for Stateless Address
+                       Autoconfiguration in IPv6
+                       - TEMP_VALID_LIFETIME";
+        }
+        leaf temporary-preferred-lifetime {
+          if-feature ipv6-privacy-autoconf;
+          type uint32;
+          units "seconds";
+          default 86400;
+          description
+            "The time period during which the temporary address is
+             preferred.";
+          reference
+            "RFC 4941: Privacy Extensions for Stateless Address
+                       Autoconfiguration in IPv6
+                       - TEMP_PREFERRED_LIFETIME";
+        }
+      }
+    }
+  }
+
+  /*
+   * Legacy operational state data nodes
+   */
+
+  augment "/if:interfaces-state/if:interface" {
+    status deprecated;
+    description
+      "Data nodes for the operational state of IP on interfaces.";
+
+    container ipv4 {
+      presence
+        "Present if IPv4 is enabled on this interface";
+      config false;
+      status deprecated;
+      description
+        "Interface-specific parameters for the IPv4 address family.";
+
+      leaf forwarding {
+        type boolean;
+        status deprecated;
+        description
+          "Indicates whether IPv4 packet forwarding is enabled or
+           disabled on this interface.";
+      }
+      leaf mtu {
+        type uint16 {
+          range "68..max";
+        }
+        units "octets";
+        status deprecated;
+        description
+          "The size, in octets, of the largest IPv4 packet that the
+           interface will send and receive.";
+        reference
+          "RFC 791: Internet Protocol";
+      }
+      list address {
+        key "ip";
+        status deprecated;
+        description
+          "The list of IPv4 addresses on the interface.";
+
+        leaf ip {
+          type inet:ipv4-address-no-zone;
+          status deprecated;
+          description
+            "The IPv4 address on the interface.";
+        }
+        choice subnet {
+          status deprecated;
+          description
+            "The subnet can be specified as a prefix length or,
+             if the server supports non-contiguous netmasks, as
+             a netmask.";
+          leaf prefix-length {
+            type uint8 {
+              range "0..32";
+            }
+            status deprecated;
+            description
+              "The length of the subnet prefix.";
+          }
+          leaf netmask {
+            if-feature ipv4-non-contiguous-netmasks;
+            type yang:dotted-quad;
+            status deprecated;
+            description
+              "The subnet specified as a netmask.";
+          }
+        }
+        leaf origin {
+          type ip-address-origin;
+          status deprecated;
+          description
+            "The origin of this address.";
+        }
+      }
+      list neighbor {
+        key "ip";
+        status deprecated;
+        description
+          "A list of mappings from IPv4 addresses to
+           link-layer addresses.
+
+           This list represents the ARP Cache.";
+        reference
+          "RFC 826: An Ethernet Address Resolution Protocol";
+
+        leaf ip {
+          type inet:ipv4-address-no-zone;
+          status deprecated;
+          description
+            "The IPv4 address of the neighbor node.";
+        }
+
+        leaf link-layer-address {
+          type yang:phys-address;
+          status deprecated;
+          description
+            "The link-layer address of the neighbor node.";
+        }
+        leaf origin {
+          type neighbor-origin;
+          status deprecated;
+          description
+            "The origin of this neighbor entry.";
+        }
+      }
+    }
+
+    container ipv6 {
+      presence
+        "Present if IPv6 is enabled on this interface";
+      config false;
+      status deprecated;
+      description
+        "Parameters for the IPv6 address family.";
+
+      leaf forwarding {
+        type boolean;
+        default false;
+        status deprecated;
+        description
+          "Indicates whether IPv6 packet forwarding is enabled or
+           disabled on this interface.";
+        reference
+          "RFC 4861: Neighbor Discovery for IP version 6 (IPv6)
+                     Section 6.2.1, IsRouter";
+      }
+      leaf mtu {
+        type uint32 {
+          range "1280..max";
+        }
+        units "octets";
+        status deprecated;
+        description
+          "The size, in octets, of the largest IPv6 packet that the
+           interface will send and receive.";
+        reference
+          "RFC 8200: Internet Protocol, Version 6 (IPv6)
+                     Specification
+                     Section 5";
+      }
+      list address {
+        key "ip";
+        status deprecated;
+        description
+          "The list of IPv6 addresses on the interface.";
+
+        leaf ip {
+          type inet:ipv6-address-no-zone;
+          status deprecated;
+          description
+            "The IPv6 address on the interface.";
+        }
+        leaf prefix-length {
+          type uint8 {
+            range "0..128";
+          }
+          mandatory true;
+          status deprecated;
+          description
+            "The length of the subnet prefix.";
+        }
+        leaf origin {
+          type ip-address-origin;
+          status deprecated;
+          description
+            "The origin of this address.";
+        }
+        leaf status {
+          type enumeration {
+            enum preferred {
+              description
+                "This is a valid address that can appear as the
+                 destination or source address of a packet.";
+            }
+            enum deprecated {
+              description
+                "This is a valid but deprecated address that should
+                 no longer be used as a source address in new
+                 communications, but packets addressed to such an
+                 address are processed as expected.";
+            }
+            enum invalid {
+              description
+                "This isn't a valid address, and it shouldn't appear
+                 as the destination or source address of a packet.";
+            }
+
+            enum inaccessible {
+              description
+                "The address is not accessible because the interface
+                 to which this address is assigned is not
+                 operational.";
+            }
+            enum unknown {
+              description
+                "The status cannot be determined for some reason.";
+            }
+            enum tentative {
+              description
+                "The uniqueness of the address on the link is being
+                 verified.  Addresses in this state should not be
+                 used for general communication and should only be
+                 used to determine the uniqueness of the address.";
+            }
+            enum duplicate {
+              description
+                "The address has been determined to be non-unique on
+                 the link and so must not be used.";
+            }
+            enum optimistic {
+              description
+                "The address is available for use, subject to
+                 restrictions, while its uniqueness on a link is
+                 being verified.";
+            }
+          }
+          status deprecated;
+          description
+            "The status of an address.  Most of the states correspond
+             to states from the IPv6 Stateless Address
+             Autoconfiguration protocol.";
+          reference
+            "RFC 4293: Management Information Base for the
+                       Internet Protocol (IP)
+                       - IpAddressStatusTC
+             RFC 4862: IPv6 Stateless Address Autoconfiguration";
+        }
+      }
+
+      list neighbor {
+        key "ip";
+        status deprecated;
+        description
+          "A list of mappings from IPv6 addresses to
+           link-layer addresses.
+
+           This list represents the Neighbor Cache.";
+        reference
+          "RFC 4861: Neighbor Discovery for IP version 6 (IPv6)";
+
+        leaf ip {
+          type inet:ipv6-address-no-zone;
+          status deprecated;
+          description
+            "The IPv6 address of the neighbor node.";
+        }
+        leaf link-layer-address {
+          type yang:phys-address;
+          status deprecated;
+          description
+            "The link-layer address of the neighbor node.";
+        }
+        leaf origin {
+          type neighbor-origin;
+          status deprecated;
+          description
+            "The origin of this neighbor entry.";
+        }
+        leaf is-router {
+          type empty;
+          status deprecated;
+          description
+            "Indicates that the neighbor node acts as a router.";
+        }
+        leaf state {
+          type enumeration {
+            enum incomplete {
+              description
+                "Address resolution is in progress, and the
+                 link-layer address of the neighbor has not yet been
+                 determined.";
+            }
+            enum reachable {
+              description
+                "Roughly speaking, the neighbor is known to have been
+                 reachable recently (within tens of seconds ago).";
+            }
+            enum stale {
+              description
+                "The neighbor is no longer known to be reachable, but
+                 until traffic is sent to the neighbor no attempt
+                 should be made to verify its reachability.";
+            }
+            enum delay {
+              description
+                "The neighbor is no longer known to be reachable, and
+                 traffic has recently been sent to the neighbor.
+                 Rather than probe the neighbor immediately, however,
+                 delay sending probes for a short while in order to
+                 give upper-layer protocols a chance to provide
+                 reachability confirmation.";
+            }
+            enum probe {
+              description
+                "The neighbor is no longer known to be reachable, and
+                 unicast Neighbor Solicitation probes are being sent
+                 to verify reachability.";
+            }
+          }
+          status deprecated;
+          description
+            "The Neighbor Unreachability Detection state of this
+             entry.";
+          reference
+            "RFC 4861: Neighbor Discovery for IP version 6 (IPv6)
+                       Section 7.3.2";
+        }
+      }
+    }
+  }
+}
diff --git a/yang/ietf-network-instance@2019-01-21.yang b/yang/ietf-network-instance@2019-01-21.yang
new file mode 100644
index 0000000..dfde7fb
--- /dev/null
+++ b/yang/ietf-network-instance@2019-01-21.yang
@@ -0,0 +1,282 @@
+module ietf-network-instance {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-network-instance";
+  prefix ni;
+
+  // import some basic types
+
+  import ietf-interfaces {
+    prefix if;
+    reference
+      "RFC 8343: A YANG Data Model for Interface Management";
+  }
+  import ietf-ip {
+    prefix ip;
+    reference
+      "RFC 8344: A YANG Data Model for IP Management";
+  }
+  import ietf-yang-schema-mount {
+    prefix yangmnt;
+    reference
+      "RFC 8528: YANG Schema Mount";
+  }
+
+  organization
+    "IETF Routing Area (rtgwg) Working Group";
+  contact
+    "WG Web:   <https://datatracker.ietf.org/wg/rtgwg>
+     WG List:  <mailto:rtgwg@ietf.org>
+
+     Author:   Lou Berger
+               <mailto:lberger@labn.net>
+     Author:   Christian Hopps
+               <mailto:chopps@chopps.org>
+     Author:   Acee Lindem
+               <mailto:acee@cisco.com>
+     Author:   Dean Bogdanovic
+               <mailto:ivandean@gmail.com>";
+  description
+    "This module is used to support multiple network instances
+     within a single physical or virtual device.  Network
+     instances are commonly known as VRFs (VPN Routing and
+     Forwarding) and VSIs (Virtual Switching Instances).
+     The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL',
+     'SHALL NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED',
+     'NOT RECOMMENDED', 'MAY', and 'OPTIONAL' in this document
+     are to be interpreted as described in BCP 14 (RFC 2119)
+     (RFC 8174) when, and only when, they appear in all capitals,
+      as shown here.
+
+     Copyright (c) 2019 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD
+     License set forth in Section 4.c of the IETF Trust's Legal
+     Provisions Relating to IETF Documents
+     (https://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 8529; see
+     the RFC itself for full legal notices.";
+
+  revision 2019-01-21 {
+    description
+      "Initial revision.";
+    reference
+      "RFC 8529";
+  }
+
+  // top-level device definition statements
+
+  container network-instances {
+    description
+      "Network instances, each of which consists of
+       VRFs and/or VSIs.";
+    reference
+      "RFC 8349: A YANG Data Model for Routing Management";
+    list network-instance {
+      key "name";
+      description
+        "List of network instances.";
+      leaf name {
+        type string;
+        mandatory true;
+        description
+          "device-scoped identifier for the network
+           instance.";
+      }
+      leaf enabled {
+        type boolean;
+        default "true";
+        description
+          "Flag indicating whether or not the network
+           instance is enabled.";
+      }
+      leaf description {
+        type string;
+        description
+          "Description of the network instance
+           and its intended purpose.";
+      }
+      choice ni-type {
+        description
+          "This node serves as an anchor point for different types
+           of network instances.  Each 'case' is expected to
+           differ in terms of the information needed in the
+           parent/core to support the NI and may differ in their
+           mounted-schema definition.  When the mounted schema is
+           not expected to be the same for a specific type of NI,
+           a mount point should be defined.";
+      }
+      choice root-type {
+        mandatory true;
+        description
+          "Well-known mount points.";
+        container vrf-root {
+          description
+            "Container for mount point.";
+          yangmnt:mount-point "vrf-root" {
+            description
+              "Root for L3VPN-type models.  This will typically
+               not be an inline-type mount point.";
+          }
+        }
+        container vsi-root {
+          description
+            "Container for mount point.";
+          yangmnt:mount-point "vsi-root" {
+            description
+              "Root for L2VPN-type models.  This will typically
+               not be an inline-type mount point.";
+          }
+        }
+        container vv-root {
+          description
+            "Container for mount point.";
+          yangmnt:mount-point "vv-root" {
+            description
+              "Root models that support both L2VPN-type bridging
+               and L3VPN-type routing.  This will typically
+               not be an inline-type mount point.";
+          }
+        }
+      }
+    }
+  }
+
+  // augment statements
+
+  augment "/if:interfaces/if:interface" {
+    description
+      "Add a node for the identification of the network
+       instance associated with the information configured
+       on a interface.
+
+       Note that a standard error will be returned if the
+       identified leafref isn't present.  If an interface cannot
+       be assigned for any other reason, the operation SHALL fail
+       with an error-tag of 'operation-failed' and an
+       error-app-tag of 'ni-assignment-failed'.  A meaningful
+       error-info that indicates the source of the assignment
+       failure SHOULD also be provided.";
+    leaf bind-ni-name {
+      type leafref {
+        path "/network-instances/network-instance/name";
+      }
+      description
+        "Network instance to which an interface is bound.";
+    }
+  }
+  augment "/if:interfaces/if:interface/ip:ipv4" {
+    description
+      "Add a node for the identification of the network
+       instance associated with the information configured
+       on an IPv4 interface.
+
+       Note that a standard error will be returned if the
+       identified leafref isn't present.  If an interface cannot
+       be assigned for any other reason, the operation SHALL fail
+       with an error-tag of 'operation-failed' and an
+       error-app-tag of 'ni-assignment-failed'.  A meaningful
+       error-info that indicates the source of the assignment
+       failure SHOULD also be provided.";
+    leaf bind-ni-name {
+      type leafref {
+        path "/network-instances/network-instance/name";
+      }
+      description
+        "Network instance to which IPv4 interface is bound.";
+    }
+  }
+  augment "/if:interfaces/if:interface/ip:ipv6" {
+    description
+      "Add a node for the identification of the network
+       instance associated with the information configured
+       on an IPv6 interface.
+
+       Note that a standard error will be returned if the
+       identified leafref isn't present.  If an interface cannot
+       be assigned for any other reason, the operation SHALL fail
+       with an error-tag of 'operation-failed' and an
+       error-app-tag of 'ni-assignment-failed'.  A meaningful
+       error-info that indicates the source of the assignment
+       failure SHOULD also be provided.";
+    leaf bind-ni-name {
+      type leafref {
+        path "/network-instances/network-instance/name";
+      }
+      description
+        "Network instance to which IPv6 interface is bound.";
+    }
+  }
+
+  // notification statements
+
+  notification bind-ni-name-failed {
+    description
+      "Indicates an error in the association of an interface to an
+       NI.  Only generated after success is initially returned when
+       bind-ni-name is set.
+
+       Note: Some errors may need to be reported for multiple
+       associations, e.g., a single error may need to be reported
+       for an IPv4 and an IPv6 bind-ni-name.
+
+       At least one container with a bind-ni-name leaf MUST be
+       included in this notification.";
+    leaf name {
+      type leafref {
+        path "/if:interfaces/if:interface/if:name";
+      }
+      mandatory true;
+      description
+        "Contains the interface name associated with the
+         failure.";
+    }
+    container interface {
+      description
+        "Generic interface type.";
+      leaf bind-ni-name {
+        type leafref {
+          path "/if:interfaces/if:interface"
+             + "/ni:bind-ni-name";
+        }
+        description
+          "Contains the bind-ni-name associated with the
+           failure.";
+      }
+    }
+    container ipv4 {
+      description
+        "IPv4 interface type.";
+      leaf bind-ni-name {
+        type leafref {
+          path "/if:interfaces/if:interface/ip:ipv4/ni:bind-ni-name";
+        }
+        description
+          "Contains the bind-ni-name associated with the
+           failure.";
+      }
+    }
+    container ipv6 {
+      description
+        "IPv6 interface type.";
+      leaf bind-ni-name {
+        type leafref {
+          path "/if:interfaces/if:interface/ip:ipv6"
+             + "/ni:bind-ni-name";
+        }
+        description
+          "Contains the bind-ni-name associated with the
+           failure.";
+      }
+    }
+    leaf error-info {
+      type string;
+      description
+        "Optionally, indicates the source of the assignment
+         failure.";
+    }
+  }
+}
diff --git a/yang/ietf-restconf-subscribed-notifications@2019-11-17.yang b/yang/ietf-restconf-subscribed-notifications@2019-11-17.yang
new file mode 100644
index 0000000..98a7990
--- /dev/null
+++ b/yang/ietf-restconf-subscribed-notifications@2019-11-17.yang
@@ -0,0 +1,85 @@
+module ietf-restconf-subscribed-notifications {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:"
+          + "ietf-restconf-subscribed-notifications";
+  prefix rsn;
+
+  import ietf-subscribed-notifications {
+    prefix sn;
+  }
+  import ietf-inet-types {
+    prefix inet;
+  }
+
+  organization
+    "IETF NETCONF (Network Configuration) Working Group";
+  contact
+    "WG Web:   <https://datatracker.ietf.org/wg/netconf/>
+     WG List:  <mailto:netconf@ietf.org>
+
+     Editor:   Eric Voit
+               <mailto:evoit@cisco.com>
+
+     Editor:   Alexander Clemm
+               <mailto:ludwig@clemm.org>
+
+     Editor:   Reshad Rahman
+               <mailto:rrahman@cisco.com>";
+  description
+    "Defines RESTCONF as a supported transport for subscribed
+     event notifications.
+
+     Copyright (c) 2019 IETF Trust and the persons identified
+     as authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject to
+     the license terms contained in, the Simplified BSD License set
+     forth in Section 4.c of the IETF Trust's Legal Provisions 
+     Relating to IETF Documents
+     (https://trustee.ietf.org/license-info). 
+
+     This version of this YANG module is part of RFC 8650; see the
+     RFC itself for full legal notices.";
+
+  revision 2019-11-17 {
+    description
+      "Initial version";
+    reference
+      "RFC 8650: Dynamic Subscription to YANG Events and Datastores
+       over RESTCONF";
+  }
+
+  grouping uri {
+    description
+      "Provides a reusable description of a URI.";
+    leaf uri {
+      type inet:uri;
+      config false;
+      description
+        "Location of a subscription-specific URI on the publisher.";
+    }
+  }
+
+  augment "/sn:establish-subscription/sn:output" {
+    description
+      "This augmentation allows RESTCONF-specific parameters for a
+       response to a publisher's subscription request.";
+    uses uri;
+  }
+
+  augment "/sn:subscriptions/sn:subscription" {
+    description
+      "This augmentation allows RESTCONF-specific parameters to be
+       exposed for a subscription.";
+    uses uri;
+  }
+
+  augment "/sn:subscription-modified" {
+    description
+      "This augmentation allows RESTCONF-specific parameters to be
+       included as part of the notification that a subscription has
+       been modified.";
+    uses uri;
+  }
+}
diff --git a/yang/ietf-subscribed-notifications@2019-09-09.yang b/yang/ietf-subscribed-notifications@2019-09-09.yang
new file mode 100644
index 0000000..e04593c
--- /dev/null
+++ b/yang/ietf-subscribed-notifications@2019-09-09.yang
@@ -0,0 +1,1350 @@
+module ietf-subscribed-notifications {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-subscribed-notifications";
+  prefix sn;
+
+  import ietf-inet-types {
+    prefix inet;
+    reference
+      "RFC 6991: Common YANG Data Types";
+  }
+  import ietf-interfaces {
+    prefix if;
+    reference
+      "RFC 8343: A YANG Data Model for Interface Management";
+  }
+  import ietf-netconf-acm {
+    prefix nacm;
+    reference
+      "RFC 8341: Network Configuration Access Control Model";
+  }
+  import ietf-network-instance {
+    prefix ni;
+    reference
+      "RFC 8529: YANG Data Model for Network Instances";
+  }
+  import ietf-restconf {
+    prefix rc;
+    reference
+      "RFC 8040: RESTCONF Protocol";
+  }
+  import ietf-yang-types {
+    prefix yang;
+    reference
+      "RFC 6991: Common YANG Data Types";
+  }
+
+  organization
+    "IETF NETCONF (Network Configuration) Working Group";
+  contact
+    "WG Web:  <https:/datatracker.ietf.org/wg/netconf/>
+     WG List: <mailto:netconf@ietf.org>
+
+     Author:  Alexander Clemm
+              <mailto:ludwig@clemm.org>
+
+     Author:  Eric Voit
+              <mailto:evoit@cisco.com>
+
+     Author:  Alberto Gonzalez Prieto
+              <mailto:alberto.gonzalez@microsoft.com>
+
+     Author:  Einar Nilsen-Nygaard
+              <mailto:einarnn@cisco.com>
+
+     Author:  Ambika Prasad Tripathy
+              <mailto:ambtripa@cisco.com>";
+  description
+    "This module defines a YANG data model for subscribing to event
+     records and receiving matching content in notification messages.
+
+     The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL', 'SHALL
+     NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED', 'NOT RECOMMENDED',
+     'MAY', and 'OPTIONAL' in this document are to be interpreted as
+     described in BCP 14 (RFC 2119) (RFC 8174) when, and only when,
+     they appear in all capitals, as shown here.
+
+     Copyright (c) 2019 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject to
+     the license terms contained in, the Simplified BSD License set
+     forth in Section 4.c of the IETF Trust's Legal Provisions
+     Relating to IETF Documents
+     (https://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 8639; see the
+     RFC itself for full legal notices.";
+
+  revision 2019-09-09 {
+    description
+      "Initial version.";
+    reference
+      "RFC 8639: A YANG Data Model for Subscriptions to
+                 Event Notifications";
+  }
+
+  /*
+   * FEATURES
+   */
+
+  feature configured {
+    description
+      "This feature indicates that configuration of subscriptions is
+       supported.";
+  }
+
+  feature dscp {
+    description
+      "This feature indicates that a publisher supports the ability
+       to set the Differentiated Services Code Point (DSCP) value in
+       outgoing packets.";
+  }
+
+  feature encode-json {
+    description
+      "This feature indicates that JSON encoding of notification
+       messages is supported.";
+  }
+
+  feature encode-xml {
+    description
+      "This feature indicates that XML encoding of notification
+       messages is supported.";
+  }
+
+  feature interface-designation {
+    description
+      "This feature indicates that a publisher supports sourcing all
+       receiver interactions for a configured subscription from a
+       single designated egress interface.";
+  }
+
+  feature qos {
+    description
+      "This feature indicates that a publisher supports absolute
+       dependencies of one subscription's traffic over another
+       as well as weighted bandwidth sharing between subscriptions.
+       Both of these are Quality of Service (QoS) features that allow
+       differentiated treatment of notification messages between a
+       publisher and a specific receiver.";
+  }
+
+  feature replay {
+    description
+      "This feature indicates that historical event record replay is
+       supported.  With replay, it is possible for past event records
+       to be streamed in chronological order.";
+  }
+
+  feature subtree {
+    description
+      "This feature indicates support for YANG subtree filtering.";
+    reference
+      "RFC 6241: Network Configuration Protocol (NETCONF),
+                 Section 6";
+  }
+
+  feature supports-vrf {
+    description
+      "This feature indicates that a publisher supports VRF
+       configuration for configured subscriptions.  VRF support for
+       dynamic subscriptions does not require this feature.";
+    reference
+      "RFC 8529: YANG Data Model for Network Instances,
+                 Section 6";
+  }
+
+  feature xpath {
+    description
+      "This feature indicates support for XPath filtering.";
+    reference
+      "XML Path Language (XPath) Version 1.0
+       (https://www.w3.org/TR/1999/REC-xpath-19991116)";
+  }
+
+  /*
+   * EXTENSIONS
+   */
+
+  extension subscription-state-notification {
+    description
+      "This statement applies only to notifications.  It indicates
+       that the notification is a subscription state change
+       notification.  Therefore, it does not participate in a regular
+       event stream and does not need to be specifically subscribed
+       to in order to be received.  This statement can only occur as
+       a substatement of the YANG 'notification' statement.  This
+       statement is not for use outside of this YANG module.";
+  }
+
+  /*
+   * IDENTITIES
+   */
+  /* Identities for RPC and notification errors */
+
+  identity delete-subscription-error {
+    description
+      "Base identity for the problem found while attempting to
+       fulfill either a 'delete-subscription' RPC request or a
+       'kill-subscription' RPC request.";
+  }
+
+  identity establish-subscription-error {
+    description
+      "Base identity for the problem found while attempting to
+       fulfill an 'establish-subscription' RPC request.";
+  }
+
+  identity modify-subscription-error {
+    description
+      "Base identity for the problem found while attempting to
+       fulfill a 'modify-subscription' RPC request.";
+  }
+
+  identity subscription-suspended-reason {
+    description
+      "Base identity for the problem condition communicated to a
+       receiver as part of a 'subscription-suspended'
+       notification.";
+  }
+
+  identity subscription-terminated-reason {
+    description
+      "Base identity for the problem condition communicated to a
+       receiver as part of a 'subscription-terminated'
+       notification.";
+  }
+
+  identity dscp-unavailable {
+    base establish-subscription-error;
+    if-feature "dscp";
+    description
+      "The publisher is unable to mark notification messages with
+       prioritization information in a way that will be respected
+       during network transit.";
+  }
+
+  identity encoding-unsupported {
+    base establish-subscription-error;
+    description
+      "Unable to encode notification messages in the desired
+       format.";
+  }
+
+  identity filter-unavailable {
+    base subscription-terminated-reason;
+    description
+      "Referenced filter does not exist.  This means a receiver is
+       referencing a filter that doesn't exist or to which it
+       does not have access permissions.";
+  }
+
+  identity filter-unsupported {
+    base establish-subscription-error;
+    base modify-subscription-error;
+    description
+      "Cannot parse syntax in the filter.  This failure can be from
+       a syntax error or a syntax too complex to be processed by the
+       publisher.";
+  }
+
+  identity insufficient-resources {
+    base establish-subscription-error;
+    base modify-subscription-error;
+    base subscription-suspended-reason;
+    description
+      "The publisher does not have sufficient resources to support
+       the requested subscription.  An example might be that
+       allocated CPU is too limited to generate the desired set of
+       notification messages.";
+  }
+
+  identity no-such-subscription {
+    base modify-subscription-error;
+    base delete-subscription-error;
+    base subscription-terminated-reason;
+    description
+      "Referenced subscription doesn't exist.  This may be as a
+       result of a nonexistent subscription ID, an ID that belongs to
+       another subscriber, or an ID for a configured subscription.";
+  }
+
+  identity replay-unsupported {
+    base establish-subscription-error;
+    if-feature "replay";
+    description
+      "Replay cannot be performed for this subscription.  This means
+       the publisher will not provide the requested historic
+       information from the event stream via replay to this
+       receiver.";
+  }
+
+  identity stream-unavailable {
+    base subscription-terminated-reason;
+    description
+      "Not a subscribable event stream.  This means the referenced
+       event stream is not available for subscription by the
+       receiver.";
+  }
+
+  identity suspension-timeout {
+    base subscription-terminated-reason;
+    description
+      "Termination of a previously suspended subscription.  The
+       publisher has eliminated the subscription, as it exceeded a
+       time limit for suspension.";
+  }
+
+  identity unsupportable-volume {
+    base subscription-suspended-reason;
+    description
+      "The publisher does not have the network bandwidth needed to
+       get the volume of generated information intended for a
+       receiver.";
+  }
+
+  /* Identities for encodings */
+
+  identity configurable-encoding {
+    description
+      "If a transport identity derives from this identity, it means
+       that it supports configurable encodings.  An example of a
+       configurable encoding might be a new identity such as
+       'encode-cbor'.  Such an identity could use
+       'configurable-encoding' as its base.  This would allow a
+       dynamic subscription encoded in JSON (RFC 8259) to request
+       that notification messages be encoded via the Concise Binary
+       Object Representation (CBOR) (RFC 7049).  Further details for
+       any specific configurable encoding would be explored in a
+       transport document based on this specification.";
+    reference
+      "RFC 8259: The JavaScript Object Notation (JSON) Data
+                 Interchange Format
+       RFC 7049: Concise Binary Object Representation (CBOR)";
+  }
+
+  identity encoding {
+    description
+      "Base identity to represent data encodings.";
+  }
+
+  identity encode-xml {
+    base encoding;
+    if-feature "encode-xml";
+    description
+      "Encode data using XML as described in RFC 7950.";
+    reference
+      "RFC 7950: The YANG 1.1 Data Modeling Language";
+  }
+
+  identity encode-json {
+    base encoding;
+    if-feature "encode-json";
+    description
+      "Encode data using JSON as described in RFC 7951.";
+    reference
+      "RFC 7951: JSON Encoding of Data Modeled with YANG";
+  }
+
+  /* Identities for transports */
+
+  identity transport {
+    description
+      "An identity that represents the underlying mechanism for
+       passing notification messages.";
+  }
+
+  /*
+   * TYPEDEFs
+   */
+
+  typedef encoding {
+    type identityref {
+      base encoding;
+    }
+    description
+      "Specifies a data encoding, e.g., for a data subscription.";
+  }
+
+  typedef stream-filter-ref {
+    type leafref {
+      path "/sn:filters/sn:stream-filter/sn:name";
+    }
+    description
+      "This type is used to reference an event stream filter.";
+  }
+
+  typedef stream-ref {
+    type leafref {
+      path "/sn:streams/sn:stream/sn:name";
+    }
+    description
+      "This type is used to reference a system-provided
+       event stream.";
+  }
+
+  typedef subscription-id {
+    type uint32;
+    description
+      "A type for subscription identifiers.";
+  }
+
+  typedef transport {
+    type identityref {
+      base transport;
+    }
+    description
+      "Specifies the transport used to send notification messages
+       to a receiver.";
+  }
+
+  /*
+   * GROUPINGS
+   */
+
+  grouping stream-filter-elements {
+    description
+      "This grouping defines the base for filters applied to event
+       streams.";
+    choice filter-spec {
+      description
+        "The content filter specification for this request.";
+      anydata stream-subtree-filter {
+        if-feature "subtree";
+        description
+          "Event stream evaluation criteria encoded in the syntax of
+           a subtree filter as defined in RFC 6241, Section 6.
+
+           The subtree filter is applied to the representation of
+           individual, delineated event records as contained in the
+           event stream.
+
+           If the subtree filter returns a non-empty node set, the
+           filter matches the event record, and the event record is
+           included in the notification message sent to the
+           receivers.";
+        reference
+          "RFC 6241: Network Configuration Protocol (NETCONF),
+                     Section 6";
+      }
+      leaf stream-xpath-filter {
+        if-feature "xpath";
+        type yang:xpath1.0;
+        description
+          "Event stream evaluation criteria encoded in the syntax of
+           an XPath 1.0 expression.
+
+           The XPath expression is evaluated on the representation of
+           individual, delineated event records as contained in
+           the event stream.
+
+           The result of the XPath expression is converted to a
+           boolean value using the standard XPath 1.0 rules.  If the
+           boolean value is 'true', the filter matches the event
+           record, and the event record is included in the
+           notification message sent to the receivers.
+
+           The expression is evaluated in the following XPath
+           context:
+
+              o  The set of namespace declarations is the set of
+                 prefix and namespace pairs for all YANG modules
+                 implemented by the server, where the prefix is the
+                 YANG module name and the namespace is as defined by
+                 the 'namespace' statement in the YANG module.
+
+                 If the leaf is encoded in XML, all namespace
+                 declarations in scope on the 'stream-xpath-filter'
+                 leaf element are added to the set of namespace
+                 declarations.  If a prefix found in the XML is
+                 already present in the set of namespace
+                 declarations, the namespace in the XML is used.
+
+              o  The set of variable bindings is empty.
+
+              o  The function library is comprised of the core
+                 function library and the XPath functions defined in
+                 Section 10 in RFC 7950.
+
+              o  The context node is the root node.";
+        reference
+          "XML Path Language (XPath) Version 1.0
+           (https://www.w3.org/TR/1999/REC-xpath-19991116)
+           RFC 7950: The YANG 1.1 Data Modeling Language,
+                     Section 10";
+      }
+    }
+  }
+
+  grouping update-qos {
+    description
+      "This grouping describes QoS information concerning a
+       subscription.  This information is passed to lower layers
+       for transport prioritization and treatment.";
+    leaf dscp {
+      if-feature "dscp";
+      type inet:dscp;
+      default "0";
+      description
+        "The desired network transport priority level.  This is the
+         priority set on notification messages encapsulating the
+         results of the subscription.  This transport priority is
+         shared for all receivers of a given subscription.";
+    }
+    leaf weighting {
+      if-feature "qos";
+      type uint8 {
+        range "0 .. 255";
+      }
+      description
+        "Relative weighting for a subscription.  Larger weights get
+         more resources.  Allows an underlying transport layer to
+         perform informed load-balance allocations between various
+         subscriptions.";
+      reference
+        "RFC 7540: Hypertext Transfer Protocol Version 2 (HTTP/2),
+                   Section 5.3.2";
+    }
+    leaf dependency {
+      if-feature "qos";
+      type subscription-id;
+      description
+        "Provides the 'subscription-id' of a parent subscription.
+         The parent subscription has absolute precedence should
+         that parent have push updates ready to egress the publisher.
+         In other words, there should be no streaming of objects from
+         the current subscription if the parent has something ready
+         to push.
+
+         If a dependency is asserted via configuration or via an RPC
+         but the referenced 'subscription-id' does not exist, the
+         dependency is silently discarded.  If a referenced
+         subscription is deleted, this dependency is removed.";
+      reference
+        "RFC 7540: Hypertext Transfer Protocol Version 2 (HTTP/2),
+                   Section 5.3.1";
+    }
+  }
+
+  grouping subscription-policy-modifiable {
+    description
+      "This grouping describes all objects that may be changed
+       in a subscription.";
+    choice target {
+      mandatory true;
+      description
+        "Identifies the source of information against which a
+         subscription is being applied as well as specifics on the
+         subset of information desired from that source.";
+      case stream {
+        choice stream-filter {
+          description
+            "An event stream filter can be applied to a subscription.
+             That filter will either come referenced from a global
+             list or be provided in the subscription itself.";
+          case by-reference {
+            description
+              "Apply a filter that has been configured separately.";
+            leaf stream-filter-name {
+              type stream-filter-ref;
+              mandatory true;
+              description
+                "References an existing event stream filter that is
+                 to be applied to an event stream for the
+                 subscription.";
+            }
+          }
+          case within-subscription {
+            description
+              "A local definition allows a filter to have the same
+               lifecycle as the subscription.";
+            uses stream-filter-elements;
+          }
+        }
+      }
+    }
+    leaf stop-time {
+      type yang:date-and-time;
+      description
+        "Identifies a time after which notification messages for a
+         subscription should not be sent.  If 'stop-time' is not
+         present, the notification messages will continue until the
+         subscription is terminated.  If 'replay-start-time' exists,
+         'stop-time' must be for a subsequent time.  If
+         'replay-start-time' doesn't exist, 'stop-time', when
+         established, must be for a future time.";
+    }
+  }
+
+  grouping subscription-policy-dynamic {
+    description
+      "This grouping describes the only information concerning a
+       subscription that can be passed over the RPCs defined in this
+       data model.";
+    uses subscription-policy-modifiable {
+      augment "target/stream" {
+        description
+          "Adds additional objects that can be modified by an RPC.";
+        leaf stream {
+          type stream-ref {
+            require-instance false;
+          }
+          mandatory true;
+          description
+            "Indicates the event stream to be considered for
+             this subscription.";
+        }
+        leaf replay-start-time {
+          if-feature "replay";
+          type yang:date-and-time;
+          config false;
+          description
+            "Used to trigger the 'replay' feature for a dynamic
+             subscription, where event records that are selected
+             need to be at or after the specified starting time.  If
+             'replay-start-time' is not present, this is not a replay
+             subscription and event record push should start
+             immediately.  It is never valid to specify start times
+             that are later than or equal to the current time.";
+        }
+      }
+    }
+    uses update-qos;
+  }
+
+  grouping subscription-policy {
+    description
+      "This grouping describes the full set of policy information
+       concerning both dynamic and configured subscriptions, with the
+       exclusion of both receivers and networking information
+       specific to the publisher, such as what interface should be
+       used to transmit notification messages.";
+    uses subscription-policy-dynamic;
+    leaf transport {
+      if-feature "configured";
+      type transport;
+      description
+        "For a configured subscription, this leaf specifies the
+         transport used to deliver messages destined for all
+         receivers of that subscription.";
+    }
+    leaf encoding {
+      when 'not(../transport) or derived-from(../transport,
+      "sn:configurable-encoding")';
+      type encoding;
+      description
+        "The type of encoding for notification messages.  For a
+         dynamic subscription, if not included as part of an
+         'establish-subscription' RPC, the encoding will be populated
+         with the encoding used by that RPC.  For a configured
+         subscription, if not explicitly configured, the encoding
+         will be the default encoding for an underlying transport.";
+    }
+    leaf purpose {
+      if-feature "configured";
+      type string;
+      description
+        "Open text allowing a configuring entity to embed the
+         originator or other specifics of this subscription.";
+    }
+  }
+
+  /*
+   * RPCs
+   */
+
+  rpc establish-subscription {
+    description
+      "This RPC allows a subscriber to create (and possibly
+       negotiate) a subscription on its own behalf.  If successful,
+       the subscription remains in effect for the duration of the
+       subscriber's association with the publisher or until the
+       subscription is terminated.  If an error occurs or the
+       publisher cannot meet the terms of a subscription, an RPC
+       error is returned, and the subscription is not created.
+       In that case, the RPC reply's 'error-info' MAY include
+       suggested parameter settings that would have a higher
+       likelihood of succeeding in a subsequent
+       'establish-subscription' request.";
+    input {
+      uses subscription-policy-dynamic;
+      leaf encoding {
+        type encoding;
+        description
+          "The type of encoding for the subscribed data.  If not
+           included as part of the RPC, the encoding MUST be set by
+           the publisher to be the encoding used by this RPC.";
+      }
+    }
+    output {
+      leaf id {
+        type subscription-id;
+        mandatory true;
+        description
+          "Identifier used for this subscription.";
+      }
+      leaf replay-start-time-revision {
+        if-feature "replay";
+        type yang:date-and-time;
+        description
+          "If a replay has been requested, this object represents
+           the earliest time covered by the event buffer for the
+           requested event stream.  The value of this object is the
+           'replay-log-aged-time' if it exists.  Otherwise, it is
+           the 'replay-log-creation-time'.  All buffered event
+           records after this time will be replayed to a receiver.
+           This object will only be sent if the starting time has
+           been revised to be later than the time requested by the
+           subscriber.";
+      }
+    }
+  }
+
+  rc:yang-data establish-subscription-stream-error-info {
+    container establish-subscription-stream-error-info {
+      description
+        "If any 'establish-subscription' RPC parameters are
+         unsupportable against the event stream, a subscription
+         is not created and the RPC error response MUST indicate the
+         reason why the subscription failed to be created.  This
+         yang-data MAY be inserted as structured data in a
+         subscription's RPC error response to indicate the reason for
+         the failure.  This yang-data MUST be inserted if hints are
+         to be provided back to the subscriber.";
+      leaf reason {
+        type identityref {
+          base establish-subscription-error;
+        }
+        description
+          "Indicates the reason why the subscription has failed to
+           be created to a targeted event stream.";
+      }
+      leaf filter-failure-hint {
+        type string;
+        description
+          "Information describing where and/or why a provided
+           filter was unsupportable for a subscription.  The
+           syntax and semantics of this hint are
+           implementation specific.";
+      }
+    }
+  }
+
+  rpc modify-subscription {
+    description
+      "This RPC allows a subscriber to modify a dynamic
+       subscription's parameters.  If successful, the changed
+       subscription parameters remain in effect for the duration of
+       the subscription, until the subscription is again modified, or
+       until the subscription is terminated.  In the case of an error
+       or an inability to meet the modified parameters, the
+       subscription is not modified and the original subscription
+       parameters remain in effect.  In that case, the RPC error MAY
+       include 'error-info' suggested parameter hints that would have
+       a high likelihood of succeeding in a subsequent
+       'modify-subscription' request.  A successful
+       'modify-subscription' will return a suspended subscription to
+       the 'active' state.";
+    input {
+      leaf id {
+        type subscription-id;
+        mandatory true;
+        description
+          "Identifier to use for this subscription.";
+      }
+      uses subscription-policy-modifiable;
+    }
+  }
+
+  rc:yang-data modify-subscription-stream-error-info {
+    container modify-subscription-stream-error-info {
+      description
+        "This yang-data MAY be provided as part of a subscription's
+         RPC error response when there is a failure of a
+         'modify-subscription' RPC that has been made against an
+         event stream.  This yang-data MUST be used if hints are to
+         be provided back to the subscriber.";
+      leaf reason {
+        type identityref {
+          base modify-subscription-error;
+        }
+        description
+          "Information in a 'modify-subscription' RPC error response
+           that indicates the reason why the subscription to an event
+           stream has failed to be modified.";
+      }
+      leaf filter-failure-hint {
+        type string;
+        description
+          "Information describing where and/or why a provided
+           filter was unsupportable for a subscription.  The syntax
+           and semantics of this hint are
+           implementation specific.";
+      }
+    }
+  }
+
+  rpc delete-subscription {
+    description
+      "This RPC allows a subscriber to delete a subscription that
+       was previously created by that same subscriber using the
+       'establish-subscription' RPC.
+
+       If an error occurs, the server replies with an 'rpc-error'
+       where the 'error-info' field MAY contain a
+       'delete-subscription-error-info' structure.";
+    input {
+      leaf id {
+        type subscription-id;
+        mandatory true;
+        description
+          "Identifier of the subscription that is to be deleted.
+           Only subscriptions that were created using
+           'establish-subscription' from the same origin as this RPC
+           can be deleted via this RPC.";
+      }
+    }
+  }
+
+  rpc kill-subscription {
+    nacm:default-deny-all;
+    description
+      "This RPC allows an operator to delete a dynamic subscription
+       without restrictions on the originating subscriber or
+       underlying transport session.
+
+       If an error occurs, the server replies with an 'rpc-error'
+       where the 'error-info' field MAY contain a
+       'delete-subscription-error-info' structure.";
+    input {
+      leaf id {
+        type subscription-id;
+        mandatory true;
+        description
+          "Identifier of the subscription that is to be deleted.
+           Only subscriptions that were created using
+           'establish-subscription' can be deleted via this RPC.";
+      }
+    }
+  }
+
+  rc:yang-data delete-subscription-error-info {
+    container delete-subscription-error-info {
+      description
+        "If a 'delete-subscription' RPC or a 'kill-subscription' RPC
+         fails, the subscription is not deleted and the RPC error
+         response MUST indicate the reason for this failure.  This
+         yang-data MAY be inserted as structured data in a
+         subscription's RPC error response to indicate the reason
+         for the failure.";
+      leaf reason {
+        type identityref {
+          base delete-subscription-error;
+        }
+        mandatory true;
+        description
+          "Indicates the reason why the subscription has failed to be
+           deleted.";
+      }
+    }
+  }
+
+  /*
+   * NOTIFICATIONS
+   */
+
+  notification replay-completed {
+    sn:subscription-state-notification;
+    if-feature "replay";
+    description
+      "This notification is sent to indicate that all of the replay
+       notifications have been sent.";
+    leaf id {
+      type subscription-id;
+      mandatory true;
+      description
+        "This references the affected subscription.";
+    }
+  }
+
+  notification subscription-completed {
+    sn:subscription-state-notification;
+    if-feature "configured";
+    description
+      "This notification is sent to indicate that a subscription has
+       finished passing event records, as the 'stop-time' has been
+       reached.";
+    leaf id {
+      type subscription-id;
+      mandatory true;
+      description
+        "This references the gracefully completed subscription.";
+    }
+  }
+
+  notification subscription-modified {
+    sn:subscription-state-notification;
+    description
+      "This notification indicates that a subscription has been
+       modified.  Notification messages sent from this point on will
+       conform to the modified terms of the subscription.  For
+       completeness, this subscription state change notification
+       includes both modified and unmodified aspects of a
+       subscription.";
+    leaf id {
+      type subscription-id;
+      mandatory true;
+      description
+        "This references the affected subscription.";
+    }
+    uses subscription-policy {
+      refine "target/stream/stream-filter/within-subscription" {
+        description
+          "Filter applied to the subscription.  If the
+           'stream-filter-name' is populated, the filter in the
+           subscription came from the 'filters' container.
+           Otherwise, it is populated in-line as part of the
+           subscription.";
+      }
+    }
+  }
+
+  notification subscription-resumed {
+    sn:subscription-state-notification;
+    description
+      "This notification indicates that a subscription that had
+       previously been suspended has resumed.  Notifications will
+       once again be sent.  In addition, a 'subscription-resumed'
+       indicates that no modification of parameters has occurred
+       since the last time event records have been sent.";
+    leaf id {
+      type subscription-id;
+      mandatory true;
+      description
+        "This references the affected subscription.";
+    }
+  }
+
+  notification subscription-started {
+    sn:subscription-state-notification;
+    if-feature "configured";
+    description
+      "This notification indicates that a subscription has started
+       and notifications will now be sent.";
+    leaf id {
+      type subscription-id;
+      mandatory true;
+      description
+        "This references the affected subscription.";
+    }
+    uses subscription-policy {
+      refine "target/stream/replay-start-time" {
+        description
+          "Indicates the time that a replay is using for the
+           streaming of buffered event records.  This will be
+           populated with the most recent of the following:
+           the event time of the previous event record sent to a
+           receiver, the 'replay-log-creation-time', the
+           'replay-log-aged-time', or the most recent publisher
+           boot time.";
+      }
+      refine "target/stream/stream-filter/within-subscription" {
+        description
+          "Filter applied to the subscription.  If the
+           'stream-filter-name' is populated, the filter in the
+           subscription came from the 'filters' container.
+           Otherwise, it is populated in-line as part of the
+           subscription.";
+      }
+      augment "target/stream" {
+        description
+          "This augmentation adds additional parameters specific to a
+           'subscription-started' notification.";
+        leaf replay-previous-event-time {
+          when '../replay-start-time';
+          if-feature "replay";
+          type yang:date-and-time;
+          description
+            "If there is at least one event in the replay buffer
+             prior to 'replay-start-time', this gives the time of
+             the event generated immediately prior to the
+             'replay-start-time'.
+
+             If a receiver previously received event records for
+             this configured subscription, it can compare this time
+             to the last event record previously received.  If the
+             two are not the same (perhaps due to a reboot), then a
+             dynamic replay can be initiated to acquire any missing
+             event records.";
+        }
+      }
+    }
+  }
+
+  notification subscription-suspended {
+    sn:subscription-state-notification;
+    description
+      "This notification indicates that a suspension of the
+       subscription by the publisher has occurred.  No further
+       notifications will be sent until the subscription resumes.
+       This notification shall only be sent to receivers of a
+       subscription; it does not constitute a general-purpose
+       notification.";
+    leaf id {
+      type subscription-id;
+      mandatory true;
+      description
+        "This references the affected subscription.";
+    }
+    leaf reason {
+      type identityref {
+        base subscription-suspended-reason;
+      }
+      mandatory true;
+      description
+        "Identifies the condition that resulted in the suspension.";
+    }
+  }
+
+  notification subscription-terminated {
+    sn:subscription-state-notification;
+    description
+      "This notification indicates that a subscription has been
+       terminated.";
+    leaf id {
+      type subscription-id;
+      mandatory true;
+      description
+        "This references the affected subscription.";
+    }
+    leaf reason {
+      type identityref {
+        base subscription-terminated-reason;
+      }
+      mandatory true;
+      description
+        "Identifies the condition that resulted in the termination.";
+    }
+  }
+
+  /*
+   * DATA NODES
+   */
+
+  container streams {
+    config false;
+    description
+      "Contains information on the built-in event streams provided by
+       the publisher.";
+    list stream {
+      key "name";
+      description
+        "Identifies the built-in event streams that are supported by
+         the publisher.";
+      leaf name {
+        type string;
+        description
+          "A handle for a system-provided event stream made up of a
+           sequential set of event records, each of which is
+           characterized by its own domain and semantics.";
+      }
+      leaf description {
+        type string;
+        description
+          "A description of the event stream, including such
+           information as the type of event records that are
+           available in this event stream.";
+      }
+      leaf replay-support {
+        if-feature "replay";
+        type empty;
+        description
+          "Indicates that event record replay is available on this
+           event stream.";
+      }
+      leaf replay-log-creation-time {
+        when '../replay-support';
+        if-feature "replay";
+        type yang:date-and-time;
+        mandatory true;
+        description
+          "The timestamp of the creation of the log used to support
+           the replay function on this event stream.  This time
+           might be earlier than the earliest available information
+           contained in the log.  This object is updated if the log
+           resets for some reason.";
+      }
+      leaf replay-log-aged-time {
+        when '../replay-support';
+        if-feature "replay";
+        type yang:date-and-time;
+        description
+          "The timestamp associated with the last event record that
+           has been aged out of the log.  This timestamp identifies
+           how far back in history this replay log extends, if it
+           doesn't extend back to the 'replay-log-creation-time'.
+           This object MUST be present if replay is supported and any
+           event records have been aged out of the log.";
+      }
+    }
+  }
+  container filters {
+    description
+      "Contains a list of configurable filters that can be applied to
+       subscriptions.  This facilitates the reuse of complex filters
+       once defined.";
+    list stream-filter {
+      key "name";
+      description
+        "A list of preconfigured filters that can be applied to
+         subscriptions.";
+      leaf name {
+        type string;
+        description
+          "A name to differentiate between filters.";
+      }
+      uses stream-filter-elements;
+    }
+  }
+  container subscriptions {
+    description
+      "Contains the list of currently active subscriptions, i.e.,
+       subscriptions that are currently in effect, used for
+       subscription management and monitoring purposes.  This
+       includes subscriptions that have been set up via
+       RPC primitives as well as subscriptions that have been
+       established via configuration.";
+    list subscription {
+      key "id";
+      description
+        "The identity and specific parameters of a subscription.
+         Subscriptions in this list can be created using a control
+         channel or RPC or can be established through configuration.
+
+         If the 'kill-subscription' RPC or configuration operations
+         are used to delete a subscription, a
+         'subscription-terminated' message is sent to any active or
+         suspended receivers.";
+      leaf id {
+        type subscription-id;
+        description
+          "Identifier of a subscription; unique in a given
+           publisher.";
+      }
+      uses subscription-policy {
+        refine "target/stream/stream" {
+          description
+            "Indicates the event stream to be considered for this
+             subscription.  If an event stream has been removed
+             and can no longer be referenced by an active
+             subscription, send a 'subscription-terminated'
+             notification with 'stream-unavailable' as the reason.
+             If a configured subscription refers to a nonexistent
+             event stream, move that subscription to the
+             'invalid' state.";
+        }
+        refine "transport" {
+          description
+            "For a configured subscription, this leaf specifies the
+             transport used to deliver messages destined for all
+             receivers of that subscription.  This object is
+             mandatory for subscriptions in the configuration
+             datastore.  This object (1) is not mandatory for dynamic
+             subscriptions in the operational state datastore and
+             (2) should not be present for other types of dynamic
+             subscriptions.";
+        }
+        augment "target/stream" {
+          description
+            "Enables objects to be added to a configured stream
+             subscription.";
+          leaf configured-replay {
+            if-feature "configured";
+            if-feature "replay";
+            type empty;
+            description
+              "The presence of this leaf indicates that replay for
+               the configured subscription should start at the
+               earliest time in the event log or at the publisher
+               boot time, whichever is later.";
+          }
+        }
+      }
+      choice notification-message-origin {
+        if-feature "configured";
+        description
+          "Identifies the egress interface on the publisher
+           from which notification messages are to be sent.";
+        case interface-originated {
+          description
+            "When notification messages are to egress a specific,
+             designated interface on the publisher.";
+          leaf source-interface {
+            if-feature "interface-designation";
+            type if:interface-ref;
+            description
+              "References the interface for notification messages.";
+          }
+        }
+        case address-originated {
+          description
+            "When notification messages are to depart from a
+             publisher using a specific originating address and/or
+             routing context information.";
+          leaf source-vrf {
+            if-feature "supports-vrf";
+            type leafref {
+              path "/ni:network-instances/ni:network-instance/ni:name";
+            }
+            description
+              "VRF from which notification messages should egress a
+               publisher.";
+          }
+          leaf source-address {
+            type inet:ip-address-no-zone;
+            description
+              "The source address for the notification messages.
+               If a source VRF exists but this object doesn't, a
+               publisher's default address for that VRF must
+               be used.";
+          }
+        }
+      }
+      leaf configured-subscription-state {
+        if-feature "configured";
+        type enumeration {
+          enum valid {
+            value 1;
+            description
+              "The subscription is supportable with its current
+               parameters.";
+          }
+          enum invalid {
+            value 2;
+            description
+              "The subscription as a whole is unsupportable with its
+               current parameters.";
+          }
+          enum concluded {
+            value 3;
+            description
+              "A subscription is inactive, as it has hit a
+               stop time.  It no longer has receivers in the
+               'active' or 'suspended' state, but the subscription
+               has not yet been removed from configuration.";
+          }
+        }
+        config false;
+        description
+          "The presence of this leaf indicates that the subscription
+           originated from configuration, not through a control
+           channel or RPC.  The value indicates the state of the
+           subscription as established by the publisher.";
+      }
+      container receivers {
+        description
+          "Set of receivers in a subscription.";
+        list receiver {
+          key "name";
+          min-elements 1;
+          description
+            "A host intended as a recipient for the notification
+             messages of a subscription.  For configured
+             subscriptions, transport-specific network parameters
+             (or a leafref to those parameters) may be augmented to a
+             specific receiver in this list.";
+          leaf name {
+            type string;
+            description
+              "Identifies a unique receiver for a subscription.";
+          }
+          leaf sent-event-records {
+            type yang:zero-based-counter64;
+            config false;
+            description
+              "The number of event records sent to the receiver.  The
+               count is initialized when a dynamic subscription is
+               established or when a configured receiver
+               transitions to the 'valid' state.";
+          }
+          leaf excluded-event-records {
+            type yang:zero-based-counter64;
+            config false;
+            description
+              "The number of event records explicitly removed via
+               either an event stream filter or an access control
+               filter so that they are not passed to a receiver.
+               This count is set to zero each time
+               'sent-event-records' is initialized.";
+          }
+          leaf state {
+            type enumeration {
+              enum active {
+                value 1;
+                description
+                  "The receiver is currently being sent any
+                   applicable notification messages for the
+                   subscription.";
+              }
+              enum suspended {
+                value 2;
+                description
+                  "The receiver state is 'suspended', so the
+                   publisher is currently unable to provide
+                   notification messages for the subscription.";
+              }
+              enum connecting {
+                value 3;
+                if-feature "configured";
+                description
+                  "A subscription has been configured, but a
+                   'subscription-started' subscription state change
+                   notification needs to be successfully received
+                   before notification messages are sent.
+
+                   If the 'reset' action is invoked for a receiver of
+                   an active configured subscription, the state
+                   must be moved to 'connecting'.";
+              }
+              enum disconnected {
+                value 4;
+                if-feature "configured";
+                description
+                  "A subscription has failed to send a
+                   'subscription-started' state change to the
+                   receiver.  Additional connection attempts are not
+                   currently being made.";
+              }
+            }
+            config false;
+            mandatory true;
+            description
+              "Specifies the state of a subscription from the
+               perspective of a particular receiver.  With this
+               information, it is possible to determine whether a
+               publisher is currently generating notification
+               messages intended for that receiver.";
+          }
+          action reset {
+            if-feature "configured";
+            description
+              "Allows the reset of this configured subscription's
+               receiver to the 'connecting' state.  This enables the
+               connection process to be reinitiated.";
+            output {
+              leaf time {
+                type yang:date-and-time;
+                mandatory true;
+                description
+                  "Time at which a publisher returned the receiver to
+                   the 'connecting' state.";
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
-- 
2.43.0

