module ietf-dhcpv6-server {
        yang-version 1.1;
        namespace "urn:ietf:params:xml:ns:yang:ietf-dhcpv6-server";
        prefix "dhcpv6-server";

        import ietf-inet-types {
                prefix inet;
  }
        import ietf-yang-types {
        prefix yang;
        }
        import ietf-dhcpv6-options {
        prefix dhcpv6-options;
  }
  import ietf-dhcpv6-types {
        prefix dhcpv6-types;
  }
  import ietf-interfaces {
        prefix if;
  }

  organization "DHC WG";
  contact
        "cuiyong@tsinghua.edu.cn
         lh.sunlinh@gmail.com
         ian.farrer@telekom.de
         sladjana.zechlin@telekom.de
         hezihao9512@gmail.com";

        description "This model defines a YANG data model that can be
        used to configure and manage a DHCPv6 server.";

  revision 2018-09-04 {
    description "";
    reference "I-D: draft-ietf-dhc-dhcpv6-yang";
  }

  revision 2018-03-04 {
        description "Resolved most issues on the DHC official
        github";
        reference "I-D: draft-ietf-dhc-dhcpv6-yang";
  }

        revision 2017-12-22 {
                description "Resolve most issues on Ian's github.";
        reference "I-D: draft-ietf-dhc-dhcpv6-yang";
        }

        revision 2017-11-24 {
        description "First version of the separated server specific
                YANG model.";
        reference "I-D: draft-ietf-dhc-dhcpv6-yang";
        }

        /*
        * Typedef
        */
        typedef threshold {
        type union {
                type uint16 {
                range 0..100;
                }
                type enumeration {
                enum "disabled" {
                        description "No threshold";
                }
        }
        }
        description "Threshold value in percent";
        }

