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

  import ietf-interfaces {
    prefix if;
  }
  import infix-dhcp-common {
    prefix dhcp;
  }

  contact      "kernelkit@googlegroups.com";
  description  "This module implements a DHCPv4 client";

  revision 2025-01-29 {
    description   "Consolidate DHCP options between client and server models.
                      - Rename option attribute 'name' -> 'id'
                      - Rename internal option type
                      - Rename options, e.g. ntpsrv -> ntp-server";
    reference     "internal";
  }
  revision 2024-09-20 {
    description   "Routes are installed in Frr (staticd), clarify preference
                   vs metric and adjust default preference 100 -> 5.";
    reference     "internal";
  }
  revision 2024-04-12 {
    description   "Adjust DHCP client hostname option, max 64 charachters.";
    reference     "internal";
  }
  revision 2024-01-30 {
    description   "Add DHCP client options, arping, and route preference.";
    reference     "internal";
  }
  revision 2023-05-22 {
    description   "Initial revision.";
    reference     "rfc2131 rfc7950";
  }

  /*
   * Typedefs
   */

  typedef route-preference {
    type uint32;
    description "This type is used for selecting route preference (distance).";
  }

  /*
   * Data Nodes
   */

  container dhcp-client {
    description "DHCPv4 client configuration";

    leaf enabled {
      type boolean;
      default "true";
      description "Globally enables the DHCP client function.";
    }

    list client-if {
      description "List of interfaces requesting DHCPv4 configuration.";
      key "if-name";

      leaf if-name {
        type if:interface-ref;
        mandatory true;
        description "Name of the interface.";
      }

      leaf enabled {
        type boolean;
        default "true";
        description "Enable DHCP client for this interface.";
      }

      leaf client-id {
        type string;
        description "Optional Client ID, option 61, RFC 2132.

                     When omitted the client sends its MAC address as client-id.

                     RFC 2132 defines client-id as [ OPT | LEN | TYPE | DATA ],
                     where TYPE is 0x01 for MAC address and 0x00 for anything
                     else.  Servers usually just do a binary match of the data
                     using the length field.  This particular setting encodes
                     the value as an ASCII string without trailing zero.

                     For full control of both type and data fields, use generic
                     option list instead, which supports entering raw HEX data.";
      }

      leaf arping {
        type boolean;
        default "true";
        description "ARP for lease to check for IP address collisions (slow).";
      }

      list option {
        key "id";
        description "List of DHCP options to request (and accept).

           The default is an empty list, meaning all supported options.  To
           restrict the client to only get IP address and default route, set
           this to: 'netmask router'";

        must "not(id = 'fqdn' and 'value/hex')" {
          error-message "FQDN option must use string format";
          error-app-tag "invalid-fqdn-format";
        }

        leaf id {
          type dhcp:options;
          description "DHCP option to request from, or inform server of.";
        }

        choice value {
          case value {
            leaf value {
              description "Optional value, to inform server, e.g., hostname.

                           Example 1)

                                option:12, value:xyzzy

                           Example 2)

                                option:hostname, value:xyzzy

                           Will be sent as [12 | 05 | 78 | 79 | 80 | 80 | 79],
                           which the server can use for static host matching.
                           For the 'hostname' option the 'auto' keyword can be
                           used to send the hostname part from IETF system.";
              type string;
              must "../id != 'hostname' or re-match(., '[a-zA-Z0-9\\-_]{1,64}')";
            }
          }
          case hex {
            leaf hex {
              description "Optional binary value, to inform server, e.g., client-id.

                           This is a raw payload option allowing full control of
                           what is sent in an option.  Often used with options 61
                           and option 43 (vendor-specific).

                           Example 1)

                                option:client-id, hex:00:c0:ff:ee

                           Will be sent as : [61 | 03 | 00 | c0 | ff | ee], which
                           is the RFC conformant formatting of option 61.

                           Example 2)

                                option:client-id, hex:c0:ff:ee

                           Will be sent as : [61 | 03 | c0 | ff | ee] meaning the
                           'htype' will be set to 'c0', while the RFC only defines
                           '00' (string) and and '01' (mac) for this field, some
                           users may want full control over this option.";
              type dhcp:octet-string;
            }
          }
        }
      }

      leaf route-preference {
        type route-preference;
        default 5;
        description
          "The preference (administrative distance) that all DHCP routes are
           installed with, option 3, 33 and 121.  The default preferfence (5)
           is higher (less worth) than static routes, but lower than those
           learned via dynamic routing protocols, like OSPF.";
      }
    }
  }
}
