RFC 9243
A YANG Data Model for DHCPv6 Configuration
Abstract π
Okay bestie, let's get into RFC 9243 π It's A YANG Data Model for DHCPv6 Configuration πΈ by I. Farrer, Ed. from Deutsche Telekom AG. It's a Standards Track document, published in June 2022 π§ with ISSN 2070-1721. The header doesn't list any documents it obsoletes or updates, so there's nothing to flag there β¨
The abstract is the vibe check: this document describes YANG data models for configuring and managing DHCPv6 (RFC 8415) servers, relays, and clients π
Status of This Memo π
This is an Internet Standards Track document π₯
It's a product of the Internet Engineering Task Force (IETF) and represents the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG) π More on Internet Standards is in Section 2 of RFC 7841.
Info about the current status, any errata, and how to give feedback lives at https://www.rfc-editor.org/info/rfc9243 π¦
Copyright Notice Β©οΈ
Copyright (c) 2022 IETF Trust and the persons identified as the document authors. All rights reserved π«Ά
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) as in effect on the date of publication. Please review those carefully, because they spell out your rights and restrictions for this document π Code Components pulled out of this document must include Revised BSD License text, as described in Section 4.e of the Trust Legal Provisions, and they come without warranty as described in the Revised BSD License π
Table of Contents ποΈ
1. Introduction
1.1. Scope
1.2. Extensibility of the DHCPv6 Server YANG Module
1.2.1. DHCPv6 Option Definitions
2. Terminology
2.1. Requirements Language
3. DHCPv6 Tree Diagrams
3.1. DHCPv6 Server Tree Diagram
3.2. DHCPv6 Relay Tree Diagram
3.3. DHCPv6 Client Tree Diagram
4. DHCPv6 YANG Modules
4.1. DHCPv6 Common YANG Module
4.2. DHCPv6 Server YANG Module
4.3. DHCPv6 Relay YANG Module
4.4. DHCPv6 Client YANG Module
5. Security Considerations
6. IANA Considerations
6.1. URI Registration
6.2. YANG Module Name Registration
7. References
7.1. Normative References
7.2. Informative References
Appendix A. Data Tree Examples
A.1. DHCPv6 Server Configuration Examples
A.2. DHCPv6 Relay Configuration Example
A.3. DHCPv6 Client Configuration Example
Appendix B. Example of Augmenting Additional DHCPv6 Option
Definitions
Appendix C. Example Vendor-Specific Server Configuration Module
Appendix D. Example Definition of Class-Selector Configuration
Acknowledgments
Contributors
Author's Address
1. Introduction β¨
So DHCPv6 [RFC8415] is how clients on IPv6 networks get configuration and other relevant parameters π This document defines YANG [RFC7950] modules for configuring and managing DHCPv6 'elements' (servers, relays, and clients), using either the Network Configuration Protocol (NETCONF) [RFC6241] or RESTCONF [RFC8040] π§
Each element gets its own module. There's also a 'common' module that holds the typedefs and groupings every element module uses π Appendix A has XML examples for each element module and shows how they all interact π
The relay and client modules handle configuration that applies to a device's interfaces. They do this by importing the ietf-interfaces YANG module [RFC8343] and using interface-refs to point at the relevant interface(s) π¦
Now the important bit, and I'm obsessed with it π DHCPv6 is itself a client configuration protocol, so this document is not trying to replace the way DHCPv6-assigned addresses and parameters get allocated through NETCONF/YANG. The DHCPv6 client module is for configuring and monitoring the DHCPv6 client function. It doesn't replace DHCPv6 address and parameter configuration π
The YANG modules in this document adopt the Network Management Datastore Architecture (NMDA) [RFC8342] π
1.1. Scope π
[RFC8415] describes the current version of the DHCPv6 base protocol specification. Lots of additional specifications have been published since, extending DHCPv6 element functionality and adding new options. The YANG modules in this document don't try to capture all of those extensions and additions. Instead, they model the DHCPv6 functions and options covered in [RFC8415]. They were also built with a focus on extensibility, so they're easy to augment with extra functionality when a particular implementation or deployment needs it π«Ά
1.2. Extensibility of the DHCPv6 Server YANG Module πΈ
The modules in this document only try to model DHCPv6-specific behavior. They don't cover configuring and managing functionality that's specific to particular server implementations. The variance between implementations is too big to standardize them in a way that's useful without being restrictive π ββοΈ
That said, implementation-specific configuration and management is also a big deal for DHCP deployment and operations π So Appendix C has an example YANG module for configuring implementation-specific functions. It shows how that functionality can be augmented into the main ietf-dhcpv6-server.yang module β¨
Next, "class selection." In DHCPv6, the server sorts incoming messages into classes so the right provisioning info can go out. This means identifying and classifying messages based on a bunch of parameters. For example, you might allocate a prefix from the correct pool, or supply a set of options meant for a specific vendor's client implementation π§ While researching implementations for this document, the team found that this function is common to all of them, but how it gets configured and implemented differs a lot π
So configuration of the class selection function was left out of the DHCPv6 server module. That lets implementors define their own suitable YANG modules. Appendix D gives an example of this, showing how it can be integrated with the main ietf-dhcpv6-server.yang module π
1.2.1. DHCPv6 Option Definitions β¨
okay so there are SO many DHCPv6 options out there now, way more than what [RFC8415] defines π . implementations are all over the place about which ones they actually support, so the move here was: only the DHCPv6 options defined in [RFC8415] get included in this doc π«Ά.
and not every one of those gets modeled, only the ones that actually need operator configuration π. like OPTION_IA_NA (3), the server creates that one when the client asks for it. the stuff inside it comes from the config inputs the server applies when the request comes in (for example, the T1/T2 timers for the address pool). so there's no field you can directly configure on it, and that's why it isn't modeled π.
here's the lineup of the options that ARE modeled, which element(s) they're modeled for, and the YANG module names π¦:
+=====================+======+=====+======+=========================+
|Name |Server|Relay|Client| Module Name |
+=====================+======+=====+======+=========================+
|OPTION_ORO (6) Option| | | X | ietf-dhcpv6-client.yang |
|Request Option | | | | |
+---------------------+------+-----+------+-------------------------+
|OPTION_PREFERENCE (7)| X | | | ietf-dhcpv6-server.yang |
|Preference Option | | | | |
+---------------------+------+-----+------+-------------------------+
|OPTION_AUTH (11) | X | X | | ietf-dhcpv6-common.yang |
|Authentication Option| | | | |
+---------------------+------+-----+------+-------------------------+
|OPTION_UNICAST (12) | X | | | ietf-dhcpv6-server.yang |
|Server Unicast Option| | | | |
+---------------------+------+-----+------+-------------------------+
|OPTION_RAPID_COMMIT | X | | X | ietf-dhcpv6-common.yang |
|(14) Rapid Commit | | | | |
|Option | | | | |
+---------------------+------+-----+------+-------------------------+
|OPTION_USER_CLASS | | | X | ietf-dhcpv6-client.yang |
|(15) User Class | | | | |
|Option | | | | |
+---------------------+------+-----+------+-------------------------+
|OPTION_VENDOR_CLASS | | | X | ietf-dhcpv6-client.yang |
|(16) Vendor Class | | | | |
|Option | | | | |
+---------------------+------+-----+------+-------------------------+
|OPTION_VENDOR_OPTS | X | | X | ietf-dhcpv6-common.yang |
|(17) Vendor-specific | | | | |
|Information Option | | | | |
+---------------------+------+-----+------+-------------------------+
|OPTION_INTERFACE_ID | | X | | ietf-dhcpv6-relay.yang |
|(18) Interface-Id | | | | |
|Option | | | | |
+---------------------+------+-----+------+-------------------------+
|OPTION_RECONF_MSG | X | | | ietf-dhcpv6-server.yang |
|(19) Reconfigure | | | | |
|Message Option | | | | |
+---------------------+------+-----+------+-------------------------+
|OPTION_RECONF_ACCEPT | X | | X | ietf-dhcpv6-client.yang |
|(20) Reconfigure | | | | |
|Accept Option | | | | |
+---------------------+------+-----+------+-------------------------+
|OPTION_INFORMATION | X | | | ietf-dhcpv6-server.yang |
|_REFRESH_TIME (32) | | | | |
|Information Refresh | | | | |
|Time Option | | | | |
+---------------------+------+-----+------+-------------------------+
|OPTION_SOL_MAX_RT | X | | | ietf-dhcpv6-server.yang |
|(82) sol max rt | | | | |
|Option | | | | |
+---------------------+------+-----+------+-------------------------+
|OPTION_INF_MAX_RT | X | | | ietf-dhcpv6-server.yang |
|(83) inf max rt | | | | |
|Option | | | | |
+---------------------+------+-----+------+-------------------------+
Table 1: Modeled DHCPv6 Options
want more options? you can add them with extra YANG modules that augment the relevant element modules from this document π. Appendix B has an example module showing how the DHCPv6 option definitions can be extended that way, and there's some guidance on writing YANG modules for additional DHCPv6 options too π§.
2. Terminology π
the reader should already be familiar with the YANG data modeling language defined in [RFC7950] πΈ. the YANG modules in this document adopt NMDA [RFC8342], and the meanings of the symbols used in tree diagrams are defined in [RFC8340] π.
you should also know the DHCPv6-relevant terminology defined in [RFC8415] and other relevant documents π«Ά.
2.1. Requirements Language π₯
okay so the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this doc are read the way BCP 14 [RFC2119] [RFC8174] describes, but ONLY when they show up in all capitals, just like here π . lowercase ones are just regular words, bestie π.
3. DHCPv6 Tree Diagrams π³
3.1. DHCPv6 Server Tree Diagram π¦
the tree diagram in Figure 1 gives you the big-picture view of the DHCPv6 server module β¨. it also includes the common functions module defined in Section 4.1, so you can see how everything fits together π.
Okay bestie, here's the full tree, the whole vibe of the DHCPv6 server module, all in one place πΈβ¨
module: ietf-dhcpv6-server
+--rw dhcpv6-server
+--rw enabled? boolean
+--rw server-duid? dhc6:duid
+--rw vendor-config
+--rw option-sets
| +--rw option-set* [option-set-id]
| +--rw option-set-id string
| +--rw description? string
| +--rw preference-option
| | +--rw pref-value? uint8
| +--rw auth-option
| | +--rw algorithm? uint8
| | +--rw rdm? uint8
| | +--rw replay-detection? uint64
| | +--rw (protocol)?
| | +--:(conf-token)
| | | +--rw token-auth-information? binary
| | +--:(rkap)
| | +--rw datatype? uint8
| | +--rw auth-info-value? binary
| +--rw server-unicast-option
| | +--rw server-address? inet:ipv6-address
| +--rw rapid-commit-option!
| +--rw vendor-specific-information-options
| | +--rw vendor-specific-information-option*
| | [enterprise-number]
| | +--rw enterprise-number uint32
| | +--rw vendor-option-data* [sub-option-code]
| | +--rw sub-option-code uint16
| | +--rw sub-option-data? binary
| +--rw reconfigure-message-option
| | +--rw msg-type? uint8
| +--rw reconfigure-accept-option!
| +--rw info-refresh-time-option
| | +--rw info-refresh-time? dhc6:timer-seconds32
| +--rw sol-max-rt-option
| | +--rw sol-max-rt-value? dhc6:timer-seconds32
| +--rw inf-max-rt-option
| +--rw inf-max-rt-value? dhc6:timer-seconds32
+--rw class-selector
+--rw allocation-ranges
+--rw option-set-id* leafref
+--rw valid-lifetime? dhc6:timer-seconds32
+--rw renew-time? dhc6:timer-seconds32
+--rw rebind-time? dhc6:timer-seconds32
+--rw preferred-lifetime? dhc6:timer-seconds32
+--rw rapid-commit? boolean
+--rw allocation-range* [id]
| +--rw id string
| +--rw description? string
| +--rw network-prefix inet:ipv6-prefix
| +--rw option-set-id* leafref
| +--rw valid-lifetime? dhc6:timer-seconds32
| +--rw renew-time? dhc6:timer-seconds32
| +--rw rebind-time? dhc6:timer-seconds32
| +--rw preferred-lifetime? dhc6:timer-seconds32
| +--rw rapid-commit? boolean
| +--rw address-pools {na-assignment}?
| | +--rw address-pool* [pool-id]
| | +--rw pool-id string
| | +--rw pool-prefix
| | | inet:ipv6-prefix
| | +--rw start-address
| | | inet:ipv6-address-no-zone
| | +--rw end-address
| | | inet:ipv6-address-no-zone
| | +--rw max-address-utilization? dhc6:threshold
| | +--rw option-set-id* leafref
| | +--rw valid-lifetime?
| | | dhc6:timer-seconds32
| | +--rw renew-time?
| | | dhc6:timer-seconds32
| | +--rw rebind-time?
| | | dhc6:timer-seconds32
| | +--rw preferred-lifetime?
| | | dhc6:timer-seconds32
| | +--rw rapid-commit? boolean
| | +--rw host-reservations
| | | +--rw host-reservation* [reserved-addr]
| | | +--rw client-duid? dhc6:duid
| | | +--rw reserved-addr
| | | | inet:ipv6-address
| | | +--rw option-set-id* leafref
| | | +--rw valid-lifetime?
| | | | dhc6:timer-seconds32
| | | +--rw renew-time?
| | | | dhc6:timer-seconds32
| | | +--rw rebind-time?
| | | | dhc6:timer-seconds32
| | | +--rw preferred-lifetime?
| | | | dhc6:timer-seconds32
| | | +--rw rapid-commit? boolean
| | +--ro active-leases
| | +--ro total-count uint64
| | +--ro allocated-count uint64
| | +--ro active-lease* [leased-address]
| | +--ro leased-address
| | | inet:ipv6-address
| | +--ro client-duid? dhc6:duid
| | +--ro ia-id uint32
| | +--ro allocation-time?
| | | yang:date-and-time
| | +--ro last-renew-rebind?
| | | yang:date-and-time
| | +--ro preferred-lifetime?
| | | dhc6:timer-seconds32
| | +--ro valid-lifetime?
| | | dhc6:timer-seconds32
| | +--ro lease-t1?
| | | dhc6:timer-seconds32
| | +--ro lease-t2?
| | | dhc6:timer-seconds32
| | +--ro status
| | +--ro code? uint16
| | +--ro message? string
| +--rw prefix-pools {prefix-delegation}?
| +--rw prefix-pool* [pool-id]
| +--rw pool-id string
| +--rw pool-prefix
| | inet:ipv6-prefix
| +--rw client-prefix-length uint8
| +--rw max-pd-space-utilization? dhc6:threshold
| +--rw option-set-id* leafref
| +--rw valid-lifetime?
| | dhc6:timer-seconds32
| +--rw renew-time?
| | dhc6:timer-seconds32
| +--rw rebind-time?
| | dhc6:timer-seconds32
| +--rw preferred-lifetime?
| | dhc6:timer-seconds32
| +--rw rapid-commit? boolean
| +--rw host-reservations
| | +--rw prefix-reservation* [reserved-prefix]
| | | +--rw client-duid? dhc6:duid
| | | +--rw reserved-prefix
| | | | inet:ipv6-prefix
| | | +--rw reserved-prefix-len? uint8
| | +--rw option-set-id* leafref
| | +--rw valid-lifetime?
| | | dhc6:timer-seconds32
| | +--rw renew-time?
| | | dhc6:timer-seconds32
| | +--rw rebind-time?
| | | dhc6:timer-seconds32
| | +--rw preferred-lifetime?
| | | dhc6:timer-seconds32
| | +--rw rapid-commit? boolean
| +--ro active-leases
| +--ro total-count uint64
| +--ro allocated-count uint64
| +--ro active-lease* [leased-prefix]
| +--ro leased-prefix
| | inet:ipv6-prefix
| +--ro client-duid? dhc6:duid
| +--ro ia-id uint32
| +--ro allocation-time?
| | yang:date-and-time
| +--ro last-renew-rebind?
| | yang:date-and-time
| +--ro preferred-lifetime?
| | dhc6:timer-seconds32
| +--ro valid-lifetime?
| | dhc6:timer-seconds32
| +--ro lease-t1?
| | dhc6:timer-seconds32
| +--ro lease-t2?
| | dhc6:timer-seconds32
| +--ro status
| +--ro code? uint16
| +--ro message? string
+--rw statistics
+--rw discontinuity-time? yang:date-and-time
+--ro solicit-count? yang:counter32
+--ro advertise-count? yang:counter32
+--ro request-count? yang:counter32
+--ro confirm-count? yang:counter32
+--ro renew-count? yang:counter32
+--ro rebind-count? yang:counter32
+--ro reply-count? yang:counter32
+--ro release-count? yang:counter32
+--ro decline-count? yang:counter32
+--ro reconfigure-count? yang:counter32
+--ro information-request-count? yang:counter32
+--ro discarded-message-count? yang:counter32
rpcs:
+---x delete-address-lease {na-assignment}?
| +---w input
| | +---w lease-address-to-delete leafref
| +--ro output
| +--ro return-message? string
+---x delete-prefix-lease {prefix-delegation}?
+---w input
| +---w lease-prefix-to-delete leafref
+--ro output
+--ro return-message? string
notifications:
+---n address-pool-utilization-threshold-exceeded
| {na-assignment}?
| +--ro pool-id leafref
| +--ro total-pool-addresses uint64
| +--ro max-allocated-addresses uint64
| +--ro allocated-address-count uint64
+---n prefix-pool-utilization-threshold-exceeded
| {prefix-delegation}?
| +--ro pool-id leafref
| +--ro total-pool-prefixes uint64
| +--ro max-allocated-prefixes uint64
| +--ro allocated-prefixes-count uint64
+---n invalid-client-detected
| +--ro message-type? enumeration
| +--ro duid? dhc6:duid
| +--ro description? string
+---n decline-received {na-assignment}?
| +--ro duid? dhc6:duid
| +--ro declined-resources* []
| +--ro (resource-type)?
| +--:(declined-address)
| | +--ro address? inet:ipv6-address
| +--:(declined-prefix)
| +--ro prefix? inet:ipv6-prefix
+---n non-success-code-sent
+--ro duid? dhc6:duid
+--ro status
+--ro code? uint16
+--ro message? string
Figure 1: DHCPv6 Server Data Module Structure π
Now let's go through the important nodes, because these ones are the main characters π
Descriptions of important nodes
enabled: This enables/disables the function of the DHCPv6 server. πdhcpv6-server: This container holds the server's DHCPv6-specific configuration. π§
server-duid: πͺͺ Every server must have a DHCP Unique Identifier (DUID) so it can introduce itself to clients. A DUID is a 2-octet type field plus a content field of arbitrary length (no more than 128 octets). There are currently four DUID types defined in [RFC8415] and [RFC6355], and you can configure the DUID using the format of one of those types or the'unstructured'format. The DUID type definitions get imported from the'ietf-dhcpv6-common.yang'module, and [IANA-HARDWARE-TYPES] and [IANA-PEN] are referenced for the relevant DUID types. πΈvendor-config: π This container is a spot for extra implementation-specific YANG nodes to augment the device's configuration. Appendix C has an example of one of these modules. πoption-sets: π§ The server can hold multiple option-sets. These are groups of DHCPv6 options with shared parameters that can be handed to clients when they ask. Theoption-set-idfield is how you point to an option-set from somewhere else in the server's config. β¨option-set: π¦ This holds the configuration parameters for DHCPv6 options. The starter set of option definitions lives right here, and other options that also matter to the relay and/or client are imported from the'ietf-dhcpv6-common'module. Other DHCPv6 option modules can be augmented where needed as they get defined. The full list of DHCPv6 options lives at [IANA-DHCPV6-OPTION-CODES]. π«Άclass-selector: π¦ Another spot for vendor-specific class selector nodes to be augmented in. Appendix D has an example of this. π§allocation-ranges: πΊοΈ Addresses and prefixes are allocated in a hierarchy. The top-levelallocation-rangescontainer holds the global configuration parameters, and under it, theallocation-rangelist is used to specify IPv6 prefixes along with prefix-specific parameters. It's giving organised. πaddress-pools: π This covers pool allocations for Identity Association for Non-temporary Addresses (IA_NA) and Identity Association for Temporary Addresses (IA_TA), with a container for defining host reservations. Active lease state from each pool also lives here. πprefix-pools: π These pools are for prefix delegation to clients. Static host reservations can be configured here too. Since not every DHCPv6 server implementation supports prefix delegation, it's turned on with a feature statement. π₯
Information about RPCs:
delete-address-lease: ποΈ This lets you delete the lease for one individual IPv6 address from the server's lease database. Per [BCP18], if available, a language identifier should be included in the output message. π·delete-prefix-lease: βοΈ This lets you delete the lease for one individual IPv6 prefix from the server's lease database. Per [BCP18], if available, a language identifier should be included in the output message. π
Information about notifications:
address/prefix-pool-utilization-threshold-exceeded: π¨ Raised when the number of leased addresses or prefixes in a pool goes over the configured usage threshold. πinvalid-client-detected: π Raised when the server spots an invalid client. A description of the error and the message type that triggered the notification can be included. π΅οΈdecline-received: π Raised when a DHCPv6 Decline message comes in from a client. πnon-success-code-sent: β Raised when a status message for a failure goes out. Status codes are drawn from [IANA-DHCPV6-STATUS-CODES]. π
3.2. DHCPv6 Relay Tree Diagram π¦
The tree diagram in Figure 2 gives you the overview of the DHCPv6 relay module, and it also includes the common functions module defined in Section 4.1. π§
The RPCs in this module come from the requirements defined in [RFC8987]. β¨
module: ietf-dhcpv6-relay
+--rw dhcpv6-relay
+--rw enabled? boolean
+--rw relay-if* [if-name]
| +--rw if-name if:interface-ref
| +--rw enabled? boolean
| +--rw destination-address* inet:ipv6-address
| +--rw link-address? inet:ipv6-address
| +--rw relay-options
| | +--rw auth-option
| | | +--rw algorithm? uint8
| | | +--rw rdm? uint8
| | | +--rw replay-detection? uint64
| | | +--rw (protocol)?
| | | +--:(conf-token)
| | | | +--rw token-auth-information? binary
| | | +--:(rkap)
| | | +--rw datatype? uint8
| | | +--rw auth-info-value? binary
| | +--rw interface-id-option
| | +--rw interface-id? binary
| +--rw statistics
| | +--rw discontinuity-time?
| | | yang:date-and-time
| | +--ro solicit-received-count?
| | | yang:counter32
| | +--ro advertise-sent-count?
| | | yang:counter32
| | +--ro request-received-count?
| | | yang:counter32
| | +--ro confirm-received-count?
| | | yang:counter32
| | +--ro renew-received-count?
| | | yang:counter32
| | +--ro rebind-received-count?
| | | yang:counter32
| | +--ro reply-sent-count?
| | | yang:counter32
| | +--ro release-received-count?
| | | yang:counter32
| | +--ro decline-received-count?
| | | yang:counter32
| | +--ro reconfigure-sent-count?
| | | yang:counter32
| | +--ro information-request-received-count?
| | | yang:counter32
| | +--ro unknown-message-received-count?
| | | yang:counter32
| | +--ro unknown-message-sent-count?
| | | yang:counter32
| | +--ro discarded-message-count?
| | yang:counter32
| +--rw prefix-delegation! {prefix-delegation}?
| +--ro pd-leases* [ia-pd-prefix]
| +--ro ia-pd-prefix inet:ipv6-prefix
| +--ro last-renew? yang:date-and-time
| +--ro client-peer-address? inet:ipv6-address
| +--ro client-duid? dhc6:duid
| +--ro server-duid? dhc6:duid
+--rw statistics
+--ro relay-forward-sent-count?
| yang:counter32
+--ro relay-forward-received-count?
| yang:counter32
+--ro relay-reply-received-count?
| yang:counter32
+--ro relay-forward-unknown-sent-count?
| yang:counter32
+--ro relay-forward-unknown-received-count?
| yang:counter32
+--ro discarded-message-count?
yang:counter32
rpcs:
+---x clear-prefix-entry {prefix-delegation}?
| +---w input
| | +---w lease-prefix leafref
| +--ro output
| +--ro return-message? string
+---x clear-client-prefixes {prefix-delegation}?
| +---w input
| | +---w client-duid dhc6:duid
| +--ro output
| +--ro return-message? string
+---x clear-interface-prefixes {prefix-delegation}?
+---w input
| +---w interface -> /dhcpv6-relay/relay-if/if-name
+--ro output
+--ro return-message? string
notifications:
+---n relay-event
+--ro topology-change
+--ro relay-if-name?
| -> /dhcpv6-relay/relay-if/if-name
+--ro last-ipv6-addr? inet:ipv6-address
Figure 2: DHCPv6 Relay Data Module Structure
Descriptions of important nodes:
enabled: π This globally enables/disables all DHCPv6 relay functions. πdhcpv6-relay: π This container holds the relay's DHCPv6-specific configuration. πΌrelay-if: π A relay can have several client-facing interfaces, so they get configured in a list. Theif-nameleaf is the key, and it's an interface-ref pointing to the matching interface defined by theietf-interfacesYANG module. π§©enabled: ποΈ This enables/disables all DHCPv6 relay functions for one specific interface. π«§destination-addresses: π― This defines a list of IPv6 addresses that client messages get relayed to. These can be unicast or multicast addresses. π¬link-address: π This configures the value the relay puts into the link-address field of Relay-Forward messages. π«prefix-delegation: π Prefix delegation isn't supported by every DHCPv6 relay implementation, so it gets enabled by this feature statement wherever it's needed. πpd-leases: π These are read-only nodes that hold info about active delegated prefix leases. πrelay-options: π§Ύ This holds config parameters for DHCPv6 options the relay can send. The starter set of option definitions lives here, and other options that matter to the server and/or client are imported from the'ietf-dhcpv6-common'module. Info for the Authentication Option (OPTION_AUTH (11)) is drawn from [IANA-DHCPV6-AUTH-NAMESPACES] and [RFC3118]. Other DHCPv6 option modules can be augmented where needed as they're defined, and the full list of DHCPv6 options is at [IANA-DHCPV6-OPTION-CODES]. π
Information about RPCs:
clear-prefix-entry: π§Ή This lets you remove a delegated lease entry from the relay. Per [BCP18], if available, a language identifier should be included in the output message. π«§clear-client-prefixes: π§½ This removes all of the delegated lease entries for a single client, referenced by client DUID, from the relay. Per [BCP18], if available, a language identifier should be included in the output message. πͺclear-interface-prefixes: πΏ This removes all of the delegated lease entries from one interface on the relay. Per [BCP18], if available, a language identifier should be included in the output message. π
Information about notifications:
topology-change: π Raised when the relay agent's topology changes, for example when a client-facing interface gets reconfigured. π οΈ
3.3. DHCPv6 Client Tree Diagram
Okay so Figure 3 is the big-picture map of the DHCPv6 client module πΊοΈβ¨ It also pulls in the common functions module from Section 4.1, so it's giving full-stack energy π
module: ietf-dhcpv6-client
+--rw dhcpv6-client
+--rw enabled? boolean
+--rw client-if* [if-name]
+--rw if-name if:interface-ref
+--rw enabled? boolean
+--rw interface-duid? dhc6:duid
| {(non-temp-addr or prefix-delegation or temp-addr)
and anon-profile}?
+--rw client-configured-options
| +--rw option-request-option
| | +--rw oro-option* uint16
| +--rw rapid-commit-option!
| +--rw user-class-option!
| | +--rw user-class-data-instance*
| | [user-class-data-id]
| | +--rw user-class-data-id uint8
| | +--rw user-class-data? binary
| +--rw vendor-class-option
| | +--rw vendor-class-option-instances*
| | [enterprise-number]
| | +--rw enterprise-number uint32
| | +--rw vendor-class-data-element*
| | [vendor-class-data-id]
| | +--rw vendor-class-data-id uint8
| | +--rw vendor-class-data? binary
| +--rw vendor-specific-information-options
| | +--rw vendor-specific-information-option*
| | [enterprise-number]
| | +--rw enterprise-number uint32
| | +--rw vendor-option-data* [sub-option-code]
| | +--rw sub-option-code uint16
| | +--rw sub-option-data? binary
| +--rw reconfigure-accept-option!
+--rw ia-na* [ia-id] {non-temp-addr}?
| +--rw ia-id uint32
| +--rw ia-na-options
| +--ro lease-state
| +--ro ia-na-address? inet:ipv6-address
| +--ro lease-t1? dhc6:timer-seconds32
| +--ro lease-t2? dhc6:timer-seconds32
| +--ro preferred-lifetime? dhc6:timer-seconds32
| +--ro valid-lifetime? dhc6:timer-seconds32
| +--ro allocation-time? yang:date-and-time
| +--ro last-renew-rebind? yang:date-and-time
| +--ro server-duid? dhc6:duid
| +--ro status
| +--ro code? uint16
| +--ro message? string
+--rw ia-ta* [ia-id] {temp-addr}?
| +--rw ia-id uint32
| +--rw ia-ta-options
| +--ro lease-state
| +--ro ia-ta-address? inet:ipv6-address
| +--ro preferred-lifetime? dhc6:timer-seconds32
| +--ro valid-lifetime? dhc6:timer-seconds32
| +--ro allocation-time? yang:date-and-time
| +--ro last-renew-rebind? yang:date-and-time
| +--ro server-duid? dhc6:duid
| +--ro status
| +--ro code? uint16
| +--ro message? string
+--rw ia-pd* [ia-id] {prefix-delegation}?
| +--rw ia-id uint32
| +--rw prefix-length-hint? uint8
| +--rw ia-pd-options
| +--ro lease-state
| +--ro ia-pd-prefix? inet:ipv6-prefix
| +--ro lease-t1? dhc6:timer-seconds32
| +--ro lease-t2? dhc6:timer-seconds32
| +--ro preferred-lifetime? dhc6:timer-seconds32
| +--ro valid-lifetime? dhc6:timer-seconds32
| +--ro allocation-time? yang:date-and-time
| +--ro last-renew-rebind? yang:date-and-time
| +--ro server-duid? dhc6:duid
| +--ro status
| +--ro code? uint16
| +--ro message? string
+--rw statistics
+--rw discontinuity-time? yang:date-and-time
+--ro solicit-count? yang:counter32
+--ro advertise-count? yang:counter32
+--ro request-count? yang:counter32
+--ro confirm-count? yang:counter32
+--ro renew-count? yang:counter32
+--ro rebind-count? yang:counter32
+--ro reply-count? yang:counter32
+--ro release-count? yang:counter32
+--ro decline-count? yang:counter32
+--ro reconfigure-count? yang:counter32
+--ro information-request-count? yang:counter32
+--ro discarded-message-count? yang:counter32
notifications:
+---n invalid-ia-address-detected
| {non-temp-addr or temp-addr}?
| +--ro ia-id uint32
| +--ro ia-na-t1-timer? uint32
| +--ro ia-na-t2-timer? uint32
| +--ro invalid-address? inet:ipv6-address
| +--ro preferred-lifetime? uint32
| +--ro valid-lifetime? uint32
| +--ro ia-options? binary
| +--ro description? string
+---n transmission-failed
| +--ro failure-type enumeration
| +--ro description? string
+---n unsuccessful-status-code
| +--ro server-duid dhc6:duid
| +--ro status
| +--ro code? uint16
| +--ro message? string
+---n server-duid-changed
{non-temp-addr or prefix-delegation or temp-addr}?
+--ro new-server-duid dhc6:duid
+--ro previous-server-duid dhc6:duid
+--ro lease-ia-na?
| -> /dhcpv6-client/client-if/ia-na/ia-id
| {non-temp-addr}?
+--ro lease-ia-ta?
| -> /dhcpv6-client/client-if/ia-ta/ia-id
| {temp-addr}?
+--ro lease-ia-pd?
-> /dhcpv6-client/client-if/ia-pd/ia-id
{prefix-delegation}?
Figure 3: DHCPv6 Client Data Module Structure
Here's what the important nodes do, bestie π«Ά
- enabled: this globally turns all DHCPv6 client functions on or off π
- dhcpv6-client: this container holds the client's DHCPv6-specific config π
- client-if: a client can have several interfaces asking for config over DHCP, so these live in a list π The
if-nameleaf is the key, and it's an interface-ref pointing at the matching interface from theietf-interfacesYANG module. - enabled (per interface): this turns all DHCPv6 client functions on or off for one specific interface π
- client-duid/interface-duid: the DUID is how the client gets identified by servers and relays πͺͺ A DUID is a 2-octet type field plus arbitrary-length content (1-128 octets) π₯ There are four DUID types defined in [RFC8415] and [RFC6355] right now. You can configure the DUID in the format of one of those types, or in the
unstructuredformat. The DUID type definitions get imported from theietf-dhcpv6-common.yangmodule, and [IANA-HARDWARE-TYPES] and [IANA-PEN] are referenced for the relevant DUID types. π A DUID only needs to be configured if the client is asking for addresses and/or prefixes from the server. Theclient-duidorinterface-duidleaf is present based on whether at least one of thenon-temp-addr,temp-addr, orprefix-delegationfeatures is enabled. Also, if the [RFC7844]anon-profilefeature is enabled, you can configure a unique DUID per DHCP-enabled interface using theinterface-duidleaf. Otherwise, there's a globalclient-duidleaf instead π¦ - client-configured-options: this holds config parameters for DHCPv6 options the client can send π§ The initial set of applicable option definitions lives right here, and any other options that are also relevant to the relay and/or server get imported from the
ietf-dhcpv6-commonmodule. Other DHCPv6 option modules can be augmented as they're defined. The full list of DHCPv6 options is at [IANA-DHCPV6-OPTION-CODES] π - ia-na, ia-ta, ia-pd: these hold config nodes for requesting one or more of each lease type β¨ Read-only nodes for the active leases of each type are here too, and the status codes come from [IANA-DHCPV6-STATUS-CODES] π Not every DHCPv6 client implementation supports every lease type, so they're turned on through individual feature statements. Stateless DHCP (Section 6.1 of [RFC8415]) is configured when all the address and prefix features are disabled πΈ
Information about notifications, iykyk:
- invalid-ia-detected: raised when the client's identity association can be proven invalid. Possible conditions include a duplicated address, an illegal address, and so on π
- retransmission-failed: raised when the retransmission mechanism defined in [RFC8415] has failed π
4. DHCPv6 YANG Modules π§
4.1. DHCPv6 Common YANG Module
The common module is the shared toolbox everyone else borrows from, and it starts right here π§°
<CODE BEGINS> file "ietf-dhcpv6-common@2022-06-20.yang"
module ietf-dhcpv6-common {
yang-version 1.1;
namespace "urn:ietf:params:xml:ns:yang:ietf-dhcpv6-common";
prefix dhc6;
organization
"IETF Dynamic Host Configuration (DHC) Working Group";
contact
"WG Web: <https://datatracker.ietf.org/wg/dhc/>
WG List: <mailto:dhcwg@ietf.org>
Author: Yong Cui <yong@csnet1.cs.tsinghua.edu.cn>
Author: Linhui Sun <lh.sunlinh@gmail.com>
Editor: Ian Farrer <ian.farrer@telekom.de>
Author: Sladjana Zeichlin <sladjana.zechlin@telekom.de>
Author: Zihao He <hezihao9512@gmail.com>
Author: Michal Nowikowski <godfryd@isc.org>";
description
"This YANG module defines common components used for the
configuration and management of DHCPv6.
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 (RFC 2119)
(RFC 8174) when, and only when, they appear in all
capitals, as shown here.
Copyright (c) 2022 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 9243
(https://www.rfc-editor.org/info/rfc9243); see the RFC itself
for full legal notices.";
revision 2022-06-20 {
description
"Initial revision.";
reference
"RFC 9243: A YANG Data Model for DHCPv6 Configuration";
}
typedef threshold {
type uint8 {
range "1..100";
}
description
"Threshold value in percent.";
}
okay bestie, the DUID typedefs are up next and they're giving main character energy π¦β¨
typedef timer-seconds32 {
type uint32;
units "seconds";
description
"Timer value type in seconds (32-bit range).";
}
typedef duid-base {
type string {
pattern '([0-9a-fA-F]{2}){3,130}';
}
description
"Each DHCP server and client has a DHCP Unique Identifier
(DUID). The DUID consists of a 2-octet type field
and an arbitrary length (1-128 octets) content field.
The duid-base type is used by other duid types with
additional pattern constraints.
Currently, there are four defined types of DUIDs
in RFCs 8415 and 6355 -- DUID-LLT, DUID-EN, DUID-LL, and
DUID-UUID. DUID-unstructured represents DUIDs that do not
follow any of the defined formats.
Type 'string' is used to represent the hexadecimal DUID value
so that pattern constraints can be applied.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 11
RFC 6355: Definition of the UUID-Based DHCPv6 Unique
Identifier (DUID-UUID), Section 4";
}
typedef duid-llt {
type duid-base {
pattern '0001'
+ '[0-9a-fA-F]{12,}';
}
description
"DUID type 1, based on Link-Layer Address Plus Time
(DUID-LLT). Constructed with a 2-octet hardware type assigned
by IANA, 4 octets containing the time the DUID is generated
(represented in seconds since midnight (UTC), January 1, 2000,
modulo 2^32), and a link-layer address. The address is encoded
without separator characters. For example:
+------+------+----------+--------------+
| 0001 | 0006 | 28490058 | 00005E005300 |
+------+------+----------+--------------+
This example includes the 2-octet DUID type of 1 (0x01); the
hardware type is 0x06 (IEEE Hardware Types), and the creation
time is 0x28490058 (constructed as described above). Finally,
the link-layer address is 0x5E005300 (EUI-48 address
00-00-5E-00-53-00).";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 11.2
IANA 'Hardware Types' registry
<https://www.iana.org/assignments/arp-parameters>";
}
typedef duid-en {
type duid-base {
pattern '0002'
+ '[0-9a-fA-F]{8,}';
}
description
"DUID type 2, assigned by vendor based on Enterprise
Number (DUID-EN). This DUID consists of the 4-octet vendor's
registered Private Enterprise Number, as maintained by IANA,
followed by a unique identifier assigned by the vendor. For
example:
+------+----------+------------------+
| 0002 | 00007ED9 | 0CC084D303000912 |
+------+----------+------------------+
This example includes the 2-octet DUID type of 2 (0x02),
4 octets for the Enterprise Number (0x7ED9), followed by
8 octets of identifier data (0x0CC084D303000912).";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 11.3
IANA 'Private Enterprise Numbers' registry
<https://www.iana.org/assignments/enterprise-numbers>";
}
typedef duid-ll {
type duid-base {
pattern '0003'
+ '([0-9a-fA-F]){4,}';
}
description
"DUID type 3, based on Link-Layer Address (DUID-LL).
Constructed with a 2-octet hardware type assigned
by IANA and a link-layer address. The address is encoded
without separator characters. For example:
+------+------+--------------+
| 0003 | 0006 | 00005E005300 |
+------+------+--------------+
This example includes the 2-octet DUID type of 3 (0x03); the
hardware type is 0x06 (IEEE Hardware Types), and the
link-layer address is 0x5E005300 (EUI-48 address
00-00-5E-00-53-00).";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 11.4
IANA 'Hardware Types' registry
<https://www.iana.org/assignments/arp-parameters>";
}
typedef duid-uuid {
type duid-base {
pattern '0004'
+ '[0-9a-fA-F]{32}';
}
description
"DUID type 4, based on Universally Unique Identifier
(DUID-UUID). This type of DUID consists of 16 octets
containing a 128-bit UUID. For example:
+------+----------------------------------+
| 0004 | 9f03b182705747e38a1e422910078642 |
+------+----------------------------------+
This example includes the 2-octet DUID type of 4 (0x04) and
the UUID 9f03b182-7057-47e3-8a1e-422910078642.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 11.5
RFC 6355: Definition of the UUID-Based DHCPv6 Unique
Identifier (DUID-UUID)";
}
typedef duid-unstructured {
type duid-base {
pattern '(000[1-4].*)' {
modifier "invert-match";
}
}
description
"Used for DUIDs following any formats other than DUID
types 1-4. For example:
+----------------------------------+
| 7b6a164d325946539dc540fb539bc430 |
+----------------------------------+
Here, an arbitrary 16-octet value is used. The only
constraint placed on this is that the first 2 octets
are not 0x01-0x04 to avoid collision with the other
defined DUID types (duid-llt, duid-en, duid-ll,
or duid-uuid).";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 11";
}
typedef duid {
type union {
type duid-llt;
type duid-en;
type duid-ll;
type duid-uuid;
type duid-unstructured;
}
description
"Represents the DUID and is neutral to the DUID's construction
format.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 11";
}
/*
* Groupings
*/
grouping status {
description
"Holds information about the most recent status code that
has been sent by the server or received by the client.";
reference
"RFC 8415: Dynamic Host Configuration Protocol
for IPv6 (DHCPv6), Section 7.5.";
container status {
description
"Status code information, relating to the success or failure
of operations requested in messages.";
leaf code {
type uint16;
description
"The numeric code for the status encoded in this option.
See the 'Status Codes' registry at
<https://www.iana.org/assignments/dhcpv6-parameters>
for the current list of status codes.";
}
leaf message {
type string;
description
"A UTF-8-encoded text string suitable for display to an
end user. It MUST NOT be null terminated.";
}
}
}
grouping auth-option-group {
description
"OPTION_AUTH (11) Authentication Option.";
reference
"RFC 8415: Dynamic Host Configuration Protocol
for IPv6 (DHCPv6), Section 21.11
RFC 3118: Authentication for DHCP Messages
IANA 'Dynamic Host Configuration Protocol (DHCP)
Authentication Option Name Spaces' registry
<https://www.iana.org/assignments/auth-namespaces>";
container auth-option {
description
"OPTION_AUTH (11) Authentication Option.";
leaf algorithm {
type uint8;
description
"The algorithm used in the authentication protocol.";
}
leaf rdm {
type uint8;
description
"The Replay Detection Method (RDM) used in this
Authentication option.";
}
leaf replay-detection {
type uint64;
description
"The replay detection information for the RDM.";
}
choice protocol {
description
"The authentication protocol used in the option. Protocol
Namespace Values 1 (delayed authentication) and 2 (Delayed
Authentication (Obsolete)) are not applicable and so are
not modeled.";
case conf-token {
leaf token-auth-information {
type binary;
description
"Protocol Namespace Value 0. The authentication
information, as specified by the protocol and
algorithm used in this Authentication option.";
}
}
case rkap {
description
"Protocol Namespace Value 3. The Reconfigure Key
Authentication Protocol (RKAP) provides protection
against misconfiguration of a client caused by a
Reconfigure message sent by a malicious DHCP
server.";
leaf datatype {
type uint8 {
range "1 .. 2";
}
description
"Type of data in the Value field carried in this
option.
1 Reconfigure key value (used in the Reply
message).
2 HMAC-MD5 digest of the message (used in
the Reconfigure message).";
}
leaf auth-info-value {
type binary {
length "16";
}
description
"Data, as defined by the Type field. A 16-octet
field.";
}
}
}
}
}
grouping rapid-commit-option-group {
description
"OPTION_RAPID_COMMIT (14) Rapid Commit Option.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 21.14";
container rapid-commit-option {
presence "Enable sending of this option";
description
"OPTION_RAPID_COMMIT (14) Rapid Commit Option.";
}
}
grouping vendor-specific-information-option-group {
description
"OPTION_VENDOR_OPTS (17) Vendor-specific Information
Option.";
reference
"RFC 8415: Dynamic Host Configuration Protocol
for IPv6 (DHCPv6), Section 21.17";
container vendor-specific-information-options {
description
"OPTION_VENDOR_OPTS (17) Vendor-specific Information
Option.";
list vendor-specific-information-option {
key "enterprise-number";
description
"The Vendor-specific Information option allows for
multiple instances in a single message. Each list entry
defines the contents of an instance of the option.";
leaf enterprise-number {
type uint32;
description
"The vendor's registered Enterprise Number, as
maintained by IANA.";
reference
"IANA 'Private Enterprise Numbers' registry
<https://www.iana.org/assignments/enterprise-numbers>";
}
list vendor-option-data {
key "sub-option-code";
description
"Vendor options, interpreted by vendor-specific
client/server functions.";
leaf sub-option-code {
type uint16;
description
"The code for the sub-option.";
}
leaf sub-option-data {
type binary;
description
"The data area for the sub-option.";
}
}
}
}
}
grouping reconfigure-accept-option-group {
description
"OPTION_RECONF_ACCEPT (20) Reconfigure Accept Option.
A client uses the Reconfigure Accept option to announce to
the server whether or not the client is willing to accept
Reconfigure messages, and a server uses this option to tell
the client whether or not to accept Reconfigure messages. In
the absence of this option, the default behavior is that the
client is unwilling to accept Reconfigure messages. The
presence node is used to enable the option.";
reference
"RFC 8415: Dynamic Host Configuration Protocol
for IPv6 (DHCPv6), Section 21.20";
container reconfigure-accept-option {
presence "Enable sending of this option";
description
"OPTION_RECONF_ACCEPT (20) Reconfigure Accept Option.";
}
}
}
<CODE ENDS>
4.2. DHCPv6 Server YANG Module π
Okay so this one is the server module, and it's literally borrowing typedefs from [RFC6991] and the module defined in [RFC8343]. Main character energy π β¨
<CODE BEGINS> file "ietf-dhcpv6-server@2022-06-20.yang"
module ietf-dhcpv6-server {
yang-version 1.1;
namespace "urn:ietf:params:xml:ns:yang:ietf-dhcpv6-server";
prefix dhc6-srv;
import ietf-inet-types {
prefix inet;
reference
"RFC 6991: Common YANG Data Types";
}
import ietf-yang-types {
prefix yang;
reference
"RFC 6991: Common YANG Data Types";
}
import ietf-dhcpv6-common {
prefix dhc6;
reference
"RFC 9243: A YANG Data Model for DHCPv6 Configuration";
}
import ietf-netconf-acm {
prefix nacm;
reference
"RFC 8341: Network Configuration Access Control Model";
}
organization
"IETF Dynamic Host Configuration (DHC) Working Group";
contact
"WG Web: <https://datatracker.ietf.org/wg/dhc/>
WG List: <mailto:dhcwg@ietf.org>
Author: Yong Cui <yong@csnet1.cs.tsinghua.edu.cn>
Author: Linhui Sun <lh.sunlinh@gmail.com>
Editor: Ian Farrer <ian.farrer@telekom.de>
Author: Sladjana Zeichlin <sladjana.zechlin@telekom.de>
Author: Zihao He <hezihao9512@gmail.com>
Author: Michal Nowikowski <godfryd@isc.org>";
description
"This YANG module defines components for the configuration
and management of DHCPv6 servers.
Copyright (c) 2022 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 9243
(https://www.rfc-editor.org/info/rfc9243); see the RFC itself
for full legal notices.";
revision 2022-06-20 {
description
"Initial revision.";
reference
"RFC 9243: A YANG Data Model for DHCPv6 Configuration";
}
/*
* Features
*/
feature na-assignment {
description
"Denotes that the server implements DHCPv6 non-temporary
address assignment.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 6.2";
}
feature prefix-delegation {
description
"Denotes that the server implements DHCPv6 prefix
delegation.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 6.3";
}
/*
* Groupings
*/
grouping resource-config {
description
"Nodes that are reused at multiple levels in the DHCPv6
server's addressing hierarchy.";
leaf-list option-set-id {
type leafref {
path "/dhcpv6-server/option-sets/option-set/option-set-id";
}
description
"The ID field of the relevant set of DHCPv6 options
(option-set) to be provisioned to clients using the
allocation-range.";
}
leaf valid-lifetime {
type dhc6:timer-seconds32;
description
"Valid lifetime for the Identity Association (IA).";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 12.1";
}
leaf renew-time {
type dhc6:timer-seconds32;
description
"Renew (T1) time.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 4.2";
}
leaf rebind-time {
type dhc6:timer-seconds32;
description
"Rebind (T2) time.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 4.2";
}
leaf preferred-lifetime {
type dhc6:timer-seconds32;
description
"Preferred lifetime for the IA.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 12.1";
}
leaf rapid-commit {
type boolean;
description
"When set to 'true', specifies that client-server exchanges
involving two messages is supported.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 5.1";
}
}
grouping lease-information {
description
"Binding information for each client that has been allocated
an IPv6 address or prefix.";
leaf client-duid {
type dhc6:duid;
description
"Client DUID.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 11";
}
leaf ia-id {
type uint32;
mandatory true;
description
"Client's Identity Association IDentifier (IAID).";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 12";
}
leaf allocation-time {
type yang:date-and-time;
description
"Time and date that the lease was made.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 18";
}
leaf last-renew-rebind {
type yang:date-and-time;
description
"Time of the last successful renew or rebind.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 18";
}
leaf preferred-lifetime {
type dhc6:timer-seconds32;
description
"The preferred lifetime expressed in seconds.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 6";
}
leaf valid-lifetime {
type dhc6:timer-seconds32;
description
"The valid lifetime for the lease expressed in seconds.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 6";
}
leaf lease-t1 {
type dhc6:timer-seconds32;
description
"The time interval after which the client should contact
the server from which the addresses in the IA_NA were
obtained to extend the lifetimes of the addresses assigned
to the Identity Association for Prefix Delegation (IA_PD).";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 4.2";
}
leaf lease-t2 {
type dhc6:timer-seconds32;
description
"The time interval after which the client should contact
any available server to extend the lifetimes of the
addresses assigned to the IA_PD.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 4.2";
}
uses dhc6:status;
}
okay bestie, these groupings are basically the stats wall πβ¨ every counter for every DHCPv6 message type, plus the little option containers that carry the good stuff π
grouping message-statistics {
description
"Counters for DHCPv6 messages.";
leaf discontinuity-time {
type yang:date-and-time;
description
"The time on the most recent occasion at which any one or
more of DHCPv6 server's counters suffered a discontinuity.
If no such discontinuities have occurred since the last
re-initialization of the local management subsystem, then
this node contains the time the local management subsystem
re-initialized itself.";
}
leaf solicit-count {
type yang:counter32;
config false;
description
"Number of Solicit (1) messages received.";
}
leaf advertise-count {
type yang:counter32;
config false;
description
"Number of Advertise (2) messages sent.";
}
leaf request-count {
type yang:counter32;
config false;
description
"Number of Request (3) messages received.";
}
leaf confirm-count {
type yang:counter32;
config false;
description
"Number of Confirm (4) messages received.";
}
leaf renew-count {
type yang:counter32;
config false;
description
"Number of Renew (5) messages received.";
}
leaf rebind-count {
type yang:counter32;
config false;
description
"Number of Rebind (6) messages received.";
}
leaf reply-count {
type yang:counter32;
config false;
description
"Number of Reply (7) messages sent.";
}
leaf release-count {
type yang:counter32;
config false;
description
"Number of Release (8) messages received.";
}
leaf decline-count {
type yang:counter32;
config false;
description
"Number of Decline (9) messages received.";
}
leaf reconfigure-count {
type yang:counter32;
config false;
description
"Number of Reconfigure (10) messages sent.";
}
leaf information-request-count {
type yang:counter32;
config false;
description
"Number of Information-request (11) messages
received.";
}
leaf discarded-message-count {
type yang:counter32;
config false;
description
"Number of messages that have been discarded for any
reason.";
}
}
grouping preference-option-group {
description
"OPTION_PREFERENCE (7) Preference Option.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 21.8";
container preference-option {
description
"OPTION_PREFERENCE (7) Preference Option.";
leaf pref-value {
type uint8;
description
"The preference value for the server in this message. A
1-octet unsigned integer.";
}
}
}
grouping server-unicast-option-group {
description
"OPTION_UNICAST (12) Server Unicast Option.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 21.12";
container server-unicast-option {
description
"OPTION_UNICAST (12) Server Unicast Option.";
leaf server-address {
type inet:ipv6-address;
description
"The 128-bit address to which the client should send
messages delivered using unicast.";
}
}
}
grouping reconfigure-message-option-group {
description
"OPTION_RECONF_MSG (19) Reconfigure Message Option.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 21.19";
container reconfigure-message-option {
description
"OPTION_RECONF_MSG (19) Reconfigure Message Option.";
leaf msg-type {
type uint8;
description
"5 for Renew message, 6 for Rebind message, and 11 for
Information-request message.";
}
}
}
grouping info-refresh-time-option-group {
description
"OPTION_INFORMATION_REFRESH_TIME (32) Information Refresh
Time Option.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 21.23";
container info-refresh-time-option {
description
"OPTION_INFORMATION_REFRESH_TIME (32) Information Refresh
Time Option.";
leaf info-refresh-time {
type dhc6:timer-seconds32;
description
"Time duration specifying an upper bound for how long a
client should wait before refreshing information retrieved
from a DHCP server.";
}
}
}
grouping sol-max-rt-option-group {
description
"OPTION_SOL_MAX_RT (82) SOL_MAX_RT Option (Max Solicit timeout
value).";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 21.24";
container sol-max-rt-option {
description
"OPTION_SOL_MAX_RT (82) SOL_MAX_RT Option.";
leaf sol-max-rt-value {
type dhc6:timer-seconds32;
description
"Maximum Solicit timeout value.";
}
}
}
grouping inf-max-rt-option-group {
description
"OPTION_INF_MAX_RT (83) INF_MAX_RT Option (Max
Information-request timeout value).";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 21.25";
container inf-max-rt-option {
description
"OPTION_INF_MAX_RT (83) INF_MAX_RT Option.";
leaf inf-max-rt-value {
type dhc6:timer-seconds32;
description
"Maximum Information-request timeout value.";
}
}
}
/*
* Data Nodes
*/
that's the groupings done π¦ the data nodes are coming up next, so stay tuned bestie π
okay the server container is literally the main character of this whole module π β¨
container dhcpv6-server {
description
"Configuration nodes for the DHCPv6 server.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 18.3";
leaf enabled {
type boolean;
description
"Enables the DHCP server function.";
}
leaf server-duid {
type dhc6:duid;
description
"DUID of the server.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 11";
}
container vendor-config {
description
"This container provides a location for augmenting vendor
or implementation-specific configuration nodes.";
}
container option-sets {
description
"A server may allow different option sets to be configured
for clients matching specific parameters, such as
topological location or client type. The 'option-set' list
is a set of options and their contents that will be
returned to clients.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 21";
list option-set {
key "option-set-id";
description
"YANG definitions for DHCPv6 options are contained in
separate YANG modules and augmented to this container as
required.";
leaf option-set-id {
type string;
description
"Option set identifier.";
}
leaf description {
type string;
description
"An optional field for storing additional information
relevant to the option set.";
}
uses preference-option-group;
uses dhc6:auth-option-group;
uses server-unicast-option-group;
uses dhc6:rapid-commit-option-group;
uses dhc6:vendor-specific-information-option-group;
uses reconfigure-message-option-group;
uses dhc6:reconfigure-accept-option-group;
uses info-refresh-time-option-group;
uses sol-max-rt-option-group;
uses inf-max-rt-option-group;
}
}
container class-selector {
description
"DHCPv6 servers use a 'class-selector' function in order
to identify and classify incoming client messages
so that they can be given the correct configuration.
The mechanisms used for implementing this function vary
greatly between different implementations; as such, it is
not possible to include them in this module. This container
provides a location for server implementors to augment their
own class-selector YANG.";
}
container allocation-ranges {
description
"This model is based on an address and parameter
allocation hierarchy. The top level is 'global' -- which
is defined as the container for all allocation-ranges.
Under this are the individual allocation-ranges.";
uses resource-config;
list allocation-range {
key "id";
description
"Network ranges are identified by the 'id' key.";
leaf id {
type string;
mandatory true;
description
"Unique identifier for the allocation range.";
}
leaf description {
type string;
description
"Description for the allocation range.";
}
leaf network-prefix {
type inet:ipv6-prefix;
mandatory true;
description
"Network prefix.";
}
uses resource-config;
container address-pools {
if-feature "na-assignment";
description
"Configuration for the DHCPv6 server's
address pools.";
list address-pool {
key "pool-id";
description
"List of address pools for allocation to clients,
distinguished by 'pool-id'.";
leaf pool-id {
type string;
mandatory true;
description
"Unique identifier for the pool.";
}
leaf pool-prefix {
type inet:ipv6-prefix;
mandatory true;
description
"IPv6 prefix for the pool. Should be contained
within the network-prefix if configured.";
}
leaf start-address {
type inet:ipv6-address-no-zone;
mandatory true;
description
"Starting IPv6 address for the pool.";
}
leaf end-address {
type inet:ipv6-address-no-zone;
mandatory true;
description
"Ending IPv6 address for the pool.";
}
leaf max-address-utilization {
type dhc6:threshold;
description
"Maximum amount of the addresses in the
pool that can be simultaneously allocated,
calculated as a percentage of the available
addresses (end-address minus start-address plus
one), and rounded up. Used to set the value for
the address-pool-utilization-threshold-exceeded
notification.";
}
uses resource-config;
container host-reservations {
description
"Configuration for host reservations from the
address pool.";
list host-reservation {
key "reserved-addr";
description
"List of host reservations.";
leaf client-duid {
type dhc6:duid;
description
"Client DUID for the reservation.";
}
leaf reserved-addr {
type inet:ipv6-address;
description
"Reserved IPv6 address.";
}
uses resource-config;
}
}
container active-leases {
config false;
description
"Holds state related to active client
leases.";
leaf total-count {
type uint64;
mandatory true;
description
"The total number of addresses in the pool.";
}
leaf allocated-count {
type uint64;
mandatory true;
description
"The number of addresses or prefixes in the pool
that are currently allocated.";
}
list active-lease {
key "leased-address";
description
"List of active address leases.";
leaf leased-address {
type inet:ipv6-address;
description
"Active address lease entry.";
}
uses lease-information;
}
}
}
}
container prefix-pools {
if-feature "prefix-delegation";
description
"Configuration for the DHCPv6 server's prefix pools.";
list prefix-pool {
key "pool-id";
description
"List of prefix pools for allocation to clients,
distinguished by 'pool-id'.";
leaf pool-id {
type string;
mandatory true;
description
"Unique identifier for the pool.";
}
leaf pool-prefix {
type inet:ipv6-prefix;
mandatory true;
description
"IPv6 prefix for the pool. Should be contained
within the network-prefix if configured.";
}
leaf client-prefix-length {
type uint8 {
range "1 .. 128";
}
mandatory true;
description
"Length of the prefixes that will be delegated
to clients.";
}
leaf max-pd-space-utilization {
type dhc6:threshold;
description
"Maximum amount of the prefixes in the pool that
can be simultaneously allocated, calculated as a
percentage of the available prefixes, and rounded
up. Used to set the value for the
prefix-pool-utilization-threshold-exceeded
notification.";
}
uses resource-config;
container host-reservations {
description
"Configuration for host reservations from the
prefix pool.";
list prefix-reservation {
key "reserved-prefix";
description
"Reserved prefix reservation.";
leaf client-duid {
type dhc6:duid;
description
"Client DUID for the reservation.";
}
leaf reserved-prefix {
type inet:ipv6-prefix;
description
"Reserved IPv6 prefix.";
}
leaf reserved-prefix-len {
type uint8;
description
"Reserved IPv6 prefix length.";
}
}
uses resource-config;
}
container active-leases {
config false;
description
"Holds state related to active client prefix
leases.";
leaf total-count {
type uint64;
mandatory true;
description
"The total number of prefixes in the pool.";
}
leaf allocated-count {
type uint64;
mandatory true;
description
"The number of prefixes in the pool that are
currently allocated.";
}
list active-lease {
key "leased-prefix";
description
"List of active prefix leases.";
leaf leased-prefix {
type inet:ipv6-prefix;
description
"Active leased prefix entry.";
}
uses lease-information;
}
}
}
}
}
container statistics {
description
"DHCPv6 message counters for the server.";
uses message-statistics;
}
}
}
/*
* RPCs
*/
rpc delete-address-lease {
nacm:default-deny-all;
if-feature "na-assignment";
description
"Deletes a client's active address lease from the server's
lease database. Note that this will not cause the address
to be revoked from the client, and the lease may be refreshed
or renewed by the client.";
input {
leaf lease-address-to-delete {
type leafref {
path "/dhcpv6-server/allocation-ranges/"
+ "allocation-range/address-pools/address-pool"
+ "/active-leases/active-lease/leased-address";
}
mandatory true;
description
"IPv6 address of an active lease that will be
deleted from the server.";
}
}
output {
leaf return-message {
type string;
description
"Response message from the server. If available, a
language identifier should be included in the message.";
reference
"BCP 18 (RFC 2277) IETF Policy on Character Sets
and Languages, Section 4.2";
}
}
}
rpc delete-prefix-lease {
nacm:default-deny-all;
if-feature "prefix-delegation";
description
"Deletes a client's active prefix lease from the server's
lease database. Note that this will not cause the prefix
to be revoked from the client, and the lease may be refreshed
or renewed by the client.";
input {
leaf lease-prefix-to-delete {
type leafref {
path "/dhcpv6-server/allocation-ranges/"
+ "allocation-range/prefix-pools/prefix-pool"
+ "/active-leases/active-lease/leased-prefix";
}
mandatory true;
description
"IPv6 prefix of an active lease that will be deleted
from the server.";
}
}
output {
leaf return-message {
type string;
description
"Response message from the server. If available, a
language identifier should be included in the message.";
reference
"BCP 18 (RFC 2277) IETF Policy on Character Sets
and Languages, Section 4.2";
}
}
}
/*
* Notifications
*/
notification address-pool-utilization-threshold-exceeded {
if-feature "na-assignment";
description
"Notification sent when the address pool
utilization exceeds the threshold configured in
max-address-utilization.";
leaf pool-id {
type leafref {
path "/dhcpv6-server/allocation-ranges/"
+ "allocation-range/address-pools/address-pool"
+ "/pool-id";
}
mandatory true;
description
"Leafref to the address pool that the notification is being
generated for.";
}
leaf total-pool-addresses {
type uint64;
mandatory true;
description
"Total number of addresses in the pool (end-address minus
start-address plus one).";
}
leaf max-allocated-addresses {
type uint64;
mandatory true;
description
"Maximum number of addresses that can be simultaneously
allocated from the pool. This value may be less than the
count of total addresses. Calculated as the
max-address-utilization (percentage) of the
total-pool-addresses and rounded up.";
}
leaf allocated-address-count {
type uint64;
mandatory true;
description
"Number of addresses allocated from the pool.";
}
}
notification prefix-pool-utilization-threshold-exceeded {
if-feature "prefix-delegation";
description
"Notification sent when the prefix pool utilization
exceeds the threshold configured in
max-pd-space-utilization.";
leaf pool-id {
type leafref {
path "/dhcpv6-server/allocation-ranges"
+ "/allocation-range/prefix-pools/prefix-pool/pool-id";
}
mandatory true;
description
"Unique identifier for the pool.";
}
leaf total-pool-prefixes {
type uint64;
mandatory true;
description
"Total number of prefixes in the pool.";
}
leaf max-allocated-prefixes {
type uint64;
mandatory true;
description
"Maximum number of prefixes that can be simultaneously
allocated from the pool. This value may be less than
the count of total prefixes. Calculated as the
max-prefix-utilization (percentage) of the
total-pool-prefixes and rounded up.";
}
leaf allocated-prefixes-count {
type uint64;
mandatory true;
description
"Number of prefixes allocated from the pool.";
}
}
notification invalid-client-detected {
description
"Notification sent when the server detects an invalid
client.";
leaf message-type {
type enumeration {
enum solicit {
description
"Solicit (1) message.";
}
enum request {
description
"Request (3) message.";
}
enum confirm {
description
"Confirm (4) message.";
}
enum renew {
description
"Renew (5) message.";
}
enum rebind {
description
"Rebind (6) message.";
}
enum release {
description
"Release (8) message.";
}
enum decline {
description
"Decline (9) message.";
}
enum info-request {
description
"Information request (11) message.";
}
}
description
"The message type received by the server that has caused
the error.";
}
leaf duid {
type dhc6:duid;
description
"Client DUID.";
}
leaf description {
type string;
description
"Description of the event (e.g., an error code or log
message).";
}
}
notification decline-received {
if-feature "na-assignment";
description
"Notification sent when the server has received a Decline (9)
message from a client.";
leaf duid {
type dhc6:duid;
description
"Client DUID.";
}
list declined-resources {
description
"List of declined addresses and/or prefixes.";
choice resource-type {
description
"Type of resource that has been declined.";
case declined-address {
leaf address {
type inet:ipv6-address;
description
"Address that has been declined.";
}
}
case declined-prefix {
leaf prefix {
type inet:ipv6-prefix;
description
"Prefix that has been declined.";
}
}
}
}
}
notification non-success-code-sent {
description
"Notification sent when the server responded to a client with
a non-success status code.";
leaf duid {
type dhc6:duid;
description
"Client DUID.";
}
uses dhc6:status;
}
}
<CODE ENDS>
4.3. DHCPv6 Relay YANG Module β¨
Okay, bestie, now we're on to the relay side π§ This module imports typedefs from [RFC6991] and modules defined in [RFC8341] and [RFC8343], so it's basically borrowing the best bits from its friends. π
<CODE BEGINS> file "ietf-dhcpv6-relay@2022-06-20.yang"
module ietf-dhcpv6-relay {
yang-version 1.1;
namespace "urn:ietf:params:xml:ns:yang:ietf-dhcpv6-relay";
prefix dhc6-rly;
import ietf-inet-types {
prefix inet;
reference
"RFC 6991: Common YANG Data Types";
}
import ietf-yang-types {
prefix yang;
reference
"RFC 6991: Common YANG Data Types";
}
import ietf-dhcpv6-common {
prefix dhc6;
reference
"RFC 9243: A YANG Data Model for DHCPv6 Configuration";
}
import ietf-interfaces {
prefix if;
reference
"RFC 8343: A YANG Data Model for Interface Management";
}
import ietf-netconf-acm {
prefix nacm;
reference
"RFC 8341: Network Configuration Access Control Model";
}
organization
"IETF Dynamic Host Configuration (DHC) Working Group";
contact
"WG Web: <https://datatracker.ietf.org/wg/dhc/>
WG List: <mailto:dhcwg@ietf.org>
Author: Yong Cui <yong@csnet1.cs.tsinghua.edu.cn>
Author: Linhui Sun <lh.sunlinh@gmail.com>
Editor: Ian Farrer <ian.farrer@telekom.de>
Author: Sladjana Zeichlin <sladjana.zechlin@telekom.de>
Author: Zihao He <hezihao9512@gmail.com>
Author: Michal Nowikowski <godfryd@isc.org>";
description
"This YANG module defines components necessary for the
configuration and management of DHCPv6 relays.
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 (RFC 2119) (RFC 8174) when, and only when,
they appear in all capitals, as shown here.
Copyright (c) 2022 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 9243
(https://www.rfc-editor.org/info/rfc9243); see the RFC itself
for full legal notices.";
revision 2022-06-20 {
description
"Initial revision.";
reference
"RFC 9243: A YANG Data Model for DHCPv6 Configuration";
}
/*
* Features
*/
feature prefix-delegation {
description
"Enable if the relay functions as a delegating router for
DHCPv6 prefix delegation.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 6.3";
}
/*
* Groupings
*/
okay bestie, the relay's memory is about to get very real π Here's how it keeps track of who's leasing what, how many messages it's handled, and the RPCs that let you clean up the mess π§
grouping pd-lease-state {
description
"State data for the relay.";
list pd-leases {
key "ia-pd-prefix";
config false;
description
"Information about an active IA_PD prefix delegation.";
leaf ia-pd-prefix {
type inet:ipv6-prefix;
description
"Prefix that is delegated.";
}
leaf last-renew {
type yang:date-and-time;
description
"Time of the last successful refresh or renew of the
delegated prefix.";
}
leaf client-peer-address {
type inet:ipv6-address;
description
"Peer-address of the leasing client.";
}
leaf client-duid {
type dhc6:duid;
description
"DUID of the leasing client.";
}
leaf server-duid {
type dhc6:duid;
description
"DUID of the delegating server.";
}
}
}
grouping message-statistics {
description
"Contains counters for the different DHCPv6 message types.";
leaf discontinuity-time {
type yang:date-and-time;
description
"The time on the most recent occasion at which any one or
more of DHCPv6 relay's counters suffered a discontinuity.
If no such discontinuities have occurred since the last
re-initialization of the local management subsystem, then
this node contains the time the local management subsystem
re-initialized itself.";
}
leaf solicit-received-count {
type yang:counter32;
config false;
description
"Number of Solicit (1) messages received.";
}
leaf advertise-sent-count {
type yang:counter32;
config false;
description
"Number of Advertise (2) messages sent.";
}
leaf request-received-count {
type yang:counter32;
config false;
description
"Number of Request (3) messages received.";
}
leaf confirm-received-count {
type yang:counter32;
config false;
description
"Number of Confirm (4) messages received.";
}
leaf renew-received-count {
type yang:counter32;
config false;
description
"Number of Renew (5) messages received.";
}
leaf rebind-received-count {
type yang:counter32;
config false;
description
"Number of Rebind (6) messages received.";
}
leaf reply-sent-count {
type yang:counter32;
config false;
description
"Number of Reply (7) messages sent.";
}
leaf release-received-count {
type yang:counter32;
config false;
description
"Number of Release (8) messages received.";
}
leaf decline-received-count {
type yang:counter32;
config false;
description
"Number of Decline (9) messages received.";
}
leaf reconfigure-sent-count {
type yang:counter32;
config false;
description
"Number of Reconfigure (10) messages sent.";
}
leaf information-request-received-count {
type yang:counter32;
config false;
description
"Number of Information-request (11) messages
received.";
}
leaf unknown-message-received-count {
type yang:counter32;
config false;
description
"Number of messages of unknown type that have
been received.";
}
leaf unknown-message-sent-count {
type yang:counter32;
config false;
description
"Number of messages of unknown type that have
been sent.";
}
leaf discarded-message-count {
type yang:counter32;
config false;
description
"Number of messages that have been discarded
for any reason.";
}
}
grouping global-statistics {
description
"Global statistics for the device.";
leaf relay-forward-sent-count {
type yang:counter32;
config false;
description
"Number of Relay-forward (12) messages sent.";
}
leaf relay-forward-received-count {
type yang:counter32;
config false;
description
"Number of Relay-forward (12) messages received.";
}
leaf relay-reply-received-count {
type yang:counter32;
config false;
description
"Number of Relay-reply (13) messages received.";
}
leaf relay-forward-unknown-sent-count {
type yang:counter32;
config false;
description
"Number of Relay-forward (12) messages containing
a message of unknown type sent.";
}
leaf relay-forward-unknown-received-count {
type yang:counter32;
config false;
description
"Number of Relay-forward (12) messages containing
a message of unknown type received.";
}
leaf discarded-message-count {
type yang:counter32;
config false;
description
"Number of messages that have been discarded
for any reason.";
}
}
grouping interface-id-option-group {
description
"OPTION_INTERFACE_ID (18) Interface-Id Option.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 21.18";
container interface-id-option {
description
"OPTION_INTERFACE_ID (18) Interface-Id Option.";
leaf interface-id {
type binary;
description
"An opaque value of arbitrary length generated by the
relay agent to identify one of the relay agent's
interfaces.";
}
}
}
/*
* Data Nodes
*/
container dhcpv6-relay {
description
"This container contains the configuration data nodes
for the relay.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 19";
leaf enabled {
type boolean;
description
"Globally enables the DHCP relay function.";
}
list relay-if {
key "if-name";
description
"List of interfaces configured for DHCPv6 relaying.";
leaf if-name {
type if:interface-ref;
description
"interface-ref to the relay interface.";
}
leaf enabled {
type boolean;
description
"Enables the DHCP relay function for this interface.";
}
leaf-list destination-address {
type inet:ipv6-address;
description
"Each DHCPv6 relay agent may be configured with a list
of destination addresses for relayed messages.
The list may include unicast addresses, multicast
addresses, or other valid addresses.";
}
leaf link-address {
type inet:ipv6-address;
description
"An address that may be used by the server to identify
the link on which the client is located.";
}
container relay-options {
description
"Definitions for DHCPv6 options that can be sent
by the relay are augmented to this location from other
YANG modules as required.";
uses dhc6:auth-option-group;
uses interface-id-option-group;
}
container statistics {
description
"DHCPv6 message counters for the relay's interface.";
uses message-statistics;
}
container prefix-delegation {
if-feature "prefix-delegation";
presence "Enables prefix delegation for this interface.";
description
"Controls and holds state information for prefix
delegation.";
uses pd-lease-state;
}
}
container statistics {
description
"Global DHCPv6 message counters for the relay.";
uses global-statistics;
}
}
/*
* RPCs
*/
rpc clear-prefix-entry {
nacm:default-deny-all;
if-feature "prefix-delegation";
description
"Clears an entry for an active delegated prefix
from the relay.";
reference
"RFC 8987: DHCPv6 Prefix Delegating Relay Requirements,
Section 4.4";
input {
leaf lease-prefix {
type leafref {
path "/dhcpv6-relay/relay-if/prefix-delegation"
+ "/pd-leases/ia-pd-prefix";
}
mandatory true;
description
"IPv6 prefix of an active lease entry that will
be deleted from the relay.";
}
}
output {
leaf return-message {
type string;
description
"Response message from the server. If available, a
language identifier should be included in the message.";
reference
"BCP 18 (RFC 2277) IETF Policy on Character Sets
and Languages, Section 4.2";
}
}
}
rpc clear-client-prefixes {
nacm:default-deny-all;
if-feature "prefix-delegation";
description
"Clears all active prefix entries for a single client.";
reference
"RFC 8987: DHCPv6 Prefix Delegating Relay Requirements,
Section 4.4";
input {
leaf client-duid {
type dhc6:duid;
mandatory true;
description
"DUID of the client.";
}
}
output {
leaf return-message {
type string;
description
"Response message from the server. If available, a
language identifier should be included in the message.";
reference
"BCP 18 (RFC 2277) IETF Policy on Character Sets
and Languages, Section 4.2";
}
}
}
rpc clear-interface-prefixes {
nacm:default-deny-all;
if-feature "prefix-delegation";
description
"Clears all delegated prefix bindings from an
interface on the relay.";
reference
"RFC 8987: DHCPv6 Prefix Delegating Relay Requirements,
Section 4.4";
input {
leaf interface {
type leafref {
path "/dhcpv6-relay/relay-if/if-name";
}
mandatory true;
description
"Reference to the relay interface that will have all
active prefix delegation bindings deleted.";
}
}
output {
leaf return-message {
type string;
description
"Response message from the server. If available, a
language identifier should be included in the message.";
reference
"BCP 18 (RFC 2277) IETF Policy on Character Sets
and Languages, Section 4.2";
}
}
}
/*
* Notifications
*/
next up: the notifications bit ππ
notification relay-event {
description
"DHCPv6 relay event notifications.";
container topology-change {
description
"Raised if the entry for an interface with DHCPv6-related
configuration or state is removed from if:interface-refs.";
leaf relay-if-name {
type leafref {
path "/dhcpv6-relay/relay-if/if-name";
}
description
"Name of the interface that has been removed.";
}
leaf last-ipv6-addr {
type inet:ipv6-address;
description
"Last IPv6 address configured on the interface.";
}
}
}
}
<CODE ENDS>
That wraps up the relay module with its relay-event notification, which fires whenever an interface with DHCPv6 config or state gets yeeted from if:interface-refs πβ¨
4.4. DHCPv6 Client YANG Module π
okay so the client module is borrowing its typedefs from [RFC6991] and the interface stuff from [RFC8343], because we don't reinvent the wheel bestie π π§
<CODE BEGINS> file "ietf-dhcpv6-client@2022-06-20.yang"
module ietf-dhcpv6-client {
yang-version 1.1;
namespace "urn:ietf:params:xml:ns:yang:ietf-dhcpv6-client";
prefix dhc6-clnt;
import ietf-inet-types {
prefix inet;
reference
"RFC 6991: Common YANG Data Types";
}
import ietf-yang-types {
prefix yang;
reference
"RFC 6991: Common YANG Data Types";
}
import ietf-dhcpv6-common {
prefix dhc6;
reference
"RFC 9243: A YANG Data Model for DHCPv6 Configuration";
}
import ietf-interfaces {
prefix if;
reference
"RFC 8343: A YANG Data Model for Interface Management";
}
organization
"IETF Dynamic Host Configuration (DHC) Working Group";
contact
"WG Web: <https://datatracker.ietf.org/wg/dhc/>
WG List: <mailto:dhcwg@ietf.org>
Author: Yong Cui <yong@csnet1.cs.tsinghua.edu.cn>
Author: Linhui Sun <lh.sunlinh@gmail.com>
Editor: Ian Farrer <ian.farrer@telekom.de>
Author: Sladjana Zeichlin <sladjana.zechlin@telekom.de>
Author: Zihao He <hezihao9512@gmail.com>
Author: Michal Nowikowski <godfryd@isc.org>";
description
"This YANG module defines components necessary for the
configuration and management of DHCPv6 clients.
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 (RFC 2119)
(RFC 8174) when, and only when, they appear in all
capitals, as shown here.
Copyright (c) 2022 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 9243
(https://www.rfc-editor.org/info/rfc9243); see the RFC itself
for full legal notices.";
revision 2022-06-20 {
description
"Initial revision.";
reference
"RFC 9243: A YANG Data Model for DHCPv6 Configuration";
}
/*
* Features
*/
feature non-temp-addr {
description
"Denotes that the client supports DHCPv6 non-temporary address
allocations.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 6.2";
}
feature temp-addr {
description
"Denotes that the client supports DHCPv6 temporary address
allocations.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 6.5";
}
feature prefix-delegation {
description
"Denotes that the client implements DHCPv6 prefix
delegation.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 6.3";
}
feature anon-profile {
description
"Denotes that the client supports DHCP anonymity profiles.";
reference
"RFC 7844: Anonymity Profiles for DHCP Clients";
}
/*
* Groupings
*/
grouping message-statistics {
description
"Counters for DHCPv6 messages.";
leaf discontinuity-time {
type yang:date-and-time;
description
"The time on the most recent occasion at which any one or
more of DHCPv6 client's counters suffered a discontinuity.
If no such discontinuities have occurred since the last
re-initialization of the local management subsystem, then
this node contains the time the local management subsystem
re-initialized itself.";
}
leaf solicit-count {
type yang:counter32;
config false;
description
"Number of Solicit (1) messages sent.";
}
leaf advertise-count {
type yang:counter32;
config false;
description
"Number of Advertise (2) messages received.";
}
leaf request-count {
type yang:counter32;
config false;
description
"Number of Request (3) messages sent.";
}
leaf confirm-count {
type yang:counter32;
config false;
description
"Number of Confirm (4) messages sent.";
}
leaf renew-count {
type yang:counter32;
config false;
description
"Number of Renew (5) messages sent.";
}
leaf rebind-count {
type yang:counter32;
config false;
description
"Number of Rebind (6) messages sent.";
}
leaf reply-count {
type yang:counter32;
config false;
description
"Number of Reply (7) messages received.";
}
leaf release-count {
type yang:counter32;
config false;
description
"Number of Release (8) messages sent.";
}
leaf decline-count {
type yang:counter32;
config false;
description
"Number of Decline (9) messages sent.";
}
leaf reconfigure-count {
type yang:counter32;
config false;
description
"Number of Reconfigure (10) messages received.";
}
leaf information-request-count {
type yang:counter32;
config false;
description
"Number of Information-request (11) messages sent.";
}
leaf discarded-message-count {
type yang:counter32;
config false;
description
"Number of messages that have been discarded for any
reason.";
}
}
grouping lease-state {
description
"Information about the active IA_NA lease.";
leaf preferred-lifetime {
type dhc6:timer-seconds32;
description
"The preferred lifetime for the leased address
expressed in seconds.";
}
leaf valid-lifetime {
type dhc6:timer-seconds32;
description
"The valid lifetime for the leased address expressed
in seconds.";
}
leaf allocation-time {
type yang:date-and-time;
description
"Time and date that the address was first leased.";
}
leaf last-renew-rebind {
type yang:date-and-time;
description
"Time of the last successful renew or rebind of the
leased address.";
}
leaf server-duid {
type dhc6:duid;
description
"DUID of the leasing server.";
}
uses dhc6:status;
}
grouping option-request-option-group {
description
"OPTION_ORO (6) Option Request Option. A client MUST include
an Option Request option in a Solicit, Request, Renew,
Rebind, or Information-request message to inform the server
about options the client wants the server to send to the
client.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Sections 21.23, 21.24, 21.25, & 21.7";
container option-request-option {
description
"OPTION_ORO (6) Option Request Option.";
leaf-list oro-option {
type uint16;
description
"List of options that the client is requesting,
identified by option code. This list MUST include the
code for option SOL_MAX_RT (82) when included in a
Solicit message. If this option is being sent in an
Information-request message, then the code for option
OPTION_INFORMATION_REFRESH_TIME (32) and INF_MAX_RT (83)
MUST be included.";
}
}
}
grouping user-class-option-group {
description
"OPTION_USER_CLASS (15) User Class Option";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 21.15";
container user-class-option {
presence "Configures the option";
description
"OPTION_USER_CLASS (15) User Class Option.";
list user-class-data-instance {
key "user-class-data-id";
min-elements 1;
description
"The user classes of which the client is a member.";
leaf user-class-data-id {
type uint8;
description
"User class data ID.";
}
leaf user-class-data {
type binary;
description
"Opaque field representing a User Class of which the
client is a member.";
}
}
}
}
grouping vendor-class-option-group {
description
"OPTION_VENDOR_CLASS (16) Vendor Class Option.";
reference
"RFC 8415: Dynamic Host Configuration Protocol
for IPv6 (DHCPv6), Section 21.16";
container vendor-class-option {
description
"OPTION_VENDOR_CLASS (16) Vendor Class Option.";
list vendor-class-option-instances {
key "enterprise-number";
description
"The vendor class option allows for multiple instances
in a single message. Each list entry defines the contents
of an instance of the option.";
leaf enterprise-number {
type uint32;
description
"The vendor's registered Enterprise Number, as
maintained by IANA.";
}
list vendor-class-data-element {
key "vendor-class-data-id";
description
"The vendor classes of which the client is a member.";
leaf vendor-class-data-id {
type uint8;
description
"Vendor class data ID.";
}
leaf vendor-class-data {
type binary;
description
"Opaque field representing a vendor class of which
the client is a member.";
}
}
}
}
}
/*
* Data Nodes
*/
Okay bestie, this is where the client side really comes together π It's the dhcpv6-client container, with its interfaces, its IA_NA, IA_TA and IA_PD lists, and two notifications to wrap it up π¦
container dhcpv6-client {
description
"DHCPv6 client configuration and state.";
leaf enabled {
type boolean;
default "true";
description
"Globally enables the DHCP client function.";
}
leaf client-duid {
if-feature "(non-temp-addr or prefix-delegation "
+ "or temp-addr) and not anon-profile";
type dhc6:duid;
description
"A single client DUID that will be used by all of the
client's DHCPv6-enabled interfaces.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 11";
}
list client-if {
key "if-name";
description
"The list of interfaces for which the client will
be requesting DHCPv6 configuration.";
leaf if-name {
type if:interface-ref;
mandatory true;
description
"Reference to the interface entry that the requested
configuration is relevant to.";
}
leaf enabled {
type boolean;
default "true";
description
"Enables the DHCP client function for this interface.";
}
leaf interface-duid {
if-feature "(non-temp-addr or prefix-delegation "
+ "or temp-addr) and anon-profile";
type dhc6:duid;
description
"Per-interface client DUIDs for use with DHCP anonymity
profiles.";
reference
"RFC 7844: Anonymity Profiles for DHCP Clients,
Section 3";
}
container client-configured-options {
description
"Definitions for DHCPv6 options that can be sent by
the client. Additional option definitions can be
augmented to this location from other YANG modules as
required.";
uses option-request-option-group;
uses dhc6:rapid-commit-option-group;
uses user-class-option-group;
uses vendor-class-option-group;
uses dhc6:vendor-specific-information-option-group;
uses dhc6:reconfigure-accept-option-group;
}
list ia-na {
if-feature "non-temp-addr";
key "ia-id";
description
"Configuration relevant for an Identity Association
for Non-temporary Addresses (IA_NA).";
reference
"RFC 8415: Dynamic Host Configuration Protocol
for IPv6 (DHCPv6), Section 13.1";
leaf ia-id {
type uint32;
description
"A unique identifier for this IA_NA.";
reference
"RFC 8415: Dynamic Host Configuration Protocol
for IPv6 (DHCPv6), Section 12";
}
container ia-na-options {
description
"An augmentation point for additional options
that the client may send in the IA_NA-options field
of OPTION_IA_NA.";
}
container lease-state {
config false;
description
"Information about the active IA_NA lease.";
leaf ia-na-address {
type inet:ipv6-address;
description
"Address that is currently leased.";
}
leaf lease-t1 {
type dhc6:timer-seconds32;
description
"The time interval after which the client should
contact the server from which the addresses in the
IA_NA were obtained to extend the lifetimes of the
addresses assigned to the IA_NA.";
}
leaf lease-t2 {
type dhc6:timer-seconds32;
description
"The time interval after which the client should
contact any available server to extend the lifetimes
of the addresses assigned to the IA_NA.";
}
uses lease-state;
}
}
list ia-ta {
if-feature "temp-addr";
key "ia-id";
description
"Configuration relevant for an Identity Association
for Temporary Addresses (IA_TA).";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 13.2";
leaf ia-id {
type uint32;
description
"The unique identifier for this IA_TA.";
reference
"RFC 8415: Dynamic Host Configuration Protocol
for IPv6 (DHCPv6), Section 12";
}
container ia-ta-options {
description
"An augmentation point for additional options
that the client may send in the IA_TA-options field
of OPTION_IA_TA.";
}
container lease-state {
config false;
description
"Information about an active IA_TA lease.";
leaf ia-ta-address {
type inet:ipv6-address;
description
"Address that is currently leased.";
}
uses lease-state;
}
}
list ia-pd {
if-feature "prefix-delegation";
key "ia-id";
description
"Configuration relevant for an Identity Association
for Prefix Delegation (IA_PD).";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 13.3";
leaf ia-id {
type uint32;
description
"The unique identifier for this IA_PD.";
reference
"RFC 8415: Dynamic Host Configuration Protocol
for IPv6 (DHCPv6), Section 12";
}
leaf prefix-length-hint {
type uint8 {
range "1..128";
}
description
"Prefix-length hint value included in the messages sent
to the server to indicate a preference for the size of
the prefix to be delegated.";
reference
"RFC 8415: Dynamic Host Configuration Protocol
for IPv6 (DHCPv6), Section 18.2.1";
}
container ia-pd-options {
description
"An augmentation point for additional options that the
client will send in the IA_PD-options field of
OPTION_IA_TA.";
}
container lease-state {
config false;
description
"Information about an active IA_PD-delegated prefix.";
leaf ia-pd-prefix {
type inet:ipv6-prefix;
description
"Delegated prefix that is currently leased.";
}
leaf lease-t1 {
type dhc6:timer-seconds32;
description
"The time interval after which the client should
contact the server from which the addresses in the
IA_NA were obtained to extend the lifetimes of the
addresses assigned to the IA_PD.";
}
leaf lease-t2 {
type dhc6:timer-seconds32;
description
"The time interval after which the client should
contact any available server to extend the lifetimes
of the addresses assigned to the IA_PD.";
}
uses lease-state;
}
}
container statistics {
description
"DHCPv6 message counters for the client.";
uses message-statistics;
}
}
}
/*
* Notifications
*/
notification invalid-ia-address-detected {
if-feature "non-temp-addr or temp-addr";
description
"Notification sent when an address received in an identity
association option is determined invalid. Possible conditions
include a duplicate or otherwise illegal address.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 18.2.10.1";
leaf ia-id {
type uint32;
mandatory true;
description
"IAID.";
}
leaf ia-na-t1-timer {
type uint32;
description
"The value of the T1 time field for non-temporary address
allocations (OPTION_IA_NA).";
}
leaf ia-na-t2-timer {
type uint32;
description
"The value of the preferred-lifetime field for non-temporary
address allocations (OPTION_IA_NA).";
}
leaf invalid-address {
type inet:ipv6-address;
description
"The IP address that has been detected to be invalid.";
}
leaf preferred-lifetime {
type uint32;
description
"The value of the preferred-lifetime field in
OPTION_IAADDR.";
}
leaf valid-lifetime {
type uint32;
description
"The value of the valid-lifetime field in OPTION_IAADDR.";
}
leaf ia-options {
type binary;
description
"A copy of the contents of the IAaddr-options field.";
}
leaf description {
type string;
description
"Description of the invalid Identity Association (IA)
detection error.";
}
}
notification transmission-failed {
description
"Notification sent when the transmission or retransmission
of a message fails.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 7.6";
leaf failure-type {
type enumeration {
enum solicit-timeout {
description
"Max Solicit timeout value (SOL_MAX_RT) exceeded.";
}
enum request-timeout {
description
"Max Request timeout value (REQ_MAX_RT) exceeded.";
}
enum request-retries-exceeded {
description
"Max Request retry attempts (REC_MAX_RC) exceeded.";
}
enum confirm-duration-exceeded {
description
"Max Confirm duration (CNF_MAX_RD) exceeded.";
}
enum renew-timeout {
description
"Max Renew timeout value (REN_MAX_RT) exceeded.";
}
enum rebind-timeout {
description
"Max Rebind timeout value (REB_MAX_RT)
exceeded.";
}
enum info-request-timeout {
description
"Max Information-request timeout value (INF_MAX_RT)
exceeded.";
}
enum release-retries-exceeded {
description
"Max Release retry attempts (REL_MAX_RC) exceeded.";
}
enum decline-retries-exceeded {
description
"Max Decline retry attempts (DEC_MAX_RT) exceeded.";
}
}
mandatory true;
description
"Description of the failure.";
}
leaf description {
type string;
description
"Information related to the failure, such as number of
retries and timer values.";
}
}
Ngl the notifications at the bottom are my favourite bit π invalid-ia-address-detected and transmission-failed are basically the client saying "something's not vibing, here's exactly what went wrong" π β¨
notification unsuccessful-status-code {
description
"Notification sent when the client receives a message that
includes an unsuccessful Status Code option.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 21.13";
leaf server-duid {
type dhc6:duid;
mandatory true;
description
"DUID of the server sending the unsuccessful error code.";
}
uses dhc6:status;
}
notification server-duid-changed {
if-feature "non-temp-addr or prefix-delegation or "
+ "temp-addr";
description
"Notification sent when the client receives a lease from a
server with different DUID to the one currently stored by the
client, e.g., in response to a Rebind message.";
reference
"RFC 8415: Dynamic Host Configuration Protocol for
IPv6 (DHCPv6), Section 18.2.5";
leaf new-server-duid {
type dhc6:duid;
mandatory true;
description
"DUID of the new server.";
}
leaf previous-server-duid {
type dhc6:duid;
mandatory true;
description
"DUID of the previous server.";
}
leaf lease-ia-na {
if-feature "non-temp-addr";
type leafref {
path "/dhcpv6-client/client-if/ia-na/ia-id";
}
description
"Reference to the IA_NA lease.";
}
leaf lease-ia-ta {
if-feature "temp-addr";
type leafref {
path "/dhcpv6-client/client-if/ia-ta/ia-id";
}
description
"Reference to the IA_TA lease.";
}
leaf lease-ia-pd {
if-feature "prefix-delegation";
type leafref {
path "/dhcpv6-client/client-if/ia-pd/ia-id";
}
description
"Reference to the IA_PD lease.";
}
}
}
<CODE ENDS>
5. Security Considerations π
Okay bestie, this part is SERIOUS, so read it carefully π«Ά The YANG modules in this document are schemas for data that's meant to be accessed through network management protocols like NETCONF [RFC6241] or RESTCONF [RFC8040]. The bottom layer for NETCONF is the secure transport layer, and the secure transport it MUST be able to do is Secure Shell (SSH) [RFC6242]. The bottom layer for RESTCONF is HTTPS, and its required secure transport is TLS [RFC8446]. Main character energy: security is the whole vibe π
The Network Configuration Access Control Model (NACM) [RFC8341] is how you restrict particular NETCONF or RESTCONF users to a preset subset of the protocol operations and content. Think of it as the bouncer at the door πͺβ¨
Now the spicy part πΆοΈ A bunch of data nodes in these modules are writable, creatable, and deletable (that's config true, which is the default). Those nodes can be sensitive or vulnerable in some networks, and writing to them without proper protection can mess up network operations. Here are the subtrees and data nodes in the ieft-dhcpv6-server.yang module and why they're sensitive:
- Denial-of-Service (DoS) attacks π, like shutting down the DHCP server or deleting the address/prefix pool config:
(dhc6-srv/vendor-config)
(dhc6-srv/allocation-ranges)
- Sneaky attacks that reconfigure DHCPv6 options π These can cause a bunch of security and privacy problems. For example, an attacker could point a DNS server option at a rogue server and redirect clients to services they control. Yikes!
(dhc6-srv/option-sets)
Here are the subtrees and data nodes in the ieft-dhcpv6-relay.yang module and their sensitivity:
- DoS attacks that disable the DHCP relay function, or change the relay's "destination-address" to an address that doesn't exist π
(dhc6-rly/relay-if)
- Changing the relay's "destination-address" so messages get sent to a rogue DHCPv6 server π±
(dhc6-rly/relay-if)
Some RPC operations in these modules may be sensitive too, so controlling access to them is super important π These RPCs use nacm:default-deny-all. Here are the operations in the ieft-dhcpv6-relay.yang module and why they matter:
- Deleting or clearing active address and prefix leases can cause a DoS attack, because traffic will no longer be routed to the client π
(dhc6-rly/clear-prefix-entry)
(dhc6-rly/clear-client-prefixes)
(dhc6-rly/clear-interface-prefixes)
An attacker who sends DHCPv6 messages that make the server generate invalid-client-detected and decline-received notifications could cause a DoS attack π A NETCONF client can mitigate this by unsubscribing from the affected notifications.
Some readable data nodes in this module may be sensitive or vulnerable too, so controlling read access (via get, get-config, or notification) matters a lot πΈ Here are the subtrees and data nodes and why they're sensitive. The following can be misused to track activity or fingerprint the device type of a host π΅οΈββοΈ:
- Information the server holds about clients with active leases:
(dhc6-srv/allocation-ranges/allocation-range/address-pools/
address-pool/active-leases)
- Information the relay holds about clients with active leases:
(dhc6-rly/relay-if/prefix-delegation/)
Info about a server's configured address and prefix pools could be used by an attacker for network reconnaissance [RFC7707] π The following could be used for that:
- Information about client address allocation ranges:
(dhc6-srv/allocation-ranges/allocation-range/address-pools/
address-pool/pool-prefix)
- Information about client prefix allocation ranges:
(dhc6-srv/allocation-ranges/allocation-range/prefix-pools/
prefix-pool/pool-prefix)
[RFC7844] describes anonymity profiles for DHCP clients π¦ They can stop client tracking on a visited network. You turn this on by implementing the anon-profile feature in the client module.
[RFC7824] covers privacy considerations for DHCPv6, and it applies here too π§
Security considerations related to DHCPv6 are discussed in [RFC8415] π
Security considerations given in [RFC7950] also apply here π«Ά
6. IANA Considerations π
This document registers four URIs and four YANG modules, ngl that's a lot of registrations π
6.1. URI Registration π
Per this document, IANA has registered the following four URIs in the "ns" subregistry within the "IETF XML Registry" [RFC3688]:
URI: urn:ietf:params:xml:ns:yang:ietf-dhcpv6-server
Registrant Contact: The IESG.
XML: N/A; the requested URI is an XML namespace.
URI: urn:ietf:params:xml:ns:yang:ietf-dhcpv6-relay
Registrant Contact: The IESG.
XML: N/A; the requested URI is an XML namespace.
URI: urn:ietf:params:xml:ns:yang:ietf-dhcpv6-client
Registrant Contact: The IESG.
XML: N/A; the requested URI is an XML namespace.
URI: urn:ietf:params:xml:ns:yang:ietf-dhcpv6-common
Registrant Contact: The IESG.
XML: N/A; the requested URI is an XML namespace.
6.2. YANG Module Name Registration π
Per this document, IANA has registered the following four YANG modules in the "YANG Module Names" subregistry [RFC6020] within the "YANG Parameters" registry.
name: ietf-dhcpv6-server
namespace: urn:ietf:params:xml:ns:yang:ietf-dhcpv6-server
maintained by IANA: N
prefix: dhc6-srv
reference: RFC 9243
name: ietf-dhcpv6-relay
namespace: urn:ietf:params:xml:ns:yang:ietf-dhcpv6-relay
maintained by IANA: N
prefix: dhc6-rly
reference: RFC 9243
name: ietf-dhcpv6-client
namespace: urn:ietf:params:xml:ns:yang:ietf-dhcpv6-client
maintained by IANA: N
prefix: dhc6-clnt
reference: RFC 9243
name: ietf-dhcpv6-common
namespace: urn:ietf:params:xml:ns:yang:ietf-dhcpv6-common
maintained by IANA: N
prefix: dhc6
reference: RFC 9243
7. References π
7.1. Normative References β¨
Okay bestie, this is the reference shelf π The normative ones are the stuff you genuinely need to have read before you can build anything, so no skipping π«Ά
[BCP18] Alvestrand, H., "IETF Policy on Character Sets and Languages", BCP 18, RFC 2277, January 1998. πΈ
https://www.rfc-editor.org/info/bcp18
[IANA-DHCPV6-AUTH-NAMESPACES] IANA, "Dynamic Host Configuration Protocol (DHCP) Authentication Option Name Spaces", https://www.iana.org/assignments/auth-namespaces. π
[IANA-DHCPV6-OPTION-CODES] IANA, "Option Codes", https://www.iana.org/assignments/dhcpv6-parameters. π
[IANA-DHCPV6-STATUS-CODES] IANA, "DHCPv6 Status Codes", https://www.iana.org/assignments/dhcpv6-parameters. π¦
[IANA-HARDWARE-TYPES] IANA, "Hardware Types", https://www.iana.org/assignments/arp-parameters. π§
[IANA-PEN] IANA, "Private Enterprise Numbers", https://www.iana.org/assignments/enterprise-numbers. π
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, https://www.rfc-editor.org/info/rfc2119. π₯
[RFC3118] Droms, R., Ed. and W. Arbaugh, Ed., "Authentication for DHCP Messages", RFC 3118, DOI 10.17487/RFC3118, June 2001, https://www.rfc-editor.org/info/rfc3118. π
[RFC3688] Mealling, M., "The IETF XML Registry", BCP 81, RFC 3688, DOI 10.17487/RFC3688, January 2004, https://www.rfc-editor.org/info/rfc3688. π
[RFC6020] Bjorklund, M., Ed., "YANG - A Data Modeling Language for the Network Configuration Protocol (NETCONF)", RFC 6020, DOI 10.17487/RFC6020, October 2010, https://www.rfc-editor.org/info/rfc6020. β
[RFC6241] Enns, R., Ed., Bjorklund, M., Ed., Schoenwaelder, J., Ed., and A. Bierman, Ed., "Network Configuration Protocol (NETCONF)", RFC 6241, DOI 10.17487/RFC6241, June 2011, https://www.rfc-editor.org/info/rfc6241. π
[RFC6242] Wasserman, M., "Using the NETCONF Protocol over Secure Shell (SSH)", RFC 6242, DOI 10.17487/RFC6242, June 2011, https://www.rfc-editor.org/info/rfc6242. π
[RFC6355] Narten, T. and J. Johnson, "Definition of the UUID-Based DHCPv6 Unique Identifier (DUID-UUID)", RFC 6355, DOI 10.17487/RFC6355, August 2011, https://www.rfc-editor.org/info/rfc6355. π«§
[RFC6991] Schoenwaelder, J., Ed., "Common YANG Data Types", RFC 6991, DOI 10.17487/RFC6991, July 2013, https://www.rfc-editor.org/info/rfc6991. π
[RFC7844] Huitema, C., Mrugalski, T., and S. Krishnan, "Anonymity Profiles for DHCP Clients", RFC 7844, DOI 10.17487/RFC7844, May 2016, https://www.rfc-editor.org/info/rfc7844. π
[RFC7950] Bjorklund, M., Ed., "The YANG 1.1 Data Modeling Language", RFC 7950, DOI 10.17487/RFC7950, August 2016, https://www.rfc-editor.org/info/rfc7950. β¨
[RFC8040] Bierman, A., Bjorklund, M., and K. Watsen, "RESTCONF Protocol", RFC 8040, DOI 10.17487/RFC8040, January 2017, https://www.rfc-editor.org/info/rfc8040. π¦
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, https://www.rfc-editor.org/info/rfc8174. πΈ
[RFC8340] Bjorklund, M. and L. Berger, Ed., "YANG Tree Diagrams", BCP 215, RFC 8340, DOI 10.17487/RFC8340, March 2018, https://www.rfc-editor.org/info/rfc8340. π³
[RFC8341] Bierman, A. and M. Bjorklund, "Network Configuration Access Control Model", STD 91, RFC 8341, DOI 10.17487/RFC8341, March 2018, https://www.rfc-editor.org/info/rfc8341. π‘οΈ
[RFC8342] Bjorklund, M., Schoenwaelder, J., Shafer, P., Watsen, K., and R. Wilton, "Network Management Datastore Architecture (NMDA)", RFC 8342, DOI 10.17487/RFC8342, March 2018, https://www.rfc-editor.org/info/rfc8342. ποΈ
[RFC8343] Bjorklund, M., "A YANG Data Model for Interface Management", RFC 8343, DOI 10.17487/RFC8343, March 2018, https://www.rfc-editor.org/info/rfc8343. π
[RFC8415] Mrugalski, T., Siodelski, M., Volz, B., Yourtchenko, A., Richardson, M., Jiang, S., Lemon, T., and T. Winters, "Dynamic Host Configuration Protocol for IPv6 (DHCPv6)", RFC 8415, DOI 10.17487/RFC8415, November 2018, https://www.rfc-editor.org/info/rfc8415. π
[RFC8446] Rescorla, E., "The Transport Layer Security (TLS) Protocol Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, https://www.rfc-editor.org/info/rfc8446. π
[RFC8987] Farrer, I., Kottapalli, N., Hunek, M., and R. Patterson, "DHCPv6 Prefix Delegating Relay Requirements", RFC 8987, DOI 10.17487/RFC8987, February 2021, https://www.rfc-editor.org/info/rfc8987. π
7.2. Informative References π·
These ones are the extra-credit reading. Super useful, just not strictly required to get the spec working, so no stress π
[GROUPINGS-TLS] Watsen, K., "YANG Groupings for TLS Clients and TLS Servers", Work in Progress, Internet-Draft, draft-ietf-netconf-tls-client-server-28, 24 May 2022, https://datatracker.ietf.org/doc/html/draft-ietf-netconf-tls-client-server-28. π§Ά
[RFC3319] Schulzrinne, H. and B. Volz, "Dynamic Host Configuration Protocol (DHCPv6) Options for Session Initiation Protocol (SIP) Servers", RFC 3319, DOI 10.17487/RFC3319, July 2003, https://www.rfc-editor.org/info/rfc3319. π
[RFC7707] Gont, F. and T. Chown, "Network Reconnaissance in IPv6 Networks", RFC 7707, DOI 10.17487/RFC7707, March 2016, https://www.rfc-editor.org/info/rfc7707. π
[RFC7824] Krishnan, S., Mrugalski, T., and S. Jiang, "Privacy Considerations for DHCPv6", RFC 7824, DOI 10.17487/RFC7824, May 2016, https://www.rfc-editor.org/info/rfc7824. πΆοΈ
Appendix A. Data Tree Examples β¨
Last stop, the examples π This section has XML examples of data trees for the different DHCPv6 elements, so you can see exactly what each piece looks like once it's all put together. Main character energy π
A.1. DHCPv6 Server Configuration Examples β¨
okay so this first example is the basic server setup, and it's giving full starter pack π π it shows the whole vibe of a working config. bestie, here's what it sets up:
- turning on the DHCP server function π
- the server's DUID π
- an option set (id=1) that holds config for the Solicit Max Retry Timeout (SOL_MAX_RT (82)) option β°
- one network range (2001:db8::/32) π
- one address pool with start and end addresses, lease timers, and an 'option-set-id' of "1" that points back to that option set we made earlier π
Figure 4: Basic Server Configuration Example XML π¦
<dhcpv6-server
xmlns="urn:ietf:params:xml:ns:yang:ietf-dhcpv6-server">
<enabled>true</enabled>
<server-duid>000200090CC084D303000912</server-duid>
<vendor-config/>
<option-sets>
<option-set>
<option-set-id>1</option-set-id>
<description>Example DHCP option set</description>
<sol-max-rt-option>
<sol-max-rt-value>3600</sol-max-rt-value>
</sol-max-rt-option>
</option-set>
</option-sets>
<class-selector/>
<allocation-ranges>
<valid-lifetime>54000</valid-lifetime>
<renew-time>7200</renew-time>
<rebind-time>32400</rebind-time>
<preferred-lifetime>43200</preferred-lifetime>
<allocation-range>
<id>1</id>
<description>example-allocation-range</description>
<network-prefix>2001:db8::/32</network-prefix>
<option-set-id>1</option-set-id>
<address-pools>
<address-pool>
<pool-id>1</pool-id>
<pool-prefix>2001:db8:1:1::/64</pool-prefix>
<start-address>2001:db8:1:1::1000</start-address>
<end-address>2001:db8:1:1::2000</end-address>
<max-address-utilization>50</max-address-utilization>
<option-set-id>1</option-set-id>
</address-pool>
</address-pools>
</allocation-range>
</allocation-ranges>
</dhcpv6-server>
next up is a static host reservation living inside an address pool π β¨ the vibe is that this host gets longer lease timers than the regular folks who grab addresses dynamically. main character energy π
<address-pools>
<address-pool>
<pool-id>1</pool-id>
<pool-prefix>2001:db8:1:1::/64</pool-prefix>
<start-address>2001:db8:1:1::1000</start-address>
<end-address>2001:db8:1:1::2000</end-address>
<max-address-utilization>50</max-address-utilization>
<option-set-id>1</option-set-id>
<host-reservations>
<host-reservation>
<reserved-addr>2001:db8:1:1::1001</reserved-addr>
<client-duid>00052001db81</client-duid>
<option-set-id>1</option-set-id>
<valid-lifetime>604800</valid-lifetime>
<renew-time>86400</renew-time>
<rebind-time>172800</rebind-time>
<preferred-lifetime>345600</preferred-lifetime>
</host-reservation>
</host-reservations>
</address-pool>
</address-pools>
Figure 5: Server Host Reservation Configuration Example XML Snippet π¦
now the prefix delegation one π this is for handing out prefixes to clients, and each client gets a /56 prefix. ngl this is so cute π₯Ή
the 'max-pd-space-utilization' is set to 80 percent, so a 'prefix-pool-utilization-threshold-exceeded' notification gets raised if the number of prefix allocations goes over that. bestie that's the warning bell ππ¨
<allocation-ranges>
<allocation-range>
<id>1</id>
<description>prefix-pool-example</description>
<network-prefix>2001:db8::/32</network-prefix>
<prefix-pools>
<valid-lifetime>54000</valid-lifetime>
<renew-time>7200</renew-time>
<rebind-time>32400</rebind-time>
<preferred-lifetime>43200</preferred-lifetime>
<prefix-pool>
<pool-id>0</pool-id>
<option-set-id>1</option-set-id>
<pool-prefix>2001:db8:1::/48</pool-prefix>
<client-prefix-length>56</client-prefix-length>
<max-pd-space-utilization>80</max-pd-space-utilization>
</prefix-pool>
</prefix-pools>
</allocation-range>
</allocation-ranges>
Figure 6: Server Prefix Delegation Configuration Example XML Snippet πΈ
last server one is the option set π§ this is a set of options that may be returned to clients, depending on what's inside a received DHCP request message. the option set ID is '1', and other spots in the config (like address pool config) reference it as the available options for clients that ask for them π«Ά
the example also shows how option definitions can be extended with augmentation β¨ here "OPTION_SIP_SERVER_D (21) SIP Servers Domain-Name List" from the example module in Appendix B got augmented into the server's option set. iconic glow-up π
<option-sets>
<option-set>
<option-set-id>1</option-set-id>
<description>Example DHCP option set</description>
<vendor-specific-information-options>
<vendor-specific-information-option>
<enterprise-number>32473</enterprise-number>
<vendor-option-data>
<sub-option-code>01</sub-option-code>
<sub-option-data>1234abcd</sub-option-data>
</vendor-option-data>
<vendor-option-data>
<sub-option-code>02</sub-option-code>
<sub-option-data>abcd1234</sub-option-data>
</vendor-option-data>
</vendor-specific-information-option>
</vendor-specific-information-options>
<sol-max-rt-option>
<sol-max-rt-value>3600</sol-max-rt-value>
</sol-max-rt-option>
<sip-server-domain-name-list-option
xmlns="https://example.com/ns/example-dhcpv6-opt-sip-serv">
<sip-server>
<sip-serv-id>0</sip-serv-id>
<sip-serv-domain-name>sip1.example.org</sip-serv-domain-name>
</sip-server>
<sip-server>
<sip-serv-id>1</sip-serv-id>
<sip-serv-domain-name>sip2.example.org</sip-serv-domain-name>
</sip-server>
</sip-server-domain-name-list-option>
</option-set>
</option-sets>
Figure 7: Server Option Set Configuration Example XML Snippet π
A.2. DHCPv6 Relay Configuration Example π¦
this one is a basic relay config for a single DHCP relay interface, and it shows how it works with the ietf-interfaces module π there are two XML docs here, one for ietf-interfaces and one for ietf-dhcpv6-relay. bestie, it's a whole duo π―ββοΈ
here's what it defines:
- configuring an interface with the ietf-interfaces module, which is the one the relay config gets applied to π―
- enabling the DHCP relay function globally and for that interface π«
- referencing that interface via an interface-ref to the ietf-interfaces module π
- defining two destination addresses that incoming DHCP messages will be relayed to π¬
- configuring the link-address value that gets sent in the relay-forward message π
- configuring a value for the Interface ID Option (OPTION_INTERFACE_ID (18)), which gets included in the relay forward message πͺͺ
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"
xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">
<interface>
<name>eth0</name>
<type>ianaift:ethernetCsmacd</type>
<description>DHCPv6 Relay Interface</description>
<enabled>true</enabled>
</interface>
</interfaces>
<dhcpv6-relay xmlns="urn:ietf:params:xml:ns:yang:ietf-dhcpv6-relay">
<enabled>true</enabled>
<relay-if>
<if-name>eth0</if-name>
<enabled>true</enabled>
<destination-address>2001:db8:2::1</destination-address>
<destination-address>2001:db8:2::2</destination-address>
<link-address>2001:db8:3::1</link-address>
<relay-options>
<interface-id-option>
<interface-id>EXAMPLEINTERFACEID01</interface-id>
</interface-id-option>
</relay-options>
</relay-if>
</dhcpv6-relay>
Figure 8: Basic Relay Configuration Example XML π
A.3. DHCPv6 Client Configuration Example π
last one! this is a basic client config and how it plays with the ietf-interfaces module π again there are two XML docs, one for ietf-interfaces and one for ietf-dhcpv6-client. here's what's going on:
- configuring an interface with the ietf-interfaces module, which is the one the client config gets applied to π―
- enabling the DHCP client function globally and for that interface β
- referencing that interface via an interface-ref to the ietf-interfaces module π
- setting the DUID for the DHCPv6-enabled interface π
- configuring a list of option codes the client will request in its Option Request Option (OPTION_ORO (6)) π
- configuring a single instance of the Vendor-specific Information Option (OPTION_VENDOR_OPTS (17)) with a single sub-option data item π§©
- requesting a non-temporary IPv6 address (IA_NA) with an identity association interface identifier of 1 π‘
- requesting an IPv6 delegated prefix address (IA_PD) with an identity association interface identifier of 2 π
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"
xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">
<interface>
<name>eth0</name>
<type>ianaift:ethernetCsmacd</type>
<description>DHCPv6 Relay Interface</description>
<enabled>true</enabled>
</interface>
</interfaces>
<dhcpv6-client
xmlns="urn:ietf:params:xml:ns:yang:ietf-dhcpv6-client">
<enabled>true</enabled>
<client-if>
<if-name>eth0</if-name>
<enabled>true</enabled>
<interface-duid>000200090CC084D303000913</interface-duid>
<client-configured-options>
<option-request-option>
<oro-option>17</oro-option>
<oro-option>23</oro-option>
<oro-option>24</oro-option>
<oro-option>82</oro-option>
</option-request-option>
<vendor-specific-information-options>
<vendor-specific-information-option>
<enterprise-number>32473</enterprise-number>
<vendor-option-data>
<sub-option-code>1</sub-option-code>
<sub-option-data>abcd1234</sub-option-data>
</vendor-option-data>
</vendor-specific-information-option>
</vendor-specific-information-options>
</client-configured-options>
<ia-na>
<ia-id>1</ia-id>
</ia-na>
<ia-pd>
<ia-id>2</ia-id>
</ia-pd>
</client-if>
</dhcpv6-client>
Figure 9: Basic Client Configuration Example XML π«Ά
that's the end of Appendix A examples, bestie!! ππβ¨
Appendix B. Example of Augmenting Additional DHCPv6 Option Definitions β¨π
okay so this appendix shows how you can extend the DHCPv6 option definitions to cover extra options π It's expected that more specification documents will be published for this later on π¦
The example defines YANG modules for OPTION_SIP_SERVER_D (21) and OPTION_SIP_SERVER_D (22) as specified in [RFC3319]. There's an example XML configuration, showing the interworking with other modules, in Figure 7 π§
Here's how the module is built, bestie π«Ά
- The module is named using a meaningful, shortened version of the document name in which the DHCP option format is specified. π
- A separate grouping is used to define each option. π
- The name of the option is taken from the registered IANA name for the option, with an '-option' suffix added. π
- The description field is taken from the relevant option code name and number. πΈ
- The reference section is the number and name of the RFC in which the DHCPv6 option is defined. π
- The remaining fields match the fields in the DHCP option. They are in the same order as defined in the DHCP option. Wherever possible, the format that is defined for the DHCP field should be matched by the relevant YANG type. β¨
- Fields that can have multiple entries or instances are defined using list or leaf-list nodes. π
Below the groupings for option definitions, augment statements are used to add the option definitions for use in the relevant DHCP element's module (server, relay, and/or client). this is the part where everything clicks, periodt π π₯
<CODE BEGINS>
module example-dhcpv6-opt-sip-serv {
yang-version 1.1;
namespace "https://example.com/ns/"
+ "example-dhcpv6-opt-sip-serv";
prefix sip-srv;
import ietf-inet-types {
prefix inet;
}
import ietf-dhcpv6-server {
prefix dhc6-srv;
}
organization
"IETF Dynamic Host Configuration (DHC) Working Group";
contact
"WG Web: <https://datatracker.ietf.org/wg/dhc/>
WG List: <mailto:dhcwg@ietf.org>
Author: Yong Cui <yong@csnet1.cs.tsinghua.edu.cn>
Author: Linhui Sun <lh.sunlinh@gmail.com>
Editor: Ian Farrer <ian.farrer@telekom.de>
Author: Sladjana Zeichlin <sladjana.zechlin@telekom.de>
Author: Zihao He <hezihao9512@gmail.com>
Author: Michal Nowikowski <godfryd@isc.org>";
description
"This YANG module contains DHCPv6 options defined in RFC 8415
that can be used by DHCPv6 servers.
Copyright (c) 2022 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 9243
(https://www.rfc-editor.org/info/rfc9243); see the RFC itself
for full legal notices.";
revision 2022-06-20 {
description
"Initial revision.";
reference
"RFC 9243: A YANG Data Model for DHCPv6 Configuration";
}
/*
* Groupings
*/
grouping sip-server-domain-name-list-option-group {
description
"OPTION_SIP_SERVER_D (21) SIP Servers Domain-Name List.";
reference
"RFC 3319: Dynamic Host Configuration Protocol
(DHCPv6) Options for Session Initiation Protocol (SIP)
Servers";
container sip-server-domain-name-list-option {
description
"OPTION_SIP_SERVER_D (21) SIP Servers Domain Name List
Option.";
list sip-server {
key "sip-serv-id";
description
"SIP server information.";
leaf sip-serv-id {
type uint8;
description
"SIP server list identifier.";
}
leaf sip-serv-domain-name {
type inet:domain-name;
description
"SIP server domain name.";
}
}
}
}
grouping sip-server-address-list-option-group {
description
"OPTION_SIP_SERVER_A (22) SIP Servers IPv6 Address List.";
reference
"RFC 3319: Dynamic Host Configuration Protocol
(DHCPv6) Options for Session Initiation Protocol (SIP)
Servers";
container sip-server-address-list-option {
description
"OPTION_SIP_SERVER_A (22) SIP Servers IPv6 Address List
Option.";
list sip-server {
key "sip-serv-id";
description
"SIP server information.";
leaf sip-serv-id {
type uint8;
description
"SIP server list entry identifier.";
}
leaf sip-serv-addr {
type inet:ipv6-address;
description
"SIP server IPv6 address.";
}
}
}
}
/*
* Augmentations
*/
augment "/dhc6-srv:dhcpv6-server/dhc6-srv:option-sets/"
+ "dhc6-srv:option-set" {
description
"Augment the option definition groupings to the server
module.";
uses sip-server-domain-name-list-option-group;
uses sip-server-address-list-option-group;
}
}
<CODE ENDS>
now the fun bit π The correct location to augment the new option definition(s) will vary according to the specific rules defined for the use of that specific option. For example, for options that will be augmented into the ietf-dhcpv6-server module, in many cases, these will be augmented to:
'/dhc6-srv:dhc6-srv/dhc6-srv:option-sets/dhc6-srv:option-set'
so that they can be defined within option sets. π§ However, there are some options that are only applicable for specific deployment scenarios, and in these cases, it may be more logical to augment the option group to a location relevant for the option.
One example for this could be OPTION_PD_EXCLUDE (67). π This option is only relevant in combination with a delegated prefix that contains a specific prefix. In this case, the following location for the augmentation may be more suitable:
'/dhc6-srv:dhc6-srv/dhc6-srv:allocation-ranges/dhc6-srv:allocation-range/dhc6-srv:prefix-pools/dhc6-srv:prefix-pool'
that's the whole appendix, iconic ππ
Appendix C. Example Vendor-Specific Server Configuration Module β¨
okay so this appendix is bestie-level fun π It shows how to extend the server YANG module from this document with vendor-specific config nodes, like setting up access to a lease storage database πΎ
The example module adds extra server attributes, like a name and a description πΈ Storage for leases lives in a lease-storage container, and you get to pick one of three options: memory (memfile), MySQL, or PostgreSQL π§ Each option comes with the config parameters it needs, so the setup is literally all there.
ngl, the example takes a shortcut to keep things simple π It assumes the DHCPv6 server lives on the same machine as the MySQL or PostgreSQL database server, and that it can talk to it securely over localhost without any extra cryptographic protection π In a real production setup, these pieces would probably be on different machines, so you'd use TLS to lock down the connection between the DHCPv6 server and the database server π There's a YANG module for configuring TLS defined in [GROUPINGS-TLS], so go check that out if you need it π¦
At the end, there's an augment statement that adds the vendor-specific config defined in "dhcpv6-server-config:config" under the "/dhcpv6-server:config/dhcpv6-server:vendor-config" mount point π
Here's the whole module, served fresh:
<CODE BEGINS>
module example-dhcpv6-server-conf {
yang-version 1.1;
namespace "https://example.com/ns/"
+ "example-dhcpv6-server-conf";
prefix dhc6-srv-conf;
import ietf-inet-types {
prefix inet;
}
import ietf-interfaces {
prefix if;
}
import ietf-dhcpv6-server {
prefix dhc6-srv;
}
organization
"IETF Dynamic Host Configuration (DHC) Working Group";
contact
"WG Web: <https://datatracker.ietf.org/wg/dhc/>
WG List: <mailto:dhcwg@ietf.org>
Author: Yong Cui <yong@csnet1.cs.tsinghua.edu.cn>
Author: Linhui Sun <lh.sunlinh@gmail.com>
Editor: Ian Farrer <ian.farrer@telekom.de>
Author: Sladjana Zeichlin <sladjana.zechlin@telekom.de>
Author: Zihao He <hezihao9512@gmail.com>
Author: Michal Nowikowski <godfryd@isc.org>";
description
"This YANG module defines components for the configuration and
management of vendor-/implementation-specific DHCPv6 server
functionality. As this functionality varies greatly between
different implementations, the module is provided as an example
only.
Copyright (c) 2022 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 9243
(https://www.rfc-editor.org/info/rfc9243); see the RFC itself
for full legal notices.";
revision 2022-06-20 {
description
"Initial revision.";
reference
"RFC 9243: A YANG Data Model for DHCPv6 Configuration";
}
/*
* Groupings
*/
grouping config {
description
"Parameters necessary for the configuration of a DHCPv6
server.";
container serv-attributes {
description
"Contains basic attributes necessary for running a DHCPv6
server.";
leaf name {
type string;
description
"Name of the DHCPv6 server.";
}
leaf description {
type string;
description
"Description of the DHCPv6 server.";
}
leaf ipv6-listen-port {
type uint16;
default "547";
description
"UDP port that the server will listen on.";
}
choice listening-interfaces {
default "all-interfaces";
description
"Configures which interface or addresses the server will
listen for incoming messages on.";
case all-interfaces {
container all-interfaces {
presence "true";
description
"Configures the server to listen for incoming messages
on all IPv6 addresses (unicast and multicast) on all
of its network interfaces.";
}
}
case interface-list {
leaf-list interfaces {
type if:interface-ref;
description
"List of interfaces on which the server will listen
for incoming messages. Messages addressed to any
valid IPv6 address (unicast and multicast) will be
received.";
}
}
case address-list {
leaf-list address-list {
type inet:ipv6-address;
description
"List of IPv6 address(es) on which the server will
listen for incoming DHCPv6 messages.";
}
}
}
leaf-list interfaces-config {
type if:interface-ref;
default "if:interfaces/if:interface/if:name";
description
"A leaf list of interfaces on which the server should
listen.";
}
container lease-storage {
description
"Configures how the server will store leases.";
choice storage-type {
description
"The type of storage that will be used for lease
information.";
case memfile {
description
"Configuration for storing leases information in a
Comma-Separated Value (CSV) file.";
leaf memfile-name {
type string;
description
"Specifies the absolute location of the lease file.
The format of the string follows the semantics of
the relevant operating system.";
}
leaf memfile-lfc-interval {
type uint64;
description
"Specifies the interval in seconds, at which the
server will perform a lease file cleanup (LFC).";
}
}
case mysql {
leaf mysql-name {
type string;
description
"Name of the MySQL database, running on the
localhost.";
}
leaf mysql-username {
type string;
description
"User name of the account under which the server
will access the database.";
}
leaf mysql-password {
type string;
description
"Password of the account under which the server
will access the database.";
}
leaf mysql-port {
type inet:port-number;
default "3306";
description
"If the database is located on a different system,
the port number may be specified.";
}
leaf mysql-lfc-interval {
type uint64;
description
"Specifies the interval in seconds, at which the
server will perform a lease file cleanup (LFC).";
}
leaf mysql-connect-timeout {
type uint64;
description
"Defines the timeout interval for connecting to the
database. A longer interval can be specified if the
database is remote.";
}
}
case postgresql {
leaf postgresql-name {
type string;
description
"Name of the PostgreSQL database, running on the
localhost.";
}
leaf postgresql-username {
type string;
description
"User name of the account under which the server
will access the database.";
}
leaf postgresql-password {
type string;
description
"Password of the account under which the server
will access the database.";
}
leaf postgresql-port {
type inet:port-number;
default "5432";
description
"If the database is located on a different system,
the port number may be specified.";
}
leaf postgresql-lfc-interval {
type uint64;
description
"Specifies the interval in seconds, at which the
server will perform a lease file cleanup (LFC).";
}
leaf postgresql-connect-timeout {
type uint64;
description
"Defines the timeout interval for connecting to the
database. A longer interval can be specified if the
database is remote.";
}
}
}
}
}
}
/*
* Augmentations
*/
augment "/dhc6-srv:dhcpv6-server/dhc6-srv:vendor-config" {
description
"Augment the server-specific YANG module to the
ietf-dhcpv6-server module.";
uses config;
}
}
<CODE ENDS>
Appendix D. Example Definition of Class-Selector Configuration β¨
okay bestie, so this appendix is a little example module called "ietf-example-dhcpv6-class-selector" π It shows how vendor-specific class selection config can be modeled and plugged into the "ietf-dhcpv6-server" module from this document π
The example module defines "client-class-names" with matching rules attached. A client can get sorted based on its "client-id", the "interface-id" (the ingress interface where its messages came in), the packet's source or destination address, the relay link address, the relay link interface-id, and more π¦ Honestly there are endless ways to classify clients, so this standard doesn't try to fully specify class selection. It just shows one way it could be defined πΈ
At the end of the example, augment statements tack the class selector rules onto the overall DHCPv6 addressing hierarchy π§ That happens in two main parts:
- the augmented class-selector configuration in the main DHCPv6 Server configuration
- client-class leafrefs augmented to "allocation-range", "address-pool", and "pd-pool", pointing to the "client-class-name" that is required
The mechanism goes like this: a class gets attached to a client based on the rules, and then the client is allowed to get an address (or addresses) or a prefix (or prefixes) from a given allocation-range or pool if the class name matches. Main character energy, fr π
<CODE BEGINS>
module example-dhcpv6-class-select {
yang-version 1.1;
namespace "https://example.com/ns/"
+ "example-dhcpv6-class-select";
prefix dhc6-class-sel;
import ietf-inet-types {
prefix inet;
}
import ietf-interfaces {
prefix if;
}
import ietf-dhcpv6-common {
prefix dhc6;
}
import ietf-dhcpv6-server {
prefix dhc6-srv;
}
organization
"IETF Dynamic Host Configuration (DHC) Working Group";
contact
"WG Web: <https://datatracker.ietf.org/wg/dhc/>
WG List: <mailto:dhcwg@ietf.org>
Author: Yong Cui <yong@csnet1.cs.tsinghua.edu.cn>
Author: Linhui Sun <lh.sunlinh@gmail.com>
Editor: Ian Farrer <ian.farrer@telekom.de>
Author: Sladjana Zeichlin <sladjana.zechlin@telekom.de>
Author: Zihao He <hezihao9512@gmail.com>
Author: Michal Nowikowski <godfryd@isc.org>";
description
"This YANG module defines components for the definition and
configuration of the client class selector function for a
DHCPv6 server. As this functionality varies greatly between
different implementations, the module provided as an example
only.
Copyright (c) 2022 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 9243
(https://www.rfc-editor.org/info/rfc9243); see the RFC itself
for full legal notices.";
revision 2022-06-20 {
description
"Initial revision.";
reference
"RFC 9243: A YANG Data Model for DHCPv6 Configuration";
}
/*
* Groupings
*/
grouping client-class-id {
description
"Definitions of client message classification for
authorization and assignment purposes.";
leaf client-class-name {
type string;
mandatory true;
description
"Unique identifier for client class identification list
entries.";
}
choice id-type {
mandatory true;
description
"Definitions for different client identifier types.";
case client-id-id {
leaf client-id {
type string;
mandatory true;
description
"String literal client identifier.";
}
description
"Client class selection based on a string literal client
identifier.";
}
case received-interface-id {
description
"Client class selection based on the incoming interface
of the DHCPv6 message.";
leaf received-interface {
type if:interface-ref;
description
"Reference to the interface entry for the incoming
DHCPv6 message.";
}
}
case packet-source-address-id {
description
"Client class selection based on the source address of
the DHCPv6 message.";
leaf packet-source-address {
type inet:ipv6-address;
mandatory true;
description
"Source address of the DHCPv6 message.";
}
}
case packet-destination-address-id {
description
"Client class selection based on the destination address
of the DHCPv6 message.";
leaf packet-destination-address {
type inet:ipv6-address;
mandatory true;
description
"Destination address of the DHCPv6 message.";
}
}
case relay-link-address-id {
description
"Client class selection based on the prefix of the
link-address field in the relay agent message header.";
leaf relay-link-address {
type inet:ipv6-prefix;
mandatory true;
description
"Prefix of the link-address field in the relay agent
message header.";
}
}
case relay-peer-address-id {
description
"Client class selection based on the value of the
peer-address field in the relay agent message header.";
leaf relay-peer-address {
type inet:ipv6-prefix;
mandatory true;
description
"Prefix of the peer-address field in the relay agent
message header.";
}
}
case relay-interface-id {
description
"Client class selection based on a received instance of
OPTION_INTERFACE_ID (18).";
leaf relay-interface {
type string;
description
"An opaque value of arbitrary length generated by the
relay agent to identify one of the relay agent's
interfaces.";
}
}
case user-class-option-id {
description
"Client class selection based on the value of the
OPTION_USER_CLASS (15) and its user-class-data field.";
leaf user-class-data {
type string;
mandatory true;
description
"User Class value to match.";
}
}
case vendor-class-present-id {
description
"Client class selection based on the presence of
OPTION_VENDOR_CLASS (16) in the received message.";
leaf vendor-class-present {
type boolean;
mandatory true;
description
"Presence of OPTION_VENDOR_CLASS (16) in the received
message.";
}
}
case vendor-class-option-enterprise-number-id {
description
"Client class selection based on the value of the
enterprise-number field in OPTION_VENDOR_CLASS (16).";
leaf vendor-class-option-enterprise-number {
type uint32;
mandatory true;
description
"Value of the enterprise-number field.";
}
}
case vendor-class-option-data {
description
"Client class selection based on the value of a data
field within a vendor-class-data entry for a matching
enterprise-number field in OPTION_VENDOR_CLASS (16).";
container vendor-class-option-data {
description
"Vendor class option data container.";
leaf enterprise-number {
type uint32;
description
"The vendor's registered Enterprise Number, as
maintained by IANA.";
}
leaf vendor-class-data-id {
type uint8;
description
"Vendor class data ID.";
}
leaf vendor-class-data {
type string;
description
"Opaque field for matching the client's vendor class
data.";
}
}
}
case client-duid-id {
description
"Client class selection based on the value of the
received client DUID.";
leaf duid {
type dhc6:duid;
description
"Client DUID.";
}
}
}
}
/*
* Augmentations
*/
augment "/dhc6-srv:dhcpv6-server/dhc6-srv:class-selector" {
description
"Augment class selector functions to the DHCPv6 server
module.";
container client-classes {
description
"Client classes to augment.";
list class {
key "client-class-name";
description
"List of the client class identifiers applicable to
clients served by this address pool.";
uses client-class-id;
}
}
}
augment "/dhc6-srv:dhcpv6-server/"
+ "dhc6-srv:allocation-ranges/dhc6-srv:allocation-range" {
description
"Augment class selector functions to the DHCPv6 server
allocation-ranges.";
leaf-list client-class {
type leafref {
path "/dhc6-srv:dhcpv6-server/dhc6-srv:"
+ "class-selector/client-classes/class/client-class-name";
}
description
"Leafrefs to client classes.";
}
}
augment "/dhc6-srv:dhcpv6-server/dhc6-srv:"
+ "allocation-ranges/dhc6-srv:allocation-range/dhc6-srv:"
+ "address-pools/dhc6-srv:address-pool" {
description
"Augment class selector functions to the DHCPv6 server
address-pools.";
leaf-list client-class {
type leafref {
path "/dhc6-srv:dhcpv6-server/dhc6-srv:"
+ "class-selector/client-classes/class/client-class-name";
}
description
"Leafrefs to client classes.";
}
}
augment "/dhc6-srv:dhcpv6-server/dhc6-srv:"
+ "allocation-ranges/dhc6-srv:allocation-range/dhc6-srv:"
+ "prefix-pools/dhc6-srv:prefix-pool" {
description
"Augment class selector functions to the DHCPv6
server prefix-pools.";
leaf-list client-class {
type leafref {
path "/dhc6-srv:dhcpv6-server/dhc6-srv:"
+ "class-selector/client-classes/class/client-class-name";
}
description
"Leafrefs to client classes.";
}
}
}
<CODE ENDS>
Acknowledgments π«Ά
the authors want to give a huge shoutout to Qi Sun, Lishan Li, Hao Wang, Tomek Mrugalski, Marcin Siodelski, Bernie Volz, Ted Lemon, Bing Liu, Tom Petch, Acee Lindem, Benjamin Kaduk, Kris Lambrechts, and Paul Dumitru π thank you for your valuable comments and contributions to this work, you literally made it better β¨
Contributors β¨
okay bestie, these are the coauthors who helped cook this doc π«Ά the whole crew is absolutely iconic
Yong Cui π
Tsinghua University
Beijing,
100084
China
Email: cuiyong@tsinghua.edu.cn
Linhui Sun πΈ
Tsinghua University
Beijing,
100084
China
Email: lh.sunlinh@gmail.com
Sladjana Zechlin π
Deutsche Telekom AG
CTO-IPT, Landgrabenweg 151
53227, Bonn
Germany
Email: sladjana.zechlin@telekom.de
Zihao He π¦
Tsinghua University
Beijing,
100084
China
Email: hezihao9512@gmail.com
Michal Nowikowski π§
Internet Systems Consortium
Gdansk
Poland
Email: godfryd@isc.org
Author's Address π
and the editor, who kept everything organized and on track π
Ian Farrer (editor) π
Deutsche Telekom AG
S&TI, Landgrabenweg 151
53227 Bonn
Germany
Email: ian.farrer@telekom.de
π¦ where this page comes from
- ietf: rfc9243 2022-06
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms