← Back to team overview

netplan-developers team mailing list archive

[Merge] ~awj/netplan:dhcp-options into netplan:master

 

Alan Johnson has proposed merging ~awj/netplan:dhcp-options into netplan:master.

Requested reviews:
  Developers of netplan (netplan-developers)

For more details, see:
https://code.launchpad.net/~awj/netplan/+git/netplan/+merge/354158
-- 
Your team Developers of netplan is requested to review the proposed merge of ~awj/netplan:dhcp-options into netplan:master.
diff --git a/doc/netplan.md b/doc/netplan.md
index 7b297d7..8102612 100644
--- a/doc/netplan.md
+++ b/doc/netplan.md
@@ -189,6 +189,11 @@ Virtual devices
 :   When set to 'mac'; pass that setting over to systemd-networkd to use the
     device's MAC address as a unique identifier rather than a RFC4361-compliant
     Client ID. This has no effect when NetworkManager is used as a renderer.
+    
+ ``dhcp-options`` (mapping)
+ 
+ :  (networkd backend only) Additional DHCP options; see the
+    ``DHCP Options`` section below.
 
 ``accept-ra`` (bool)
 
@@ -278,6 +283,37 @@ similar to ``gateway*``, and ``search:`` is a list of search domains.
 
 :   Configure policy routing for the device; see the ``Routing`` section below.
 
+## DHCP Options
+Several DHCP configuration options are supported via the ``networkd`` backend.
+
+These only have an effect if ``dhcp4`` or ``dhcp6`` is set to ``true``.
+
+``dhcp-options`` (mapping)
+
+:    The ``dhcp-options`` block defines additional DHCP configuration for the
+     ``networkd`` backend.
+
+     ``use-dns`` (boolean)
+     :    Default: ``true``. When ``true``, the DNS servers received from the
+          DHCP server will be used and take precedence over any statically
+          configured ones.
+
+     ``use-ntp`` (boolean)
+     :    Default: ``true``. When ``true`` , the NTP servers received from the
+          DHCP server will be used by systemd-timesyncd and take precedence
+          over any statically configured ones.
+
+     ``send-hostname`` (boolean)
+     :    Default: ``true``. When ``true``, the machine's hostname will be sent
+          to the DHCP server.
+
+     ``use-hostname`` (boolean)
+     :    Default: ``true``. When ``true``, the hostname received from the DHCP
+          server will be set as the transient hostname of the system.
+
+     ``hostname`` (string)
+     :    Use this value for the hostname which is sent to the DHCP server,
+          instead of machine's hostname.
 
 ## Routing
 Complex routing is possible with netplan. Standard static routes as well
diff --git a/src/networkd.c b/src/networkd.c
index 8cb0a36..34a8c1c 100644
--- a/src/networkd.c
+++ b/src/networkd.c
@@ -419,6 +419,23 @@ write_network_file(net_definition* def, const char* rootdir, const char* path)
             g_string_append_printf(s, "ClientIdentifier=%s\n", def->dhcp_identifier);
         if (def->critical)
             g_string_append_printf(s, "CriticalConnection=true\n");
