module ietf-network-bridge-scheduler {
  namespace "urn:ietf:params:xml:ns:yang:ietf-network-bridge-scheduler";
  prefix sched;

  import ietf-network-bridge {
    prefix netbr;
  }
  import ietf-network-bridge-flows {
    prefix flow;
  }
  import ietf-interfaces {
    prefix if;
  }

  organization
    "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
  contact
    "WG Web:   <http://tools.ietf.org/wg/netmod/>
     WG List:  <mailto:netmod@ietf.org>

     Editor:   Vladimir Vassilev
               <mailto:vladimir@lightside-instruments.com>";
  description
    "This module contains a collection of YANG definitions for
     description and management of network bridge schedulers.

     Copyright (c) 2020 IETF Trust and the persons identified as
     authors of the code. All rights reserved.

     Redistribution and use in source and binary forms, with or
     without modification, is permitted pursuant to, and subject
     to the license terms contained in, the Simplified BSD
     License set forth in Section 4.c of the IETF Trust's
     Legal Provisions Relating to IETF Documents
     (http://trustee.ietf.org/license-info).

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

  revision 2021-02-17 {
    description
      "Initial revision.";
    reference
      "RFC XXXX: Network Bridge";
  }

  identity gate-controller {
    description
      "Represents the gate control block type e.g. round-robin,
       priority-based, time-aware-802dot1qbv etc.";
  }

  identity aggregator {
    base gate-controller;
    description
      "Abstract identity that all gate control blocks with multiple
       inputs and single output use as basetype e.g. round-robin,
       priority-based, time-aware-802dot1qbv etc.";
  }

  identity filter {
    base gate-controller;
    description
      "Abstract identity that all gate control blocks with corresponding
       input and output instances use as basetype e.g. rate-limiters,
       simple propagation delays, shapers etc.";
  }

  identity gate-controller-input {
    description
      "Identifies gate controller input type.";
  }

  identity private-queue-aggregator-input {
    base gate-controller-input;
    description
      "Abstract input identifier for gate controller
       inputs of the aggregator type where all
       instances of the input types derived from
       this identifier have their own private queue.";
  }

  identity shared-queue-aggregator-input {
    base gate-controller-input;
    description
      "Abstract input identifier for gate controller
       inputs of the aggregator type where all
       instances of the input types derived from
       this identifier have shared queue.";
  }

  identity filter-input {
    base gate-controller-input;
    description
      "Abstract input identifier for gate controller
       inputs of the filter type.";
  }

  identity traffic-class {
    description
      "Identifies traffic class.";
  }

  identity port-class {
    description
      "Identifies port class. Ports that belong to a class
       will have the same scheduler-class on their egress
       and have identical flow path through the rest of
       the scheduler classes.";
  }

  typedef port-class-ref {
    type leafref {
      path "/netbr:bridge/sched:port-classes/sched:port-class";
    }
    description
      "This type is used by data models that need to reference
       configured port-class.";
  }

  typedef traffic-class-ref {
    type leafref {
      path "/netbr:bridge/sched:traffic-classes/sched:traffic-class";
    }
    description
      "This type is used by data models that need to reference
       configured traffic-class.";
  }

  grouping gate-controller-input-config {
    description
      "Common gate controller input configuration data definitions.";
    leaf constant-propagation-delay {
      type uint64;
      units "picoseconds";
      description
        "Constant delay attributed to delays in the gate-controller.";
    }
    leaf configurable-delay-line {
      type uint64;
      units "picoseconds";
      description
        "Some gate controllers can delay the flow of packets with
         configurable delay which is added to the constant
         propagation-delay. Only inputs with zero queue lengths
         have deterministic delays equal to the sum of the
         constant-propagation-delay and the configurable-delay-line
         leafs. Inputs with queues have variable higher delay with
         dynamic component based on the controllers logic.";
    }
    leaf queue-len {
      type uint32;
      units "bytes";
      description
        "Length of the queue.";
    }
  }

  grouping gate-controller-queue-state {
    description
      "Common gate controller queue state data definitions.";
    leaf queued-pkts {
      type uint64;
      config false;
      description
        "Number of packets queued.";
    }
    leaf queued-bytes {
      type uint64;
      config false;
      description
        "Number of bytes of the packets queued.";
    }
    leaf discards {
      type uint64;
      config false;
      description
        "The total number of discarded packets that were
         received on this input. This includes but is not
         limited to the overflow-discards. For example
         gate-controllers can start discarding certain
         packets before the input queue is filled. These
         discards are not registered as overflow-discards.

         The lower 32 bits of the sum of all discards
         counters part of a scheduler are equal to the
         /if:interfaces/if:interface/if:statistics/if:out-discards
         counter for the corresponding interface.";
    }
    leaf overflow-discards {
      type uint64;
      config false;
      description
        "Unintended discard caused by overflow of
         the input queue of the gate controller.";
    }
    leaf error-discards {
      type uint64;
      config false;
      description
        "Unintended discards caused by error
         in the scheduler.";
    }
  }

  augment "/flow:flows/flow:flow" {
    description
      "Adds traffic-class to the flow model.";
    leaf traffic-class {
      type leafref {
        path "/netbr:bridge/sched:traffic-classes/sched:traffic-class";
      }
      description
        "Specifies the traffic class of a flow.
         When not present the default traffic class is used.";
    }
  }

  augment "/netbr:bridge/netbr:ports/netbr:port" {
    description
      "Adds port class and class-instance-index leafs.";
    leaf class {
      type port-class-ref;
      description
        "A port class allows discrimination of ports based on features
         and supported scheduler options.";
    }
    leaf class-instance-index {
      type uint32;
      description
        "Index enumerating the instances of the same port class.";
    }
  }

  augment "/netbr:bridge" {
    description
      "Adds scheduler specific data to the bridge model.";
    leaf default-traffic-class {
      type traffic-class-ref;
      description
        "Specifies the traffic-class for flows without
         /flow:flows/flow:flow/sched:traffic-class leaf.";
    }
    leaf default-port-class {
      type traffic-class-ref;
      description
        "Specifies the traffic-class for flows without
         /flow:flows/flow:flow/sched:traffic-class leaf.";
    }
    container traffic-classes {
      description
        "Contains the leaf-list of available traffic classes.";
      leaf-list traffic-class {
        type identityref {
          base traffic-class;
        }
        description
          "Leaf-list of available traffic classes.";
      }
    }
    container port-classes {
      description
        "Contains the leaf-list of available port classes.";
      leaf-list port-class {
        type identityref {
          base port-class;
        }
        description
          "Leaf-list of available port classes.";
      }
    }
  }

  augment "/if:interfaces/if:interface" {
    description
      "Augments the interface model with scheduler specific data.";
    container scheduler {
      description
        "Each egress capable interface has scheduler. The scheduler
         is a tree of interconnected gate controllers.";
      container gate-controllers {
        description
          "Contains the list of gate controllers.";
        list gate-controller {
          key "id";
          description
            "The gate controller model can be augmented by
             external modules defining custom gate controller
             types.";
          leaf id {
            type string;
            description
              "Gate controller identifier.";
          }
          leaf type {
            type identityref {
              base gate-controller;
            }
            mandatory true;
            description
              "Gate controller type.";
          }
          container inputs {
            description
              "Contains the list of inputs.";
            list input {
              key "class index";
              description
                "Double key list. There can be multiple
                 instances of each input class.";
              leaf class {
                type identityref {
                  base gate-controller-input;
                }
                description
                  "Input class.";
              }
              leaf index {
                type uint32;
                description
                  "Index of the input instance of the corresponding
                   input class.";
              }
              uses gate-controller-queue-state;
            }
          }
          container input-classes {
            description
              "Contains the list of input-classes.";
            list input-class {
              key "class";
              description
                "Contains configuration and state data that is common
                 for all instances of certain input class.";
              leaf class {
                type identityref {
                  base gate-controller-input;
                }
                description
                  "Input class.";
              }
              uses gate-controller-queue-state;
            }
          }
        }
      }
    }
  }

  augment "/netbr:bridge" {
    description
      "Augments the bridge module with
       scheduler specific configuration data.";
    container scheduler-classes {
      description
        "Contains list of scheduler-classes.";
      list scheduler-class {
        key "egress-port-class";
        description
          "All ports of same class inherit the scheduler configuration.
           The instance specific scheduler configuration defined under
           /interfaces/interface/scheduler can override this
           configuration.";
        leaf egress-port-class {
          type sched:port-class-ref;
          description
            "The port class the scheduler coonfiguration
             applies for.";
        }
        container inputs {
          description
            "Contains list of inputs.";
          list input {
            key "traffic-class ingress-port-class";
            description
              "Double key list. There can be multiple
               instances of each input class.";
            leaf traffic-class {
              type traffic-class-ref;
              description
                "Reference to traffic class.";
            }
            leaf ingress-port-class {
              type port-class-ref;
              description
                "Reference to port class.";
            }
            leaf gate-controller {
              type leafref {
                path "../../../gate-controllers/gate-controller/id";
              }
              description
                "Reference to gate controller id.";
            }
            leaf input-class {
              type leafref {
                path "../../../gate-controllers/gate-controller"
                   + "[id=current()/../gate-controller]"
                   + "/inputs/input/class";
              }
              description
                "Reference to a input class defined for the specified
                 gate controller.";
            }
            leaf base-index {
              type uint32;
              default "0";
              description
                "Base index for the inputs of this class.";
            }
          }
        }
        container gate-controllers {
          description
            "Contains the list of gate controllers.";
          list gate-controller {
            key "id";
            description
              "The gate controller model can be augmented by
               external modules defining custom gate controller
               types.";
            leaf id {
              type string;
              description
                "Gate controller identifier.";
            }
            leaf type {
              type identityref {
                base gate-controller;
              }
              mandatory true;
              description
                "Gate controller type.";
            }
            container inputs {
              description
                "Contains the list of inputs.";
              list input {
                key "class";
                description
                  "Double key list. There can be multiple
                   instances of each input class.";
                leaf class {
                  type identityref {
                    base gate-controller-input;
                  }
                  mandatory true;
                  description
                    "Input class.";
                }
                leaf instance-count {
                  type uint32;
                  description
                    "Number of input instances of the specified
                     class.";
                }
                uses gate-controller-input-config;
              }
            }
            container output {
              description
                "Configuration of the gate-controller input
                  the output is connected to.";
              leaf gate-controller {
                type leafref {
                  path "../../../gate-controller/id";
                }
                description
                  "Specifies the gate-controller
                   this output is connected to.";
              }
              leaf input-class {
                type leafref {
                  path "../../../gate-controller"
                     + "[id=current()/../gate-controller]/"
                     + "inputs/input/class";
                }
                description
                  "Specifies the input-class of the gate-controller
                   the input this output is connected to.";
              }
              leaf index {
                type uint32;
                description
                  "In case the gate-controller is aggregator this is the
                   index of the only input it is connected to from the
                   specified class.
                   If the gate-controller is filter with more then one
                   input-output pairs this is the base index and the
                   remaining indexes are connected to consecutive input
                   indexes of the specified input class.";
              }
            }
          }
        }
      }
    }
  }
}
