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

  import ietf-inet-types {
    prefix inet;
    reference
      "RFC 9911: Common YANG Data Types, Section 4";
  }

  import ietf-yang-types {
    prefix yang;
    reference
      "RFC 9911: Common YANG Data Types, Section 3";
  }

  import ietf-routing-types {
    prefix rt-types;
    reference
      "RFC 8294: Common YANG Data Types for the Routing Area";
  }

  import ietf-interfaces {
    prefix if;
    reference
      "RFC 8343: A YANG Data Model for Interface Management";
  }

  import ietf-routing {
    prefix rt;
    reference
      "RFC 8349: A YANG Data Model for Routing Management
                 (NMDA Version)";
  }

  organization
    "IETF Multicast Backbone Deployment (MBONED) Working Group";

  contact
    "WG Web:   <https://datatracker.ietf.org/wg/mboned/>
     WG List:  MBONED <mailto:mboned@ietf.org>

     Editor:   Yisong Liu
               <mailto:liuyisong@chinamobile.com>
     Editor:   Changwang Lin
               <mailto:linchangwang.04414@h3c.com>
     Editor:   Zheng(Sandy) Zhang
               <mailto:zhang.zheng@zte.com.cn>
     Editor:   Xuesong Geng
               <mailto:gengxuesong@huawei.com>
     Editor:   Vinod Kumar Nagaraj
               <mailto:vinkumar@juniper.net>";

  description
    "This module describes a YANG data model for managing the
     Automatic Multicast Tunneling (AMT) protocol.

     The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL', 'SHALL
     NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED', 'NOT RECOMMENDED',
     'MAY', and 'OPTIONAL' in this document are to be interpreted as
     described in BCP 14 (RFC 2119) (RFC 8174) when, and only when,
     they appear in all capitals, as shown here.

     Copyright (c) 2026 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).

     All revisions of IETF and IANA published modules can be found
     at the YANG Parameters registry group
     (https://www.iana.org/assignments/yang-parameters).

     This version of this YANG module is part of RFC XXXX; see the
     RFC itself for full legal notices.";

  revision 2026-03-10 {
    description
      "Initial Version";
    reference
      "RFC XXXX: A YANG Data Model for Automatic Multicast
                 Tunneling (AMT)";
  }

  feature amt-gateway {
    description
      "Indicates support of AMT Gateway functionality.";
    reference
      "RFC 7450: Automatic Multicast Tunneling, Section 4.1.2";
  }

  feature amt-relay {
    description
      "Indicates support of AMT Relay functionality.";
    reference
      "RFC 7450: Automatic Multicast Tunneling, Section 4.1.3";
  }

  typedef ip-multicast-source-address {
    type union {
      type rt-types:ipv4-multicast-source-address;
      type rt-types:ipv6-multicast-source-address;
    }
    description
      "This type represents a version-neutral IP multicast source
       address. The format of the textual representation implies
       the IP address family.";
  }

  identity tunnel-state-base {
    description
      "Base identity for AMT tunnel states.";
  }

  identity up {
    base tunnel-state-base;
    description
      "The AMT tunnel has been successfully established.";
  }

  identity establishing {
    base tunnel-state-base;
    description
      "The AMT tunnel is being established.";
  }

  identity initial {
    base tunnel-state-base;
    description
      "Initial AMT tunnel state.";
  }

  identity discovering {
    base tunnel-state-base;
    description
      "The Relay Discovery message has been sent
       and is waiting for the Advertisement message.";
  }

  identity requesting {
    base tunnel-state-base;
    description
      "The Request message has been sent, waiting for the Query
       message.";
  }

  identity discovery-method-base {
    description
      "Base identity for all methods used to discover an
       AMT Relay Address.

       New discovery methods should be defined by creating
       new identities derived from this base identity.";
  }

  identity by-amt-solicit {
    base discovery-method-base;
    description
      "Find the Relay Address by sending an AMT Discovery message.
       This method involves sending an AMT Discovery message to
       discover available Relays in the network.";
    reference
      "RFC 7450: Automatic Multicast Tunneling, Section 5.1.1";
  }

  identity by-dns-reverse-ip {
    base discovery-method-base;
    description
      "Find the Relay Address by DNS reverse IP AMT Discovery.

       This method uses DNS reverse IP lookup to discover AMT
       Relays based on the client's IP address.";
    reference
      "RFC 8777: DNS Reverse IP Automatic Multicast Tunneling (AMT)
                 Discovery";
  }

  augment "/rt:routing/rt:control-plane-protocols" {
    description
      "AMT augmentation to the routing instance model.";
    container amt {
      presence "Enables AMT";
      description
        "Management parameters for the AMT protocol.";
      container relay {
        if-feature "amt-relay";
        description
          "Parameters of the AMT Relay service.";
        container addresses {
          description
            "Parameters of AMT Relay Addresses.";
          list address {
            key "family";
            description
              "Each entry contains parameters for an AMT Relay
               Address identified by the 'family' key. Under
               normal operation, these addresses SHOULD belong
               to the same address family indicated by 'family'.
               Any mismatch is an indication of abnormal
               configuration and is therefore allowed to be
               reported.

               The 'anycast-prefix' serve as the discovery entry
               for AMT Relays, while unicast IP addresses
               'local-address' are the actual communication entities
               of AMT Relays. The AMT Gateway first locates the AMT
               Relay via the 'anycast-prefix' and then uses its
               'local-address' to complete all subsequent AMT
               interactions.";
            leaf family {
              type identityref {
                base rt:address-family;
              }
              description
                "Indicates the address family for the entry.";
            }
            leaf anycast-prefix {
              type inet:ip-prefix;
              description
                "An anycast IP prefix of the AMT Relay Discovery
                 Address which is used when sending discovery
                 messages to a Relay.

                 If 'family' is IPv4, it SHOULD be an IPv4 prefix;
                 If 'family' is IPv6, it SHOULD be an IPv6 prefix.

                 Any mismatch is an indication of abnormal
                 configuration and is therefore allowed to be
                 reported.";
            }
            leaf local-address {
              type inet:ip-address;
              description
                "A unicast IP address of the AMT Relay Address
                 that is statically configured on the Relay device.
                 This address is used by the AMT Gateway to establish
                 tunnels.

                 If 'family' is IPv4, it SHOULD be an IPv4 address;
                 If 'family' is IPv6, it SHOULD be an IPv6 address.

                 Any mismatch is an indication of abnormal
                 configuration and is therefore allowed to be
                 reported.";
            }
          }
        }
        leaf tunnel-limit {
          type uint32;
          description
            "The maximum number of endpoint Gateways that a Relay can
             serve simultaneously.";
        }
        leaf secret-key-rotation-interval {
          type uint32;
          units "minutes";
          description
            "Specifies the interval period for computing a new
             private secret. This maximum RECOMMENDED interval
             is 120 minutes.";
          reference
               "RFC 7450: Automatic Multicast Tunneling,
                          Section 5.3.6";
        }
        container relay-dns-resource-records {
          description
            "The DNS Resource Records (RRs) of the AMT Relay.";
          list record {
            key "source-address";
            description
              "Specifies an RR entry.";
            leaf source-address {
              type inet:ip-address;
              description
                "The unicast IP address of multicast sender.";
            }
            leaf precedence {
              type uint32;
              description
                "The precedence value of this record, used
                 for Relay selection priority.

                 Lower values indicate higher priority.
                 Relays listed in AMT Relay records with
                 a lower value for precedence are to be
                 attempted first.";
              reference
                "RFC 8777: DNS Reverse IP Automatic Multicast
                           Tunneling (AMT) Discovery,
                           Section 4.2.1";
            }
            leaf d-bit {
              type boolean;
              default false;
              description
                "If the D-bit is set to true, the Gateway MAY
                 send an AMT Request message directly to the
                 discovered Relay Address without first
                 sending an AMT Discovery message.

                 If the D-bit is set to false, the Gateway MUST
                 receive an AMT Relay advertisement message
                 for an address before sending an AMT
                 Request message to that address.";
              reference
                "RFC 8777: DNS Reverse IP Automatic Multicast
                           Tunneling (AMT) Discovery,
                           Section 4.2.2";
            }
            leaf relay-type {
              type enumeration {
                enum empty {
                  value 0;
                  description
                    "The relay field is empty.";
                }
                enum ipv4-address {
                  value 1;
                  description
                    "The relay field contains a 4-octet IPv4
                     address.";
                }
                enum ipv6-address {
                  value 2;
                  description
                    "The relay field contains a 16-octet IPv6
                     address.";
                }
                enum domain-name {
                  value 3;
                  description
                    "The relay field contains a wire-encoded
                     domain name.";
                }
              }
              description
                "Indicates the type of Relay in the AMT Relay RR.

                 Value 0 indicates that no AMT Relay should be
                 used for multicast traffic from this source.

                 Values 1 and 2 indicate that the IP address is
                 used to describe the AMT Relay.

                 Value 3 indicates that the domain name is
                 used to describe the AMT Relay.";
              reference
                "RFC 8777: DNS Reverse IP Automatic Multicast
                           Tunneling (AMT) Discovery,
                           Section 4.2.3";
            }
            leaf discovery-address {
              type inet:ip-address;
              must "(../relay-type = 'ipv4-address' or "
                 + "../relay-type = 'ipv6-address')" {
                error-message
                  "The 'discovery-address' can only be configured
                   when the 'relay-type' is ipv4-address or
                   ipv6-address.";
              }
              description
                "The IP address of AMT Relay Discovery Address.

                 When the 'relay-type' value is 1 or 2, this
                 data node is used to indicate the AMT Relay of
                 the AMT Relay RR.";
            }
            leaf domain-name {
              type inet:domain-name;
              must "../relay-type = 'domain-name'" {
                error-message
                  "The 'domain-name' can only be configured when
                   the 'relay-type' is domain-name.";
              }
              description
                "The wire-encoded domain name of the AMT Relay.

                 When the 'relay-type' value is 3, this data node
                 is used to indicate the AMT Relay of the AMT
                 Relay RR.";
            }
          }
        }
        container tunnels {
          config false;
          description
            "AMT tunnel session information, which contains
             session parameters, state, and statistics for
             all AMT tunnels established between Gateways
             and this Relay.";
          list tunnel {
            key "gateway-address gateway-port";
            description
              "Records a tunnel entry.";
            leaf gateway-address {
              type inet:ip-address;
              description
                "The IP address of an AMT Gateway.";
            }
            leaf gateway-port {
              type inet:port-number;
              description
                "The UDP port number of an AMT Gateway.";
            }
            leaf local-address {
              type inet:ip-address;
              description
                "The local IP address of the AMT Relay.";
            }
            leaf local-port {
              type inet:port-number;
              description
                "The local UDP port number of the AMT Relay.";
            }
            leaf state {
              type identityref {
                base tunnel-state-base;
              }
              description
                "The state of AMT tunnel.";
            }
            container multicast-flows {
              config false;
              description
                "The multicast flow information in the AMT tunnel.

                 Contains operational data for all multicast
                 flows being forwarded through AMT tunnels between
                 this Relay and connected Gateways.";
              list flow {
                key "source-address group-address";
                description
                  "Records the characteristics of a multicast flow.";
                leaf source-address {
                  type ip-multicast-source-address;
                  description
                    "The source IP address of a multicast flow.

                     It MUST belong to the same address family as
                     group-address.";
                }
                leaf group-address {
                  type rt-types:ip-multicast-group-address;
                  description
                    "The group IP address of a multicast flow.

                     It MUST belong to the same address family as
                     source-address.";
                }
              }
            }
            leaf multicast-group-num {
              type yang:gauge32;
              description
                "Number of multicast groups.";
            }
            leaf request-message-count {
              type yang:zero-based-counter64;
              description
                "Number of AMT Request messages received
                 in the tunnel.";
            }
            leaf membership-query-message-count {
              type yang:zero-based-counter64;
              description
                "Number of AMT membership Query messages sent
                 in the tunnel.";
            }
            leaf membership-update-message-count {
              type yang:zero-based-counter64;
              description
                "Number of AMT membership Update messages received
                 in the tunnel.";
            }
            leaf discontinuity-time {
              type yang:date-and-time;
              description
                "The time on the most recent occasion at which any
                 one or more of this AMT tunnel's counters suffered
                 a discontinuity.

                 If no such discontinuities have occurred since the
                 last re-initialization of the AMT tunnel, then this
                 node contains the time when the AMT tunnel was last
                 initialized or the tunnel was established.";
            }
          }
        }
        container relay-message-statistics {
          config false;
          description
            "Message statistics of an AMT Relay.";
          container received {
            description
              "Received message statistics of AMT Relay.";
            leaf relay-discovery {
              type yang:zero-based-counter64;
              description
                "Number of AMT Relay Discovery messages
                 received.";
            }
            leaf request {
              type yang:zero-based-counter64;
              description
                "Number of AMT membership Request messages
                 received.";
            }
            leaf membership-update {
              type yang:zero-based-counter64;
              description
                "Number of AMT membership Update messages
                 received.";
            }
            leaf teardown {
              type yang:zero-based-counter64;
              description
                "Number of AMT Teardown messages received.";
            }
          }
          container sent {
            description
              "Sent message statistics of AMT Relay.";
            leaf relay-advertisement {
              type yang:zero-based-counter64;
              description
                "Number of AMT Relay advertisement messages sent.";
            }
            leaf membership-query {
              type yang:zero-based-counter64;
              description
                "Number of AMT membership Query messages sent.";
            }
          }
          container error {
            description
              "Error message statistics of AMT Relay.";
            leaf incomplete-packet {
              type yang:zero-based-counter64;
              description
                "Number of messages received with length errors
                 so severe that further classification could not
                 occur.";
            }
            leaf invalid-mac {
              type yang:zero-based-counter64;
              description
                "Number of messages received with an invalid
                 Message Authentication Code (MAC).";
            }
            leaf unexpected-type {
              type yang:zero-based-counter64;
              description
                "Number of messages received with an unknown
                 message type specified.";
            }
            leaf invalid-relay-discovery-address {
              type yang:zero-based-counter64;
              description
                "Number of AMT Relay Discovery messages
                 received with an address other than the
                 configured anycast address.";
            }
            leaf invalid-membership-request-address {
              type yang:zero-based-counter64;
              description
                "Number of AMT membership request messages
                 received with an address other than the
                 configured AMT local address.";
            }
            leaf invalid-membership-update-address {
              type yang:zero-based-counter64;
              description
                "Number of AMT membership update messages
                 received with an address other than the
                 configured AMT local address.";
            }
            leaf incomplete-relay-discovery-messages {
              type yang:zero-based-counter64;
              description
                "Number of AMT Relay Discovery messages
                 received that are not fully formed.";
            }
            leaf incomplete-membership-request-messages {
              type yang:zero-based-counter64;
              description
                "Number of AMT membership request messages
                 received that are not fully formed.";
            }
            leaf incomplete-membership-update-messages {
              type yang:zero-based-counter64;
              description
                "Number of AMT membership update messages
                 received that are not fully formed.";
            }
            leaf no-active-gateway {
              type yang:zero-based-counter64;
              description
                "Number of AMT membership update messages
                 received for a tunnel that does not exist
                 for the Gateway that sent the message.";
            }
            leaf invalid-inner-header-checksum {
              type yang:zero-based-counter64;
              description
                "Number of AMT membership update messages
                 received with an invalid IP checksum.";
            }
            leaf gateways-timed-out {
              type yang:zero-based-counter64;
              description
                "Number of Gateways that timed out because
                 of inactivity.";
            }
          }
          leaf discontinuity-time {
            type yang:date-and-time;
            description
              "The time on the most recent occasion at which any
               one or more of this AMT tunnel's message counters
               suffered a discontinuity.

               If no such discontinuities have occurred since the
               last re-initialization of the AMT tunnel, then this
               node contains the time when the AMT tunnel was last
               initialized or the tunnel was established.";
          }
        }
      } // relay
      container gateway {
        if-feature "amt-gateway";
        description
          "Parameters of AMT Gateway service.";
        container pseudo-interfaces {
          description
            "Parameters of AMT pseudo-interface.";
          list interface {
            key "name";
            description
              "An entry of AMT pseudo-interface.";
            leaf name {
              type if:interface-ref;
              description
                "Indicates the name of a pseudo interface.";
            }
            leaf discovery-method {
              type identityref {
                base discovery-method-base;
              }
              description
                "The method used to discover the relay address.";
            }
            leaf relay-discovery-address {
              type inet:ip-address;
              description
                "Specifies the AMT Relay Discovery Address.";
            }
            leaf relay-address {
              type inet:ip-address;
              description
                "Specifies the IP address of the AMT Relay.";
            }
            leaf relay-port {
              type inet:port-number;
              description
                "The UDP port number of the AMT Relay.";
            }
            leaf local-address {
              type inet:ip-address;
              config false;
              description
                "The local IP address of this AMT tunnel.";
            }
            leaf local-port {
              type inet:port-number;
              config false;
              description
                "The local UDP port number of this AMT tunnel.";
            }
            leaf upstream-interface {
              type if:interface-ref;
              description
                "Indicates the upstream interface to reach the AMT
                 Relay.";
            }
            leaf discovery-timeout {
              type uint32;
              units "seconds";
              description
                "Initial time to wait for a response to
                 a Relay Discovery message.";
            }
            leaf discovery-retrans-count {
              type uint32;
              description
                "Maximum number of Relay Discovery retransmissions
                 to allow before terminating Relay Discovery
                 and reporting an error.";
            }
            leaf request-timeout {
              type uint32;
              units "seconds";
              description
                "Initial time to wait for a response
                 to a Request message";
            }
            leaf request-retrans-count {
              type uint32;
              description
                "Maximum number of Request retransmissions
                 to allow before abandoning a Relay and restarting
                 Relay Discovery or reporting an error.";
            }
            leaf dest-unreach-retry-count {
              type uint32;
              description
                "The maximum number of times a Gateway should
                 attempt to send the same Request or Membership
                 Update message after receiving an ICMP Destination
                 Unreachable message.";
            }
            leaf tunnel-state {
              type identityref {
                base tunnel-state-base;
              }
              config false;
              description
                "The tunnel's state.";
            }
            leaf relay-discovery-message-count {
              type yang:zero-based-counter64;
              config false;
              description
                "Number of AMT Relay Discovery messages sent
                 on the interface.";
            }
            leaf relay-advertisement-message-count {
              type yang:zero-based-counter64;
              config false;
              description
                "Number of AMT Relay advertisement messages received
                 on the interface.";
            }
            leaf request-message-count {
              type yang:zero-based-counter64;
              config false;
              description
                "Number of AMT membership request messages sent
                 on the interface.";
            }
            leaf membership-query-message-count {
              type yang:zero-based-counter64;
              config false;
              description
                "Number of AMT membership query messages received
                 on the interface.";
            }
            leaf membership-update-message-count {
              type yang:zero-based-counter64;
              config false;
              description
                "Number of AMT membership update messages sent
                 on the interface.";
            }
            leaf discontinuity-time {
              type yang:date-and-time;
              config false;
              description
                "The time on the most recent occasion at which any
                 one or more of this interface's counters suffered
                 a discontinuity.

                 If no such discontinuities have occurred since the
                 last re-initialization of the AMT tunnel based on
                 this interface, then this node contains the time
                 when the AMT tunnel was last initialized or the
                 tunnel was established.";
            }
          }
        }
        container gateway-message-statistics {
          config false;
          description
            "Message statistics of the AMT Gateway.";
          leaf discontinuity-time {
            type yang:date-and-time;
            description
              "The time on the most recent occasion at which the AMT
               Gateway message counters suffered a discontinuity.

               If no such discontinuities have occurred since the
               last re-initialization of the Gateway, then this
               data node contains the time when the Gateway was last
               initialized.";
          }
          container received {
            description
              "Received message statistics of the AMT Gateway.";
            leaf relay-advertisement {
              type yang:zero-based-counter64;
              description
                "Number of AMT Relay advertisement messages
                 received.";
            }
            leaf membership-query {
              type yang:zero-based-counter64;
              description
                "Number of AMT membership query messages
                 received.";
            }
          }
          container sent {
            description
              "Sent message statistics of the AMT Gateway.";
            leaf relay-discovery {
              type yang:zero-based-counter64;
              description
                "Number of AMT Relay Discovery messages sent.";
            }
            leaf request {
              type yang:zero-based-counter64;
              description
                "Number of AMT membership request messages sent.";
            }
            leaf membership-update {
              type yang:zero-based-counter64;
              description
                "Number of AMT membership update messages sent.";
            }
            leaf teardown {
              type yang:zero-based-counter64;
              description
                "Number of AMT teardown messages sent.";
            }
          }
        }
      } // gateway
    } // amt
  } // augment
}
