summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucas Christian <lucas@lucasec.com>2020-10-04 17:50:53 -0500
committerLucas Christian <lucas@lucasec.com>2020-10-04 17:50:53 -0500
commit51a6eaa324775049ee666503ca0a63571750ac25 (patch)
treee043768206ee3d6ec8c39df8e6f3c5d5c83c986f
parent41ff73882fb6dad2484d841ed59494f0c963bf5e (diff)
downloadvyos-1x-51a6eaa324775049ee666503ca0a63571750ac25.tar.gz
vyos-1x-51a6eaa324775049ee666503ca0a63571750ac25.zip
dhcpv6: T2961: support stateless dhcpv6 clients
This commit adds support for configuring the DHCPv6 server to serve "stateless" DHCPv6 clients (those that send an information-request message and do not request an address). The change introduces a `common-options` node at the `shared-network-name` level, which allows specifying options applicable to clients regardless of subnet assigned (or in the case of stateless clients, when no subnet is assigned). Parameters specified at the subnet level take precedence over those set at the shared-network level. Presently, only parameters that are meaningful to stateless clients have been exposed under `common-options`, as there is no precedent of exposing parameters at multiple levels under the current DHCPv4 or DHCPv6 configuration syntax. If desired, additional parameters could certainly be added with relative ease.
-rw-r--r--data/templates/dhcpv6-server/dhcpdv6.conf.tmpl9
-rw-r--r--interface-definitions/dhcpv6-server.xml.in42
-rwxr-xr-xsrc/conf_mode/dhcpv6_server.py26
3 files changed, 77 insertions, 0 deletions
diff --git a/data/templates/dhcpv6-server/dhcpdv6.conf.tmpl b/data/templates/dhcpv6-server/dhcpdv6.conf.tmpl
index ff7822b0d..bdeea71da 100644
--- a/data/templates/dhcpv6-server/dhcpdv6.conf.tmpl
+++ b/data/templates/dhcpv6-server/dhcpdv6.conf.tmpl
@@ -12,6 +12,15 @@ option dhcp6.preference {{ preference }};
{% for network in shared_network %}
{%- if not network.disabled -%}
shared-network {{ network.name }} {
+ {%- if network.common.info_refresh_time %}
+ option dhcp6.info-refresh-time {{ network.common.info_refresh_time }};
+ {%- endif %}
+ {%- if network.common.domain_search %}
+ option dhcp6.domain-search "{{ network.common.domain_search | join('", "') }}";
+ {%- endif %}
+ {%- if network.common.dns_server %}
+ option dhcp6.name-servers {{ network.common.dns_server | join(', ') }};
+ {%- endif %}
{%- for subnet in network.subnet %}
subnet6 {{ subnet.network }} {
{%- for range in subnet.range6_prefix %}
diff --git a/interface-definitions/dhcpv6-server.xml.in b/interface-definitions/dhcpv6-server.xml.in
index 4073b46b2..acc33d40f 100644
--- a/interface-definitions/dhcpv6-server.xml.in
+++ b/interface-definitions/dhcpv6-server.xml.in
@@ -43,6 +43,48 @@
<valueless/>
</properties>
</leafNode>
+ <node name="common-options">
+ <properties>
+ <help>Common options to distribute to all clients, including stateless clients</help>
+ </properties>
+ <children>
+ <leafNode name="info-refresh-time">
+ <properties>
+ <help>Time (in seconds) that stateless clients should wait between refreshing the information they were given</help>
+ <valueHelp>
+ <format>1-4294967295</format>
+ <description>DHCPv6 information refresh time</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-4294967295"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="domain-search">
+ <properties>
+ <help>Domain name for client to search</help>
+ <constraint>
+ <regex>[-_a-zA-Z0-9.]+</regex>
+ </constraint>
+ <constraintErrorMessage>Invalid domain name. May only contain letters, numbers and .-_</constraintErrorMessage>
+ <multi/>
+ </properties>
+ </leafNode>
+ <leafNode name="name-server">
+ <properties>
+ <help>IPv6 address of a Recursive DNS Server</help>
+ <valueHelp>
+ <format>ipv6</format>
+ <description>IPv6 address of DNS name server</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv6-address"/>
+ </constraint>
+ <multi/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
<tagNode name="subnet">
<properties>
<help>IPv6 DHCP subnet for this shared network [REQUIRED]</help>
diff --git a/src/conf_mode/dhcpv6_server.py b/src/conf_mode/dhcpv6_server.py
index 4ce4cada1..1777d4db7 100755
--- a/src/conf_mode/dhcpv6_server.py
+++ b/src/conf_mode/dhcpv6_server.py
@@ -65,6 +65,7 @@ def get_config(config=None):
config = {
'name': network,
'disabled': False,
+ 'common': {},
'subnet': []
}
@@ -72,6 +73,31 @@ def get_config(config=None):
if conf.exists(['disable']):
config['disabled'] = True
+ # Common options shared among subnets. These can be overridden if
+ # the same option is specified on a per-subnet or per-host
+ # basis. These are the only options that can be handed out to
+ # stateless clients via an information-request message.
+ if conf.exists(['common-options']):
+ conf.set_level(base + ['shared-network-name', network, 'common-options'])
+
+ # How often stateless clients should refresh their information. This is
+ # mostly taken as a hint by clients, and only if they request it.
+ # (if not specified, the server does not supply this to the client)
+ if conf.exists(['info-refresh-time']):
+ config['common']['info_refresh_time'] = conf.return_value(['info-refresh-time'])
+
+ # The domain-search option specifies a 'search list' of Domain Names to be used
+ # by the client to locate not-fully-qualified domain names.
+ if conf.exists(['domain-search']):
+ config['common']['domain_search'] = conf.return_values(['domain-search'])
+
+ # Specifies a list of Domain Name System name servers available to the client.
+ # Servers should be listed in order of preference.
+ if conf.exists(['name-server']):
+ config['common']['dns_server'] = conf.return_values(['name-server'])
+
+ conf.set_level(base + ['shared-network-name', network])
+
# check for multiple subnet configurations in a shared network
if conf.exists(['subnet']):
for net in conf.list_nodes(['subnet']):