        /*
        * Data Nodes
        */
        container server {
                presence "Enables the server";
        description "DHCPv6 server portion";

    /*
     * Configuration data
     */
    container server-config {
        description "This container contains the configuration data
            of a server.";
        container serv-attributes {
                    description
                     "This container contains basic attributes of a DHCPv6 server
                     such as IPv6 address, server name  and so on. Some optional
                     functions that can be provided  by the server is also included.";
                    container duid {
                      description "Sets the DUID of server";
                      uses dhcpv6-types:duid;
                    }
                    leaf name {
                type string;
                description "server's name";
                    }
                    leaf description {
                type string;
                description "description of the server.";
                    }
                    leaf-list ipv6-address {
                type inet:ipv6-address;
                description "server's IPv6 address.";
                    }
                    leaf-list interfaces-config {
                // Note - this should probably be references to
                // entries in the ietf-interfaces model
                type if:interface-ref;
                description "A leaf list to denote which one or more interfaces
                        the server should listen on. The default value is to listen
                        on all the interfaces. This node is also used to set a unicast
                        address for the server to listen with a specific interface.
                  For example, if people want the server to listen on a unicast
                  address with a specific interface, he can use the format like
                  'eth1/2001:db8::1'.";
                    }
                                container lease-storage {
                                        description "Indicates how the server stores the lease";
                                        choice storage-type {
                                                description "the type of lease storage";
                                                // leaf persist {
                                                //              type boolean;
                                                //              mandatory true;
                                                //              description "controls whether the new leases and updates to existing leases are
                                                //              written to the file";
                                                // }
                                                case memfile {
                                                        description "the server stores lease information in a CSV file";

                                                        leaf memfile-name {
                                                                type string;
                                                                description "specifies an absolute location of the lease file in which new leases
                                                                and lease updates will be recorded";
                                                        }

                                                        leaf memfile-lfc-interval {
                                                                type uint64;
                                                                description "specifies the interval in seconds, at which the server will perform a
                                                                lease file cleanup (LFC)";
                                                        }

                                                }
                                                case mysql {
                                                        leaf mysql-name {
                                                                type string;
                                                                description "type of the database";
                                                        }
                                                        leaf mysql-host {
                                                                type string;
                                                                description "If the database is located
                                                                on a different system to the DHCPv6 server, the database host name must also be specified.";
                                                        }
                                                        leaf mysql-password {
                                                                type string;
                                                                description "the credentials of the account under which the server will access the database";
                                                        }
                                                        leaf mysql-port {
                                                                type uint8;
                                                                description "If the database is located on a different system, the port number may be specified";
                                                        }
                                                        leaf mysql-lfc-interval {
                                                                type uint64;
                                                                description "specifies the interval in seconds, at which the server will perform a
                                                                lease file cleanup (LFC)";
                                                        }
                                                        leaf mysql-connect-timeout {
                                                                type uint64;
                                                                description "If the database is located on a different system, a longer interval needs to be specified";
                                                        }

                                                }
                                                case postgresql {
                                                        leaf postgresql-name {
                                                                type string;
                                                                description "type of the database";
                                                        }
                                                        leaf postgresql-host {
                                                                type string;
                                                                description "If the database is located
                                                                on a different system to the DHCPv6 server, the database host name must also be specified.";
                                                        }
                                                        leaf postgresql-password {
                                                                type string;
                                                                description "the credentials of the account under which the server will access the database";
                                                        }
                                                        leaf postgresql-port {
                                                                type uint8;
                                                                description "If the database is located on a different system, the port number may be specified";
                                                        }
                                                        leaf postgresql-lfc-interval {
                                                                type uint64;
                                                                description "specifies the interval in seconds, at which the server will perform a
                                                                lease file cleanup (LFC)";
                                                        }
                                                        leaf postgresql-connect-timeout {
                                                                type uint64;
                                                                description "If the database is located on a different system, a longer interval needs to be specified";
                                                        }
                                                }
                                                case cassandra {
                                                        leaf cassandra-name {
                                                                type string;
                                                                description "type of the database";
                                                        }
                                                        leaf cassandra-contact-points {
                                                                type string;
                                                                description "Cassandra takes a list of comma separated IP addresses to contact the cluster";
                                                        }
                                                        leaf cassandra-password {
                                                                type string;
                                                                description "the credentials of the account under which the server will access the database";
                                                        }
                                                        leaf cassandra-lfc-interval {
                                                                type uint64;
                                                                description "specifies the interval in seconds, at which the server will perform a
                                                                lease file cleanup (LFC)";
                                                        }
                                                        leaf cassandra-connect-timeout {
                                                                type uint64;
                                                                description "If the database is located on a different system, a longer interval needs to be specified";
                                                        }
                                                }
                                        }
                                }
                    uses dhcpv6-types:vendor-infor;
        }

            container option-sets {
                description "DHCPv6 employs various options to carry additional
          information and parameters in DHCP messages. This container defines
          all the possible options that need to be configured at the server
          side. ";
        list option-set {
                        key option-set-id;
                        description "A server may allow different option sets to be
                configured for different conditions (i.e. different networks,
                clients and etc). This 'option-set' list enables various sets of
                options being defined and configured in a single server. Different
                sets are distinguished by the key called 'option-set-id'. All the
                possible options discussed above are defined in the list and each
                option is corresponding to a container. Since all the options in
                the list are optional, each container in this list has a 'presence'
                statement to indicate whether this option (container) will be
                included in the current option set or not. In addition, each container
                also has a 'if-feature' statement to indicate whether the server
                supports this option (container).";
            leaf option-set-id {
                type uint32;
                description "option set id";
            }
          uses dhcpv6-options:server-option-definitions;
          uses dhcpv6-options:custom-option-definitions;
        }
            }

            container network-ranges {
        description "This model supports a hierarchy
                to achieve dynamic configuration. That is to say we could configure the
                server at different levels through this model. The top level is a global
                level which is defined as the container 'network-ranges'. The following
                levels are defined as sub-containers under it. The 'network-ranges'
                contains the parameters (e.g. option-sets) that would be allocated to
                all the clients served by this server.";

        leaf option-set-id {
          type leafref {
            path "/server/server-config/option-sets/option-set/option-set-id";
          }
          description
                "The ID field of relevant global option-set to be provisioned to
                clients.";
        }
        list network-range {
                key network-range-id;
                description
                "Under the 'network-ranges' container, a 'network-range' list
                 is defined to configure the server at a network level which is also
                 considered as the second level. Different network are identified by the
                 key 'network-range-id'. This is because a server may have different
           configuration parameters (e.g. option sets) for different networks.";
                leaf network-range-id {
                        type uint32;
                        mandatory true;
                        description "equivalent to subnet id";
                }
                leaf network-description {
                        type string;
                        mandatory true;
                        description "description of the subnet";
                }
                leaf network-prefix {
                        type inet:ipv6-prefix;
                        mandatory true;
                  description "subnet prefix";
                }
                leaf option-set-id {
            type leafref {
              path "/server/server-config/option-sets/option-set/option-set-id";
            }
            description "The ID field of relevant option-set to be provisioned to
            clients of this network-range.";
                }

                container address-pools {
            description
            "A container that describes the DHCPv6 server's
             address pools.";
            list address-pool {
                key pool-id;
                description "A DHCPv6 server can be configured with
                several address pools. This list defines such address pools
                which are distinguished by the key called 'pool-id'.";
                leaf pool-id {
                        type uint32;
                mandatory true;
                description "pool id";
                }
                                leaf pool-prefix {
                type inet:ipv6-prefix;
                mandatory true;
                description "pool prefix";
                    }
                leaf start-address {
                type inet:ipv6-address-no-zone;
                mandatory true;
                description "start address";
                }
                leaf end-address {
                type inet:ipv6-address-no-zone;
                mandatory true;
                description "end address";
              }
                leaf valid-lifetime {
                type yang:timeticks;
                mandatory true;
                description "valid liftime for IA";
                }
                leaf renew-time {
                type yang:timeticks;
                mandatory true;
                description "renew time";
              }
                leaf rebind-time {
                type yang:timeticks;
                mandatory true;
                description "rebind time";
                }
                leaf preferred-lifetime {
                      type yang:timeticks;
                      mandatory true;
                      description "preferred lifetime for IA";
                }
                leaf rapid-commit {
                                        type boolean;
                                        mandatory true;
                                        description "A boolean value specifies whether the pool
                                        supports client-server exchanges involving two messages.";
                                        }
              leaf client-class {
                type string;
                description
                "If this leaf is specified, this pool will only serve
                the clients belonging to this class.";
              }
                leaf max-address-count {
                type threshold;
                mandatory true;
                description "maximum count of addresses that can
                        be allocated in this pool. This value may be
                        less than count of total addresses.";
                }
                leaf option-set-id {
                type leafref {
                        path "/server/server-config/option-sets/option-set/option-set-id";
                }
                mandatory true;
                description "The ID field of relevant option-set to be
                                provisioned to clients of this address-pool.";
                }
                  }
                }

                container pd-pools {
            description "If a server supports prefix delegation function, this
                container will be used to define  the delegating router's prefix
                pools.";
            list pd-pool {
                key pool-id;
                description "Similar to server's address pools, a delegating
                        router can also be configured with multiple prefix pools
                        specified by a list called 'prefix-pool'.";
                                                        leaf pool-id {
                        type uint32;
                      mandatory true;
                      description "pool id";
                    }
                    leaf prefix {
                        type inet:ipv6-prefix;
                        mandatory true;
                        description "ipv6 prefix";
                    }
                    leaf prefix-length {
                        type uint8;
                        mandatory true;
                        description "prefix length";
                    }
                    leaf valid-lifetime {
                        type yang:timeticks;
                mandatory true;
                description "valid lifetime for IA";
                    }
                    leaf renew-time {
                type yang:timeticks;
                mandatory true;
                description "renew time";
                    }
                leaf rebind-time {
                type yang:timeticks;
                mandatory true;
                description "rebind time";
                        }
                    leaf preferred-lifetime {
                type yang:timeticks;
                mandatory true;
                description "preferred lifetime for IA";
                    }
                leaf rapid-commit {
                                        type boolean;
                                        mandatory true;
                                        description "A boolean value specifies whether the server
                                        support client-server exchanges involving two messages defined.";
                                        }
                                        leaf client-class {
                type string;
                description "client class";
              }
                    leaf max-pd-space-utilization {
                type threshold;
                mandatory true;
                description "Maximum utilization of pd space in this pool";
                    }
                    leaf option-set-id {
                        type leafref {
                                path "/server/server-config/option-sets/option-set/option-set-id";
                        }
                        mandatory true;
                        description "The ID field of relevant option-set to be
                          provisioned to clients of this prefix-pool.";
                    }
                  }
                }

          container host-reservations {
            description
                "This container allows the server to make reservations at host level.";
            list host-reservation {
              key cli-id;
              description "This list allows the server to reserve addresses,
              prefixes, hostname and options for different clients.";
              leaf cli-id {
                type uint32;
                mandatory true;
                description "client id";
              }

              choice client-identifier {
                description "When making reservations, the server needs to choose a
                identifier to identify the client. Currently 'DUID' and 'hardware
                address' are supported.";
                case duid {
                  description "DUID";
                  uses dhcpv6-types:duid;
                }
                case hw-address {
                  description "hardware address";
                  leaf hardware-address {
                  type yang:mac-address;
                  description "MAC address of client";
                  }
                }
              }

              leaf-list reserv-addr {
                type inet:ipv6-address;
                description "reserved addr";
              }

              list prefix-reservation {
                key reserv-prefix-id;
                description "reserved prefix reservation";
                leaf reserv-prefix-id {
                        type uint32;
                        mandatory true;
                        description "reserved prefix id";
                }
                leaf reserv-prefix {
                        type inet:ipv6-prefix;
                        mandatory true;
                        description "reserved prefix";
                      }
                leaf reserv-prefix-len {
                        type uint8;
                        mandatory true;
                        description "reserved prefix length";
                }
              }

              leaf hostname {
                type string;
                description "reserved hostname";
              }

              leaf option-set-id {
                type leafref {
                  path "/server/server-config/option-sets/option-set/option-set-id";
                }
                description "The ID field of relevant option-set to be provisioned
                  in the host reservation.";
              }
            }
          }

        }
                        }

        container relay-opaque-paras {
        description "This container contains some opaque values in Relay Agent
                options that need to be configured on the server side only for value
                match. Such Relay Agent options include Interface-Id option,
                Remote-Id option and Subscriber-Id option.";
        list relays {
                key relay-name;
                description "relay agents";
                leaf relay-name {
                type string;
                mandatory true;
                description "relay agent name";
          }
                list interface-info {
                key if-name;
                description "interface info";
                leaf if-name {
                        type string;
                        mandatory true;
                        description "interface name";
                }
                leaf interface-id {
                type string;
                mandatory true;
                        description "interface id";
                }
                }
                list subscribers {
                  key subscriber;
                        description "subscribers";
                        leaf subscriber {
                                type uint32;
                        mandatory true;
                        description "subscriber";
                  }
                leaf subscriber-id {
                type string;
                        mandatory true;
                        description "subscriber id";
                }
                }
                list remote-host {
                key ent-num;
                description "remote host";
                leaf ent-num {
                        type uint32;
                        mandatory true;
                        description "enterprise number";
                }
                leaf remote-id {
                        type string;
                        mandatory true;
                        description "remote id";
                }
                }
              }
                }

            container rsoo-enabled-options {
        description "rsoo enabled options";
        list rsoo-enabled-option {
                key option-code;
                description "rsoo enabled option";
                leaf option-code {
                type uint16;
                mandatory true;
                description "option code";
                }
                leaf description {
                type string;
                mandatory true;
                description "description of the option";
                }
        }
            }

                }

          /*
           * State data
           */
    container server-state {
        config "false";
        description "states of server";
        container network-ranges {
                description "This model supports a hierarchy to achieve dynamic configuration.
                        That is to say we could configure the server  at different levels through
                        this model. The top level is a global level which is defined as the container
                        'network-ranges'. The following levels are defined as sub-containers under it.
                        The 'network-ranges' contains the parameters (e.g. option-sets) that  would be
                        allocated to all the clients served by this server.";
                list network-range {
                        key network-range-id;
                description "The ID field of relevant option-set to be provisioned
                        to clients of this network-range.";
                        leaf network-range-id {
                        type uint32;
                        mandatory true;
                        description "equivalent to subnet id";
                }
                container address-pools {
                        description "A container that describes the DHCPv6 server's address pools";
                        list address-pool {
                                key pool-id;
                                description "A DHCPv6 server can be configured with
                                several address pools. This list defines such address pools
                                which are distinguished by the key called 'pool-id'.";
                leaf pool-id {
                        type uint32;
                        mandatory true;
                        description "pool id";
                    }
                                        leaf total-address-count {
                                                type uint64;
                                                mandatory true;
                                                description "count of total addresses in the pool";
                                        }
                                        leaf allocated-address-conut {
                                                type uint64;
                                                mandatory true;
                                                description "count of allocated addresses in the pool";
                                        }
                        }
                        list binding-info {
                                key cli-id;
                                description "A list that records a binding information for each DHCPv6
                                        client that has already been allocated IPv6 addresses.";
                                leaf cli-id {
                                        type uint32;
                                        mandatory true;
                                        description "client id";
                }
                                container duid {
                                        description "Read the DUID";
                                        uses dhcpv6-types:duid;
                }
                                list cli-ia {
                                        key iaid;
                                        description "client IA";
                                        leaf ia-type {
                                                type string;
                                                mandatory true;
                                                description "IA type";
                                        }
                                        leaf iaid {
                                                type uint32;
                                                mandatory true;
                                                description "IAID";
                                        }
                                        leaf-list cli-addr {
                                                type inet:ipv6-address;
                                                description "client addr";
                                        }
                                        leaf pool-id {
                                                type uint32;
                                                mandatory true;
                                                description "pool id";
                                        }
                                }
                        }
                        }
                        container pd-pools {
                                description "If a server supports prefix delegation function,
                                        this container will be used to define the delegating
                                        router's prefix pools.";
                                list prefix-pool {
                key pool-id;
                description "Similar to server's address pools, a delegating
                        router can also be configured with multiple prefix pools
                        specified by a list called 'prefix-pool'.";
                leaf pool-id {
                        type uint32;
                        mandatory true;
                        description "pool id";
                }
                leaf pd-space-utilization {
                        type threshold;
                        mandatory true;
                        description "current PD space utilization";
                }
                                }
                                list binding-info {
                                        key cli-id;
                                        description "A list records a binding information for each DHCPv6
                                                client that has already been alloated IPv6 prefixes.";
                                                leaf cli-id {
                                                        type uint32;
                                                        mandatory true;
                                                        description "client id";
                                                }
                                                container duid {
                                                        description "Reads the DUID";
                                                        uses dhcpv6-types:duid;
                                                }
                                                list cli-iapd {
                                                        key iaid;
                                                        description "client IAPD";
                                                        leaf iaid {
                                                                type uint32;
                                                                mandatory true;
                                                                description "IAID";
                                                        }
                                                        leaf-list cli-prefix {
                                                                type inet:ipv6-prefix;
                                                                description "client ipv6 prefix";
                                                        }
                                                        leaf-list cli-prefix-len {
                                                                type uint8;
                                                                description "client prefix length";
                                                        }
                                                        leaf pool-id {
                                                                type uint32;
                                                                mandatory true;
                                                                description "pool id";
                                                        }
                                                }
                                }
                        }

                container host-reservations {
            description "This container provides host reservations in the host level.";
                                                list binding-info {
                                key cli-id;
                                description
                                        "A list records a binding information for each DHCPv6
                                        client that has already been alloated IPv6 addresses or prefixes
                                        by host reservations.";
                                        leaf cli-id {
                                                type uint32;
                                                mandatory true;
                                                description "client id";
                                        }
                                        container duid {
                                                description "Reads the DUID";
                                                uses dhcpv6-types:duid;
                                        }
                                        list cli-ia {
                                        key iaid;
                                        description "client IA";
                                        leaf ia-type {
                                                type string;
                                                mandatory true;
                                                description "IA type, IA_NA or IA_TA";
                                        }
                                        leaf iaid {
                                                type uint32;
                                                mandatory true;
                                                description "IAID";
                                        }
                                        leaf-list cli-addr {
                                                type inet:ipv6-address;
                                                description "client addr";
                                        }
                                }

                                        list cli-iapd {
                                                key iaid;
                                                description "client IAPD";
                                                leaf iaid {
                                                        type uint32;
                                                        mandatory true;
                                                        description "IAID";
                                                }
                                                leaf-list cli-prefix {
                                                        type inet:ipv6-prefix;
                                                        description "client ipv6 prefix";
                                                }
                                                leaf-list cli-prefix-len {
                                                        type uint8;
                                                        description "client prefix length";
                                                }
                                        }
                        }
                }

                                        }
                        }

        container packet-stats {
                description "A container presents the packet statistics related to
                        the DHCPv6 server.";
          leaf solicit-count {
                                                type uint32;
                                                mandatory true;
                                                description "solicit counter";
          }
          leaf request-count {
                                                type uint32;
                                                mandatory true;
                                                description "request counter";
          }
          leaf renew-count {
                                                type uint32;
                                                mandatory true;
                                                description "renew counter";
          }
          leaf rebind-count {
                                                type uint32;
                                                mandatory true;
                                                description "rebind counter";
          }
          leaf decline-count {
                                                type uint32;
                                                mandatory true;
                                                description "decline count";
          }
          leaf release-count {
                type uint32;
                mandatory true;
                description "release counter";
          }
          leaf info-req-count {
                type uint32;
                mandatory true;
                description "information request counter";
          }
          leaf advertise-count {
                type uint32;
                mandatory true;
                description "advertise counter";
          }
          leaf confirm-count {
                type uint32;
                mandatory true;
                description "confirm counter";
          }
          leaf reply-count {
                                                type uint32;
                                                mandatory true;
                                                description "reply counter";
          }
          leaf reconfigure-count {
                                                type uint32;
                                                mandatory true;
                                                description "reconfigure counter";
          }
          leaf relay-forward-count {
                type uint32;
                mandatory true;
                description "relay forward counter";
          }
          leaf relay-reply-count {
                type uint32;
                mandatory true;
                description "relay reply counter";
          }
        }
        }
        }

