chiark / gitweb /
networkd: send hostname to dhcp server
[elogind.git] / src / network / networkd-link.c
index c99cafc24bfb409f34ac2aef04ee07739d2bcde4..3324276bcc5b9c6ea2c1ae001f2d9a6b32563b3b 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <netinet/ether.h>
 #include <linux/if.h>
+#include <unistd.h>
 
 #include "networkd.h"
 #include "libudev-private.h"
@@ -78,7 +79,7 @@ static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
 
         r = sd_rtnl_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
         if (r < 0)
-                return r;
+                log_debug_link(link, "MAC address not found for new device, continuing without");
 
         r = asprintf(&link->state_file, "/run/systemd/netif/links/%"PRIu64,
                      link->ifindex);
@@ -106,8 +107,6 @@ static void link_free(Link *link) {
         if (!link)
                 return;
 
-        assert(link->manager);
-
         while ((address = link->addresses)) {
                 LIST_REMOVE(addresses, link->addresses, address);
                 address_free(address);
@@ -128,7 +127,8 @@ static void link_free(Link *link) {
         sd_dhcp6_client_unref(link->dhcp6_client);
         sd_icmp6_nd_unref(link->icmp6_router_discovery);
 
-        hashmap_remove(link->manager->links, &link->ifindex);
+        if (link->manager)
+                hashmap_remove(link->manager->links, &link->ifindex);
 
         free(link->ifname);
 
@@ -1724,6 +1724,8 @@ static int link_enslaved(Link *link) {
         assert(link->state == LINK_STATE_ENSLAVING);
         assert(link->network);
 
+        log_debug_link(link, "enslaved");
+
         if (!(link->flags & IFF_UP)) {
                 r = link_up(link);
                 if (r < 0) {
@@ -1750,7 +1752,7 @@ static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
                 return 1;
 
         r = sd_rtnl_message_get_errno(m);
-        if (r < 0) {
+        if (r < 0 && r != -EEXIST) {
                 log_struct_link(LOG_ERR, link,
                                 "MESSAGE=%-*s: could not enslave: %s",
                                 IFNAMSIZ,
@@ -1761,9 +1763,7 @@ static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
                 return 1;
         }
 
-        log_debug_link(link, "enslaved");
-
-        if (link->enslaving == 0)
+        if (link->enslaving <= 0)
                 link_enslaved(link);
 
         return 1;
@@ -1928,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;
 
@@ -1993,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)
@@ -2001,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) {