module infix-routing {
  yang-version 1.1;
  namespace "urn:infix:routing:ns:yang:1.0";
  prefix infix-rt;

  import ietf-routing {
    prefix rt;
  }
  import ietf-ipv4-unicast-routing {
    prefix v4ur;
  }
  import ietf-ipv6-unicast-routing {
    prefix v6ur;
  }
  import ietf-ospf {
    prefix ospf;
  }
  import ietf-bfd-types {
    prefix bfd-types;
  }
  import ietf-rip {
    prefix rip;
  }

  organization "KernelKit";
  contact      "kernelkit@googlegroups.com";
  description  "Deviations and augments for ietf-routing, ietf-ospf, and ietf-rip.";

  revision 2026-03-11 {
    description "Remove interface-type deviation to expose standard ietf-ospf
                 interface types including point-to-multipoint and hybrid.
                 Un-deviate static-neighbors for non-broadcast P2MP support.";
  }

  revision 2025-12-02 {
    description "Add configurable OSPF debug logging container.
                 Add RIP (Routing Information Protocol) support.";
    reference "RFC 8695";
  }

  revision 2025-11-12 {
    description "Add area-id augmentation to OSPF local-rib routes.
                 Add uptime, role, and interface-name augmentations to OSPF neighbor state.
                 Allows displaying which area a route was learned from,
                 how long neighbors have been up, their DR/BDR role, and
                 the interface with local address.";
    reference "Issue #1190";
  }

  revision 2025-11-11 {
    description "Add BFD IP single-hop support (RFC 9127).
                 Deviate session-statistics (not implemented yet).";
    reference "RFC 9127, Issue #1190";
  }
  revision 2025-11-10 {
    description "Add must constraint to prevent backbone area as stub/NSSA.
                 Enable OSPF operational data for CLI: un-deviate priority,
                 hello-timer, wait-timer, route metric and route-tag fields.";
    reference "RFC 2328, RFC 3101, Issue #1190";
  }
  revision 2024-11-27 {
    description "Deviate address-family in OSPF";
    reference "internal";
  }
  revision 2024-11-15 {
    description "Fix pyang linter errors and warnings:
                  - Drop OSPF database deviations, already deviated earlier
                  - Drop unused imports";
    reference "internal";
  }
  revision 2024-10-01 {
    description "Remove possibility to have loopack in multiple areas.";
    reference "internal";
  }
  revision 2024-09-23 {
    description "Augment static routes with optional route-preference (distance).";
    reference "internal";
  }
  revision 2024-09-22 {
    description "- Enable OSPF route metrics in RIB
                 - Enable 'active' route flag for RIB
                 - Enable 'last-updated' route field for RIB
                 - Augment route in RIB with 'installed' flag
                 - Aadjust YANG prefix for consistency: ietf-r: -> rt:";
    reference "internal";
  }
  revision 2024-09-21 {
    description "Drop RIB source-protocol deviation for standard, add kernel proto.";
    reference "internal";
  }
  revision 2024-09-20 {
    description "Deviate to only show supported routing types";
    reference "internal";
  }
  revision 2024-09-13 {
    description "Declare deviations for non-supported OSPF RPCs and Notifications";
    reference "internal";
  }
  revision 2024-03-06 {
    description "Obsolete leaf enable in favor for enabled in default-route-advertise";
    reference "internal";
  }
  revision 2024-01-09 {
    description "Add operational, area, bfd support
                 and other minor features";
    reference "internal";
  }
  revision 2023-11-23 {
    description "Limit to one instance per control plane protocol,
                 and change to infix (iproute2) specific source protocol names
                 for routes";
    reference "internal";
  }
  revision 2023-10-27 {
    description "Initial revision.";
    reference "internal";
  }

  /* General routing */

  deviation "/rt:routing/rt:router-id" {
    description "Set in OSPF";
    deviate not-supported;
  }
  deviation "/rt:routing-state" {
    description "Obsolete";
    deviate not-supported;
  }

  identity kernel {
    base rt:routing-protocol;
    description
      "'Kernel' routing pseudo-protocol.";
  }