        /*
        * Notifications
        */

        notification notifications {
          description "dhcpv6 server notification module";
    container dhcpv6-server-event {
        description "dhcpv6 server event";
        container address-pool-running-out {
        description "raised when the address pool is going to
                run out.  A threshold for utilization ratio of the pool has
                been defined in the server feature so that it will notify the
                administrator when the utilization ratio reaches the
                threshold, and such threshold is a settable parameter";
        leaf total-address-count {
                type uint64;
                mandatory true;
                description "count of total addresses in the pool";
        }
        leaf max-address-count {
                type uint64;
                mandatory true;
                description "maximum count of addresses that can be allocated
                        in the pool. This value may be less than count of total
                        addresses";
        }
        leaf allocated-address-conut {
                type uint64;
                mandatory true;
                description "count of allocated addresses in the pool";
        }
                    container duid {
                        description "server duid";
                        uses dhcpv6-types:duid;
                    }
        leaf serv-name {
                type string;
                description "server name";
        }
        leaf pool-name {
                type string;
                mandatory true;
                description "pool name";
        }
        }
                container pd-pool-running-out {
        description "raised when the address/prefix pool is going to
                run out.  A threshold for utilization ratio of the pool has
                been defined in the server feature so that it will notify the
                administrator when the utilization ratio reaches the
                threshold, and such threshold is a settable parameter";
                        leaf max-pd-space-utilization {
                type threshold;
                mandatory true;
                description "maximum pd space utilization";
                }
                        leaf pd-space-utilization {
                                type threshold;
                                mandatory true;
                                description "current pd space utilization";
                        }
        container duid {
                description "Sets the DUID";
                uses dhcpv6-types:duid;
        }
        leaf serv-name {
                type string;
                description "server name";
        }
        leaf pool-name {
                type string;
                mandatory true;
                description "pool name";
        }
            }
            container invalid-client-detected {
                description "raised when the server has found a client which
                can be regarded as a potential attacker. Some description
                could also be included.";
        container duid {
                description "Sets the DUID";
                uses dhcpv6-types:duid;
        }
        leaf description {
                type string;
                description "description of the event";
                }
            }
          }
        }
}
