Skip to content

Basic DHCP server support #703

@troglobit

Description

@troglobit

Introduction

This task is a subset of issue #446, detailing requirements for a Basic DHCP Server which can later be expanded upon, without major rewrites or breaking configuration file syntax changes.

Note: this does not include support for acting as a DHCP relay.

Requirements (subset of #446)

  1. The server implementation should1 be dnsmasq, since it is already acting as system name resolver with openresolv, and can also act as TFTP (and PXE) server
  2. Must be possible to set up an IP address pool without an interface
  3. All DHCP options must be generalized, without exception
    • Common settings, that many vendors have dedicated settings for, like "default router", "dns server", should be managed as DHCP options instead
    • Configuring from the CLI should infer2 the dnsmasq default (sensible) options: netmask (option 1), broadcast address (option 28), DNS server (option 6), default route (option 3), domain name (option 15)
    • When configuring from any other source (NETCONF/RESTCONF), the user must know of these defaults from the YANG model description
    • An empty option list should tell dnsmasq to send no options
  4. Support static host leases
    • Support matching on MAC address, client-id option, and make it possible (future) to add Option 82 sub-options without causing syntax changes for the former two match options
  5. Use common vernacular in the YANG model (see Add support for DHCP server #446)

Proposed YANG model (tree view)

$ yanglint -f tree -p ../src/infix/output/target/usr/share/yang/ infix-dhcp-server.yang
module: infix-dhcp-server
  +--rw dhcp-server
     +--rw enabled?      boolean
     +--rw option* [key]
     |  +--rw key         dhcp-server-options
     |  +--rw (optval)?
     |     +--:(address)
     |     |  +--rw address?   inet:ipv4-address
     |     +--:(name)
     |     |  +--rw name?   inet:domain-name
     |     +--:(classless-routes)
     |     |  +--rw static-route* [destination]
     |     |     +--rw destination    inet:ipv4-prefix
     |     |     +--rw next-hop?      inet:ipv4-address
     |     +--:(default-opt)
     |        +--rw value?   string
     +--rw subnet* [subnet]
     |  +--rw subnet         inet:ipv4-prefix
     |  +--rw description?   string
     |  +--rw if-name?       if:interface-ref
     |  +--rw option* [key]
     |  |  +--rw key         dhcp-server-options
     |  |  +--rw (optval)?
     |  |     +--:(address)
     |  |     |  +--rw address?   inet:ipv4-address
     |  |     +--:(name)
     |  |     |  +--rw name?   inet:domain-name
     |  |     +--:(classless-routes)
     |  |     |  +--rw static-route* [destination]
     |  |     |     +--rw destination    inet:ipv4-prefix
     |  |     |     +--rw next-hop?      inet:ipv4-address
     |  |     +--:(default-opt)
     |  |        +--rw value?   string
     |  +--rw pool
     |  |  +--rw start-address?   inet:ipv4-address
     |  |  +--rw end-address?     inet:ipv4-address
     |  |  +--rw lease-time?      dhcp-lease-time
     |  +--rw host* [address]
     |  |  +--rw address        inet:ipv4-address
     |  |  +--rw description?   string
     |  |  +--rw match
     |  |  |  +--rw (match)?
     |  |  |     +--:(mac-address)
     |  |  |     |  +--rw mac-address?   yang:mac-address
     |  |  |     +--:(hostname)
     |  |  |     |  +--rw hostname?   string
     |  |  |     +--:(client-id)
     |  |  |        +--rw client-id?   union
     |  |  +--rw hostname?      inet:domain-name
     |  |  +--rw lease-time?    dhcp-lease-time
     |  |  +--rw option* [key]
     |  |     +--rw key         dhcp-server-options
     |  |     +--rw (optval)?
     |  |        +--:(address)
     |  |        |  +--rw address?   inet:ipv4-address
     |  |        +--:(name)
     |  |        |  +--rw name?   inet:domain-name
     |  |        +--:(classless-routes)
     |  |        |  +--rw static-route* [destination]
     |  |        |     +--rw destination    inet:ipv4-prefix
     |  |        |     +--rw next-hop?      inet:ipv4-address
     |  |        +--:(default-opt)
     |  |           +--rw value?   string
     |  +--ro leases
     |     +--ro total-count?   uint32
     |     +--ro lease* [address]
     |        +--ro address              inet:ip-address
     |        +--ro hardware-address?    yang:mac-address
     |        +--ro hostname?            string
     |        +--ro expires?             yang:date-and-time
     |        +--ro client-identifier?   string
     +--ro statistics
        +--ro sent
        |  +--ro offer-count?   yang:counter32
        |  +--ro ack-count?     yang:counter32
        |  +--ro nack-count?    yang:counter32
        +--ro received
        |  +--ro decline-count?    yang:counter32
        |  +--ro discover-count?   yang:counter32
        |  +--ro request-count?    yang:counter32
        |  +--ro release-count?    yang:counter32
        |  +--ro inform-count?     yang:counter32
        +---x clear

Notes

  • Inference reduced to not include option 1 and option 28, instead these options will always be sent by dnsmasq as sane defaults when it is able, i.e., when the request is received on a local interface matching the configured subnet. For the relay case these options must still be provided since there is no way for dnsmasq to derive the netmask and broadcast addresses

Footnotes

  1. RFC2119 applies.

  2. I.e., employ the use of SR_EV_UPDATE when changes to the candidate datastore happen.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

Status

Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions