<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!ENTITY RFC7950 PUBLIC "" "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7950.xml">
<!ENTITY RFC2475 PUBLIC "" "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2475.xml">
<!ENTITY RFC2474 PUBLIC "" "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2474.xml">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?><?rfc strict="yes" ?>
<?rfc toc="yes"?>
<?rfc tocdepth="4"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes" ?>
<?rfc compact="yes" ?>
<?rfc subcompact="no" ?>
<rfc category="std" docName="draft-chen-rtgwg-qos-yang-03">
<front>
<title abbrev="QoS YANG">YANG Data Model for QoS</title>
<author fullname="I. Chen" initials="I." surname="Chen">
      <organization>Kuatro Technologies</organization>
      <address>
        <email>ichen@kuatrotech.com</email>
        <!-- uri and facsimile elements may also be added -->
      </address>
</author>
<date day="19" month="October" year="2016" />
<area>Routing</area>
<workgroup>RTGWG</workgroup>
<abstract>
<t>
This document defines a YANG data model to describe quality-of-service (QoS)
configurations.
</t>
</abstract>
</front>

<middle>
<section title="Introduction"> <!-- 1, line 97-->
<t>This document defines a YANG <xref target="RFC7950"/> data model to specify Quality-of-Service (QoS)
configurations.  QoS configurations include policies and profiles that
allow an administrator of a device to classify,
mark, rate-limit, and perform other actions on incoming and outgoing packets.
</t>
<section title="Tree Diagram"> <!-- 1.1, line 108-->
<t>A simplified graphical representation of the data model is presented
in Section 2.
</t>
<t>The meaning of the symbols in these diagrams is as follows:
</t>
<t>o  Brackets "[" and "]" enclose list keys.
</t>
<t>o  Curly braces "{" and "}" contain names of optional features that
   make the corresponding node conditional.
</t>
<t>o  Abbreviations before data node names: "rw" means configuration
   (read-write), and "ro" state data (read-only).
</t>
<t>o  Symbols after data node names: "?" means an optional node and "*"
   denotes a "list" or "leaf-list".
</t>
<t>o  Parentheses enclose choice and case nodes, and case nodes are also
   marked with a colon (":").
</t>
<t>o  Ellipsis ("...") stands for contents of subtrees that are not
   shown.
</t>
</section> <!-- ends: "1.1 from line 108-->
</section> <!-- ends: "1 from line 97-->
<section title="Design of the Data Model" anchor="section-1"> <!-- 2, line 136-->
<t>This data model intends to describe the processing that a device
performs on incoming and outgoing packets.  These actions include, but are not
limited to, classification of packets, mapping of packets, and rate limiting,
scheduling and queuing of packets.
</t>
<t>This data model has one top level container, qos, which
consists of several second level containers.  Each of these second level
containers describes a particular category of traffic handling, such
as mapping traffic from one class to another class.  A 
second-level container further consists of a list of different permutations of
options within a traffic processing category.
</t>
<t>For example, the "class-maps" processing category below consists of a list of
"class-map", which can be used to describe the mapping of a certain type of
incoming traffic to a certain differentiated service (DS) codepoint <xref target="RFC2475"/>
such that the device handles that type of incoming traffic as prescribed by the classification <xref target="RFC2474"/>.
</t>
<t>
<figure align="left">
<artwork align="left">
module: ietf-qos
   +--rw qos
      +--rw class-definitions
      |  +--rw class-definition* [name]
      |     +--rw name    string
      |        .
      |        .
      |        .
      +--rw class-maps
      |  +--rw class-map* [name]
      |     +--rw name        string
      |        .
      |        .
      |        .
      +--rw congestion-avoidance-maps
      |  +--rw congestion-avoidance-map* [name]
      |     +--rw name    string
      |        .
      |        .
      |        .
      +--rw profiles
      |  +--rw profile* [name]
      |     +--rw name           string
      |        .
      |        .
      |        .
      +--rw queue-maps
      |  +--rw queue-map* [name]
      |     +--rw name          string
      |        .
      |        .
      |        .
      +--rw policies
         +--rw policy* [name]
            +--rw name                   string
               .
               .
               .
</artwork>
</figure>
</t>
</section> <!-- ends: "2 from line 136-->
<section title="Related Work">
<t>
An important aspect of QoS configurations involves the pattern of specifying a set
of conditions, where matching a particular condition results in one or more actions.
This is a common pattern, and it is seen in /qos/policies branch in <xref
target="section-1"/>, as well as several other proposed YANG models
<xref target="aclyang"/> <xref target="pbfyang"/> <xref target="supayang"/>.
Another example of
a YANG module that models such a condition-action pattern is the YANG module 
ietf-qos-policy@2016-03-03.yang <xref target="dsyang"/>, which prescribes a
high-level but basic QoS policy as a set of conditions and associated actions, 
but does not include details of the conditions or the actions.  
</t>
<t>
Besides the condition-action pattern, the other similarity between the YANG
model proposed in this
document and ietf-qos-policy@2016-03-03.yang is that both claim to model QoS.
Consequently, the authors of the two documents have put in contact to
understand the similarities and differences between the two YANG models.
While there are no resolutions yet, the goal of all involved is to
eliminate unnecessary duplication and design one coherent QoS
model (or more if needed).
</t>
</section>
<section title="YANG Module"> <!-- 3, line 198-->
<t>
<figure>
<artwork><![CDATA[
<CODE BEGINS> file "ietf-qos.yang"

module ietf-qos {
  namespace "urn:ietf:params:xml:ns:yang:ietf-qos";
  prefix qos;

  organization "IETF when standardized";
  contact "IETF when standardized";

  description 
    "QOS YANG Model";

  revision "2015-06-04" {
    description "Initial revision";
    reference "";
  }
  
  typedef dscp-code-all-values-type {
    type union {
      type uint8 {
        range "0..63";
      }
      type enumeration {
        enum "af11" {
          description
            "DSCP 10";
        }
        enum "af12" {
          description
            "DSCP 12";
        }
        enum "af13" {
          description
            "DSCP 14";
        }
        enum "af21" {
          description
            "DSCP 18";
        }
        enum "af22" {
          description
            "DSCP 20";
        }
        enum "af23" {
          description
            "DSCP 22";
        }
        enum "af31" {
          description
            "DSCP 26";
        }
        enum "af32" {
          description
            "DSCP 28";
        }
        enum "af33" {
          description
            "DSCP 30";
        }
        enum "af41" {
          description
            "DSCP 34";
        }
        enum "af42" {
          description
            "DSCP 36";
        }
        enum "af43" {
          description
            "DSCP 38";
        }
        enum "cs0" {
          description
            "Class selector 000 000 (0)";
        }
        enum "cs1" {
          description
            "Class Selector 001 000 (8)";
        }
        enum "cs2" {
          description
            "Class Selector 010 000 (16)";
        }
        enum "cs3" {
          description
            "Class Selector 011 000 (24)";
        }
        enum "cs4" {
          description
            "Class Selector 100 000 (32)";
        }
        enum "cs5" {
          description
            "Class Selector 101 000 (40)";
        }
        enum "cs6" {
          description
            "Class Selector 110 000 (48)";
        }
        enum "cs7" {
          description
            "Class Selector 111 000 (56)";
        }
        enum "df" {
          description
            "Default forwarding 000 000 (0)";
        }
        enum "ef" {
          description
            "Expedited forwarding 101 110 (46)";
        }
        enum "all" {
          description
            "All classes";
        }
      }
    }
    description "dscp-code-all-values-type";
  }
  grouping radius-guided-grp {
    description "radius-guided-grp";
    leaf radius-guided {
      type empty;
      description "radius-guided";
    }
  }

  grouping mdrr-congestion-avoidance-map-grp {
    description "mdrr-congestion-avoidance-map-grp";
    leaf congestion-avoidance-map-reference {
      type leafref {
        path "/qos:qos/qos:congestion-avoidance-maps"
           + "/qos:congestion-avoidance-map/qos:name";
      }
      must
        "/qos:qos/qos:congestion-avoidance-maps" +
        "/qos:congestion-avoidance-map/" +
        "[qos:name = current()]/qos:mdrr" {
        description "Must be an mdrr congestion avoidance map";
      }
      description "congestion-avoidance-map-reference";
    }
  }
  
  grouping pwfq-congestion-avoidance-map-grp {
    description "pwfq-congestion-avoidance-map-grp";
    leaf congestion-avoidance-map-reference {
      type leafref {
        path "/qos:qos/qos:congestion-avoidance-maps"
           + "/qos:congestion-avoidance-map/qos:name";
      }
      must
        "/qos:qos/qos:congestion-avoidance-maps/" +
        "/qos:congestion-avoidance-map/" +
        "[qos:name = current()]/qos:pwfq" {
        description "Must be a pwfq congestion avoidance map";
      }
      description "congestion-avoidance-map-reference";
    }
  }

  grouping queue-map-grp {
    description "queue-map-grp";
    leaf queue-map-reference {
      type leafref {
        path "/qos:qos/qos:queue-maps/qos:queue-map/qos:name";
      }
      description "queue-map-reference";
    }
  }

  grouping rate-option-grp {
    description "rate-option-grp";
    choice burst-option {
      description "burst-option";
      case burst {
        leaf burst {
          type uint32 {
            range "1..4250000000";
          }
          units "byte";
          description "burst";
        }
      }
      case time-burst {
        leaf time-burst {
          type uint32 {
            range "1..10000";
          }
          units "millisecond";
          description "time-burst";
        }
      }
    }
    choice excess-burst-option {
      description "excess-burst-option";
      case excess-burst {
        leaf excess-burst {
          type uint32 {
            range "1..4250000000";
          }
          units "byte";
          description "excess-burst";
        }
      }
      case time-excess-burst {
        leaf time-excess-burst {
          type uint32 {
            range "1..10000";
          }
          description "time-excess-burst";
        }
      }
    }
  }

  grouping rate-counters-grp {
    description "rate-counters-grp";
    choice counter-choice {
      description "counter-choice";
      case counters {
        container counters {
          presence "";
          description "counters";
          container hierarchical-counters {
            presence "";
            description "hierarchical-counters";
            leaf dual-stack {
              type empty;
              description "dual-stack";
            }
          }
        }
      }
      case hierarchical-counters {
        container hierarchical-counters {
          presence "";
          description "hierarchical-counters";
          leaf dual-stack {
            type empty;
            description "dual-stack";
          }
        }
      }
    }
  }

  grouping rate-percentage-grp {
    description "rate-percentage-grp";
    leaf percentage {
      type uint8 {
        range "1..100";
      }
      units "percent";
      description "percentage";
    }
  }

  grouping marking-priority-detail-grp {
    description "marking-priority-detail-grp";
    choice marking-priority-detail {
      description "mark-priority-detail";
      case drop-precedence {
        leaf drop-precedence {
          type union {
            type uint8 {
              range "1..7";
            }
            type enumeration {
              enum "ignore" {
                description "ignore";
              }
            }
          }
          description "drop-precedence";
        }
      }
      case af-drop {
        leaf af-drop {
          type uint8 {
            range "1..3";
          }
          description "af-drop";
        }
      }
    }
  }

  grouping marking-grp {
    description "marking-grp";
    choice marking {
      description "marking";
      case dscp {
        leaf mark-dscp {
          type dscp-code-all-values-type;
          description "mark-dscp";
        }
      }
      case precedence {
        leaf mark-precedence {
          type uint8 {
            range "1..3";
          }
          description "mark-precedence";
        }
      }
      case priority {
        leaf mark-priority {
          type union {
            type uint8 {
              range "1..7";
            }
            type enumeration {
              enum "ignore" {
                description "ignore";
              }
            }
          }
          description "mark-priority";
        }
        uses marking-priority-detail-grp;
      }
    }
  }

  grouping rate-conform-grp {
    description "rate-conform-grp";
    container conform-handling {
      description "conform-handling";
      choice options {
        description "options";
        case mark-packet {
          uses marking-grp;
        }
        case no-action {
          leaf no-action {
            type empty;
            description "no-action";
          }
        }
      }
    }
  }

  grouping rate-exceed-grp {
    description "rate-exceed-grp";
    container exceed-handling {
      description "exceed-handling";
      choice options {
        description "options";
        case drop-packet {
          leaf drop-packet {
            type empty;
            description "drop-packet";
          }
        }
        case mark-packet {
          uses marking-grp;
        }
        case no-action {
          leaf no-action {
            type empty;
            description "no-action";
          }
        }
      }
    }
  }

  grouping rate-violate-grp {
    description "rate-violate-grp";
    container violate-handling {
      description "violate-handling";
      choice options {
        description "options";
        case drop-packet {
          leaf drop-packet {
            type empty;
            description "drop-packet";
          }
        }
        case mark-packet {
          uses marking-grp;
        }
        case no-action {
          leaf no-action {
            type empty;
            description "no-action";
          }
        }
      }
    }
  }

  grouping policy-packet-handling-grp {
    description "policy-packet-handling-grp";
    choice policy-packet-handling {
      description "policy-packet-handling";
      case mark-dscp {
        leaf mark-dscp {
          type dscp-code-all-values-type;
          description "mark-dscp";
        }
      }
      case mark-precedence {
        leaf mark-precedence {
          type uint8 {
            range "1..3";
          }
          description "mark-precedence";
        }
      }
      case mark-priority {
        leaf mark-priority {
          type union {
            type uint8 {
              range "1..7";
            }
            type enumeration {
              enum "ignore" {
                description "ignore";
              }
            }
          }
          description "mark-priority";
        }
        uses marking-priority-detail-grp;
      }
      case rate-limiting {
        choice rate-type {
          description "rate-type";
          case bit-rate-type {
            container bit-rate {
              description "bit-rate";
              uses rate-option-grp;
              uses rate-counters-grp;
              container actions {
                description "actions";
                uses rate-conform-grp;
                uses rate-exceed-grp;
              }
            }
          }
          case percentage-type {
            container percentage {
              description "percentage";
              leaf percentage {
                type uint8 {
                  range "1..100";
                }
                units "percent";
                description "percentage";
              }
              uses rate-counters-grp;
            }
          }
        }
      }
    }
  }
  
  grouping inline-rate-specifications-packet-handling-grp {
    description "inline-rate-specifications-packet-handling-grp";
    choice inline-rate-specifications {
      description "inline-rate-specifications";
      case mark-dscp {
        leaf mark-dscp {
          type dscp-code-all-values-type;
          description "mark-dscp";
        }
      }
      case mark-precedence {
        leaf mark-precedence {
          type uint8 {
            range "1..3";
          }
          description "mark-precedence";
        }
      }
      case mark-priority {
        leaf mark-priority {
          type union {
            type uint8 {
              range "1..7";
            }
            type enumeration {
              enum "ignore" {
                description "ignore";
              }
            }
          }
          description "mark-priority";
        }
        uses marking-priority-detail-grp;
      }
      case rate-limiting {
        container rate {
          description "Specify rate limits inline";
          uses rate-option-grp;
          uses rate-counters-grp;
          container actions {
            description "actions";
            uses rate-conform-grp;
            uses rate-exceed-grp;
            uses rate-violate-grp;
          }
        }
      }
    }
  }

  grouping policy-card-family-1-3-bit-rate-grp {
    description "policy-card-family-1-3-bit-rate-grp";
    leaf bit-rate {
      type uint32 {
        range "66..100000000";
      }
      description "bit-rate";
    }
  }
  
  grouping policy-card-family-2-bit-rate-grp {
    description "policy-card-family-2-bit-rate-grp";
    leaf bit-rate {
      type uint32 {
        range "5..100000000";
      }
      description "bit-rate";
    }
  }

  grouping informational-grp {
    description "informational-grp";
    leaf informational {
      type empty;
      description "informational";
    }
  }
 
  grouping metering-or-policing-grp {
    description "metering-or-policing-grp";
    uses radius-guided-grp;
    choice card-family {
      description "card-family";
      case card-family-1 {
        container card-family-1 {
          description "card-family-1";
          uses metering-or-policing-card-family-1-grp;
        }
      }
      case card-family-2 {
        container card-family-2 {
          description "card-family-2";
          uses metering-or-policing-card-family-2-grp;
        }
      }
      case card-family-3 {
        container card-family-3 {
          description "card-family-3";
          uses metering-or-policing-card-family-3-grp;
        }
      }
      case default-card-family {
        /* The default card-family is card-family-1. */
        uses metering-or-policing-card-family-1-grp;
      }
    }
  }
  
  grouping metering-or-policing-card-family-1-grp {
    description "metering-or-policing-card-family-1-grp";
    uses policy-group-grp {
      augment "policy/group/class-group/class-group/classes/class/" +
              "packet-handling" {
        description "augment packet-handling";
        uses policy-packet-handling-grp {
          augment "policy-packet-handling/" +
                  "rate-limiting/rate-type/bit-rate-type/bit-rate" {
            description "bit-rate";
            uses policy-card-family-1-3-bit-rate-grp;
          }
        }
      }
    }
    uses inline-rate-specifications-packet-handling-grp {
      augment "inline-rate-specifications/rate-limiting/rate" {
        description "augment rate";
        uses policy-card-family-1-3-bit-rate-grp;
        uses informational-grp;
      }
    }
    uses rate-calculation-exclude-layer-2-overhead-grp;
  }

  grouping metering-or-policing-card-family-2-grp {
    description "metering-or-policing-card-family-2-grp";
    uses policy-group-grp {
      augment "policy/group/class-group/class-group/classes/class/" +
              "packet-handling" {
        description "packet-handling";
        uses policy-packet-handling-grp {
          augment "policy-packet-handling/" +
                  "rate-limiting/rate-type/bit-rate-type/bit-rate" {
            description "augment bit-rate";
            uses policy-card-family-2-bit-rate-grp;
          }
        }
      }
    }
    uses inline-rate-specifications-packet-handling-grp {
      augment "inline-rate-specifications/rate-limiting/rate" {
        description "augment rate";
        uses policy-card-family-2-bit-rate-grp;
        uses informational-grp;
      }
    }
    uses rate-calculation-exclude-layer-2-overhead-grp;
  }
  
  grouping metering-or-policing-card-family-3-grp {
    description "metering-or-policing-card-family-3-grp";
    uses policy-group-grp {
      augment "policy/group/class-group/class-group/classes/class/" +
              "packet-handling" {
        description "augment packet-handling";
        uses policy-packet-handling-grp {
          augment "policy-packet-handling/" +
                  "rate-limiting/rate-type/bit-rate-type/bit-rate" {
            uses policy-card-family-2-bit-rate-grp;
            description "augment bit-rate";
          }
        }
      }
    }
    uses inline-rate-specifications-packet-handling-grp {
      augment "inline-rate-specifications/rate-limiting/rate" {
        description "augment rate";
        uses policy-card-family-1-3-bit-rate-grp;
        uses informational-grp;
      }
    }
    uses rate-calculation-exclude-layer-2-overhead-grp;
  }
  
  grouping policy-group-grp {
    description "policy-group-grp";
    container policy {
      description "policy";
      choice group {
        description "group";
        case class-group {
          container class-group {
            description "Reference a previously defined class";
            leaf class-group-reference {
              type leafref {
                path "/qos:qos/qos:class-definitions"
                   + "/qos:class-definition/qos:name";
              }
              description "class-group-reference";
            }
            container classes {
              description "classes";
              list class {
                key "name";
                max-elements 8;
                description "class";
                leaf name {
                  type leafref {
                    path "/qos:qos/qos:class-definitions"
                       + "/qos:class-definition"
                       + "[qos:name = "
                       + "current()/../../../class-group-reference]"
                       + "/qos:qos/qos:class";
                  }
                  description "name";
                }
                container packet-handling {
                  description "packet-handling";
                  leaf parent-class {
                    type string;
                    description "parent-class";
                  }
                }
              }
            }
          }
        }
        case access-group {
          container access-group {
            description "access-group";
            container ip-access-group {
              presence "Map an IPv4 access policy";
              description "Reference an IPv4 policy";
              leaf policy-name {
                type string;
                mandatory true;
                description "policy-name";
              }
              leaf context-name {
                type string;
                mandatory true;
                description "context-name";
              }
            }
            container ipv6-access-group {
              presence "Map an IPv6 access policy";
              description "Reference an IPv6 policy";
              leaf policy-name {
                type string;
                mandatory true;
                description "policy-name";
              }
              leaf context-name {
                type string;
                mandatory true;
                description "context-name";
              }
            }
            container l2-access-group {
              presence "Map a layer-2 access policy";
              description "Reference a layer-2 policy";
              leaf policy-name {
                type string;
                mandatory true;
                description "policy-name";
              }
            }
            container classes {
              description "classes";
              list class {
                key "name";
                max-elements 8;
                description "class";
                leaf name {
                  type string;
                  description "name";
                }
                container packet-handling {
                  description "packet-handling";
                  leaf parent-class {
                    type string;
                    description "parent-class";
                  }
                }
              }
            }
          }
        }
      }
    }
  }

  grouping rate-calculation-exclude-layer-2-overhead-grp {
    description "rate-calculation-exclude-layer-2-overhead-grp";
    leaf rate-calculation-exclude-layer-2-overhead {
      type empty;
      description
        "Specify that rate calculation excludes the size of" +
        "Layer 2 overhead for the layer 3 circuit on which " +
        "a policy is applied";
    }
  }

  grouping mdrr-qos-mode-grp {
    description "mdrr-qos-mode-grp";
    leaf qos-mode {
      type enumeration {
        enum "priority" {
          description "priority";
        }
        enum "strict" {
          description "strict";
        }
        enum "wrr" {
          description "wrr";
        }
      }
      default "wrr";
      description "qos-mode";
    }
  }

  grouping mdrr-queue-grp {
    description "mdrr-queue-grp";
    leaf num-queues {
      type uint8 {
        range "1 | 2 | 4 | 8";
      }
      description "num-queues";
    }
    list queue {
      when "../num-queues and ../qos-mode != 'priority'" {
        description "only when the number of queues is >= 1";
      }
      must "num < ../num-queues" {
        description "queue's num must be less than num-queues";
      }
      key "num";
      description "queue";
      leaf num {
        type uint8 {
          range "0..8";
        }
        description "num";
      }
      leaf weight {
        when "../num != 0 or ../../qos-mode != 'strict'" {
          description
          "queue 0's weight is not configurable in strict mode"; 
        }
        type uint8 {
          range "5..100";
        }
        description "weight";
      }
    }
  }

  grouping queue-0-weight-grp {
    description "queue-0-weight-group";
    leaf queue-0-weight {
      type uint8 {
        range "5..100";
      }
      units "percentage";
      must "../qos-mode != 'strict'" {
        description "qos-mode must not be strict mode";
      }
      description "queue-0-weight";
    }
  }

  grouping mdrr-rate-choice-grp {
    description "mdrr-rate-choice-grp";
    choice mdrr-rate {
      description "mdrr-rate";
      case specify-rate {
        leaf rate {
          type uint32 {
            range "56..10000000";
          }
          units "kbps";
          mandatory true;
          description "rate";
        }
        leaf burst {
          type uint32 {
            range "1..8000000";
          }
          units "byte";
          mandatory true;
          description "burst";
        }
      }
    }
  }

  grouping mdrr-grp {
    description "mdrr-grp";
    uses mdrr-congestion-avoidance-map-grp;
    uses queue-map-grp;
    uses mdrr-qos-mode-grp;
    uses mdrr-queue-grp;
    uses mdrr-rate-choice-grp;
  }

  grouping pwfq-queue-choice-priority-or-rate-grp {
    description "pwfq-queue-choice-priority-or-rate-grp";
    choice priority-or-rate {
      mandatory true;
      description "priority-or-rate";
      case priority {
        leaf priority {
          type uint8 {
            range "0..7";
          }
          mandatory true;
          description "priority";
        }
        leaf weight {
          type uint16 {
            range "1..1023";
          }
          mandatory true;
          description "weight";
        }
      }
      case rate {
        choice absolute-or-percentage {
          description "absolute-or-percentage";
          case absolute {
            leaf rate-maximum {
              type uint32 {
                range "4..10000000";
              }
              units "kbps";
              description "rate-maximum";
            }
          }
          case percentage {
            leaf rate-maximum-percentage {
              type uint8 {
                range "1..100";
              }
              units "percent";
              description "rate-maximum-percentage";
            }
          }
        }
      }
    }
  }

  grouping pwfq-queue-choice-grp {
    description "pwfq-queue-choice-grp";
    leaf num-queues {
      type uint8 {
        range "1 | 2 | 4 | 8";
      }
      description "num-queues";
    }
    list queue {
      when "../num-queues > 0" {
        description "queue entries exist only when num-queues > 0";
      }
      must "priority < ../num-queues" {
        description "queue priority must be < num-queues";
      }
      key "num";
      description "queue";
      leaf num {
        type uint8 {
          range "0..7";
        }
        description "priority";
      }
      uses pwfq-queue-choice-priority-or-rate-grp;
    }
  }

  grouping pwfq-rate-card-family-1-grp {
    description "pwfq-rate-card-family-1-grp";
    choice rate-or-weight {
      description "rate-or-weight";
      case rate-minimum {
        container rate-minimum {
          presence "Configure minimum rate";
          description "rate-minimum";
          leaf rate-minimum {
            type uint32 {
              range "8..1000000";
            }
            units "kbps";
            mandatory true;
            description "rate-minimum";
          }
          leaf burst {
            type uint32 {
              range "64..1875000000";
            }
            units "byte";
            description "burst";
          }
        }
      }
      case weight {
        leaf weight {
          type uint16 {
            range "1..1023";
          }
          description "weight";
        }
      }
    }
    container rate-maximum {
      presence "Configure maximum rate";
      description "rate-maximum";
      leaf rate-maximum {
        type uint32 {
          range "8..10000000";
        }
        units "kbps";
        mandatory true;
        description "rate-maximum";
      }
      leaf burst {
        type uint32 {
          range "64..1875000000";
        }
        units "byte";
        description "burst";
      }
    }
  }
  
  grouping pwfq-rate-card-family-2-grp {
    description "pwfq-rate-card-family-2-grp";
    choice rate-or-weight {
      description "rate-or-weight";
      case rate-minimum {
        container rate-minimum {
          presence "Configure minimum rate";
          description "rate-minimum";
          leaf rate-minimum {
            type uint32 {
              range "8..1000000";
            }
            units "kbps";
            mandatory true;
            description "rate-minimum";
          }
        }
      }
      case weight {
        leaf weight {
          type uint16 {
            range "1..4096";
          }
          description "weight";
        }
      }
    }
    container rate-maximum {
      presence "Configure maximum rate";
      description "rate-maximum";
      leaf rate-maximum {
        type uint32 {
          range "64..1000000";
        }
        units "kbps";
        mandatory true;
        description "rate-maximum";
      }
    }
  }

  grouping pwfq-rate-card-family-3-grp {
    description "pwfq-rate-card-family-3-grp";
    container rate-minimum {
      presence "Configure minimum rate";
      description "rate-minimum";
      leaf rate-minimum {
        type uint32 {
          range "8..1000000";
        }
        units "kbps";
        mandatory true;
        description "rate-minimum";
      }
      leaf burst {
        type uint32 {
          range "64..1875000000";
        }
        units "byte";
        description "burst";
      }
    }
    container rate-maximum {
      presence "Configure maximum rate";
      description "rate-maximum";
      leaf rate-maximum {
        type uint32 {
          range "8..10000000";
        }
        units "kbps";
        mandatory true;
        description "rate-maximum";
      }
      container counters {
        presence "Enable counting";
        description "counters";
        leaf dual-stack {
          type empty;
          description "Enable dual-stack costing";
        }
      }
    }
  }

  grouping pwfq-queue-priority-group-grp {
    description "pwfq-queue-priority-group-grp";
    list queue-priority-group {
      key "priority-group";
      description "queue-priority-group";
      leaf priority-group {
        type uint8 {
          range "0..7";
        }
        description "priority-group";
      }
      choice absolute-minimum-percentage {
        mandatory true;
        description "absolute-minimum-percentage";
        /* Allow users of this grouping to add different cases */
      }
    }
  }

  grouping pwfq-grp {
    description "pwfq-grp";
    choice card-family {
      description "card-family";
      case card-family-1 {
        container card-family-1 {
          must "rate-minimum/rate <= rate-maximum/rate" {
            description "minimum rate <= maximum rate";
          }
          description "card-family-1";
          uses pwfq-congestion-avoidance-map-grp;
          uses queue-map-grp;
          uses pwfq-queue-choice-grp;
          uses pwfq-queue-priority-group-grp {
            augment "queue-priority-group/"
                  + "absolute-minimum-percentage" {
              description "augment absolute-minimum-percentage";
              case rate-absolute {
                container rate-absolute {
                  description "rate-absolute";
                  leaf rate {
                    type uint32 {
                      range "8..100000000";
                    }
                    units "kbps";
                    description "rate";
                  }
                  leaf exceed {
                    type empty;
                    description "empty";
                  }
                }
              }
              case rate-percentage {
                container rate-percentage {
                  description "rate-percentage";
                  leaf rate-percentage {
                    type uint8 {
                      range "1..100";
                    }
                    units "percent";
                    description "rate-percentage";
                  }
                }
              }
            }
          }
          uses pwfq-rate-card-family-1-grp;
        }
      }
      case card-family-2 {
        container card-family-2 {
          must "rate-minimum/rate <= rate-maximum/rate" {
            description "minimum rate must be <= maximum rate";
          }
          description "card-family-2";
          uses pwfq-congestion-avoidance-map-grp;
          uses queue-map-grp;
          uses pwfq-queue-choice-grp;
          uses pwfq-queue-priority-group-grp {
            augment "queue-priority-group/"
                  + "absolute-minimum-percentage" {
              description "absolute-minimum-percentage";
              case rate-absolute {
                container rate-absolute {
                  description "rate-absolute";
                  leaf rate {
                    type uint32 {
                      range "8..10000000";
                    }
                    units "kpbs";
                    description "rate";
                  }
                  leaf exceed {
                    type empty;
                    description "exceed";
                  }
                }
              }
              case rate-percentage {
                container rate-percentage {
                  description "rate-percentage";
                  leaf rate-percentage {
                    type uint8 {
                      range "1..100";
                    }
                    units "percent";
                    description "rate-percentage";
                  }
                  leaf exceed {
                    type empty;
                    description "exceed";
                  }
                }
              }
            }
          }
          uses pwfq-rate-card-family-2-grp;
        }
      }
      case card-family-3 {
        container card-family-3 {
          must "rate-minimum/rate <= rate-maximum/rate" {
            description "minimum rate must be <= maximum rate";
          }
          description "card-family-3";
          uses pwfq-congestion-avoidance-map-grp;
          uses queue-map-grp;
          uses pwfq-queue-choice-grp;
          uses pwfq-queue-priority-group-grp {
            augment "queue-priority-group/"
                  + "absolute-minimum-percentage" {
              description "augment absolute-minimum-percentage";
              case rate-absolute {
                container rate-absolute {
                  description "rate-absolute";
                  leaf rate {
                    type uint32 {
                      range "8..100000000";
                    }
                    units "kbps";
                    description "rate";
                  }
                }
              }
              case rate-minimum {
                container rate-minimum {
                  description "rate-minimum";
                  leaf rate-minimum {
                    type uint32 {
                      range "8..100000000";
                    }
                    description "rate-minimum";
                  }
                }
              }
              case rate-percentage {
                container rate-percentage {
                  description "rate-percentage";
                  leaf rate-percentage {
                    type uint8 {
                      range "1..100";
                    }
                    units "percent";
                    description "rate-percentage";
                  }
                }
              }
              case rate-minimum-percentage {
                container rate-minimum-percentage {
                  description "rate-minimum-percentage";
                  leaf rate-minimum-percentage {
                    type uint8 {
                      range "1..100";
                    }
                    units "percent";
                    description "rate-minimum-percentage";
                  }
                }
              }
            }
          }
          uses pwfq-rate-card-family-3-grp;
        }
      }
      case default-card-family {
        /* Same as card-family-1 */
        uses pwfq-congestion-avoidance-map-grp;
        uses queue-map-grp;
        uses pwfq-queue-choice-grp;
        uses pwfq-queue-priority-group-grp {
          augment "queue-priority-group/"
                + "absolute-minimum-percentage" {
            description "augment absolute-minimum-percentage";
            case rate-absolute {
              container rate-absolute {
                description "rate-absolute";
                leaf rate {
                  type uint32 {
                    range "8..100000000";
                  }
                  units "kbps";
                  description "rate";
                }
                leaf exceed {
                  type empty;
                  description "exceed";
                }
              }
            }
            case rate-percentage {
              container rate-percentage {
                description "rate-percentage";
                leaf rate-percentage {
                  type uint8 {
                    range "1..100";
                  }
                  units "percent";
                  description "rate-percentage";
                }
                leaf exceed {
                  type empty;
                  description "exceed";
                }
              }
            }
          }
        }
        uses pwfq-rate-card-family-1-grp;
        must "rate-minimum/rate <= rate-maximum/rate" {
          description "minimum rate must be <= maximum rate";
        }
      }
    }
  }

  grouping arp-rate-limit-grp {
    description "arp-rate-limit-grp";
    container arp {
      presence "arp";
      description "arp";
      leaf rate {
        type uint32 {
          range "1..2500000";
        }
        units "packet per second";
        mandatory true;
        description "rate";
      }
      leaf burst {
        type uint32 {
          range "1..25000000";
        }
        units "packet";
        mandatory true;
        description "burst";
      }
    }
  }

  grouping qos-class-definition-grp {
    description "qos-class-definition";
    list qos {
      key "class";
      unique "dscp-code";
      description "qos class";
      leaf dscp-code {
        type uint8 {
          range "1..63";
        }
        description "dscp-code";
      }
      leaf class {
        type string {
          length "1..39";
        }
        mandatory true;
        description "class name";
      }
    }
  }
  
  grouping class-map-grp {
    description "class-map grouping";
    choice marking-type {
      description "marking-type choice";
      case atm-class-map {
        uses atm-class-map-grp;
      }
      case ethernet-class-map {
        uses ethernet-class-map-grp;
      }
      case ip-class-map {
        uses ip-class-map-grp;
      }
      case mpls-class-map {
        uses mpls-class-map-grp;
      }
    }
  }

  grouping atm-class-map-grp {
    description "atm-class-map-grp";
    container atm {
      presence "atm-class-map";
      description "atm";
      choice direction {
        description "direction choice";
        case in {
          container in {
            presence "atm-class-map-in";
            description "in";
            list atm {
              key "class";
              leaf class {
                type uint8 {
                  range "0..1";
                }
                description "class";
              }
              uses atm-in-mapping-grp;
              description "atm list";
            }
          }
        }
        case out {
          container out {
            presence "atm-class-map-out";
            description "out";
            list qos {
              key "dscp-code";
              leaf dscp-code {
                type uint8 {
                  range "0..63";
                }
                description "dscp-code";
              }
              uses atm-out-mapping;
              description "qos list";
            }
          }
        }
      }
    }
  } 

  grouping atm-in-mapping-grp {
    description "atm-in-mapping grouping";
    choice atm-in-mapping {
      description "atm-in-mapping choice";
      case to-qos {
        leaf to-qos {
          type uint8 {
            range "0..63";
          }
          description "to-qos";
        }
      }
      case use-ethernet {
        leaf use-ethernet {
          type leafref {
            path "/qos/class-maps/class-map/name";
          }
          must
            "/qos/class-maps/class-map[name = current()]/ethernet "
          + "and "
          + "/qos/class-maps/class-map[name = current()]/ethernet/"
          + "in" {
            description "must use ethernet in class-map";
          }
          description "use-ethernet";
        }
      }
      case use-ip {
        leaf use-ip {
          type leafref {
            path "/qos/class-maps/class-map/name";
          }
          must "/qos/class-maps/class-map[name = current()]/ip and"
             + "/qos/class-maps/class-map[name = current()]/ip/in" {
            description "must use ip in class-map";
          }
          description "use-ip";
        }
      }
    }
  }

  grouping atm-out-mapping {
    description "atm-out-mapping grouping";
    leaf to-atm {
      type uint8 {
        range "0..1";
      }
      description "to-atm";
    }
  }

  grouping ethernet-class-map-grp {
    description "ethernet-class-map grouping";
    container ethernet {
      presence "ethernet-class-map";
      description "ethernet";
      choice direction {
        description "direction choice";
        case in {
          container in {
            presence "ethernet-class-map-in";
            description "in";
            list ethernet {
              key "class";
              leaf class {
                type uint8 {
                  range "0..7";
                }
                description "class";
              }
              uses ethernet-in-mapping-grp;
              description "ethernet list";
            }
            uses mapping-schema-grp;
          }
        }
        case out {
          container out {
            presence "ethernet-class-map-out";
            description "out";
            list qos {
              key "dscp-code";
              leaf dscp-code {
                type uint8 {
                  range "0..63";
                }
                description "dscp-code";
              }
              uses ethernet-out-mapping-grp;
              description "qos list";
            }
            uses mapping-schema-grp;
          }
        }
      }
    }
  }

  grouping ethernet-in-mapping-grp {
    description "ethernet-in-mapping grouping";
    choice ethernet-in-mapping {
      description "ethernet-in-mapping choice";
      case to-qos {
        leaf to-qos {
          type uint8 {
            range "0..63";
          }
          description "to-qos";
        }
      }
      case use-ip {
        leaf use-ip {
          type leafref {
            path "/qos/class-maps/class-map/name";
          }
          must "/qos/class-maps/class-map[name = current()]/ip and"
             + "/qos/class-maps/class-map[name = current()]/ip/in" {
            description "must use ip in class-map";
          }
          description "use-ip";
        }
      }
    }
  }  
  
  grouping ethernet-out-mapping-grp {
    description "ethernet-out-mapping grouping";
    choice ethernet-out-mapping {
      description "ethernet-out-mapping choice";
      case to-ethernet {
        leaf to-ethernet {
          type uint8 {
            range "0..7";
          }
          description "to-ethernet";
        }
      }
      case use-ethernet {
        leaf use-ethernet {
          type leafref {
            path "/qos/class-maps/class-map/name";
          }
          must
            "/qos/class-maps/class-map[name = current()]/ethernet "
          + " and"
          + "/qos/class-maps/class-map[name = current()]/ethernet/"
          + "out" {
            description "must use ethernet out class-map";
          }
          description "use-ethernet";
        }
      }
    }
  }

  grouping mapping-schema-grp {
    description "mapping-schema grouping";
    leaf mapping-schema {
      type enumeration {
        enum "5P3D" {
          description "5P3D";
        }
        enum "6P2D" {
          description "6P2D";
        }
        enum "7P1D" {
          description "7P1D";
        }
        enum "8P0D" {
          description "7P1D";
        }
      }
      description "mapping-schema";
    }
  }

  grouping ip-class-map-grp {
    description "ip-class-map grouping";
    container ip {
      presence "ip-class-map";
      description "ip";
      choice direction {
        description "direction choice";
        case in {
          container in {
            presence "ip-class-map-in";
            description "in direction";
            list ip {
              must "dscp-code != to-qos" {
                description
                  "dscp-code must be different from to-qos";
              }
              key "dscp-code";
              leaf dscp-code {
                type uint8 {
                  range "0..63";
                }
                description "dscp-code";
              }
              leaf to-qos {
                type uint8 {
                  range "0..63";
                }
                description "to-qos";
              }
              description "ip list";
            }
          }
        }
        case out {
          container out {
            presence "ip-class-map-out";
            description "out direction";
            list qos {
              must "dscp-code != to-qos" {
                description
                  "dscp-code must be different from to-qos";
              }
              key "dscp-code";
              leaf dscp-code {
                type uint8 {
                  range "0..63";
                }
                description "dscp-code";
              }
              leaf to-ip {
                type uint8 {
                  range "0..63";
                }
                description "to-ip";
              }
              description "qos list";
            }
          }
        }
      }
    }
  }

  grouping mpls-class-map-grp {
    description "mpls-class-map grouping";
    container mpls {
      presence "mpls-class-map";
      description "mpls";
      choice direction {
        description "direction choice";
        case in {
          container in {
            presence "mpls-class-map-in";
            description "in direction";
            list mpls {
              key "exp-value";
              leaf exp-value {
                type uint8 {
                  range "0..7";
                }
                description "exp-value";
              }
              uses mpls-in-mapping-grp;
              description "mpls list";
            }
            uses mapping-schema-grp;
          }
        }
        case out {
          container out {
            presence "mpls-class-map-out";
            description "out";
            list qos {
              key "dscp-code";
              leaf dscp-code {
                type uint8 {
                  range "0..63";
                }
                description "dscp-code";
              }
              uses mpls-out-mapping-grp;
              description "qos list";
            }
            uses mapping-schema-grp;
          }
        }
      }
    }
  }

  grouping mpls-in-mapping-grp {
    description "mpls-in-mapping grouping";
    choice mapping {
      description "mapping choice";
      case to-qos {
        leaf to-qos {
          type uint8 {
            range "0..63";
          }
          description "to-qos";
        }
      }
      case use-ethernet {
        leaf use-ethernet {
          type leafref {
            path "/qos/class-maps/class-map/name";
          }
          must
            "/qos/class-maps/class-map[name = current()]/ethernet "
          + "and"
          + "/qos/class-maps/class-map[name = current()]/ethernet/"
          + "in" {
            description "must use ethernet incoming map";
          }
          description "use-ethernet";
        }
      }
      case use-ip {
        leaf use-ip {
          type leafref {
            path "/qos/class-maps/class-map/name";
          }
          must "/qos/class-maps/class-map[name = current()]/ip and"
             + "/qos/class-maps/class-map[name = current()]/ip/in" {
            description "must use ip in class-map";
          }
          description "use-ip";
        }
      }
    }
  }

  grouping mpls-out-mapping-grp {
    description "mpls-out-mapping grouping";
    choice mapping {
      description "mapping choice";
      case to-mpls {              
        leaf to-mpls {
          type uint8 {
            range "0..7";
          }
          description "to-mpls";
        }
      }
      case use-mpls {
        leaf use-mpls {
          type leafref {
            path "/qos/class-maps/class-map/name";
          }
          must
            "/qos/class-maps/class-map[name = current()]/mpls and"
          + "/qos/class-maps/class-map[name = current()]/mpls/out" {
            description "must use mpls out class-map";
          }
          description "use-mpls";
        }
      }
    }
  }
  
  grouping congestion-avoidance-map-grp {
    description "congestion-avoidance-map grouping";
    choice map-type {
      description "map-type choice";
      case mdrr {
        container mdrr {
          presence "congestion-avoidance-map-mdrr";
          description "mdrr";
          uses mdrr-map-grp;
        }
      }
      case pwfq {
        container pwfq {
          presence "congestion-avoidance-map-pwfq";
          description "pwfq";
          uses pwfq-map-grp;
        }
      }
    }
  }
  
  grouping mdrr-map-grp {
    description "mdrr-map-grp";
    list queue {
      key "num";
      description "queue";
      leaf num {
        type uint8 {
          range "0..7";
        }
        description "queue number";
      }
      uses queue-depth-grp;
      uses exponent-weighting-grp;
      uses drop-profile-grp;
    }
  }

  grouping queue-depth-grp {
    description "queue-depth-grp";
    leaf depth {
      type uint32 {
        range "1..65536";
      }
      description "depth";
    }
  }

  grouping exponent-weighting-grp {
    description "exponent-weighting-grp";
    leaf exponential-weight {
      type uint8 {
        range "1..15";
      }
      description "exponential-weight";
    }
  }

  grouping drop-profile-grp {
    description "drop-profile-grp";
    container default {
      must "min-threshold <= max-threshold" {
        description "min-threshold must be <= max-threshold";
      }
      presence "default drop profile";
      uses threshold-grp;
      description "default drop profile";
    }
    container profile-1 {
      must "min-threshold <= max-threshold" {
        description "min-threshold must be <= max-threshold";
      }
      presence "drop profile-1";
      uses threshold-grp;
      uses dscp-grp;
      description "drop profile-1";
    }
    container profile-2 {
      must "min-threshold <= max-threshold" {
        description "min-threshold must be <= max-threshold";
      }
      presence "drop profile-2";
      uses threshold-grp;
      uses dscp-grp;
      description "drop profile-2";
    }
  }

  grouping average-packet-size-grp {
    description "average-packet-size-grp";
    leaf average-packet-size {
      type uint16 {
        range "128..9600";
      }
      description "Packet size must be multiples of 128";
    }
  }

  grouping threshold-grp {
    description "threshold-grp";
    leaf min-threshold {
      type uint16 {
        range "1..10240";
      }
      mandatory true;
      description "min-threshold";
    }
    leaf max-threshold {
      type uint16 {
        range "2..10240";
      }
      mandatory true;
      description "max-threshold";
    }
    leaf probability {
      type uint16 {
        range "1..1023";
      }
      mandatory true;
      description "probability";
    }
  }

  grouping dscp-grp {
    description "dscp-grp";
    leaf-list dscp {
      type union {
        type enumeration {
          enum "af11" {
            description "DSCP 10";
          }
          enum "af12" {
            description "DSCP 12";
          }
          enum "af13" {
            description "DSCP 14";
          }
          enum "af21" {
            description "DSCP 18";
          }
          enum "af22" {
            description "DSCP 20";
          }
          enum "af23" {
            description "DSCP 22";
          }
          enum "af31" {
            description "DSCP 26";
          }
          enum "af32" {
            description "DSCP 28";
          }
          enum "af33" {
            description "DSCP 30";
          }
          enum "af41" {
            description "DSCP 34";
          }
          enum "af42" {
            description "DSCP 36";
          }
          enum "af43" {
            description "DSCP 38";
          }
          enum "cs1" {
            description "Class Selector 001 000 (8)";
          }
          enum "cs2" {
            description "Class Selector 010 000 (16)";
          }
          enum "cs3" {
            description "Class Selector 011 000 (24)";
          }
          enum "cs4" {
            description "Class Selector 100 000 (32)";
          }
          enum "cs5" {
            description "Class Selector 101 000 (40)";
          }
          enum "cs6" {
            description "Class Selector 110 000 (48)";
          }
          enum "cs7" {
            description "Class Selector 111 000 (56)";
          }
          enum "df" {
            description
              "Default forwarding 000 000 (0). "
            + "This is synonymous to cs0";
          }
          enum "ef" {
            description "Expedited forwarding 101 110 (46)";
          }
        }
        type uint8 {
          range "1..7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | "
              + "27 | 29 | 31 | 33 | 35 | 37 | 39 | 41..45 | 47 | "
              + "49..55 | 57..63";
        }
      }
      min-elements 1;
      description "dscp";
    }
  }

  grouping pwfq-map-grp {
    description "pwfq-map-grp";
    choice card-family {
      description "card-family";
      case card-family-1 {
        container card-family-1 {
          description "card-family-1";
          list queue {
            key "num";
            description "queue";
            leaf num {
              type uint8 {
                range "0..7";
              }
              description "queue number";
            }
            uses queue-depth-grp;
            uses drop-profile-grp;
          }
        }
      }
      case card-family-2 {
        description "card-family-2";
        container card-family-2 {
          description "card-family-2";
          list queue {
            key "num";
            description "queue";
            leaf num {
              type uint8 {
                range "0..7";
              }
              description "queue number";
            }
            uses queue-depth-grp;
            uses drop-profile-grp;
            uses exponent-weighting-grp;
          }
        }
      }
      case card-family-3 {
        container card-family-3 {
          description "card-family-3";
          list queue {
            key "num";
            description "queue";
            leaf num {
              type uint8 {
                range "0..7";
              }
              description "queue number";
            }
            uses queue-depth-grp;
            uses drop-profile-grp;
            uses exponent-weighting-grp;
            uses average-packet-size-grp;
          }
        }
      }
    }
  }

  grouping qos-profile-grp {
    description "qos";
    leaf name {
      type string;
      description "qos-profile name";
    }

    choice qos-profile-choice {
      mandatory true;
      description "qos-profile choice";

      case overhead {
        container overhead {
        presence "";
        description "overhead";

        container card-family {
          choice card-family {
            description "card family";

            case card-family-1 {
              description "card-family-1";
               container card-family-1 {
               presence "";
               description "card-family-1";
                container encaps-access-line {
                  description "encaps-access-line";
                  choice encaps-access-line {
                    mandatory true;
                    description "encaps-access-line";
                    case ethernet {
                      leaf ethernet {
                        type empty;
                        description "ethernet";
                      }
                    }
                    case value {
                      leaf value {
                        type uint8 {
                          range "0..255";
                        }
                        description "value";
                      }
                    }
                  }
                }
                leaf reserved {
                  type uint8 {
                    range "1..255";
                  }
                  description "reserved";
                }
              }
            }
            case card-family-2 {
              container card-family-2 {
                description "2";
                uses qos-grp;
              }
            }
            case card-family-3 {
                container card-family-3 {
                  description "3";
                  uses qos-grp;
                }
              }
            }
          description "card-family";
          }
        }
      }
      case resource {
        leaf resource {
          type empty;
          description resource ;
        }
        leaf tm-resource {
          type uint8 {
            range "1..4";
          }
          description "tm-resource";
        }
        container slot-port {
          description "slot-port";
          leaf slot-port {
            type string;
            mandatory true;
            description "slot-port";
          }
          leaf tm-resource {
            type uint8 {
              range "1..4";
            }
          description "tm-resource";
          }
        }
      }
    }
  }

  grouping qos-grp {
    description "qos";
    container encaps-access-line {
      description "encaps-access-line";
      choice encaps-access-line {
        description "encaps-access-line";
        case ether-aal5-llc {
          leaf ether-aal5-llc {
            type empty;
            description "ether-aal5-llc";
          }
        }
        case ether-aal5-llc-fcs {
          leaf ether-aal5-llc-fcs {
            type empty;
            description "ether-aal5-llc-fcs";
          }
        }
        case ether-aal5-null {
          leaf ether-aal5-null {
            type empty;
            description "ether-aal5-null";
          }
        }
        case ether-aal5-null-fcs {
          leaf ether-aal5-null-fcs {
            type empty;
            description "ether-aal5-null-fcs";
          }
        }
        case ethernet {
          leaf ethernet {
            type empty;
            description "ethernet";
          }
        }
        case ipoa-llc {
          leaf ipoa-llc {
            type empty;
            description "ipoa-llc";
          }
        }
        case ipoa-null {
          leaf ipoa-null {
            type empty;
            description "ipoa-null";
          }
        }
        case pppoa-llc {
          leaf pppoa-llc {
            type empty;
            description "pppoa-llc";
          }
        }
        case pppoa-null {
          leaf pppoa-null {
            type empty;
            description "pppoa-null";
          }
        }
        case value {
          container value {
            description "value";
            leaf value {
              type uint8 {
                range "0..255";
              }
              mandatory true;
              description "value";
            }
            container data-link {
              description "data-link";
              choice data-link {
                description "data-link";
                case atm {
                  leaf atm {
                    type empty;
                    description "atm";
                  }
                }
                case ethernet {
                  leaf ethernet {
                    type empty;
                    description "ethernet";
                  }
                }
              }
            }
          }
        }
      }
    }
    leaf rate-factor {
      type uint8 {
        range "1..100";
      }
      description "rate-factor";
    }
    leaf reserved {
      type uint8 {
        range "1..255";
      }
      description "reserved";
    }
  }
  
  grouping qos-queue-map-grp {
    description "qos";
    /* List which enter the sub-grouping num-queues-grp */
      list num-queues {
        key "num";
        description "num-queues";
        leaf num {
          type uint8 {
            range "2 | 4 | 8";
          }
          description "num-queues";
        }
        uses num-queues-grp {
          refine "queue" {
            must "id < num" {
              description
                "A queue's id must be less than number of queues";
            }
          }
        }
      }
    }

  grouping num-queues-grp {
    description "num-queues";
    list queue {
      key "id";
      description "queue";
      leaf id {
        type uint8 {
          range "0..7";
        }
        description "queue";
      }
      leaf-list priority {
        type uint8 {
          range "0..7";
        }
        description "priority";
      }
    }
  }
  container qos {
    description "qos";
    
    container class-definitions {
      description "class-definition";
      list class-definition {    
        key "name";
        max-elements 14;
        leaf name {
          type string;
          description "qos-class-definition name";
        }
        uses qos-class-definition-grp;
        description "class-definition";
      }
    }
    container class-maps {
      description "class-maps";
      list class-map {
        key "name";
        leaf name {
          type string;
          description "class-map-name";
        }
        description "class-map";
        uses class-map-grp;
      }
    }
    container congestion-avoidance-maps {
      description "congestion-avoidance-maps";
      list congestion-avoidance-map {
        key "name";
        leaf name {
          type string;
          description "congestion-avoidance-map name";
        }
        uses congestion-avoidance-map-grp;
        description "congestion-avoidance-map";
      }
    }
    container profiles {
      description "profile";
      list profile {
        key "name";
        uses qos-profile-grp;
        description "profile";
      }
    }
    container queue-maps {
      description "queue-maps";
      list queue-map {
        key "name";
        leaf name {
          type string;
          description "queue-map-name";
        }
        description "queue-map";
        uses qos-queue-map-grp;
      }
    }
    container policies {
      description "policies";
      list policy {
        key "name";
        description "policy";
        leaf name {
          type string;
          description "name";
        }
        choice policy-type {
          description "policy-type";
          case metering {
            container metering {
              presence "metering policy";
              description "metering policy";
              uses metering-or-policing-grp;
            }
          }
          case policing {
            container policing {
              presence "policing policy";
              description "policing policy";
              uses metering-or-policing-grp;
            }
          }
          case mdrr {
            container mdrr {
              presence "mdrr policy";
              description "mdrr policy";
              uses mdrr-grp;
            }
          }
          case pwfq {
            container pwfq {
              presence "pwfq policy";
              description "pwfq policy";
              uses pwfq-grp;
            }
          }
          case protocol-rate-limit {
            container protocol-rate-limit {
              presence "protocol-rate-limit policy";
              description "protocol-rate-limit policy";
              uses arp-rate-limit-grp;
            }
          }
        }
      }
    }
  }
}
<CODE ENDS>
]]>
</artwork>
</figure>
</t>
</section> <!-- ends: "3 from line 198-->
<section title="Security Consideration"> <!-- 4, line 2634-->
<t>TBD. 
</t>
</section> <!-- ends: "4 from line 2634-->
<section title="IANA Considerations"> <!-- 5, line 2640-->
<t>TBD.
</t>
</section> <!-- ends: "5 from line 2640-->
<section title="Acknowledgments"> <!-- 6, line 2646-->
<t>The author thanks Sudhakar Chunduru from Ericsson for answering my
questions about QoS. 
</t>
</section> <!-- ends: "6 from line 2646-->
</middle>
<back>
<references title="Normative References">
    &RFC7950;
    &RFC2474;
    <!--  Nichols, K., Blake, S., Baker, F., and D. Black, "Definition of theDifferentiated Services Field (DS Field) in the IPv4 and IPv6 Headers", RFC2474, DOI 10.17487/RFC2474, December 1998,<http://www.rfc-editor.org/info/rfc2474>. -->
