An Information Model for Packet Discard Reporting
John Evans
Amazon
1 Principal Place, Worship Street
London
EC2A 2FA
UK
jevanamz@amazon.co.uk
Oleksandr Pylypenko
Amazon
410 Terry Ave N
Seattle
WA
98109
US
opyl@amazon.com
Jeffrey Haas
Juniper Networks
1133 Innovation Way
Sunnyvale
CA
94089
US
jhaas@juniper.net
Aviran Kadosh
Cisco Systems, Inc.
170 West Tasman Dr.
San Jose
CA
95134
US
akadosh@cisco.com
Mohamed Boucadair
Orange
France
mohamed.boucadair@orange.com
18 October 2024
Operations and Management Area
OPSAWG
Internet-Draft
The primary function of a network is to transport and deliver packets according to service level objectives. Understanding both where and why packet loss occurs within a network is essential for effective network operation. Device-reported packet loss provides the most direct signal for network operations to identify the customer impact resulting from unintended packet loss. This document defines an information model for packet loss reporting, which classifies these signals to enable automated network mitigation of unintended packet loss.
Introduction
To effectively automate network operations, a network operator must be able to detect anomalous packet loss, determine its root cause, and then apply appropriate actions to mitigate any customer-impacting issues. Some packet loss is normal or intended in IP/MPLS networks, however. Therefore, precise classification of packet loss signals is crucial both to ensure that anomalous packet loss is easily detected and that the right action or sequence of actions is taken to mitigate the impact, as taking the wrong action can make problems worse.
Existing metrics for reporting packet loss, such as ifInDiscards, ifOutDiscards, ifInErrors, and ifOutErrors defined in [RFC1213], are insufficient for several reasons. First, they lack precision; for instance, ifInDiscards aggregates all discarded inbound packets without specifying the cause, making it challenging to distinguish between intended and unintended discards. Second, these definitions are ambiguous, leading to inconsistent vendor implementations. For example, in some implementations ifInErrors accounts only for errored packets that are dropped, while in others, it includes all errored packets, whether they are dropped or not. Many implementations support more discard metrics than these, however, they have been inconsistently implemented due to the lack of a standardised classification scheme and clear semantics for packet loss reporting. For example, [RFC7270] provides support for reporting discards per flow in IPFIX using forwardingStatus, however, the defined drop reason codes also lack sufficient clarity (e.g., the "For us" reason code) to support automated root cause analysis and impact mitigation.
Hence, this document presents an information model for packet loss reporting, introducing a classification scheme to facilitate automated mitigation of unintended packet loss. The model addresses the aforementioned issues while remaining protocol-agnostic and implementation-independent, in accordance with [RFC3444].
The specific implementations of this information model (i.e., protocols and associated data models) are outside the scope of this document. The scope of this document is limited to reporting packet loss at Layer 3 and frames discarded at Layer 2, although the information model might be extended in future to cover segments dropped at Layer 4. This document considers only the signals that may trigger automated mitigation plans and not how they are defined or executed.
Section 3 describes the problem to be solved. Section 4 describes the information model and requirements with a set of examples. Section 5 provides examples of discard signal-to-cause-to-auto-mitigation action mapping. Section 6 presents the information model as an abstract data structure in YANG, in accordance with [RFC8791]. Appendix A provides an example of where packets may be discarded in a device. Appendix B details the authors' experience from implementing this model.
Terminology
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 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.
A packet discard is any packet dropped by a device, whether intentionally or unintentionally.
Intended packet loss refers to packet discards that occur due to deliberate network policies or configurations - such as Access Control Lists (ACLs) or policing mechanisms - designed to enforce security or quality of service.
Unintended packet loss refers to packet discards resulting from network errors, misconfigurations, hardware failures, or other anomalies not aligned with the network operator's intended behaviour. These losses negatively impact network performance and service delivery.
For example, intended packet loss occurs when packets are dropped because they match a security policy denying certain traffic types. Unintended packet loss might happen due to a faulty interface causing corrupted packets, leading to their discard.
The meanings of the symbols in the YANG tree diagrams are defined in [RFC8340].
Problem Statement
At the highest-level, unintended packet loss is the discarding of packets that the network operator otherwise intends to deliver, i.e. which indicates an error state. There are many possible reasons for unintended packet loss, including: erroring links may corrupt packets in transit; incorrect routing tables may result in packets being dropped because they do not match a valid route; configuration errors may result in a valid packet incorrectly matching an Access Control List (ACL) and being dropped. While the specific definition of unintended packet loss is network-dependent, for any network there are a small set of potential actions that can be taken to minimise customer impact by automatically mitigating unintended packet loss:
1. Take a device, link, or set of devices and/or links out of service.
2. Return a device, link, or set of devices and/or links back into service.
3. Move traffic to other links or devices.
4. Roll back a recent change to a device that might have caused the problem.
5. Escalate to a network operator as a last resort.
A precise signal of impact is crucial, as taking the wrong action can be worse than taking no action. For example, taking a congested device out of service can make congestion worse by moving the traffic to other links or devices, which are already congested.
To detect whether device-reported discards indicate a problem and to determine what actions should be taken to mitigate the impact and remediate the cause, depends on four primary features of the packet loss signal:
FEATURE-LOSS-CAUSE:
The cause of the loss.
FEATURE-LOSS-RATE:
The rate and/or degree of the loss.
FEATURE-LOSS-DURATION:
The duration of the loss.
FEATURE-LOSS-LOCATION:
The location of the loss.
FEATURE-LOSS-RATE, FEATURE-LOSS-DURATION, and FEATURE-LOSS-LOCATION are already addressed with passive monitoring statistics, for example, obtained with SNMP [RFC1157] / MIB-II [RFC1213] or NETCONF [RFC6241]. FEATURE-LOSS-CAUSE, however, is dependent on the classification scheme used for packet loss reporting. The next section defines a new classification scheme to address this problem.
Information Model
Design Rationale
This document uses YANG [RFC6020] to represent the information model for three main reasons. First, YANG, along with its data structure extensions [RFC8791], allows designers to define the model in an abstract way, decoupled from specific implementations. This abstraction ensures consistency and provides flexibility for diverse potential implementations, with the structure and groupings easily adaptable to data models such as those specific to SNMP [RFC1157], NETCONF [RFC6241], RESTCONF [RFC8040], or IPFIX [RFC7011]. Second, this approach ensures a lossless translation from the information model to a YANG data model, preserving both semantics and structure. Lastly, YANG capitalises on the community's broad familiarity with its syntax and use, facilitating easier adoption and evolution.
Structure
The classification scheme is structured as a hierarchical tree that follows the structure: component/direction/type/layer/sub-type/sub-sub-type/.../metric. The elements of the tree are defined as follows:
- Component: Specifies where in the device the discards are accounted. It can be:
  - interface: discards of traffic to or from a specific network interface.
  - device: discards of traffic transiting the device.
  - control-plane: discards of traffic to or from the device's control plane.
  - flow: discards of traffic associated with a specific traffic flow.
- Direction:
  - ingress: counters for incoming packets or frames.
  - egress: counters for outgoing packets or frames.
- Type:
  - traffic: counters for successfully received or transmitted packets or frames.
  - discards: counters for packets or frames that were dropped.
- Layer:
  - l2: Layer 2 discards, such as frames with CRC errors.
  - l3: Layer 3 discards, such as IP packets with invalid headers.
- Sub-Type:
  - For discards:
    - errors: discards due to errors in processing packets or frames (e.g., checksum errors).
    - policy: discards due to policy enforcement (e.g., ACL drops).
    - no-buffer: discards due to lack of buffer space (e.g., congestion-related drops).
Each sub-type may further contain specific reasons for discards, providing more detailed insight into the cause of packet loss.

module: ietf-packet-discard-reporting

  structure packet-discard-reporting:
    +-- interface* [name]
       +-- name             string
       +-- ingress
       |  +-- traffic
       |  |  +-- l2
       |  |  |  +-- frames?   uint64
       |  |  |  +-- bytes?    uint64
       |  |  +-- l3
       |  |  |  +-- address-family-stat* [address-family]
       |  |  |     +-- address-family    identityref
       |  |  |     +-- packets?          uint64
       |  |  |     +-- bytes?            uint64
       |  |  |     +-- unicast
       |  |  |     |  +-- packets?   uint64
       |  |  |     |  +-- bytes?     uint64
       |  |  |     +-- multicast
       |  |  |        +-- packets?   uint64
       |  |  |        +-- bytes?     uint64
       |  |  +-- qos
       |  |     +-- class* [id]
       |  |        +-- id         string
       |  |        +-- packets?   uint64
       |  |        +-- bytes?     uint64
       |  +-- discards
       |     +-- l2
       |     |  +-- frames?   uint64
       |     |  +-- bytes?    uint64
       |     +-- l3
       |     |  +-- address-family-stat* [address-family]
       |     |     +-- address-family    identityref
       |     |     +-- packets?          uint64
       |     |     +-- bytes?            uint64
       |     |     +-- unicast
       |     |     |  +-- packets?   uint64
       |     |     |  +-- bytes?     uint64
       |     |     +-- multicast
       |     |        +-- packets?   uint64
       |     |        +-- bytes?     uint64
       |     +-- errors
       |     |  +-- l2
       |     |  |  +-- rx
       |     |  |     +-- frames?          uint32
       |     |  |     +-- crc-error?       uint32
       |     |  |     +-- invalid-mac?     uint32
       |     |  |     +-- invalid-vlan?    uint32
       |     |  |     +-- invalid-frame?   uint32
       |     |  +-- l3
       |     |  |  +-- rx
       |     |  |  |  +-- packets?          uint32
       |     |  |  |  +-- checksum-error?   uint32
       |     |  |  |  +-- mtu-exceeded?     uint32
       |     |  |  |  +-- invalid-packet?   uint32
       |     |  |  +-- ttl-expired?     uint32
       |     |  |  +-- no-route?        uint32
       |     |  |  +-- invalid-sid?     uint32
       |     |  |  +-- invalid-label?   uint32
       |     |  +-- internal
       |     |     +-- packets?        uint32
       |     |     +-- parity-error?   uint32
       |     +-- policy
       |     |  +-- l2
       |     |  |  +-- frames?   uint32
       |     |  |  +-- acl?      uint32
       |     |  +-- l3
       |     |     +-- packets?      uint32
       |     |     +-- acl?          uint32
       |     |     +-- policer
       |     |     |  +-- packets?   uint32
       |     |     |  +-- bytes?     uint32
       |     |     +-- null-route?   uint32
       |     |     +-- rpf?          uint32
       |     |     +-- ddos?         uint32
       |     +-- no-buffer
       |        +-- class* [id]
       |           +-- id         string
       |           +-- packets?   uint64
       |           +-- bytes?     uint64
       +-- egress
       |  +-- traffic
       |  |  +-- l2
       |  |  |  +-- frames?   uint64
       |  |  |  +-- bytes?    uint64
       |  |  +-- l3
       |  |  |  +-- address-family-stat* [address-family]
       |  |  |     +-- address-family    identityref
       |  |  |     +-- packets?          uint64
       |  |  |     +-- bytes?            uint64
       |  |  |     +-- unicast
       |  |  |     |  +-- packets?   uint64
       |  |  |     |  +-- bytes?     uint64
       |  |  |     +-- multicast
       |  |  |        +-- packets?   uint64
       |  |  |        +-- bytes?     uint64
       |  |  +-- qos
       |  |     +-- class* [id]
       |  |        +-- id         string
       |  |        +-- packets?   uint64
       |  |        +-- bytes?     uint64
       |  +-- discards
       |     +-- l2
       |     |  +-- frames?   uint64
       |     |  +-- bytes?    uint64
       |     +-- l3
       |     |  +-- address-family-stat* [address-family]
       |     |     +-- address-family    identityref
       |     |     +-- packets?          uint64
       |     |     +-- bytes?            uint64
       |     |     +-- unicast
       |     |     |  +-- packets?   uint64
       |     |     |  +-- bytes?     uint64
       |     |     +-- multicast
       |     |        +-- packets?   uint64
       |     |        +-- bytes?     uint64
       |     +-- errors
       |     |  +-- l2
       |     |  |  +-- tx
       |     |  |     +-- frames?   uint32
       |     |  +-- l3
       |     |     +-- tx
       |     |        +-- packets?   uint32
       |     +-- policy
       |     |  +-- l3
       |     |     +-- acl?       uint32
       |     |     +-- policer
       |     |        +-- packets?   uint32
       |     |        +-- bytes?     uint32
       |     +-- no-buffer
       |        +-- class* [id]
       |           +-- id         string
       |           +-- packets?   uint64
       |           +-- bytes?     uint64
       +-- control-plane
          +-- ingress
          |  +-- traffic
          |  |  +-- packets?   uint32
          |  |  +-- bytes?     uint32
          |  +-- discards
          |     +-- packets?   uint32
          |     +-- bytes?     uint32
          |     +-- policy
          |        +-- packets?   uint32
          +-- egress
             +-- traffic
             |  +-- packets?   uint32
             |  +-- bytes?     uint32
             +-- discards
                +-- packets?   uint32
                +-- bytes?     uint32

For additional context, Appendix A provides an example of where packets may be discarded in a device.
Requirements
Requirements 1-10 relate to packets forwarded or discarded by the device, while requirement 11 relates to packets destined for or originating from the device:
1. All instances of Layer 2 frame or Layer 3 packet receipt, transmission, and discards MUST be accounted for.
2. All instances of Layer 2 frame or Layer 3 packet receipt, transmission, and discards SHOULD be attributed to the physical or logical interface of the device where they occur. Where they cannot be attributed to the interface, they MUST be attributed to the device.
3. An individual frame MUST only be accounted for by either the Layer 2 traffic class or the Layer 2 discard classes within a single direction or context, i.e., ingress or egress or device.
4. An individual packet MUST only be accounted for by either the Layer 3 traffic class or the Layer 3 discard classes within a single direction or context, i.e., ingress or egress or device.
5. A frame accounted for at Layer 2 SHOULD NOT be accounted for at Layer 3 and vice versa. An implementation MUST indicate which layers a discard is counted against.
6. The aggregate Layer 2 and Layer 3 traffic and discard classes SHOULD account for all underlying frames or packets received, transmitted, and discarded across all other classes.
7. The aggregate Quality of Service (QoS) traffic and no buffer discard classes MUST account for all underlying packets received, transmitted, and discarded across all other classes.
8. In addition to the Layer 2 and Layer 3 aggregate classes, an individual discarded packet MUST only account against a single error, policy, or no-buffer discard subclass.
9. When there are multiple reasons for discarding a packet, the ordering of discard class reporting MUST be defined.
10. If Diffserv [RFC2475] is not used, no-buffer discards SHOULD be reported as class0.
11. Traffic to the device control plane has its own class, however, traffic from the device control plane SHOULD be accounted for in the same way as other egress traffic.
Examples
Assuming all the requirements are met, a "good" unicast IPv4 packet received would increment:
- interface/ingress/traffic/l3/v4/unicast/packets
- interface/ingress/traffic/l3/v4/unicast/bytes
- interface/ingress/traffic/qos/class_0/packets
- interface/ingress/traffic/qos/class_0/bytes
A received unicast IPv6 packet discarded due to Hop Limit expiry would increment:
- interface/ingress/discards/l3/v6/unicast/packets
- interface/ingress/discards/l3/v6/unicast/bytes
- interface/ingress/discards/l3/rx/ttl-expired/packets
An IPv4 packet discarded on egress due to no buffers would increment:
- interface/egress/discards/l3/v4/unicast/packets
- interface/egress/discards/l3/v4/unicast/bytes
- interface/egress/discards/no-buffer/class_0/packets
- interface/egress/discards/no-buffer/class_0/bytes
Example Signal-Cause-Mitigation Mapping
Table 1 gives an example discard signal-to-cause-to-mitigation action mapping. Mappings for a specific network will be dependent on the definition of unintended packet loss for that network.

Example Signal-Cause-Mitigation Mapping
Discard class | Cause | Discard rate | Discard duration | Unintended? | Possible actions
ingress/discards/errors/l2/rx | Upstream device or link error | >Baseline | O(1min) | Y | Take upstream link or device out-of-service
ingress/discards/errors/l3/rx/ttl-expired | Tracert | <=Baseline | | N | no action
ingress/discards/errors/l3/rx/ttl-expired | Convergence | >Baseline | O(1s) | Y | no action
ingress/discards/errors/l3/rx/ttl-expired | Routing loop | >Baseline | O(1min) | Y | Roll-back change
.*/policy/.* | Policy | | | N | no action
ingress/discards/errors/l3/no-route | Convergence | >Baseline | O(1s) | Y | no action
ingress/discards/errors/l3/no-route | Config error | >Baseline | O(1min) | Y | Roll-back change
ingress/discards/errors/l3/no-route | Invalid destination | >Baseline | O(10min) | N | Escalate to operator
ingress/discards/errors/local | Device errors | >Baseline | O(1min) | Y | Take device out-of-service
egress/discards/no-buffer | Congestion | <=Baseline | | N | no action
egress/discards/no-buffer | Congestion | >Baseline | O(1min) | Y | Bring capacity back into service or move traffic
The 'Baseline' in the 'Discard Rate' column is both discard class and network dependent.
YANG Module
The "ietf-packet-discard-reporting" uses the "sx" structure defined in [RFC8791].

<CODE BEGINS> file "ietf-packet-discard-reporting@2024-06-04.yang"
module ietf-packet-discard-reporting {
  yang-version 1.1;
  namespace
    "urn:ietf:params:xml:ns:yang:ietf-packet-discard-reporting";
  prefix plr;

  import ietf-yang-structure-ext {
    prefix sx;
    reference
      "RFC 8791: YANG Data Structure Extensions";
  }

  organization
    "IETF OPSAWG (Operations and Management Area Working Group)";
  contact
    "WG Web:   https://datatracker.ietf.org/wg/opsawg/
     WG List:  mailto:opsawg@ietf.org

     Author:   John Evans
               <mailto:jevanamz@amazon.co.uk>

     Author:   Oleksandr Pylypenko
               <mailto:opyl@amazon.com>

     Author:   Jeffrey Haas
               <mailto:jhaas@juniper.net>

     Author:   Aviran Kadosh
               <mailto:akadosh@cisco.com>

     Author:   Mohamed Boucadair
               <mailto:mohamed.boucadair@orange.com>";
  description
    "This module defines an information model for packet discard
     reporting.

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

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

  revision 2024-06-04 {
    description
      "Initial revision.";
    reference
      "RFC XXXX: An Information Model for Packet Discard Reporting";
  }

  /*
   * Groupings
   */

  grouping basic-packets-64 {
    description
      "Grouping for 64-bit Layer 3 packet counters.";
    leaf packets {
      type uint64;
      description
        "Number of Layer 3 packets.";
    }
  }

  grouping basic-packets-bytes-64 {
    description
      "Grouping for 64-bit Layer 3 packet and byte counters.";
    uses basic-packets-64;
    leaf bytes {
      type uint64;
      description
        "Number of Layer 3 bytes.";
    }
  }

  grouping basic-frames-64 {
    description
      "Grouping for 64-bit Layer 2 frame counters.";
    leaf frames {
      type uint64;
      description
        "Number of Layer 2 frames.";
    }
  }

  grouping basic-frames-bytes-64 {
    description
      "Grouping for 64-bit Layer 2 frame and byte counters.";
    uses basic-frames-64;
    leaf bytes {
      type uint64;
      description
        "Number of Layer 2 bytes.";
    }
  }

  grouping basic-packets-32 {
    description
      "Grouping for 32-bit Layer 3 packet counters.";
    leaf packets {
      type uint32;
      description
        "Number of Layer 3 packets.";
    }
  }

  grouping basic-packets-bytes-32 {
    description
      "Grouping for 32-bit Layer 3 packet and byte counters.";
    uses basic-packets-32;
    leaf bytes {
      type uint32;
      description
        "Number of Layer 3 bytes.";
    }
  }

  grouping basic-frames-32 {
    description
      "Grouping for 32-bit Layer 2 frame counters.";
    leaf frames {
      type uint32;
      description
        "Number of Layer 2 frames.";
    }
  }

