Add ietf-netconf-client/sever yang models 36/106436/7
authorRuslan Kashapov <ruslan.kashapov@pantheon.tech>
Fri, 9 Jun 2023 09:33:37 +0000 (12:33 +0300)
committerRuslan Kashapov <ruslan.kashapov@pantheon.tech>
Mon, 26 Jun 2023 07:51:08 +0000 (10:51 +0300)
Added models: ietf-netconf-client, ietf-netconf-server,
ietf-x509-cert-to-name (new rfc7407 module)

JIRA: NETCONF-590
Change-Id: I7e4880339c599bce6932bd952283129e341adac1
Signed-off-by: Ruslan Kashapov <ruslan.kashapov@pantheon.tech>
artifacts/pom.xml
features/odl-netconf-client/pom.xml
features/odl-netconf-impl/pom.xml
model/pom.xml
model/rfc7407-ietf-x509-cert-to-name/pom.xml [new file with mode: 0644]
model/rfc7407-ietf-x509-cert-to-name/src/main/yang/ietf-x509-cert-to-name@2014-12-10.yang [new file with mode: 0644]
protocol/netconf-client/pom.xml
protocol/netconf-client/src/main/yang/ietf-netconf-client@2023-04-17.yang [new file with mode: 0644]
protocol/netconf-server/pom.xml
protocol/netconf-server/src/main/yang/ietf-netconf-server@2023-04-17.yang [new file with mode: 0644]

index 4431099bf69f11a4624b7b419b0097a4cd3a9063..c858ac60dd4987d7af36a311cf5f59be82e04eda 100644 (file)
                 <artifactId>rfc8639</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <!-- RFC7407 A YANG Data Model for SNMP Configuration -->
+            <dependency>
+                <groupId>org.opendaylight.netconf.model</groupId>
+                <artifactId>rfc7407-ietf-x509-cert-to-name</artifactId>
+                <version>${project.version}</version>
+            </dependency>
 
             <!-- draft-ietf-netconf-crypto-types -->
             <dependency>
index fd30965b13b7d84266e822651e63b6ce5d71772f..2702d7bda23c4f969075e2bb43917742dbc08193 100644 (file)
             <type>xml</type>
             <classifier>features</classifier>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.netconf</groupId>
+            <artifactId>odl-netconf-transport</artifactId>
+            <type>xml</type>
+            <classifier>features</classifier>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.netconf</groupId>
             <artifactId>netconf-client</artifactId>
index 833dc06fade7d42f64b374f308d347e5abac1542..beee90b1eff5aeea9f0485fd07c996651174a3c1 100644 (file)
             <type>xml</type>
             <classifier>features</classifier>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.netconf</groupId>
+            <artifactId>odl-netconf-transport</artifactId>
+            <type>xml</type>
+            <classifier>features</classifier>
+        </dependency>
 
         <dependency>
             <groupId>org.opendaylight.netconf</groupId>
index 0a6fb0b69ec3ebc357ce06c2861691541728f69d..01fd451453eb41e4a3110d4995c0eddca3efd96a 100644 (file)
@@ -34,6 +34,7 @@
         <module>rfc6241</module>
         <module>rfc6243</module>
         <module>rfc6470</module>
+        <module>rfc7407-ietf-x509-cert-to-name</module>
         <module>rfc8040-ietf-restconf-monitoring</module>
         <module>rfc8341</module>
         <module>rfc8526</module>
diff --git a/model/rfc7407-ietf-x509-cert-to-name/pom.xml b/model/rfc7407-ietf-x509-cert-to-name/pom.xml
new file mode 100644 (file)
index 0000000..0d6d455
--- /dev/null
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (c) 2023 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+  ~
+  ~ This program and the accompanying materials are made available under the
+  ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+  ~ and is available at http://www.eclipse.org/legal/epl-v10.html
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.netconf</groupId>
+        <artifactId>netconf-parent</artifactId>
+        <version>6.0.0-SNAPSHOT</version>
+        <relativePath>../../parent</relativePath>
+    </parent>
+
+    <groupId>org.opendaylight.netconf.model</groupId>
+    <artifactId>rfc7407-ietf-x509-cert-to-name</artifactId>
+    <packaging>bundle</packaging>
+    <name>${project.artifactId}</name>
+    <description>RFC-7407: A YANG Data Model for SNMP Configuration</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal.binding.model.ietf</groupId>
+            <artifactId>rfc6991-ietf-yang-types</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/model/rfc7407-ietf-x509-cert-to-name/src/main/yang/ietf-x509-cert-to-name@2014-12-10.yang b/model/rfc7407-ietf-x509-cert-to-name/src/main/yang/ietf-x509-cert-to-name@2014-12-10.yang
new file mode 100644 (file)
index 0000000..cbc9be2
--- /dev/null
@@ -0,0 +1,303 @@
+module ietf-x509-cert-to-name {
+
+  namespace "urn:ietf:params:xml:ns:yang:ietf-x509-cert-to-name";
+  prefix x509c2n;
+
+  import ietf-yang-types {
+    prefix yang;
+  }
+
+  organization
+    "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+  contact
+    "WG Web:   <http://tools.ietf.org/wg/netmod/>
+     WG List:  <mailto:netmod@ietf.org>
+
+     WG Chair: Thomas Nadeau
+               <mailto:tnadeau@lucidvision.com>
+
+     WG Chair: Juergen Schoenwaelder
+               <mailto:j.schoenwaelder@jacobs-university.de>
+
+     Editor:   Martin Bjorklund
+               <mailto:mbj@tail-f.com>
+
+     Editor:   Juergen Schoenwaelder
+               <mailto:j.schoenwaelder@jacobs-university.de>";
+
+  description
+    "This module contains a collection of YANG definitions for
+     extracting a name from an X.509 certificate.
+     The algorithm used to extract a name from an X.509 certificate
+     was first defined in RFC 6353.
+
+     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).
+
+     This version of this YANG module is part of RFC 7407; see
+     the RFC itself for full legal notices.";
+
+  reference
+    "RFC 6353: Transport Layer Security (TLS) Transport Model for
+       the Simple Network Management Protocol (SNMP)";
+
+  revision 2014-12-10 {
+    description
+      "Initial revision.";
+    reference
+      "RFC 7407: A YANG Data Model for SNMP Configuration";
+
+  }
+
+  typedef tls-fingerprint {
+    type yang:hex-string {
+      pattern '([0-9a-fA-F]){2}(:([0-9a-fA-F]){2}){0,254}';
+    }
+    description
+     "A fingerprint value that can be used to uniquely reference
+      other data of potentially arbitrary length.
+
+      A tls-fingerprint value is composed of a 1-octet hashing
+      algorithm identifier followed by the fingerprint value.  The
+      first octet value identifying the hashing algorithm is taken
+      from the IANA 'TLS HashAlgorithm Registry' (RFC 5246).  The
+      remaining octets are filled using the results of the hashing
+      algorithm.";
+    reference
+     "RFC 6353: Transport Layer Security (TLS) Transport Model
+        for the Simple Network Management Protocol (SNMP).
+        SNMP-TLS-TM-MIB.SnmpTLSFingerprint";
+  }
+
+  /* Identities */
+
+  identity cert-to-name {
+    description
+      "Base identity for algorithms to derive a name from a
+       certificate.";
+  }
+
+  identity specified {
+    base cert-to-name;
+    description
+      "Directly specifies the name to be used for the certificate.
+       The value of the leaf 'name' in the cert-to-name list is
+       used.";
+    reference
+      "RFC 6353: Transport Layer Security (TLS) Transport Model
+         for the Simple Network Management Protocol (SNMP).
+         SNMP-TLS-TM-MIB.snmpTlstmCertSpecified";
+  }
+
+  identity san-rfc822-name {
+    base cert-to-name;
+    description
+      "Maps a subjectAltName's rfc822Name to a name.  The local part
+       of the rfc822Name is passed unaltered, but the host-part of
+       the name must be passed in lowercase.  For example, the
+       rfc822Name field FooBar@Example.COM is mapped to name
+       FooBar@example.com.";
+    reference
+      "RFC 6353: Transport Layer Security (TLS) Transport Model
+         for the Simple Network Management Protocol (SNMP).
+         SNMP-TLS-TM-MIB.snmpTlstmCertSANRFC822Name";
+  }
+
+  identity san-dns-name {
+    base cert-to-name;
+    description
+      "Maps a subjectAltName's dNSName to a name after first
+       converting it to all lowercase (RFC 5280 does not specify
+       converting to lowercase, so this involves an extra step).
+       This mapping results in a 1:1 correspondence between
+       subjectAltName dNSName values and the name values.";
+    reference
+      "RFC 6353: Transport Layer Security (TLS) Transport Model
+         for the Simple Network Management Protocol (SNMP).
+         SNMP-TLS-TM-MIB.snmpTlstmCertSANDNSName";
+  }
+
+  identity san-ip-address {
+    base cert-to-name;
+    description
+      "Maps a subjectAltName's iPAddress to a name by
+       transforming the binary-encoded address as follows:
+
+         1) for IPv4, the value is converted into a
+            decimal-dotted quad address (e.g., '192.0.2.1').
+
+         2) for IPv6 addresses, the value is converted into a
+            32-character, all-lowercase hexadecimal string
+            without any colon separators.
+
+       This mapping results in a 1:1 correspondence between
+       subjectAltName iPAddress values and the name values.";
+    reference
+      "RFC 6353: Transport Layer Security (TLS) Transport Model
+         for the Simple Network Management Protocol (SNMP).
+         SNMP-TLS-TM-MIB.snmpTlstmCertSANIpAddress";
+  }
+
+  identity san-any {
+    base cert-to-name;
+    description
+      "Maps any of the following fields using the corresponding
+       mapping algorithms:
+
+         +------------+-----------------+
+         | Type       | Algorithm       |
+         |------------+-----------------|
+         | rfc822Name | san-rfc822-name |
+         | dNSName    | san-dns-name    |
+         | iPAddress  | san-ip-address  |
+         +------------+-----------------+
+
+       The first matching subjectAltName value found in the
+       certificate of the above types MUST be used when deriving
+       the name.  The mapping algorithm specified in the
+       'Algorithm' column MUST be used to derive the name.
+
+       This mapping results in a 1:1 correspondence between
+       subjectAltName values and name values.  The three sub-mapping
+       algorithms produced by this combined algorithm cannot produce
+       conflicting results between themselves.";
+    reference
+      "RFC 6353: Transport Layer Security (TLS) Transport Model
+         for the Simple Network Management Protocol (SNMP).
+         SNMP-TLS-TM-MIB.snmpTlstmCertSANAny";
+  }
+
+  identity common-name {
+    base cert-to-name;
+    description
+      "Maps a certificate's CommonName to a name after converting
+       it to a UTF-8 encoding.  The usage of CommonNames is
+       deprecated, and users are encouraged to use subjectAltName
+       mapping methods instead.  This mapping results in a 1:1
+       correspondence between certificate CommonName values and name
+       values.";
+    reference
+      "RFC 6353: Transport Layer Security (TLS) Transport Model
+         for the Simple Network Management Protocol (SNMP).
+         SNMP-TLS-TM-MIB.snmpTlstmCertCommonName";
+  }
+
+  /*
+   * Groupings
+   */
+
+  grouping cert-to-name {
+    description
+      "Defines nodes for mapping certificates to names.  Modules
+       that use this grouping should describe how the resulting
+       name is used.";
+
+    list cert-to-name {
+      key id;
+      description
+        "This list defines how certificates are mapped to names.
+         The name is derived by considering each cert-to-name
+         list entry in order.  The cert-to-name entry's fingerprint
+         determines whether the list entry is a match:
+
+         1) If the cert-to-name list entry's fingerprint value
+            matches that of the presented certificate, then consider
+            the list entry a successful match.
+
+         2) If the cert-to-name list entry's fingerprint value
+            matches that of a locally held copy of a trusted CA
+            certificate, and that CA certificate was part of the CA
+            certificate chain to the presented certificate, then
+            consider the list entry a successful match.
+
+        Once a matching cert-to-name list entry has been found, the
+        map-type is used to determine how the name associated with
+        the certificate should be determined.  See the map-type
+        leaf's description for details on determining the name value.
+        If it is impossible to determine a name from the cert-to-name
+        list entry's data combined with the data presented in the
+        certificate, then additional cert-to-name list entries MUST
+        be searched to look for another potential match.
+
+        Security administrators are encouraged to make use of
+        certificates with subjectAltName fields that can be mapped to
+        names so that a single root CA certificate can allow all
+        child certificates' subjectAltName fields to map directly to
+        a name via a 1:1 transformation.";
+      reference
+       "RFC 6353: Transport Layer Security (TLS) Transport Model
+          for the Simple Network Management Protocol (SNMP).
+          SNMP-TLS-TM-MIB.snmpTlstmCertToTSNEntry";
+
+      leaf id {
+        type uint32;
+        description
+          "The id specifies the order in which the entries in the
+           cert-to-name list are searched.  Entries with lower
+           numbers are searched first.";
+        reference
+          "RFC 6353: Transport Layer Security (TLS) Transport Model
+             for the Simple Network Management Protocol
+             (SNMP).
+             SNMP-TLS-TM-MIB.snmpTlstmCertToTSNID";
+      }
+
+      leaf fingerprint {
+        type x509c2n:tls-fingerprint;
+        mandatory true;
+        description
+          "Specifies a value with which the fingerprint of the
+           full certificate presented by the peer is compared.  If
+           the fingerprint of the full certificate presented by the
+           peer does not match the fingerprint configured, then the
+           entry is skipped, and the search for a match continues.";
+        reference
+          "RFC 6353: Transport Layer Security (TLS) Transport Model
+             for the Simple Network Management Protocol
+             (SNMP).
+             SNMP-TLS-TM-MIB.snmpTlstmCertToTSNFingerprint";
+      }
+
+      leaf map-type {
+        type identityref {
+          base cert-to-name;
+        }
+        mandatory true;
+        description
+          "Specifies the algorithm used to map the certificate
+           presented by the peer to a name.
+
+           Mappings that need additional configuration objects should
+           use the 'when' statement to make them conditional based on
+           the map-type.";
+        reference
+          "RFC 6353: Transport Layer Security (TLS) Transport Model
+             for the Simple Network Management Protocol
+             (SNMP).
+             SNMP-TLS-TM-MIB.snmpTlstmCertToTSNMapType";
+      }
+
+      leaf name {
+        when "../map-type = 'x509c2n:specified'";
+        type string;
+        mandatory true;
+        description
+          "Directly specifies the NETCONF username when the
+           map-type is 'specified'.";
+        reference
+          "RFC 6353: Transport Layer Security (TLS) Transport Model
+             for the Simple Network Management Protocol
+             (SNMP).
+             SNMP-TLS-TM-MIB.snmpTlstmCertToTSNData";
+      }
+    }
+  }
+}
index b2fbfc64e7e603f6558eeaa93a14924009cac44f..8e8114ace92f563fb764da1532a725163939854e 100644 (file)
       <groupId>org.osgi</groupId>
       <artifactId>org.osgi.service.component.annotations</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.netconf</groupId>
+      <artifactId>transport-tcp</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.netconf</groupId>
+      <artifactId>transport-tls</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.netconf</groupId>
+      <artifactId>transport-ssh</artifactId>
+    </dependency>
 
     <dependency>
       <groupId>org.opendaylight.yangtools</groupId>
diff --git a/protocol/netconf-client/src/main/yang/ietf-netconf-client@2023-04-17.yang b/protocol/netconf-client/src/main/yang/ietf-netconf-client@2023-04-17.yang
new file mode 100644 (file)
index 0000000..08027a2
--- /dev/null
@@ -0,0 +1,569 @@
+module ietf-netconf-client {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-client";
+  prefix ncc;
+
+  import ietf-yang-types {
+    prefix yang;
+    reference
+      "RFC 6991: Common YANG Data Types";
+  }
+
+  import ietf-tcp-client {
+    prefix tcpc;
+    reference
+      "RFC DDDD: YANG Groupings for TCP Clients and TCP Servers";
+  }
+
+  import ietf-tcp-server {
+    prefix tcps;
+    reference
+      "RFC DDDD: YANG Groupings for TCP Clients and TCP Servers";
+  }
+
+  import ietf-ssh-client {
+    prefix sshc;
+    reference
+      "RFC EEEE: YANG Groupings for SSH Clients and SSH Servers";
+  }
+
+  import ietf-tls-client {
+    prefix tlsc;
+    reference
+      "RFC FFFF: YANG Groupings for TLS Clients and TLS Servers";
+  }
+
+  organization
+    "IETF NETCONF (Network Configuration) Working Group";
+
+  contact
+    "WG Web:   https://datatracker.ietf.org/wg/netconf
+     WG List:  NETCONF WG list <mailto:netconf@ietf.org>
+     Author:   Kent Watsen <mailto:kent+ietf@watsen.net>";
+
+  description
+    "This module contains a collection of YANG definitions
+     for configuring NETCONF clients.
+
+     Copyright (c) 2023 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 Revised
+     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 HHHH
+     (https://www.rfc-editor.org/info/rfcHHHH); see the RFC
+     itself for full legal notices.
+
+     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.";
+
+  revision 2023-04-17 {
+    description
+      "Initial version";
+    reference
+      "RFC HHHH: NETCONF Client and Server Models";
+  }
+
+  // Features
+
+  feature ssh-initiate {
+    description
+      "The 'ssh-initiate' feature indicates that the NETCONF client
+       supports initiating SSH connections to NETCONF servers.";
+    reference
+      "RFC 6242:
+         Using the NETCONF Protocol over Secure Shell (SSH)";
+  }
+
+  feature tls-initiate {
+    description
+      "The 'tls-initiate' feature indicates that the NETCONF client
+       supports initiating TLS connections to NETCONF servers.";
+    reference
+      "RFC 7589: Using the NETCONF Protocol over Transport
+         Layer Security (TLS) with Mutual X.509 Authentication";
+  }
+
+  feature ssh-listen {
+    description
+      "The 'ssh-listen' feature indicates that the NETCONF client
+       supports opening a port to listen for incoming NETCONF
+       server call-home SSH connections.";
+    reference
+      "RFC 8071: NETCONF Call Home and RESTCONF Call Home";
+  }
+
+  feature tls-listen {
+    description
+      "The 'tls-listen' feature indicates that the NETCONF client
+       supports opening a port to listen for incoming NETCONF
+       server call-home TLS connections.";
+    reference
+      "RFC 8071: NETCONF Call Home and RESTCONF Call Home";
+  }
+
+  feature central-netconf-client-supported {
+    description
+      "The 'central-netconf-client-supported' feature indicates
+       that the server that implements this module supports
+       the top-level 'netconf-client' node.
+
+       This feature is needed as some servers may want to use
+       features defined in this module, which requires this
+       module to be implemented, without having to support
+       the top-level 'netconf-client' node.";
+  }
+
+  // Groupings
+
+  grouping netconf-client-grouping {
+    description
+      "A reusable grouping for configuring a NETCONF client
+       without any consideration for how underlying transport
+       sessions are established.
+
+       This grouping currently does not define any nodes. It
+       exists only so the model can be consistent with other
+       'client-server' models.";
+  }
+
+  grouping netconf-client-initiate-stack-grouping {
+    description
+      "A reusable grouping for configuring a NETCONF client
+       'initiate' protocol stack for a single connection.";
+    choice transport {
+      mandatory true;
+      description
+        "Selects between available transports.";
+      case ssh {
+        if-feature "ssh-initiate";
+        container ssh {
+          description
+            "Specifies IP and SSH specific configuration
+             for the connection.";
+          container tcp-client-parameters {
+            description
+              "A wrapper around the TCP client parameters
+               to avoid name collisions.";
+            uses tcpc:tcp-client-grouping {
+              refine "remote-port" {
+                default "830";
+                description
+                  "The NETCONF client will attempt to connect
+                   to the IANA-assigned well-known port value
+                   for 'netconf-ssh' (830) if no value is
+                   specified.";
+              }
+            }
+          }
+          container ssh-client-parameters {
+            description
+              "A wrapper around the SSH client parameters to
+               avoid name collisions.";
+            uses sshc:ssh-client-grouping;
+          }
+          container netconf-client-parameters {
+            description
+              "A wrapper around the NETCONF client parameters
+               to avoid name collisions.
+
+               This container does not define any nodes.  It
+               exists as a potential augmentation target by
+               other modules.";
+            uses ncc:netconf-client-grouping;
+          }
+        }
+      }
+      case tls {
+        if-feature "tls-initiate";
+        container tls {
+          description
+            "Specifies IP and TLS specific configuration
+             for the connection.";
+          container tcp-client-parameters {
+            description
+              "A wrapper around the TCP client parameters
+               to avoid name collisions.";
+            uses tcpc:tcp-client-grouping {
+              refine "remote-port" {
+                default "6513";
+                description
+                  "The NETCONF client will attempt to connect
+                   to the IANA-assigned well-known port value
+                   for 'netconf-tls' (6513) if no value is
+                   specified.";
+              }
+            }
+          }
+          container tls-client-parameters {
+            must client-identity {
+              description
+                "NETCONF/TLS clients MUST pass some
+                 authentication credentials.";
+            }
+            description
+              "A wrapper around the TLS client parameters
+               to avoid name collisions.";
+            uses tlsc:tls-client-grouping;
+          }
+          container netconf-client-parameters {
+            description
+              "A wrapper around the NETCONF client parameters
+               to avoid name collisions.
+
+               This container does not define any nodes.  It
+               exists as a potential augmentation target by
+               other modules.";
+            uses ncc:netconf-client-grouping;
+          }
+        }
+      }
+    }
+  } // netconf-client-initiate-stack-grouping
+
+  grouping netconf-client-listen-stack-grouping {
+    description
+      "A reusable grouping for configuring a NETCONF client
+       'listen' protocol stack for a single connection.  The
+       'listen' stack supports call home connections, as
+       described in RFC 8071";
+    reference
+      "RFC 8071: NETCONF Call Home and RESTCONF Call Home";
+    choice transport {
+      mandatory true;
+      description
+        "Selects between available transports.";
+      case ssh {
+        if-feature "ssh-listen";
+        container ssh {
+          description
+            "SSH-specific listening configuration for inbound
+             connections.";
+          container tcp-server-parameters {
+            description
+              "A wrapper around the TCP server parameters
+               to avoid name collisions.";
+            uses tcps:tcp-server-grouping {
+              refine "local-port" {
+                default "4334";
+                description
+                  "The NETCONF client will listen on the IANA-
+                   assigned well-known port for 'netconf-ch-ssh'
+                   (4334) if no value is specified.";
+              }
+            }
+          }
+          container ssh-client-parameters {
+            description
+              "A wrapper around the SSH client parameters
+               to avoid name collisions.";
+            uses sshc:ssh-client-grouping;
+          }
+          container netconf-client-parameters {
+            description
+              "A wrapper around the NETCONF client parameters
+               to avoid name collisions.
+
+               This container does not define any nodes.  It
+               exists as a potential augmentation target by
+               other modules.";
+            uses ncc:netconf-client-grouping;
+          }
+        }
+      }
+      case tls {
+        if-feature "tls-listen";
+        container tls {
+          description
+            "TLS-specific listening configuration for inbound
+             connections.";
+          container tcp-server-parameters {
+            description
+              "A wrapper around the TCP server parameters
+               to avoid name collisions.";
+            uses tcps:tcp-server-grouping {
+              refine "local-port" {
+                default "4335";
+                description
+                  "The NETCONF client will listen on the IANA-
+                   assigned well-known port for 'netconf-ch-tls'
+                   (4335) if no value is specified.";
+              }
+            }
+          }
+          container tls-client-parameters {
+            must client-identity {
+              description
+                "NETCONF/TLS clients MUST pass some
+                 authentication credentials.";
+            }
+            description
+              "A wrapper around the TLS client parameters
+               to avoid name collisions.";
+            uses tlsc:tls-client-grouping;
+          }
+          container netconf-client-parameters {
+            description
+              "A wrapper around the NETCONF client parameters
+               to avoid name collisions.
+
+               This container does not define any nodes.  It
+               exists as a potential augmentation target by
+               other modules.";
+            uses ncc:netconf-client-grouping;
+          }
+        }
+      }
+    }
+  } // netconf-client-listen-stack-grouping
+
+  grouping netconf-client-app-grouping {
+    description
+      "A reusable grouping for configuring a NETCONF client
+       application that supports both 'initiate' and 'listen'
+       protocol stacks for a multiplicity of connections.";
+    container initiate {
+      if-feature "ssh-initiate or tls-initiate";
+      presence
+        "Indicates that client-initiated connections have been
+         configured.  This statement is present so the mandatory
+         descendant nodes do not imply that this node must be
+         configured.";
+      description
+        "Configures client initiating underlying TCP connections.";
+      list netconf-server {
+        key "name";
+        min-elements 1;
+        description
+          "List of NETCONF servers the NETCONF client is to
+           maintain simultaneous connections with.";
+        leaf name {
+          type string;
+          description
+            "An arbitrary name for the NETCONF server.";
+        }
+        container endpoints {
+          description
+            "Container for the list of endpoints.";
+          list endpoint {
+            key "name";
+            min-elements 1;
+            ordered-by user;
+            description
+              "A user-ordered list of endpoints that the NETCONF
+               client will attempt to connect to in the specified
+               sequence.  Defining more than one enables
+               high-availability.";
+            leaf name {
+              type string;
+              description
+                "An arbitrary name for the endpoint.";
+            }
+            uses netconf-client-initiate-stack-grouping;
+          } // list endpoint
+        } // container endpoints
+
+        container connection-type {
+          description
+            "Indicates the NETCONF client's preference for how the
+             NETCONF connection is maintained.";
+          choice connection-type {
+            mandatory true;
+            description
+              "Selects between available connection types.";
+            case persistent-connection {
+              container persistent {
+                presence
+                  "Indicates that a persistent connection is to be
+                   maintained.";
+                description
+                  "Maintain a persistent connection to the NETCONF
+                   server.  If the connection goes down, immediately
+                   start trying to reconnect to the NETCONF server,
+                   using the reconnection strategy.
+
+                   This connection type minimizes any NETCONF server
+                   to NETCONF client data-transfer delay, albeit at
+                   the expense of holding resources longer.";
+              }
+            }
+            case periodic-connection {
+              container periodic {
+                presence "Indicates that a periodic connection is
+                          to be maintained.";
+                description
+                  "Periodically connect to the NETCONF server.
+
+                   This connection type decreases resource
+                   utilization, albeit with increased delay in
+                   NETCONF server to NETCONF client interactions.
+
+                   The NETCONF client should close the underlying
+                   TCP connection upon completing planned activities.
+
+                   Connections are established at the same start
+                   time regardless how long the previous connection
+                   stayed open.
+
+                   In the case that the previous connection is still
+                   active, establishing a new connection is NOT
+                   RECOMMENDED.";
+                leaf period {
+                  type uint16;
+                  units "minutes";
+                  default "60";
+                  description
+                    "Duration of time between periodic connections.";
+                }
+                leaf anchor-time {
+                  type yang:date-and-time {
+                    // constrained to minute-level granularity
+                    pattern '[0-9]{4}-(1[0-2]|0[1-9])-(0[1-9]|[1-2]'
+                          + '[0-9]|3[0-1])T(0[0-9]|1[0-9]|2[0-3]):['
+                          + '0-5][0-9]:00(Z|[\+\-]((1[0-3]|0[0-9]):'
+                          + '([0-5][0-9])|14:00))?';
+                  }
+                  description
+                    "Designates a timestamp before or after which a
+                     series of periodic connections are determined.
+                     The periodic connections occur at a whole
+                     multiple interval from the anchor time.
+
+                     If an 'anchor-time' is not provided, then the
+                     server may implicitly set it to the time when
+                     this configuraton is applied (e.g., on boot).
+
+                     For example, for an anchor time is 15 minutes
+                     past midnight and a period interval of 24 hours,
+                     then a periodic connection will occur 15 minutes
+                     past midnight everyday.";
+                }
+                leaf idle-timeout {
+                  type uint16;
+                  units "seconds";
+                  default 180; // three minutes
+                  description
+                    "Specifies the maximum number of seconds that
+                     a NETCONF session may remain idle. A NETCONF
+                     session will be dropped if it is idle for an
+                     interval longer then this number of seconds.
+                     If set to zero, then the NETCONF client will
+                     never drop a session because it is idle.";
+                }
+              }
+            }
+          }
+        }
+        container reconnect-strategy {
+          description
+            "The reconnection strategy directs how a NETCONF client
+             reconnects to a NETCONF server, after discovering its
+             connection to the server has dropped, even if due to a
+             reboot.  The NETCONF client starts with the specified
+             endpoint and tries to connect to it max-attempts times
+             before trying the next endpoint in the list (round
+             robin).";
+          leaf start-with {
+            type enumeration {
+              enum first-listed {
+                description
+                  "Indicates that reconnections should start with
+                   the first endpoint listed.";
+              }
+              enum last-connected {
+                description
+                  "Indicates that reconnections should start with
+                   the endpoint last connected to.  If no previous
+                   connection has ever been established, then the
+                   first endpoint configured is used.   NETCONF
+                   clients SHOULD be able to remember the last
+                   endpoint connected to across reboots.";
+              }
+              enum random-selection {
+                description
+                  "Indicates that reconnections should start with
+                   a random endpoint.";
+              }
+            }
+            default "first-listed";
+            description
+              "Specifies which of the NETCONF server's endpoints
+               the NETCONF client should start with when trying
+               to connect to the NETCONF server.";
+          }
+          leaf max-wait {
+            type uint16 {
+              range "1..max";
+            }
+            units "seconds";
+            default "5";
+            description
+              "Specifies the amount of time in seconds after which,
+               if the connection is not established, an endpoint
+               connection attempt is considered unsuccessful.";
+          }
+          leaf max-attempts {
+            type uint8 {
+              range "1..max";
+            }
+            default "3";
+            description
+              "Specifies the number times the NETCONF client tries
+               to connect to a specific endpoint before moving on
+               to the next endpoint in the list (round robin).";
+          }
+        }
+      } // netconf-server
+    } // initiate
+
+    container listen {
+      if-feature "ssh-listen or tls-listen";
+      presence
+        "Indicates that client-listening ports have been configured.
+         This statement is present so the mandatory descendant nodes
+         do not imply that this node must be configured.";
+      description
+        "Configures the client to accept call-home TCP connections.";
+      leaf idle-timeout {
+        type uint16;
+        units "seconds";
+        default "180"; // three minutes
+        description
+          "Specifies the maximum number of seconds that a NETCONF
+           session may remain idle. A NETCONF session will be
+           dropped if it is idle for an interval longer than this
+           number of seconds.  If set to zero, then the server
+           will never drop a session because it is idle.";
+      }
+      list endpoint {
+        key "name";
+        min-elements 1;
+        description
+          "List of endpoints to listen for NETCONF connections.";
+        leaf name {
+          type string;
+          description
+            "An arbitrary name for the NETCONF listen endpoint.";
+        }
+        uses netconf-client-listen-stack-grouping;
+      } // endpoint
+    } // listen
+  } // netconf-client-app-grouping
+
+  // Protocol accessible node for clients that implement this module.
+  container netconf-client {
+    if-feature central-netconf-client-supported;
+    uses netconf-client-app-grouping;
+    description
+      "Top-level container for NETCONF client configuration.";
+  }
+}
index 9c0878711d1cda20ac59725dfdad0f74abcbc06c..4f11037be8d3c431ea20b4df737df7f62fae9b4c 100644 (file)
       <groupId>org.opendaylight.netconf.model</groupId>
       <artifactId>rfc6470</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.netconf.model</groupId>
+      <artifactId>rfc7407-ietf-x509-cert-to-name</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.opendaylight.netconf</groupId>
       <artifactId>netconf-api</artifactId>
       <groupId>org.osgi</groupId>
       <artifactId>org.osgi.service.component.annotations</artifactId>
     </dependency>
-
+    <dependency>
+      <groupId>org.opendaylight.netconf</groupId>
+      <artifactId>transport-tcp</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.netconf</groupId>
+      <artifactId>transport-tls</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.netconf</groupId>
+      <artifactId>transport-ssh</artifactId>
+    </dependency>
     <!-- Test dependencies -->
     <dependency>
       <groupId>io.netty</groupId>
diff --git a/protocol/netconf-server/src/main/yang/ietf-netconf-server@2023-04-17.yang b/protocol/netconf-server/src/main/yang/ietf-netconf-server@2023-04-17.yang
new file mode 100644 (file)
index 0000000..ddb0595
--- /dev/null
@@ -0,0 +1,680 @@
+module ietf-netconf-server {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-server";
+  prefix ncs;
+
+  import ietf-yang-types {
+    prefix yang;
+    reference
+      "RFC 6991: Common YANG Data Types";
+  }
+
+  import ietf-x509-cert-to-name {
+    prefix x509c2n;
+    reference
+      "RFC 7407: A YANG Data Model for SNMP Configuration";
+  }
+
+  import ietf-tcp-client {
+    prefix tcpc;
+    reference
+      "RFC DDDD: YANG Groupings for TCP Clients and TCP Servers";
+  }
+
+  import ietf-tcp-server {
+    prefix tcps;
+    reference
+      "RFC DDDD: YANG Groupings for TCP Clients and TCP Servers";
+  }
+
+  import ietf-ssh-common {
+    prefix sshcmn;
+    reference
+      "RFC EEEE: YANG Groupings for SSH Clients and SSH Servers";
+  }
+
+  import ietf-ssh-server {
+    prefix sshs;
+    reference
+      "RFC EEEE: YANG Groupings for SSH Clients and SSH Servers";
+  }
+
+  import ietf-tls-server {
+    prefix tlss;
+    reference
+      "RFC FFFF: YANG Groupings for TLS Clients and TLS Servers";
+  }
+
+  organization
+    "IETF NETCONF (Network Configuration) Working Group";
+
+  contact
+    "WG Web:   https://datatracker.ietf.org/wg/netconf
+     WG List:  NETCONF WG list <mailto:netconf@ietf.org>
+     Author:   Kent Watsen <mailto:kent+ietf@watsen.net>";
+
+  description
+    "This module contains a collection of YANG definitions
+     for configuring NETCONF servers.
+
+     Copyright (c) 2023 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 Revised
+     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 HHHH
+     (https://www.rfc-editor.org/info/rfcHHHH); see the RFC
+     itself for full legal notices.
+
+     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.";
+
+  revision 2023-04-17 {
+    description
+      "Initial version";
+    reference
+      "RFC HHHH: NETCONF Client and Server Models";
+  }
+
+  // Features
+
+  feature ssh-listen {
+    description
+      "The 'ssh-listen' feature indicates that the NETCONF server
+       supports opening a port to accept NETCONF over SSH
+       client connections.";
+    reference
+      "RFC 6242:
+         Using the NETCONF Protocol over Secure Shell (SSH)";
+  }
+
+  feature tls-listen {
+    description
+      "The 'tls-listen' feature indicates that the NETCONF server
+       supports opening a port to accept NETCONF over TLS
+       client connections.";
+    reference
+      "RFC 7589: Using the NETCONF Protocol over Transport
+                 Layer Security (TLS) with Mutual X.509
+                 Authentication";
+  }
+
+  feature ssh-call-home {
+    description
+      "The 'ssh-call-home' feature indicates that the NETCONF
+       server supports initiating a NETCONF over SSH call
+       home connection to NETCONF clients.";
+    reference
+      "RFC 8071: NETCONF Call Home and RESTCONF Call Home";
+  }
+
+  feature tls-call-home {
+    description
+      "The 'tls-call-home' feature indicates that the NETCONF
+       server supports initiating a NETCONF over TLS call
+       home connection to NETCONF clients.";
+    reference
+      "RFC 8071: NETCONF Call Home and RESTCONF Call Home";
+  }
+
+  feature central-netconf-server-supported {
+    description
+      "The 'central-netconf-server-supported' feature indicates
+       that the server supports the top-level 'netconf-server'
+       node.
+
+       This feature is needed as some servers may want to use
+       features defined in this module, which requires this
+       module to be implemented, without having to support
+       the top-level 'netconf-server' node.";
+  }
+
+  // Groupings
+
+  grouping netconf-server-grouping {
+    description
+      "A reusable grouping for configuring a NETCONF server
+       without any consideration for how underlying transport
+       sessions are established.
+
+       Note that this grouping uses a fairly typical descendant
+       node name such that a stack of 'uses' statements will
+       have name conflicts.  It is intended that the consuming
+       data model will resolve the issue by wrapping the 'uses'
+       statement in a container called, e.g.,
+       'netconf-server-parameters'.  This model purposely does
+       not do this itself so as to provide maximum flexibility
+       to consuming models.";
+
+    container client-identity-mappings {
+      description
+        "Specifies mappings through which NETCONF client X.509
+         certificates are used to determine a NETCONF username,
+         per RFC 7407.
+
+         For TLS-based transports, if no matching and valid
+         cert-to-name list entry can be found, then the NETCONF
+         server MUST close the connection, and MUST NOT accept
+         NETCONF messages over it, per Section 7 in RFC 7589.
+
+         For SSH-based transports, a matching cert-to-name
+         entry overrides the username provided by the SSH
+         implementation, consistent with the second paragraph
+         of Section 3 in RFC 6242.";
+      reference
+        "RFC 6242:
+           Using the NETCONF Protocol over Secure Shell (SSH)
+         RFC 7589:
+           Using the NETCONF Protocol over Transport Layer
+           Security (TLS) with Mutual X.509 Authentication";
+      uses x509c2n:cert-to-name {
+        refine "cert-to-name/fingerprint" {
+          mandatory false;
+          description
+            "A 'fingerprint' value does not need to be specified
+             when the 'cert-to-name' mapping is independent of
+             fingerprint matching.  A 'cert-to-name' having no
+             fingerprint value will match any client certificate
+             and therefore should only be present at the end of
+             the user-ordered 'cert-to-name' list.";
+        }
+      }
+    }
+  }
+
+  grouping netconf-server-listen-stack-grouping {
+    description
+      "A reusable grouping for configuring a NETCONF server
+       'listen' protocol stack for a single connection.";
+    choice transport {
+      mandatory true;
+      description
+        "Selects between available transports.";
+      case ssh {
+        if-feature "ssh-listen";
+        container ssh {
+          description
+            "SSH-specific listening configuration for inbound
+             connections.";
+          container tcp-server-parameters {
+            description
+              "A wrapper around the TCP client parameters
+               to avoid name collisions.";
+            uses tcps:tcp-server-grouping {
+              refine "local-port" {
+                default "830";
+                description
+                  "The NETCONF server will listen on the
+                   IANA-assigned well-known port value
+                   for 'netconf-ssh' (830) if no value
+                   is specified.";
+              }
+            }
+          }
+          container ssh-server-parameters {
+            description
+              "A wrapper around the SSH server parameters
+               to avoid name collisions.";
+            uses sshs:ssh-server-grouping;
+          }
+          container netconf-server-parameters {
+            description
+              "A wrapper around the NETCONF server parameters
+               to avoid name collisions.";
+            uses ncs:netconf-server-grouping {
+              refine "client-identity-mappings" {
+                if-feature "sshcmn:ssh-x509-certs";
+                description
+                  "Augments in an 'if-feature' statement
+                   ensuring the 'client-identity-mappings'
+                   descendant is enabled only when SSH
+                   supports X.509 certificates.";
+              }
+              augment "client-identity-mappings" {
+                description
+                  "Adds a flag indicating if a cert-to-name
+                   is required.";
+                leaf mapping-required {
+                  type boolean;
+                  description
+                    "Indicates that the cert-to-name mapping
+                     is required (i.e., the SSH-level username
+                     is ignored).";
+                }
+              }
+            }
+          }
+        }
+      }
+      case tls {
+        if-feature "tls-listen";
+        container tls {
+          description
+            "TLS-specific listening configuration for inbound
+             connections.";
+          container tcp-server-parameters {
+            description
+              "A wrapper around the TCP client parameters
+               to avoid name collisions.";
+            uses tcps:tcp-server-grouping {
+              refine "local-port" {
+                default "6513";
+                description
+                  "The NETCONF server will listen on the
+                   IANA-assigned well-known port value
+                   for 'netconf-tls' (6513) if no value
+                   is specified.";
+              }
+            }
+          }
+          container tls-server-parameters {
+            description
+              "A wrapper around the TLS server parameters to
+               avoid name collisions.";
+            uses tlss:tls-server-grouping {
+              refine "client-authentication" {
+                must 'ca-certs or ee-certs';
+                description
+                  "NETCONF/TLS servers MUST validate client
+                   certificates.  This configures certificates
+                   at the socket-level (i.e. bags), more
+                   discriminating client-certificate checks
+                   SHOULD be implemented by the application.";
+                reference
+                  "RFC 7589:
+                    Using the NETCONF Protocol over Transport Layer
+                    Security (TLS) with Mutual X.509 Authentication";
+              }
+            }
+          }
+          container netconf-server-parameters {
+            description
+              "A wrapper around the NETCONF server parameters
+               to avoid name collisions.";
+            uses ncs:netconf-server-grouping {
+              refine "client-identity-mappings/cert-to-name" {
+                min-elements 1;
+                description
+                  "The TLS transport requires a mapping.";
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  grouping netconf-server-callhome-stack-grouping {
+    description
+      "A reusable grouping for configuring a NETCONF server
+       'call-home' protocol stack, for a single connection.";
+    choice transport {
+      mandatory true;
+      description
+        "Selects between available transports.";
+      case ssh {
+        if-feature "ssh-call-home";
+        container ssh {
+          description
+            "Specifies SSH-specific call-home transport
+             configuration.";
+          container tcp-client-parameters {
+            description
+              "A wrapper around the TCP client parameters
+               to avoid name collisions.";
+            uses tcpc:tcp-client-grouping {
+              refine "remote-port" {
+                default "4334";
+                description
+                  "The NETCONF server will attempt to connect
+                   to the IANA-assigned well-known port for
+                   'netconf-ch-ssh' (4334) if no value is
+                   specified.";
+              }
+            }
+          }
+          container ssh-server-parameters {
+            description
+              "A wrapper around the SSH server parameters
+               to avoid name collisions.";
+            uses sshs:ssh-server-grouping;
+          }
+          container netconf-server-parameters {
+            description
+              "A wrapper around the NETCONF server parameters
+               to avoid name collisions.";
+            uses ncs:netconf-server-grouping {
+              refine "client-identity-mappings" {
+                if-feature "sshcmn:ssh-x509-certs";
+                description
+                  "Augments in an 'if-feature' statement
+                   ensuring the 'client-identity-mappings'
+                   descendant is enabled only when SSH
+                   supports X.509 certificates.";
+              }
+              augment "client-identity-mappings" {
+                description
+                  "Adds a flag indicating if a cert-to-name
+                   is required.";
+                leaf mapping-required {
+                  type boolean;
+                  description
+                    "Indicates that the cert-to-name mapping
+                     is required (i.e., the SSH-level username
+                     is ignored).";
+                }
+              }
+            }
+          }
+        }
+      }
+      case tls {
+        if-feature "tls-call-home";
+        container tls {
+          description
+            "Specifies TLS-specific call-home transport
+             configuration.";
+          container tcp-client-parameters {
+            description
+              "A wrapper around the TCP client parameters
+               to avoid name collisions.";
+            uses tcpc:tcp-client-grouping {
+              refine "remote-port" {
+                default "4335";
+                description
+                  "The NETCONF server will attempt to connect
+                   to the IANA-assigned well-known port for
+                   'netconf-ch-tls' (4335) if no value is
+                   specified.";
+              }
+            }
+          }
+          container tls-server-parameters {
+            description
+              "A wrapper around the TLS server parameters to
+               avoid name collisions.";
+            uses tlss:tls-server-grouping {
+              refine "client-authentication" {
+                must 'ca-certs or ee-certs';
+                description
+                  "NETCONF/TLS servers MUST validate client
+                   certificates.  This configures certificates
+                   at the socket-level (i.e. bags), more
+                   discriminating client-certificate checks
+                   SHOULD be implemented by the application.";
+                reference
+                  "RFC 7589:
+                    Using the NETCONF Protocol over Transport Layer
+                    Security (TLS) with Mutual X.509 Authentication";
+              }
+            }
+          }
+          container netconf-server-parameters {
+            description
+              "A wrapper around the NETCONF server parameters
+               to avoid name collisions.";
+            uses ncs:netconf-server-grouping {
+              refine "client-identity-mappings/cert-to-name" {
+                min-elements 1;
+                description
+                  "The TLS transport requires a mapping.";
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  grouping netconf-server-app-grouping {
+    description
+      "A reusable grouping for configuring a NETCONF server
+       application that supports both 'listen' and 'call-home'
+       protocol stacks for a multiplicity of connections.";
+    container listen {
+      if-feature "ssh-listen or tls-listen";
+      presence
+        "Indicates that server-listening ports have been configured.
+         This statement is present so the mandatory descendant
+         nodes do not imply that this node must be configured.";
+      description
+        "Configures listen behavior";
+      leaf idle-timeout {
+        type uint16;
+        units "seconds";
+        default "180"; // three minutes
+        description
+          "Specifies the maximum number of seconds that a NETCONF
+           session may remain idle. A NETCONF session will be
+           dropped if it is idle for an interval longer than this
+           number of seconds.  If set to zero, then the server
+           will never drop a session because it is idle.";
+      }
+      list endpoint {
+        key "name";
+        min-elements 1;
+        description
+          "List of endpoints to listen for NETCONF connections.";
+        leaf name {
+          type string;
+          description
+            "An arbitrary name for the NETCONF listen endpoint.";
+        }
+        uses netconf-server-listen-stack-grouping;
+      }
+    }
+    container call-home {
+      if-feature "ssh-call-home or tls-call-home";
+      presence
+        "Indicates that server-initiated call home connections have
+         been configured.  This statement is present so the mandatory
+         descendant nodes do not imply that this node must be
+         configured.";
+      description
+        "Configures the NETCONF server to initiate the underlying
+         transport connection to NETCONF clients.";
+      list netconf-client {
+        key "name";
+        min-elements 1;
+        description
+          "List of NETCONF clients the NETCONF server is to
+           maintain simultaneous call-home connections with.";
+        leaf name {
+          type string;
+          description
+            "An arbitrary name for the remote NETCONF client.";
+        }
+        container endpoints {
+          description
+            "Container for the list of endpoints.";
+          list endpoint {
+            key "name";
+            min-elements 1;
+            ordered-by user;
+            description
+              "A non-empty user-ordered list of endpoints for this
+               NETCONF server to try to connect to in sequence.
+               Defining more than one enables high-availability.";
+            leaf name {
+              type string;
+              description
+                "An arbitrary name for this endpoint.";
+            }
+            uses netconf-server-callhome-stack-grouping;
+          }
+        }
+        container connection-type {
+          description
+            "Indicates the NETCONF server's preference for how the
+             NETCONF connection is maintained.";
+          choice connection-type {
+            mandatory true;
+            description
+              "Selects between available connection types.";
+            case persistent-connection {
+              container persistent {
+                presence
+                  "Indicates that a persistent connection is to be
+                   maintained.";
+                description
+                  "Maintain a persistent connection to the NETCONF
+                   client. If the connection goes down, immediately
+                   start trying to reconnect to the NETCONF client,
+                   using the reconnection strategy.
+
+                   This connection type minimizes any NETCONF client
+                   to NETCONF server data-transfer delay, albeit at
+                   the expense of holding resources longer.";
+              }
+            }
+            case periodic-connection {
+              container periodic {
+                presence "Indicates that a periodic connection is
+                          to be maintained.";
+                description
+                  "Periodically connect to the NETCONF client.
+
+                   This connection type decreases resource
+                   utilization, albeit with increased delay in
+                   NETCONF client to NETCONF server interactions.
+
+                   The NETCONF client SHOULD gracefully close the
+                   connection using <close-session> upon completing
+                   planned activities.  If the NETCONF session is
+                   not closed gracefully, the NETCONF server MUST
+                   immediately attempt to reestablish the connection.
+
+                   Connections are established at the same start
+                   time regardless how long the previous connection
+                   stayed open.
+
+                   In the case that the previous connection is still
+                   active (i.e., the NETCONF client has not closed
+                   it yet), establishing a new connection is NOT
+                   RECOMMENDED.";
+                leaf period {
+                  type uint16;
+                  units "minutes";
+                  default "60";
+                  description
+                    "Duration of time between periodic connections.";
+                }
+                leaf anchor-time {
+                  type yang:date-and-time {
+                    // constrained to minute-level granularity
+                    pattern '[0-9]{4}-(1[0-2]|0[1-9])-(0[1-9]|[1-2]'
+                          + '[0-9]|3[0-1])T(0[0-9]|1[0-9]|2[0-3]):['
+                          + '0-5][0-9]:00(Z|[\+\-]((1[0-3]|0[0-9]):'
+                          + '([0-5][0-9])|14:00))?';
+                  }
+                  description
+                    "Designates a timestamp before or after which a
+                     series of periodic connections are determined.
+                     The periodic connections occur at a whole
+                     multiple interval from the anchor time.
+
+                     If an 'anchor-time' is not provided, then the
+                     server may implicitly set it to the time when
+                     this configuraton is applied (e.g., on boot).
+
+                     For example, for an anchor time is 15 minutes
+                     past midnight and a period interval of 24 hours,
+                     then a periodic connection will occur 15 minutes
+                     past midnight everyday.";
+                }
+                leaf idle-timeout {
+                  type uint16;
+                  units "seconds";
+                  default "180"; // three minutes
+                  description
+                    "Specifies the maximum number of seconds that
+                     a NETCONF session may remain idle. A NETCONF
+                     session will be dropped if it is idle for an
+                     interval longer than this number of seconds.
+                     If set to zero, then the server will never
+                     drop a session because it is idle.";
+                }
+              }
+            } // case periodic-connection
+          } // choice connection-type
+        } // container connection-type
+        container reconnect-strategy {
+          description
+            "The reconnection strategy directs how a NETCONF server
+             reconnects to a NETCONF client, after discovering its
+             connection to the client has dropped, even if due to a
+             reboot.  The NETCONF server starts with the specified
+             endpoint and tries to connect to it max-attempts times
+             before trying the next endpoint in the list (round
+             robin).";
+          leaf start-with {
+            type enumeration {
+              enum first-listed {
+                description
+                  "Indicates that reconnections should start with
+                   the first endpoint listed.";
+              }
+              enum last-connected {
+                description
+                  "Indicates that reconnections should start with
+                   the endpoint last connected to.  If no previous
+                   connection has ever been established, then the
+                   first endpoint configured is used.   NETCONF
+                   servers SHOULD be able to remember the last
+                   endpoint connected to across reboots.";
+              }
+              enum random-selection {
+                description
+                  "Indicates that reconnections should start with
+                   a random endpoint.";
+              }
+            }
+            default "first-listed";
+            description
+              "Specifies which of the NETCONF client's endpoints
+               the NETCONF server should start with when trying
+               to connect to the NETCONF client.";
+          }
+          leaf max-wait {
+            type uint16 {
+              range "1..max";
+            }
+            units "seconds";
+            default "5";
+            description
+              "Specifies the amount of time in seconds after which,
+               if the connection is not established, an endpoint
+               connection attempt is considered unsuccessful.";
+          }
+          leaf max-attempts {
+            type uint8 {
+              range "1..max";
+            }
+            default "3";
+            description
+              "Specifies the number times the NETCONF server tries
+               to connect to a specific endpoint before moving on
+               to the next endpoint in the list (round robin).";
+          }
+        } // container reconnect-strategy
+      } // list netconf-client
+    } // container call-home
+  } // grouping netconf-server-app-grouping
+
+  // Protocol accessible node for servers that implement this module.
+  container netconf-server {
+    if-feature central-netconf-server-supported;
+    uses netconf-server-app-grouping;
+    description
+      "Top-level container for NETCONF server configuration.";
+  }
+}