[systemd-commits] man/systemd.network.xml src/libsystemd-network src/network src/systemd

Tom Gundersen tomegun at kemper.freedesktop.org
Tue Jul 1 13:03:43 PDT 2014


 man/systemd.network.xml                  |    7 +++++
 src/libsystemd-network/sd-dhcp-client.c  |   42 +++++++++++++++++++++++++++++++
 src/network/networkd-link.c              |   26 +++++++++++++++++++
 src/network/networkd-network-gperf.gperf |    5 ++-
 src/network/networkd-network.c           |    1 
 src/network/networkd.h                   |    1 
 src/systemd/sd-dhcp-client.h             |    1 
 7 files changed, 81 insertions(+), 2 deletions(-)

New commits:
commit 4cc7a82c9490a3c5ae03b1d6d168ce40ba499e23
Author: Eugene Yakubovich <eugene.yakubovich at coreos.com>
Date:   Tue Jul 1 11:58:49 2014 -0700

    networkd: send hostname to dhcp server
    
    Send hostname (option 12) in DISCOVER and REQUEST messages so the
    DHCP server could use it to register with dynamic DNS and such.
    
    To opt-out of this behaviour set SendHostname to false in [DHCP]
    section of .network file
    
    [tomegun: rebased, made sure a failing set_hostname is a noop and moved
              config from DHCPv4 to DHCP]

diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 707ced1..2b0eb56 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -405,6 +405,13 @@
                                         </listitem>
                                 </varlistentry>
                                 <varlistentry>
+                                        <term><varname>SendHostname=</varname></term>
+                                        <listitem>
+                                                <para>When true (the default), the machine's hostname will be sent to the DHCP
+                                                server</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
                                         <term><varname>UseHostname=</varname></term>
                                         <listitem>
                                                 <para>When true (the default), the hostname received from the DHCP server
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index 8e9f5bd..d8a9d20 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -56,6 +56,7 @@ struct sd_dhcp_client {
                 uint8_t type;
                 struct ether_addr mac_addr;
         } _packed_ client_id;
+        char *hostname;
         uint32_t xid;
         usec_t start_time;
         uint16_t secs;
@@ -178,6 +179,27 @@ int sd_dhcp_client_set_mac(sd_dhcp_client *client,
         return 0;
 }
 
+int sd_dhcp_client_set_hostname(sd_dhcp_client *client,
+                                const char *hostname) {
+        char *new_hostname = NULL;
+
+        assert_return(client, -EINVAL);
+
+        if (streq_ptr(client->hostname, hostname))
+                return 0;
+
+        if (hostname) {
+                new_hostname = strdup(hostname);
+                if (!new_hostname)
+                        return -ENOMEM;
+        }
+
+        free(client->hostname);
+        client->hostname = new_hostname;
+
+        return 0;
+}
+
 int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
         assert_return(client, -EINVAL);
         assert_return(ret, -EINVAL);
@@ -386,6 +408,17 @@ static int client_send_discover(sd_dhcp_client *client) {
                         return r;
         }
 
+        /* it is unclear from RFC 2131 if client should send hostname in
+           DHCPDISCOVER but dhclient does and so we do as well
+        */
+        if (client->hostname) {
+                r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
+                                       DHCP_OPTION_HOST_NAME,
+                                       strlen(client->hostname), client->hostname);
+                if (r < 0)
+                        return r;
+        }
+
         r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
                                DHCP_OPTION_END, 0, NULL);
         if (r < 0)
@@ -477,6 +510,14 @@ static int client_send_request(sd_dhcp_client *client) {
                 return -EINVAL;
         }
 
+        if (client->hostname) {
+                r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
+                                       DHCP_OPTION_HOST_NAME,
+                                       strlen(client->hostname), client->hostname);
+                if (r < 0)
+                        return r;
+        }
+
         r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
                                DHCP_OPTION_END, 0, NULL);
         if (r < 0)
@@ -1364,6 +1405,7 @@ sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) {
                 sd_dhcp_lease_unref(client->lease);
 
                 free(client->req_opts);
+                free(client->hostname);
                 free(client);
         }
 
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index a523a3e..3324276 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -21,6 +21,7 @@
 
 #include <netinet/ether.h>
 #include <linux/if.h>
+#include <unistd.h>
 
 #include "networkd.h"
 #include "libudev-private.h"
@@ -1927,6 +1928,18 @@ static int link_enter_enslave(Link *link) {
         return 0;
 }
 