  grouping basic-frames-bytes-32 {
    description
      "Grouping for 32-bit Layer 2 frame and byte counters.";
    uses basic-frames-32;
    leaf bytes {
      type uint32;
      description
        "Number of Layer 2 bytes.";
    }
  }

  grouping l2-traffic {
    description
      "Layer 2 traffic counters.";
    uses basic-frames-bytes-64;
  }

  identity address-family {
    description
      "Defines a type for the address family.";
  }

  identity ipv4 {
    base address-family;
    description
      "Identity for an IPv4 address family.";
  }

  identity ipv6 {
    base address-family;
    description
      "Identity for an IPv6 address family.";
  }

  identity all {
    base address-family;
    description
      "Identity for all address families.";
  }

  grouping ip {
    description
      "Layer 3 traffic counters per address family.";
    list address-family-stat {
      key "address-family";
      description
        "Reports per address family traffic counters.";
      leaf address-family {
        type identityref {
          base address-family;
        }
        description
          "Specifies an address family.";
      }
      uses basic-packets-bytes-64;
      container unicast {
        description
          "Unicast traffic counters.";
        uses basic-packets-bytes-64;
      }
      container multicast {
        description
          "Multicast traffic counters.";
        uses basic-packets-bytes-64;
      }
    }
  }

  grouping l3-traffic {
    description
      "Layer 3 traffic counters.";
      uses ip;
  }

  grouping qos {
    description
      "Quality of Service (QoS) traffic
       counters.";
    list class {
      key "id";
      min-elements 1;
      description
        "QoS class traffic counters.";
      leaf id {
        type string;
        description
          "QoS class identifier.";
      }
      uses basic-packets-bytes-64;
    }
  }

  grouping traffic {
    description
      "All traffic counters.";
    container l2 {
      description
        "Layer 2 traffic counters.";
      uses l2-traffic;
    }
    container l3 {
      description
        "Layer 3 traffic counters.";
      uses l3-traffic;
    }
    container qos {
      description
        "QoS traffic counters.";
      uses qos;
    }
  }

  grouping control-plane {
    description
      "Control plane packet counters.";
    container ingress {
      description
        "Control plane ingress counters.";
      container traffic {
        description
          "Control plane ingress packets received.";
        uses basic-packets-bytes-32;
      }
      container discards {
        description
          "Control plane ingress packet discard counters.";
        uses basic-packets-bytes-32;
        container policy {
          description
            "Number of control plane packets discarded
             due to policy.";
          uses basic-packets-32;
        }
      }
    }
    container egress {
      description
        "Control plane egress counters.";
      container traffic {
        description
          "Control plane packets transmitted.";
        uses basic-packets-bytes-32;
      }
      container discards {
        description
          "Control plane egress packet discard counters.";
        uses basic-packets-bytes-32;
      }
    }
  }

  grouping errors-l2-rx {
    description
      "Layer 2 ingress frame error discard counters.";
    container rx {
      description
        "Layer 2 ingress frame receive error discard counters.";
      leaf frames {
        type uint32;
        description
          "The number of frames discarded due to errors with the received frame.";
      }
      leaf crc-error {
        type uint32;
        description
          "The number of frames discarded due to CRC error.";
      }
      leaf invalid-mac {
        type uint32;
        description
          "The number of frames discarded due to an invalid
           MAC address.";
      }
      leaf invalid-vlan {
        type uint32;
        description
          "The number of frames discarded due to an invalid
           VLAN tag.";
      }
      leaf invalid-frame {
        type uint32;
        description
          "The number of invalid frames discarded due to other reasons, not limited to: malformed frames, frame-size violations.";
      }
    }
  }

  grouping errors-l3-rx {
    description
      "Layer 3 ingress packet error discard counters.";
    container rx {
      description
        "Layer 3 ingress packet receive error discard counters.";
      leaf packets {
        type uint32;
        description
          "The number of Layer 3 packets discarded due to errors in the received packet.";
      }
      leaf checksum-error {
        type uint32;
        description
          "The number of received packets discarded due to a checksum
           error.";
      }
      leaf mtu-exceeded {
        type uint32;
        description
          "The number of received packets discarded due to MTU
           exceeded.";
      }
      leaf invalid-packet {
        type uint32;
        description
          "The number of invalid packets discarded due to other reasons, not limited to: invalid packet length, invalid header fields, invalid options, invalid protocol version, invalid flags or control bits, malformed packets.";
      }
    }
    leaf ttl-expired {
      type uint32;
      description
        "The number of received packets discarded due to expired
         TTL.";
    }
    leaf no-route {
      type uint32;
      description
        "The number of packets discarded due to not matching a valid route.";
    }
    leaf invalid-sid {
      type uint32;
      description
        "The number of packets discarded due to an invalid Segment Routing (SR) SID.";
    }
    leaf invalid-label {
      type uint32;
      description
        "The number of packets discarded due to an invalid MPLS label.";
    }
  }

  grouping errors-l3-int {
    description
      "Internal error discard counters.";
    leaf packets {
      type uint32;
      description
        "The number of packets discarded due to internal errors.";
    }
    leaf parity-error {
      type uint32;
      description
        "The number of packets discarded due to parity errors.";
    }
  }

  grouping errors-rx {
    description
      "Ingress error discard counters.";
    container l2 {
      description
        "Layer 2 received frame error discard counters.";
      uses errors-l2-rx;
    }
    container l3 {
      description
        "Layer 3 received packet error discard counters.";
      uses errors-l3-rx;
    }
    container internal {
      description
        "Internal error discard counters.";
      uses errors-l3-int;
    }
  }

  grouping errors-l2-tx {
    description
      "Layer 2 transmit error discard counters.";
    container tx {
      description
        "Layer 2 transmit frame error discard counters.";
      leaf frames {
        type uint32;
        description
          "The number of Layer 2 frames discarded due to errors when
           transmitting.";
      }
    }
  }

  grouping errors-l3-tx {
    description
      "Layer 3 transmit error discard counters.";
    container tx {
      description
        "Layer 3 transmit packet error discard counters.";
      leaf packets {
        type uint32;
        description
          "The number of Layer 3 packets discarded due to errors when
           transmitting.";
      }
    }
  }

  grouping errors-tx {
    description
      "Egress error discard counters.";
    container l2 {
      description
        "Layer 2 transmit frame error discard counters.";
      uses errors-l2-tx;
    }
    container l3 {
      description
        "Layer 3 transmit packet error discard counters.";
      uses errors-l3-tx;
    }
  }

  grouping policy-l2-rx {
    description
      "Layer 2 policy ingress packet discard
       counters.";
    leaf frames {
      type uint32;
      description
        "The number of Layer 2 frames discarded due
         to policy.";
    }
    leaf acl {
      type uint32;
      description
        "The number of frames discarded due to
         Layer 2 ACLs.";
    }
  }

  grouping policy-l3-rx {
    description
      "Layer 3 policy ingress packet discard
       counters.";
    leaf packets {
      type uint32;
      description
        "The number of Layer 3 packets discarded due
         to policy.";
    }
    leaf acl {
      type uint32;
      description
        "The number of packets discarded due to
         Layer 3 ACLs.";
    }
    container policer {
      description
        "The number of packets discarded due ingress policer violations.";
      uses basic-packets-bytes-32;
    }
    leaf null-route {
      type uint32;
      description
        "The number of packets discarded due to matching a
         null route.";
    }
    leaf rpf {
      type uint32;
      description
        "The number of packets discarded due to failing Reverse
         Path Forwarding (RPF) check.";
    }
    leaf ddos {
      type uint32;
      description
        "The number of packets discarded due to DDoS
         protection policies.";
    }
  }

  grouping policy-rx {
    description
      "Policy-related ingress packet
       discard counters.";
    container l2 {
      description
        "Layer 2 policy ingress packet discard counters.";
      uses policy-l2-rx;
    }
    container l3 {
      description
        "Layer 3 policy ingress packet discard counters.";
      uses policy-l3-rx;
    }
  }

  grouping policy-l3-tx {
    description
      "Layer 3 policy egress packet discard counters.";
    leaf acl {
      type uint32;
      description
        "The number of packets discarded due to Layer 3
         egress ACLs.";
    }
    container policer {
      description
        "The number of packets discarded due egress policer violations.";
      uses basic-packets-bytes-32;
    }
  }

  grouping policy-tx {
    description
      "Policy egress packet discard counters.";
    container l3 {
      description
        "Layer 3 policy egress packet discard counters.";
      uses policy-l3-tx;
    }
  }

  grouping interface {
    description
      "Interface-level traffic and discard counters.";
    container ingress {
      description
        "Ingress counters.";
      container traffic {
        description
          "Ingress traffic counters.";
        uses traffic;
      }
      container discards {
        description
          "Ingress discard counters.";
        container l2 {
          description
            "Ingress Layer 2 frame discard counters.";
          uses l2-traffic;
        }
        container l3 {
          description
            "Ingress Layer 3 packet discard counters.";
          uses l3-traffic;
        }
        container errors {
          description
            "Ingress error discard counters.";
          uses errors-rx;
        }
        container policy {
          description
            "Ingress policy-related discard counters.";
          uses policy-rx;
        }
        container no-buffer {
          description
            "Ingress discard counters due to buffer
             unavailability.";
          uses qos;
        }
      }
    }
    container egress {
      description
        "Egress counters.";
      container traffic {
        description
          "Egress traffic counters.";
        uses traffic;
      }
      container discards {
        description
          "Egress packet and frame discard counters.";
        container l2 {
          description
            "Layer 2 egress frame discard counters.";
          uses l2-traffic;
        }
        container l3 {
          description
            "Layer 3 egress packet discard counters.";
          uses l3-traffic;
        }
        container errors {
          description
            "Egress packet error discard counters.";
          uses errors-tx;
        }
        container policy {
          description
            "Egress policy-related packet discard counters.";
          uses policy-tx;
        }
        container no-buffer {
          description
            "Egress packet discard counters due to buffer
             unavailability.";
          uses qos;
        }
      }
    }
    container control-plane {
      description
        "Control plane packet counters.";
      uses control-plane;
    }
  }

  /*
   * Main structure definition
   */

  sx:structure packet-discard-reporting {
    description
      "Specifies the abstract structure of packet discard reporting data.";
    list interface {
      key "name";
      description
        "Indicates a list of interfaces for which packet discard reporting
         data is provided.";
      leaf name {
        type string;
        description
          "Indicates the name of the interface.";
      }
      uses interface;
    }
  }
}
<CODE ENDS>

Security Considerations
The document defines a YANG module using [RFC8791]. As such, this document does not define data nodes. Following the guidance in Section 3.7 of [I-D.ietf-netmod-rfc8407bis], the YANG security template is not used.
IANA Considerations
IANA is requested to register the following URI in the "ns" subregistry within the "IETF XML Registry" [RFC3688]:

   URI:  urn:ietf:params:xml:ns:ietf-packet-discard-reporting
   Registrant Contact:  The IESG.
   XML:  N/A; the requested URI is an XML namespace.

IANA is requested to register the following YANG module in the "YANG Module Names" subregistry [RFC6020] within the "YANG Parameters" registry:

   Name:  ietf-packet-discard-reporting
   Namespace:  urn:ietf:params:xml:ns:ietf-packet-discard-reporting
   Prefix:  plr
   Maintained by IANA?  N
   Reference:  RFC XXXX

Contributors

Nadav Chachmon
Cisco Systems, Inc.
170 West Tasman Dr.
San Jose, CA 95134
United States of America
Email: nchachmo@cisco.com

Acknowledgments
The content of this document has benefitted from feedback from JR Rivers, Ronan Waide, Chris DeBruin, and Marcoz Sanz.

References

Normative References
[RFC8791]

YANG Data Structure Extensions
A. Bierman
M. Björklund
K. Watsen
June 2020
RFC 8791
DOI 10.17487/RFC8791
[RFC2119]

Key words for use in RFCs to Indicate Requirement Levels
S. Bradner
March 1997
BCP 14
RFC 2119
DOI 10.17487/RFC2119
[RFC8174]

Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words
B. Leiba
May 2017
BCP 14
RFC 8174
DOI 10.17487/RFC8174
[RFC6020]

YANG - A Data Modeling Language for the Network Configuration Protocol (NETCONF)
M. Bjorklund, Ed.
October 2010
RFC 6020
DOI 10.17487/RFC6020
[RFC3688]

The IETF XML Registry
M. Mealling
January 2004
BCP 81
RFC 3688
DOI 10.17487/RFC3688

Informative References
[RFC6241]

Network Configuration Protocol (NETCONF)
R. Enns, Ed.
M. Bjorklund, Ed.
J. Schoenwaelder, Ed.
A. Bierman, Ed.
June 2011
RFC 6241
DOI 10.17487/RFC6241
[RED93]

Random Early Detection gateways for Congestion Avoidance
V. Jacobson
n.d.
[RFC2475]

An Architecture for Differentiated Services
S. Blake
D. Black
M. Carlson
E. Davies
Z. Wang
W. Weiss
December 1998
RFC 2475
DOI 10.17487/RFC2475
[RFC8289]

Controlled Delay Active Queue Management
K. Nichols
V. Jacobson
A. McGregor, Ed.
J. Iyengar, Ed.
January 2018
RFC 8289
DOI 10.17487/RFC8289
[RFC1213]

Management Information Base for Network Management of TCP/IP-based internets: MIB-II
K. McCloghrie
M. Rose
March 1991
STD 17
RFC 1213
DOI 10.17487/RFC1213
[RFC7270]

Cisco-Specific Information Elements Reused in IP Flow Information Export (IPFIX)
A. Yourtchenko
P. Aitken
B. Claise
June 2014
RFC 7270
DOI 10.17487/RFC7270
[RFC3444]

On the Difference between Information Models and Data Models
A. Pras
J. Schoenwaelder
January 2003
RFC 3444
DOI 10.17487/RFC3444
[RFC8340]

YANG Tree Diagrams
M. Bjorklund
L. Berger, Ed.
March 2018
BCP 215
RFC 8340
DOI 10.17487/RFC8340
[RFC1157]

Simple Network Management Protocol (SNMP)
J.D. Case
M. Fedor
M.L. Schoffstall
J. Davin
May 1990
RFC 1157
DOI 10.17487/RFC1157
[RFC8040]

RESTCONF Protocol
A. Bierman
M. Bjorklund
K. Watsen
January 2017
RFC 8040
DOI 10.17487/RFC8040
[RFC7011]

Specification of the IP Flow Information Export (IPFIX) Protocol for the Exchange of Flow Information
B. Claise, Ed.
B. Trammell, Ed.
P. Aitken
September 2013
STD 77
RFC 7011
DOI 10.17487/RFC7011
[I-D.ietf-netmod-rfc8407bis]

Guidelines for Authors and Reviewers of Documents Containing YANG Data Models
Andy Bierman
YumaWorks
Mohamed Boucadair
Orange
Qin Wu
Huawei
11 October 2024
Internet-Draft draft-ietf-netmod-rfc8407bis-18
Where do packets get dropped?
Figure 1 depicts an example of where and why packets may be discarded in a typical single-ASIC, shared-buffered type device. Packets ingress on the left and egress on the right.

Example of where packets get dropped

                                                      +----------+
                                                      |          |
                                                      |  CPU     |
                                                      |          |
                                                      +--+---^---+
                                                from_cpu |   | to_cpu
                                                         |   |
                          +------------------------------v---+-------------------------------+
                          |                                                                  |

            +----------+  +----------+  +----------+  +----------+  +----------+  +----------+  +----------+
            |          |  |          |  |          |  |          |  |          |  |          |  |          |
 Packet rx ->  Phy     +-->  Mac     +--> Ingress  +--> Buffers  +--> Egresss  +-->  Mac     +-->  Phy     +-> Packet tx
            |          |  |          |  |  Pipeline|  |          |  |  Pipeline|  |          |  |          |
            +----------+  +----------+  +----------+  +----------+  +----------+  +----------+  +----------+

  Intended                               policy/acl                  policy/acl
  Discards:                              policy/policer              policy/policer
                                         policy/urpf
                                         policy/null-route

Unintended                 error/rx/l2   error/l3/rx   no-buffer     error/l3/tx
  Discards:                              error/local
                                         error/l3/no-route
                                         error/l3/rx/ttl-expired

Discard Class Descriptions
discards/policy/:
These are intended discards, meaning packets dropped by a device due to a configured policy. There are multiple sub-classes.
discards/error/l2/rx/:
Frames discarded due to errors in the received Layer 2 frame. There are multiple sub-classes, such as those resulting from failing CRC, invalid header, invalid MAC address, or invalid VLAN.
discards/error/l3/rx/:
These are discards which occur due to errors in the received packet, indicating an upstream problem rather than an issue with the device dropping the errored packets. There are multiple sub-classes, including header checksum errors, MTU exceeded, and invalid packet, i.e. due to incorrect version, incorrect header length, or invalid options.
discards/error/l3/rx/ttl-expired:
There can be multiple causes for TTL-expired (or Hop limit exceeded) discards: i) trace-route; ii) TTL (Hop limit) set too low by the end-system; iii) routing loops.
discards/error/l3/no-route/:
Discards occur due to a packet not matching any route.
discards/error/local/:
A device may discard packets within its switching pipeline due to internal errors, such as parity errors. Any errored discards not explicitly assigned to the above classes are also accounted for here.
discards/no-buffer/:
Discards occur due to no available buffer to enqueue the packet. These can be tail-drop discards or due to an active queue management algorithm, such as RED [RED93] or CODEL [RFC8289].
Implementation Experience
This appendix captures the authors' experience gained from implementing and applying this information model across multiple vendors' platforms, as guidance for future implementers.
1. The number and granularity of classes described in Section 3 represent a compromise. It aims to offer sufficient detail to enable appropriate automated actions while avoiding excessive detail, which may hinder quick problem identification. Additionally, it helps limit the quantity of data produced per interface, thus constraining the data volume and device CPU impacts. Although further granularity is possible, the scheme described has generally proven to be sufficient for the task of auto-mitigating unintended packet loss.
2. There are many possible ways to define the discard classification tree. For example, we could have used a multi-rooted tree, rooted in each protocol. Instead, we opted to define a tree where protocol discards and causal discards are accounted for orthogonally. This decision reduces the number of combinations of classes and has proven sufficient for determining mitigation actions.
3. NoBuffer discards can be realized differently with different memory architectures. Whether a NoBuffer discard is attributed to ingress or egress can differ accordingly. For successful auto-mitigation, discards due to egress interface congestion should be reported on egress, while discards due to device-level congestion (e.g. due to exceeding the device forwarding rate) should be reported on ingress.
4. Platforms often account for the number of packets discarded where the TTL has expired (or Hop Limit exceeded), and the device CPU has returned an ICMP Time Exceeded message. There is typically a policer applied to limit the number of packets sent to the device CPU, however, which implicitly limits the rate of TTL discards that are processed. One method to account for all packet discards due to TTL expired, even those that are dropped by a policer when being forwarded to the CPU, is to use accounting of all ingress packets received with TTL=1.
5. Where no route discards are implemented with a default null route, separate discard accounting is required for any explicit null routes configured, in order to differentiate between interface/ingress/discards/policy/null-route/packets and interface/ingress/discards/errors/no-route/packets.
6. It is useful to account separately for transit packets discarded by ACLs or policers, and packets discarded by ACLs or policers which limit the number of packets to the device control plane.
7. It is not possible to identify a configuration error - e.g., when intended discards are unintended - with device packet loss metrics alone. For example, additional context is needed to determine if ACL discards are intended or due to a misconfigured ACL, i.e., with configuration validation before deployment or by detecting a significant change in ACL discards after a configuration change compared to before.
8. Where traffic byte counters need to be 64-bit, packet and discard counters that increase at a lower rate may be encoded in fewer bits, e.g., 32-bit.
9. Aggregate counters need to be able to deal with the possibility of discontinuities in the underlying counters.
10. In cases where the reporting device is the source or destination of a tunnel, the ingress protocol for a packet may differ from the egress protocol; if IPv4 is tunnelled over IPv6 for example. Some implementations may attribute egress discards to the ingress protocol.
11. While the classification tree is seven layers deep, a minimal implementation may only implement the top six layers.