  typedef infix-distribute-protocol {
    type enumeration {
      enum ospf {
        description "Redistribute OSPF routes";
      }
      enum rip {
        description "Redistribute RIP routes";
      }
      enum static {
        description "Redistribute Static routes";
      }
      enum connected {
        description "Redistribute Connected routes";
      }
    }
  }

  identity infix-routing-type {
    description "Infix routing type";
  }
  identity ospfv2 {
    base ospf:ospfv2;
    base infix-routing-type;
    description "OSPFv2 (IPv4) routing protocol";
  }
  identity ripv2 {
    base rip:ripv2;
    base infix-routing-type;
    description "RIPv2 (IPv4) routing protocol";
  }
  identity bfdv1 {
    base bfd-types:bfdv1;
    base infix-routing-type;
    description "BFD protocol version 1";
  }
  identity static {
    base rt:static;
    base infix-routing-type;
    description "Static route";
  }

  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rt:type" {
    deviate replace {
      type identityref {
        base infix-routing-type;
      }
    }
  }

  /* Static routes */
  typedef distance {
     description "Capped IETF route-preference, 0-255, for distance.";
     type rt:route-preference {
       range "0..255";
     }
  }

  grouping route-pref {
     leaf route-preference {
       description "Adjust preference between routes of same destination prefix.

                    This attribute, also known as 'administrative distance', allows
                    for selecting the preferred route among routes with the same
                    destination prefix.  A smaller value indicates a route that is
                    more preferred.";
       type distance;
     }
  }

  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rt:static-routes/v4ur:ipv4/v4ur:route/v4ur:next-hop/v4ur:next-hop-options/v4ur:next-hop-list" {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rt:static-routes/v6ur:ipv6/v6ur:route/v6ur:next-hop/v6ur:next-hop-options/v6ur:next-hop-list" {
    deviate not-supported;
  }
  augment "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rt:static-routes/v4ur:ipv4/v4ur:route" {
    uses route-pref {
      refine route-preference {
        default "1";
      }
    }
  }
  augment "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rt:static-routes/v6ur:ipv6/v6ur:route" {
    uses route-pref {
      refine route-preference {
        default "1";
      }
    }
  }

  /* show routes */
  deviation "/rt:routing/rt:ribs/rt:rib/rt:default-rib" {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:ribs/rt:rib/rt:active-route" {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:ribs/rt:rib/rt:routes/rt:route/ospf:tag" {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:ribs/rt:rib/rt:routes/rt:route/ospf:route-type" {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:ribs/rt:rib/rt:description" {
    deviate not-supported;
  }
  augment "/rt:routing/rt:ribs/rt:rib/rt:routes/rt:route/"
        + "rt:next-hop/rt:next-hop-options/rt:next-hop-list/"
        + "rt:next-hop-list/rt:next-hop" {
    description "IETF use 'active' for selected routes within a protocol (RIB).
                 This augment adds an 'installed' leaf for marking routes that
                 are installed in the kernel FIB with the given next-hop.";
    leaf installed {
      description "The presence of this leaf indicates that the route is
                   installed in the kernel FIB with the given next-hop.";
      type empty;
    }
  }

  /* OSPF */


  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol" {
    deviate add {
      must "count(../control-plane-protocol[type = current()/type]) = 1" {
        error-message "Only one instance per routing protocol is allowed.";
      }
    }
  }
/*
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rt:type" {
    deviate add {
      must "derived-from-or-self(., 'ospf:ospfv2') or "+
           "derived-from-or-self(., 'rt:static')" {
          description "Only OSPFv2 and Static routes are supported in Infix.";
        }
    }
  }
*/
  augment "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf" {
    description "ietf-ospf lack the setting to generate a default route";
    container default-route-advertise {
      description "Distribute default route to network";
      leaf enable {
        status obsolete;
        description "Legacy, replaced by 'enabled'.";
        type boolean;
      }
      leaf enabled {
        description "Distribute default route";
        type boolean;
      }
      leaf always {
        description "Always distribute default route, even if no local default route exist.
                     If set to false, a default route will only be distributed if a default route exist
                     in the local routing table.";
        type boolean;
      }
    }
  }
  augment "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf" {
    description "ietf-ospf does not contain redistribution
                 7. How should route redistribution be configured? I see ietf-rip.yang has a separate
                 container for that purpose, but ietf-ospf.yang (and other IGP modules) don't do the
                 same. I also noticed the BGP model is using definition from ietf-routing-policy.yang.

                 Different vendors handle redistribution in different ways. This could be added with
                 an augmentation if there were agreement.

                 https://marc.info/?l=ms-ospf&m=166258444409552&w=2";
    container redistribute {
      list redistribute {
        key "protocol";
        description "Redistribute protocols into OSPF";
        leaf protocol {
          type infix-distribute-protocol;
          description "Set protocol to redistribute";
        }
      }
    }
  }
  augment "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf" {
    description "Add support for configurable OSPF debug logging.
                 Allows users to enable specific OSPF debug categories for troubleshooting.
                 All debug options default to disabled to prevent log flooding in
                 production environments.";
    container debug {
      description "OSPF debug logging configuration";
      leaf bfd {
        type boolean;
        default false;
        description "Enable OSPF BFD (Bidirectional Forwarding Detection) debug messages";
      }
      leaf packet {
        type boolean;
        default false;
        description "Enable detailed OSPF packet debug messages (all packet types)";
      }
      leaf ism {
        type boolean;
        default false;
        description "Enable OSPF Interface State Machine debug messages";
      }
      leaf nsm {
        type boolean;
        default false;
        description "Enable OSPF Neighbor State Machine debug messages";
      }
      leaf default-information {
        type boolean;
        default false;
        description "Enable OSPF default route origination debug messages";
      }
      leaf nssa {
        type boolean;
        default false;
        description "Enable OSPF NSSA (Not-So-Stubby Area) debug messages";
      }
    }
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface" {
    deviate add {
      must "count(../../../../ospf:areas/ospf:area/ospf:interfaces/ospf:interface[ospf:name=current()/name]) <= 1" {
        error-message "Only one area per interface is allowed.";
      }
    }
  }


  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:auto-cost" {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:database" {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:graceful-restart" {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:enabled" {
    deviate not-supported;
  }

  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:spf-control" {
    deviate not-supported;
  }

  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:address-family" {
    deviate not-supported;
  }

  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:preference" {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:stub-router" {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:topologies" {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:statistics" {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:database-control" {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:lsa-log" {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:spf-log" {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:fast-reroute" {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:node-tags" {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:mpls" {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:nsr" {
    deviate not-supported;
  }

  /* OSPF Area */
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:area-type" {
    deviate add {
      must "(../ospf:area-id != '0.0.0.0') or "
         + "(derived-from-or-self(., 'ospf:normal-area'))" {
        error-message "Area 0.0.0.0 (backbone) cannot be configured as "
                    + "stub or NSSA.";
        description
          "The backbone area (area 0.0.0.0) must be a normal area. "
        + "It cannot be configured as a stub area or NSSA as per "
        + "RFC 2328 and RFC 3101.";
      }
    }
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:virtual-links" {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:sham-links" {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:ranges" {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:database" {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:topologies" {
    deviate not-supported;
  }

  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:statistics" {
    deviate not-supported;
  }

  /* OSPF Area Interface */
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:static-neighbors/ospf:neighbor" {
    deviate add {
      must "../../ospf:interface-type = 'point-to-multipoint' or ../../ospf:interface-type = 'non-broadcast'" {
        error-message "Static neighbors are only applicable to point-to-multipoint or non-broadcast interface types.";
      }
    }
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:multi-areas"    {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:node-flag"    {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:bfd/ospf:local-multiplier"
  {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:bfd/ospf:interval-config-type"
  {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:priority"
  {
    deviate add {
      default "1";
    }
    description
      "FRR uses a default priority of 1 for DR/BDR election.
       Setting default to match FRR behavior.";
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:fast-reroute"
  {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:authentication"
  {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:statistics"
  {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:neighbors/ospf:neighbor/ospf:statistics"
  {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:neighbors/ospf:neighbor/ospf:cost"
  {
    deviate not-supported;
  }

  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:database"
  {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:topologies"
  {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:instance-id"
  {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:interface-id"
  {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:demand-circuit"
  {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:ttl-security"
  {
    deviate not-supported;
  }
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:lls"
  {
    deviate not-supported;
  }

  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:mtu-ignore"
  {
    deviate not-supported;
  }

  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:prefix-suppression"
  {
    deviate not-supported;
  }

  /* OSPF RPCs */
  deviation "/ospf:clear-neighbor" {
    deviate not-supported;
  }

  deviation "/ospf:clear-database" {
    deviate not-supported;
  }

  /* OSPF Notifications */
  deviation "/ospf:if-state-change" {
    deviate not-supported;
  }

  deviation "/ospf:if-config-error" {
    deviate not-supported;
  }

  deviation "/ospf:nbr-state-change" {
    deviate not-supported;
  }

  deviation "/ospf:nbr-restart-helper-status-change" {
    deviate not-supported;
  }

  deviation "/ospf:if-rx-bad-packet" {
    deviate not-supported;
  }

  deviation "/ospf:lsdb-approaching-overflow" {
    deviate not-supported;
  }

  deviation "/ospf:lsdb-overflow" {
    deviate not-supported;
  }

  deviation "/ospf:nssa-translator-status-change" {
    deviate not-supported;
  }

  deviation "/ospf:restart-status-change" {
    deviate not-supported;
  }

  /* RIP */
  /* RIP features not supported in Infix/FRR */
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rip:rip/rip:originate-default-route/rip:route-policy" {
    deviate not-supported;
    description "Route policies are not supported.";
  }

  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rip:rip/rip:triggered-update-threshold" {
    deviate not-supported;
    description "Triggered update threshold is not supported in FRR.";
  }

  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rip:rip/rip:maximum-paths" {
    deviate not-supported;
    description "Maximum paths configuration is not supported in FRR.";
  }

  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rip:rip/rip:output-delay" {
    deviate not-supported;
    description "Output delay configuration is not supported in FRR.";
  }

  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rip:rip/rip:distribute-list" {
    deviate not-supported;
    description "Distribute lists are not supported.";
  }

  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rip:rip/rip:redistribute" {
    deviate not-supported;
    description "Use Infix-specific redistribute container instead.";
  }

  /* RIP Interface features not supported */
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rip:rip/rip:interfaces/rip:interface/rip:authentication" {
    deviate not-supported;
    description "RIP authentication is not supported.";
  }

  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rip:rip/rip:interfaces/rip:interface/rip:bfd" {
    deviate not-supported;
    description "BFD support for RIP is not available in FRR.";
  }

  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rip:rip/rip:interfaces/rip:interface/rip:no-listen" {
    deviate not-supported;
    description "No-listen mode is not supported.";
  }

  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rip:rip/rip:interfaces/rip:interface/rip:originate-default-route" {
    deviate not-supported;
    description "Per-interface default route origination is not supported.";
  }

  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rip:rip/rip:interfaces/rip:interface/rip:summary-address" {
    deviate not-supported;
    description "Summary addresses are not supported.";
  }

  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rip:rip/rip:interfaces/rip:interface/rip:timers" {
    deviate not-supported;
    description "Per-interface timers are not supported in FRR.";
  }

  /* RIP Operational state not supported */
  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rip:rip/rip:interfaces/rip:interface/rip:statistics" {
    deviate not-supported;
    description "Per-interface statistics are not collected.";
  }

  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rip:rip/rip:next-triggered-update" {
    deviate not-supported;
    description "Next triggered update information is not available.";
  }

  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rip:rip/rip:num-of-routes" {
    deviate not-supported;
    description "Number of routes is not tracked separately.";
  }

  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rip:rip/rip:ipv6" {
    deviate not-supported;
    description "RIPng (IPv6) is not currently supported in Infix.";
  }

  deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rip:rip/rip:statistics" {
    deviate not-supported;
    description "Global statistics are not collected.";
  }

  /* RIP RPC */
  deviation "/rip:clear-rip-route" {
    deviate not-supported;
    description "Clear RIP route RPC is not supported.";
  }

  /* RIP Augmentations */
  augment "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rip:rip" {
    description "Infix-specific redistribute container for RIP.
                 The standard ietf-rip redistribute container has complex protocol-specific
                 lists (bgp, isis, ospfv2, etc.), but Infix uses a simpler model similar to OSPF.";
    container redistribute {
      list redistribute {
        key "protocol";
        description "Redistribute protocols into RIP";
        leaf protocol {
          type infix-distribute-protocol;
          description "Set protocol to redistribute";
        }
      }
    }
  }

  augment "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/rip:rip" {
    description "Add support for configurable RIP debug logging.
                 Allows users to enable specific RIP debug categories for troubleshooting.
                 All debug options default to disabled to prevent log flooding in
                 production environments.";
    container debug {
      description "RIP debug logging configuration";
      leaf events {
        type boolean;
        default false;
        description "Enable RIP events debug messages (sending/receiving packets, timers, interface changes)";
      }
      leaf packet {
        type boolean;
        default false;
        description "Enable detailed RIP packet debug messages (packet dumps with origin and port)";
      }
      leaf kernel {
        type boolean;
        default false;
        description "Enable kernel routing table debug messages (route add/delete, interface updates)";
      }
    }
  }

  /* Add send/receive version control per RIP interface
   * The standard ietf-rip model doesn't include version control,
   * but FRR supports this and it's useful for controlling RIP protocol versions
   * on a per-interface basis (e.g., for NBMA links or mixed networks).
   */
  augment "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/"
        + "rip:rip/rip:interfaces/rip:interface" {
    when "derived-from-or-self(../../../rt:type, 'infix-routing:ripv2')" {
      description
        "This augmentation is only valid for RIPv2.";
    }
    description
      "Infix extension to add RIP version control per interface.";

    leaf send-version {
      type enumeration {
        enum "1" {
          description "Send RIPv1 packets";
        }
        enum "2" {
          description "Send RIPv2 packets";
        }
        enum "1-2" {
          description "Send both RIPv1 and RIPv2 packets";
        }
      }
      description
        "RIP version to send on this interface. If not configured, FRR defaults to version 2.";
    }

    leaf receive-version {
      type enumeration {
        enum "1" {
          description "Receive RIPv1 packets";
        }
        enum "2" {
          description "Receive RIPv2 packets";
        }
        enum "1-2" {
          description "Receive both RIPv1 and RIPv2 packets";
        }
      }
      description
        "RIP version to receive on this interface. If not configured, FRR defaults to version 2.";
    }
  }

  /*
   * Augmentations
   */

  /* Add area-id to OSPF local-rib routes
   * The standard ietf-ospf model doesn't include area information in routes,
   * but FRR provides this and it's useful for operators to see which area
   * a route was learned from.
   */
  augment "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/"
        + "ospf:ospf/ospf:local-rib/ospf:route" {
    when "derived-from-or-self(../../../rt:type, 'infix-routing:ospfv2')" {
      description
        "This augmentation is only valid for OSPFv2.";
    }
    description
      "Infix extension to add area information to OSPF routes.";

    leaf area-id {
      type ospf:area-id-type;
      config false;
      description
        "Area ID from which this route was learned. Not applicable
         for inter-area routes learned from area border routers or
         external routes.";
    }
  }

  /* Add uptime to OSPF neighbor operational state
   * The standard ietf-ospf model doesn't include neighbor uptime,
   * but FRR provides this and it's useful for monitoring neighbor stability.
   */
  augment "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/"
        + "ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/"
        + "ospf:neighbors/ospf:neighbor" {
    when "derived-from-or-self(../../../../../../../rt:type, 'infix-routing:ospfv2')" {
      description
        "This augmentation is only valid for OSPFv2.";
    }
    description
      "Infix extension to add uptime information to OSPF neighbors.";

    leaf uptime {
      type uint32;
      units "seconds";
      config false;
      description
        "Time since the neighbor transitioned to the Full state.
         Reported in seconds for consistency with other timers.";
    }

    leaf role {
      type enumeration {
        enum DR {
          description "Designated Router";
        }
        enum BDR {
          description "Backup Designated Router";
        }
        enum DROther {
          description "Neither DR nor BDR";
        }
      }
      config false;
      description
        "OSPF neighbor's role on the network segment (DR, BDR, or DROther).
         This is derived from the neighbor's priority and router ID during
         the DR/BDR election process.";
    }

    leaf interface-name {
      type string;
      config false;
      description
        "Interface name with local address in format 'interface:address'.
         Example: 'e5:10.0.23.1' indicates interface e5 with local address 10.0.23.1.
         This is useful for networks where multiple addresses exist on an interface.";
    }
  }
}