+/* make sure the hostname is not "localhost" */
+static bool is_localhost(const char *hostname) {
+        assert(hostname);
+
+        return streq(hostname, "localhost") ||
+               streq(hostname, "localhost.") ||
+               endswith(hostname, ".localhost") ||
+               endswith(hostname, ".localhost.") ||
+               endswith(hostname, ".localdomain") ||
+               endswith(hostname, ".localdomain.");
+}
+
 static int link_configure(Link *link) {
         int r;
 
@@ -1992,6 +2005,7 @@ static int link_configure(Link *link) {
                         if (r < 0)
                                 return r;
                 }
+
                 if (link->network->dhcp_routes) {
                         r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_STATIC_ROUTE);
                         if (r < 0)
@@ -2000,6 +2014,18 @@ static int link_configure(Link *link) {
                         if (r < 0)
                                 return r;
                 }
+
+                if (link->network->dhcp_sendhost) {
+                        _cleanup_free_ char *hostname = gethostname_malloc();
+                        if (!hostname)
+                                return -ENOMEM;
+
+                        if (!is_localhost(hostname)) {
+                                r = sd_dhcp_client_set_hostname(link->dhcp_client, hostname);
+                                if (r < 0)
+                                        return r;
+                        }
+                }
         }
 
         if (link->network->dhcp_server) {
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index b6d52e7..3aaae4c 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -47,11 +47,12 @@ DHCP.UseDNS,                 config_parse_bool,                  0,
 DHCP.UseMTU,                 config_parse_bool,                  0,                             offsetof(Network, dhcp_mtu)
 DHCP.UseHostname,            config_parse_bool,                  0,                             offsetof(Network, dhcp_hostname)
 DHCP.UseDomainName,          config_parse_bool,                  0,                             offsetof(Network, dhcp_domainname)
+DHCP.UseRoutes,            config_parse_bool,                  0,                             offsetof(Network, dhcp_routes)
+DHCP.SendHostname,         config_parse_bool,                  0,                             offsetof(Network, dhcp_sendhost)
 DHCP.CriticalConnection,     config_parse_bool,                  0,                             offsetof(Network, dhcp_critical)
-/* backwards compatibility */
+/* backwards compatibility: do not add new entries to this section */
 DHCPv4.UseDNS,               config_parse_bool,                  0,                             offsetof(Network, dhcp_dns)
 DHCPv4.UseMTU,               config_parse_bool,                  0,                             offsetof(Network, dhcp_mtu)
 DHCPv4.UseHostname,          config_parse_bool,                  0,                             offsetof(Network, dhcp_hostname)
 DHCPv4.UseDomainName,        config_parse_bool,                  0,                             offsetof(Network, dhcp_domainname)
-DHCPv4.UseRoutes,            config_parse_bool,                  0,                             offsetof(Network, dhcp_routes)
 DHCPv4.CriticalConnection,   config_parse_bool,                  0,                             offsetof(Network, dhcp_critical)
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index f60f7c8..9ab4f23 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -90,6 +90,7 @@ static int network_load_one(Manager *manager, const char *filename) {
         network->dhcp_hostname = true;
         network->dhcp_domainname = true;
         network->dhcp_routes = true;
+        network->dhcp_sendhost = true;
 
         r = config_parse(NULL, filename, file, "Match\0Network\0Address\0Route\0DHCPv4\0", config_item_perf_lookup,
                         (void*) network_network_gperf_lookup, false, false, network);
diff --git a/src/network/networkd.h b/src/network/networkd.h
index d1b0bb7..c2b88ac 100644
--- a/src/network/networkd.h
+++ b/src/network/networkd.h
@@ -169,6 +169,7 @@ struct Network {
         bool dhcp_mtu;
         bool dhcp_hostname;
         bool dhcp_domainname;
+        bool dhcp_sendhost;
         bool dhcp_critical;
         bool dhcp_routes;
         bool ipv4ll;
diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h
index 0ed7d0f..c3ea059 100644
--- a/src/systemd/sd-dhcp-client.h
+++ b/src/systemd/sd-dhcp-client.h
@@ -51,6 +51,7 @@ int sd_dhcp_client_set_request_address(sd_dhcp_client *client,
 int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index);
 int sd_dhcp_client_set_mac(sd_dhcp_client *client,
                            const struct ether_addr *addr);
+int sd_dhcp_client_set_hostname(sd_dhcp_client *client, const char *hostname);
 int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret);
 
 int sd_dhcp_client_stop(sd_dhcp_client *client);



More information about the systemd-commits mailing list