</references>
<references title="Informative References">
    &RFC2475;
    <!--  Blake, S., Black, D., Carlson, M., Davies, E., Wang, Z., and W.Weiss, "An Architecture for Differentiated Services", RFC 2475, DOI10.17487/RFC2475, December 1998, <http://www.rfc-editor.org/info/rfc2475>. -->
  <reference anchor="dsyang" target="https://tools.ietf.org/html/draft-asechoud-netmod-qos-model-01">
    <front>
      <title>Work-in-progress, 'draft-asechoud-netmod-qos-model-01'</title>
      <author fullname="A. Choudhary" surname="Choudhary" initials="A."/>
      <author fullname="M. Jethanandani" surname="Jethanandani" initials="J."/>
      <author fullname="N. Strahle" surname="Strahle" initials="N."/>
      <author fullname="E. Aries" surname="Aries" initials="E."/>
      <date year="2016" month="July" day="15"/>
    </front>
  </reference>
  <reference anchor="aclyang"
	     target="https://tools.ietf.org/html/draft-ietf-netmod-acl-model-09">
    <front>
      <title>Work-in-progress, 'draft-ietf-netmod-acl-model-09'</title>
      <author surname="Bogdanovic" initials="D."/>
      <author surname="Sreenivasa" initials="K."/>
      <author surname="Huang" initials="L."/>
      <author surname="Blair" initials="D."/>
      <date year="2016" month="October" day="12"/>
    </front>
  </reference>
  <reference anchor="pbfyang" target="https://tools.ietf.org/html/draft-ietf-i2rs-pkt-eca-data-model-02">
    <front>
      <title>Work-in-progress, 'draft-ietf-i2rs-pkt-eca-data-model-02'</title>
      <author surname="Hares" initials="S."/>
      <author surname="Wu" initials="Q."/>
      <author surname="White" initials="R."/>
      <date year="2016" month="October"/>
    </front>
  </reference>
  <reference anchor="supayang" target="https://tools.ietf.org/html/draft-ietf-supa-generic-policy-data-model-02">
    <front>
      <title>Work-in-progress, 'draft-ietf-supa-generic-policy-data-model-02'</title>
      <author surname="Halpern" initials="J."/>
      <author surname="Strassner" initials="J."/>
      <author surname="Van der Meer" initials="S."/>
      <date year="2016" month="October"/>
    </front>
  </reference>
</references>
</back>
</rfc>
<!-- generated from file draft-yang-qos.nf with nroff2xml 0.1.0 by Tomek Mrugalski -->