+
+        /* Only write DHCP options that differ from the networkd default. */
+        if (!def->dhcp_options.use_dns) {
+          g_string_append_printf(s, "UseDNS=false\n");
+        }
+        if (!def->dhcp_options.use_ntp) {
+          g_string_append_printf(s, "UseNTP=false\n");
+        }
+        if (!def->dhcp_options.send_hostname) {
+          g_string_append_printf(s, "SendHostname=false\n");
+        }
+        if (!def->dhcp_options.use_hostname) {
+          g_string_append_printf(s, "UseHostname=false\n");
+        }
+        if (def->dhcp_options.hostname) {
+            g_string_append_printf(s, "Hostname=%s\n", def->dhcp_options.hostname);
+        }
     }
 
     /* these do not contain secrets and need to be readable by
diff --git a/src/parse.c b/src/parse.c
index b4b0364..f529f35 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -1265,6 +1265,15 @@ const mapping_entry_handler nameservers_handlers[] = {
     {NULL}
 };
 
+const mapping_entry_handler dhcp_options_handlers[] = {
+    {"use-dns", YAML_SCALAR_NODE, handle_netdef_bool, NULL, netdef_offset(dhcp_options.use_dns)},
+    {"use-ntp", YAML_SCALAR_NODE, handle_netdef_bool, NULL, netdef_offset(dhcp_options.use_ntp)},
+    {"send-hostname", YAML_SCALAR_NODE, handle_netdef_bool, NULL, netdef_offset(dhcp_options.send_hostname)},
+    {"use-hostname", YAML_SCALAR_NODE, handle_netdef_bool, NULL, netdef_offset(dhcp_options.use_hostname)},
+    {"hostname", YAML_SCALAR_NODE, handle_netdef_str, NULL, netdef_offset(dhcp_options.hostname)},
+    {NULL}
+};
+
 const mapping_entry_handler ethernet_def_handlers[] = {
     {"accept-ra", YAML_SCALAR_NODE, handle_accept_ra},
     {"addresses", YAML_SEQUENCE_NODE, handle_addresses},
@@ -1272,6 +1281,7 @@ const mapping_entry_handler ethernet_def_handlers[] = {
     {"dhcp4", YAML_SCALAR_NODE, handle_netdef_bool, NULL, netdef_offset(dhcp4)},
     {"dhcp6", YAML_SCALAR_NODE, handle_netdef_bool, NULL, netdef_offset(dhcp6)},
     {"dhcp-identifier", YAML_SCALAR_NODE, handle_dhcp_identifier},
+    {"dhcp-options", YAML_MAPPING_NODE, NULL, dhcp_options_handlers},
     {"gateway4", YAML_SCALAR_NODE, handle_gateway4},
     {"gateway6", YAML_SCALAR_NODE, handle_gateway6},
     {"link-local", YAML_SEQUENCE_NODE, handle_link_local},
@@ -1296,6 +1306,7 @@ const mapping_entry_handler wifi_def_handlers[] = {
     {"dhcp4", YAML_SCALAR_NODE, handle_netdef_bool, NULL, netdef_offset(dhcp4)},
     {"dhcp6", YAML_SCALAR_NODE, handle_netdef_bool, NULL, netdef_offset(dhcp6)},
     {"dhcp-identifier", YAML_SCALAR_NODE, handle_dhcp_identifier},
+    {"dhcp-options", YAML_MAPPING_NODE, NULL, dhcp_options_handlers},
     {"gateway4", YAML_SCALAR_NODE, handle_gateway4},
     {"gateway6", YAML_SCALAR_NODE, handle_gateway6},
     {"link-local", YAML_SEQUENCE_NODE, handle_link_local},
@@ -1479,6 +1490,12 @@ handle_network_type(yaml_document_t* doc, yaml_node_t* node, const void* data, G
             /* systemd-networkd defaults to IPv6 LL enabled; keep that default */
             cur_netdef->linklocal.ipv6 = TRUE;
             g_hash_table_insert(netdefs, cur_netdef->id, cur_netdef);
+
+            /* Default DHCP options. */
+            cur_netdef->dhcp_options.use_dns = TRUE;
+            cur_netdef->dhcp_options.use_ntp = TRUE;
+            cur_netdef->dhcp_options.send_hostname = TRUE;
+            cur_netdef->dhcp_options.use_hostname = TRUE;
         }
 
         // XXX: breaks multi-pass parsing.
diff --git a/src/parse.h b/src/parse.h
index 54d103f..00e83af 100644
--- a/src/parse.h
+++ b/src/parse.h
@@ -78,6 +78,13 @@ typedef struct net_definition {
     gboolean dhcp4;
     gboolean dhcp6;
     char* dhcp_identifier;
+    struct {
+        gboolean use_dns;
+        gboolean use_ntp;
+        gboolean send_hostname;
+        gboolean use_hostname;
+        char* hostname;
+    } dhcp_options;
     ra_mode accept_ra;
     GArray* ip4_addresses;
     GArray* ip6_addresses;

Follow ups