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

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

  organization
    "IETF DHC (Dynamic Host Configuration) Working group";

  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 relay.";

    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 relay specific
       YANG model.";
    reference
      "I-D: draft-ietf-dhc-dhcpv6-yang";
  }

  /*
   * Data Nodes
   */

  container relay {
    presence
      "Enables the relay";
    description
      "DHCPv6 relay portion";

    container relay-config {
      description
        "This container contains the configuration data
        of the relay.";
      container relay-attributes {
        description
          "A container describes some basic attributes of the relay
           agent including some relay agent specific options data that
           need to be configured previously.
           Such options include Remote-Id option and Subscriber-Id
           option.";
        leaf name {
          type string;
          description
            "Relay agent name";
        }
        leaf description {
          type string;
          description
            "Textual description of the relay agent";
        }
        leaf-list dest-addrs {
          type inet:ipv6-address;
          description
            "Each DHCPv6 relay agent may be configured with a list
             of destination addresses.
             This node defines such a list of IPv6 addresses that
             may include unicast addresses, multicast addresses or
             other addresses.";
        }
        list subscribers {
          key subscriber;
          description
            "Subscribers";
          leaf subscriber {
            type uint8;
            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";
          }
        }
        uses dhcpv6-types:vendor-infor;
      }

      container rsoo-option-sets {
        description
         "DHCPv6 relay agent could provide some information that would
          be useful to DHCPv6 client.
          Since relay agent cannot provide options directly to the
          client, RSOO-enabled options are defined to propose options
          for the server to send to the client.
          This container models such RSOO-enabled options.";
        reference
          "RFC6422";
        list option-set {
          key option-set-id;
          description
            "This list under the 'rsoo-option-sets' container is similar
             to the that defined in server module.
             It allows the relay to implement several sets of RSOO-enabled
             options for different interfaces.
             The list only includes the EAP Re-authentication Protocol
             (ERP) Local Domain Name DHCPv6 Option defined in RFC6440,
             since it is the only one RSOO-enabled options accepted by
             IANA so far.";
          leaf option-set-id {
            type uint32;
            description "Option sed id";
          }
          uses dhcpv6-options:relay-supplied-option-definitions;
        }
      }

      list relay-if {
        // if - This should reference an entry in ietf-interfaces
        key if-name;
        description
        "A relay agent may have several interfaces, we should provide
         a way to configure and manage parameters on the interface-level.
         A list that describes specific interfaces and their corresponding
         parameters is employed to fulfil the configfuration. Here we use
         a string called 'if-name' as the key of list.";
        leaf if-name {
          type if:interface-ref;
          mandatory true;
          description
            "Interface name";
        }
        leaf interface-id {
          type string;
          description
            "Interface id";
        }

        /*
        leaf enable {
          type boolean;
          mandatory true;
          description "whether this interface is enabled";
        }
        */

        leaf ipv6-address {
          type inet:ipv6-address;
          description
            "IPv6 address for this interface";
        }

        leaf rsoo-option-set-id {
          type leafref {
            path "/relay/relay-config/rsoo-option-sets/option-set/option-set-id";
          }
          description "Configured Relay Supplied Option set";
        }

        list next-entity {
          key dest-addr;
          description
            "This node defines a list that is used to describe the
             next hop entity of this relay distinguished by their
             addresses.";
          leaf dest-addr {
            type inet:ipv6-address;
            mandatory true;
            description
              "Destination addr";
          }
          leaf available {
            type boolean;
            mandatory true;
            description
              "Whether the next entity is available or not";
          }
          leaf multicast {
            type boolean;
            mandatory true;
            description
              "Whether the address is multicast or not";
          }
          leaf server {
            type boolean;
            mandatory true;
            description
              "Whether the next entity is a server";
          }
        }
      }
    }


    container relay-state {
      config "false";
      description
        "State data of relay";
      list relay-if {
        key if-name;
        description
        "A relay agent may have several interfaces, we should provide
         a way to configure and manage parameters on the interface-level.
         A list that describes specific interfaces and their corresponding
         parameters is employed to fulfil the configfuration. Here we use
         a string called 'if-name' as the key of list.";
        leaf if-name{
          type string;
          mandatory true;
          description
            "Interface name";
        }
        list pd-route {
          // if - need to look at if/how we model these. If they are
          // going to be modelled, then they should be ro state
          // entries (we're not trying to configure routes here)
          key pd-route-id;
          description "pd route";
          leaf pd-route-id {
            type uint8;
            mandatory true;
            description
              "PD route id";
          }
          leaf requesting-router-id {
            type uint32;
            mandatory true;
            description
              "Requesting router id";
          }
          leaf delegating-router-id {
            type uint32;
            mandatory true;
            description
              "Delegating router id";
          }
          leaf next-router {
            type inet:ipv6-address;
            mandatory true;
            description
              "Next router";
          }
          leaf last-router {
            type inet:ipv6-address;
            mandatory true;
            description
              "Previous router";
          }
        }
        list next-entity {
          key dest-addr;
          description "This node defines a list that is used to
            describe the next hop entity of this relay agent.
            Different entities are distinguished by their
            addresses.";
          leaf dest-addr {
            type inet:ipv6-address;
            mandatory true;
            description "destination addr";
          }
          container packet-stats {
            description "packet statistics";
            leaf solicit-rvd-count {
              type uint32;
              mandatory true;
              description "solicit received counter";
            }
            leaf request-rvd-count {
              type uint32;
              mandatory true;
              description "request received counter";
            }
            leaf renew-rvd-count {
              type uint32;
              mandatory true;
              description "renew received counter";
            }
            leaf rebind-rvd-count {
              type uint32;
              mandatory true;
              description "rebind recevied counter";
            }
            leaf decline-rvd-count {
              type uint32;
              mandatory true;
              description "decline received counter";
            }
            leaf release-rvd-count {
              type uint32;
              mandatory true;
              description "release received counter";
            }
            leaf info-req-rvd-count {
              type uint32;
              mandatory true;
              description "information request counter";
            }
            leaf relay-for-rvd-count {
              type uint32;
              mandatory true;
              description "relay forward received counter";
            }
            leaf relay-rep-rvd-count {
              type uint32;
              mandatory true;
              description "relay reply received counter";
            }
            leaf packet-to-cli-count {
              type uint32;
              mandatory true;
              description "packet to client counter";
            }
            leaf adver-sent-count {
              type uint32;
              mandatory true;
              description "advertisement sent counter";
            }
            leaf confirm-sent-count {
              type uint32;
              mandatory true;
              description "confirm sent counter";
            }
            leaf reply-sent-count {
              type uint32;
              mandatory true;
              description "reply sent counter";
            }
            leaf reconfig-sent-count {
              type uint32;
              mandatory true;
              description "reconfigure sent counter";
            }
            leaf relay-for-sent-count {
              type uint32;
              mandatory true;
              description "relay forward sent counter";
            }
            leaf relay-rep-sent-count {
              type uint32;
              mandatory true;
              description "relay reply sent counter";
            }
          }
        }
      }
      container relay-stats {
        config "false";
        description
          "Relay statistics";
        leaf cli-packet-rvd-count {
          type uint32;
          mandatory true;
          description
            "Client packet received counter";
        }
        leaf relay-for-rvd-count {
          type uint32;
          mandatory true;
          description
            "Relay forward received counter";
        }
        leaf relay-rep-rvd-count {
          type uint32;
          mandatory true;
          description
            "Relay reply recevied counter";
        }
        leaf packet-to-cli-count {
          type uint32;
          mandatory true;
          description
            "Packet to client counter";
        }
        leaf relay-for-sent-count {
          type uint32;
          mandatory true;
          description
            "Relay forward sent counter";
        }
        leaf relay-rep-sent-count {
          type uint32;
          mandatory true;
          description
            "Relay reply sent counter";
        }
        leaf discarded-packet-count {
          type uint32;
          mandatory true;
          description
            "Discarded packet counter";
        }
      }
    }
  }

  /*
   * Notifications
   */

  notification notifications {
    description "DHCPv6 relay notification module";
    container dhcpv6-relay-event {
      description
        "DHCPv6 relay event";
      container topo-changed {
        description
        "Raised when the topology of the relay agent is changed.";
        leaf relay-if-name {
          type string;
          mandatory true;
          description
            "Relay interface name";
        }
        leaf first-hop {
          type boolean;
          mandatory true;
          description
            "First hop";
        }
        leaf last-entity-addr {
          type inet:ipv6-address;
          mandatory true;
          description
            "Last entity address";
        }
      }
    }
  }
}
