]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/network/networkd-dhcp4.c
Merge pull request #20303 from andir/sysconfig-example
[thirdparty/systemd.git] / src / network / networkd-dhcp4.c
index c986031b87bce63ad4c9a3723ecf48a31fc6f02a..6b4f6aaabd46d4ba42822a68bd0b7d441f996e17 100644 (file)
@@ -992,6 +992,12 @@ static int dhcp4_request_address(Link *link, bool announce) {
         addr->route_metric = link->network->dhcp_route_metric;
         addr->duplicate_address_detection = link->network->dhcp_send_decline ? ADDRESS_FAMILY_IPV4 : ADDRESS_FAMILY_NO;
 
+        if (link->network->dhcp_label) {
+                addr->label = strdup(link->network->dhcp_label);
+                if (!addr->label)
+                        return log_oom();
+        }
+
         if (address_get(link, addr, NULL) < 0)
                 link->dhcp4_configured = false;
 
@@ -1311,7 +1317,7 @@ static int dhcp4_set_hostname(Link *link) {
         else {
                 r = gethostname_strict(&hostname);
                 if (r < 0 && r != -ENXIO) /* ENXIO: no hostname set or hostname is "localhost" */
-                        return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to get hostname: %m");
+                        return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to get hostname: %m");
 
                 hn = hostname;
         }
@@ -1319,9 +1325,9 @@ static int dhcp4_set_hostname(Link *link) {
         r = sd_dhcp_client_set_hostname(link->dhcp_client, hn);
         if (r == -EINVAL && hostname)
                 /* Ignore error when the machine's hostname is not suitable to send in DHCP packet. */
-                log_link_debug_errno(link, r, "DHCP4 CLIENT: Failed to set hostname from kernel hostname, ignoring: %m");
+                log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set hostname from kernel hostname, ignoring: %m");
         else if (r < 0)
-                return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set hostname: %m");
+                return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set hostname: %m");
 
         return 0;
 }
@@ -1351,7 +1357,7 @@ static int dhcp4_set_client_identifier(Link *link) {
                                                          duid->raw_data_len > 0 ? duid->raw_data : NULL,
                                                          duid->raw_data_len);
                 if (r < 0)
-                        return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set IAID+DUID: %m");
+                        return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set IAID+DUID: %m");
                 break;
         }
         case DHCP_CLIENT_ID_DUID_ONLY: {
@@ -1367,7 +1373,7 @@ static int dhcp4_set_client_identifier(Link *link) {
                                                     duid->raw_data_len > 0 ? duid->raw_data : NULL,
                                                     duid->raw_data_len);
                 if (r < 0)
-                        return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set DUID: %m");
+                        return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set DUID: %m");
                 break;
         }
         case DHCP_CLIENT_ID_MAC: {
@@ -1385,7 +1391,7 @@ static int dhcp4_set_client_identifier(Link *link) {
                                                  hw_addr,
                                                  hw_addr_len);
                 if (r < 0)
-                        return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set client ID: %m");
+                        return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set client ID: %m");
                 break;
         }
         default:
@@ -1395,15 +1401,6 @@ static int dhcp4_set_client_identifier(Link *link) {
         return 0;
 }
 
-static int dhcp4_configure_duid(Link *link) {
-        assert(link);
-
-        if (!IN_SET(link->network->dhcp_client_identifier, DHCP_CLIENT_ID_DUID, DHCP_CLIENT_ID_DUID_ONLY))
-                return 1;
-
-        return dhcp_configure_duid(link, link_get_dhcp4_duid(link));
-}
-
 static int dhcp4_set_request_address(Link *link) {
         Address *a;
 
@@ -1424,7 +1421,7 @@ static int dhcp4_set_request_address(Link *link) {
         if (!a)
                 return 0;
 
-        log_link_debug(link, "DHCP4 CLIENT: requesting " IPV4_ADDRESS_FMT_STR, IPV4_ADDRESS_FMT_VAL(a->in_addr.in));
+        log_link_debug(link, "DHCPv4 CLIENT: requesting " IPV4_ADDRESS_FMT_STR, IPV4_ADDRESS_FMT_VAL(a->in_addr.in));
 
         return sd_dhcp_client_set_request_address(link->dhcp_client, &a->in_addr.in);
 }
@@ -1445,15 +1442,15 @@ static bool link_needs_dhcp_broadcast(Link *link) {
         if (r < 0 && link->sd_device && sd_device_get_property_value(link->sd_device, "ID_NET_DHCP_BROADCAST", &val) >= 0) {
                 r = parse_boolean(val);
                 if (r < 0)
-                        log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to parse ID_NET_DHCP_BROADCAST, ignoring: %m");
+                        log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to parse ID_NET_DHCP_BROADCAST, ignoring: %m");
                 else
-                        log_link_debug(link, "DHCP4 CLIENT: Detected ID_NET_DHCP_BROADCAST='%d'.", r);
+                        log_link_debug(link, "DHCPv4 CLIENT: Detected ID_NET_DHCP_BROADCAST='%d'.", r);
 
         }
         return r == true;
 }
 
-int dhcp4_configure(Link *link) {
+static int dhcp4_configure(Link *link) {
         sd_dhcp_option *send_option;
         void *request_options;
         int r;
@@ -1461,88 +1458,81 @@ int dhcp4_configure(Link *link) {
         assert(link);
         assert(link->network);
 
-        if (!link_dhcp4_enabled(link))
-                return 0;
-
         if (link->dhcp_client)
-                return -EBUSY; /* Already configured. */
-
-        r = dhcp4_configure_duid(link);
-        if (r <= 0)
-                return r;
+                return log_link_debug_errno(link, SYNTHETIC_ERRNO(EBUSY), "DHCPv4 client is already configured.");
 
         r = sd_dhcp_client_new(&link->dhcp_client, link->network->dhcp_anonymize);
         if (r < 0)
-                return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to allocate DHCP4 client: %m");
+                return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to allocate DHCPv4 client: %m");
 
         r = sd_dhcp_client_attach_event(link->dhcp_client, link->manager->event, 0);
         if (r < 0)
-                return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to attach event to DHCP4 client: %m");
+                return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to attach event to DHCPv4 client: %m");
 
         r = sd_dhcp_client_set_mac(link->dhcp_client,
                                    link->hw_addr.bytes,
                                    link->bcast_addr.length > 0 ? link->bcast_addr.bytes : NULL,
                                    link->hw_addr.length, link->iftype);
         if (r < 0)
-                return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set MAC address: %m");
+                return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set MAC address: %m");
 
         r = sd_dhcp_client_set_ifindex(link->dhcp_client, link->ifindex);
         if (r < 0)
-                return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set ifindex: %m");
+                return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set ifindex: %m");
 
         r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp4_handler, link);
         if (r < 0)
-                return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set callback: %m");
+                return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set callback: %m");
 
         r = sd_dhcp_client_set_request_broadcast(link->dhcp_client, link_needs_dhcp_broadcast(link));
         if (r < 0)
-                return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for broadcast: %m");
+                return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for broadcast: %m");
 
         if (link->mtu > 0) {
                 r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu);
                 if (r < 0)
-                        return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set MTU: %m");
+                        return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set MTU: %m");
         }
 
         if (!link->network->dhcp_anonymize) {
                 if (link->network->dhcp_use_mtu) {
                         r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_INTERFACE_MTU);
                         if (r < 0)
-                                return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for MTU: %m");
+                                return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for MTU: %m");
                 }
 
                 if (link->network->dhcp_use_routes) {
                         r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_STATIC_ROUTE);
                         if (r < 0)
-                                return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for static route: %m");
+                                return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for static route: %m");
 
                         r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE);
                         if (r < 0)
-                                return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for classless static route: %m");
+                                return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for classless static route: %m");
                 }
 
                 if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
                         r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_DOMAIN_SEARCH_LIST);
                         if (r < 0)
-                                return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for domain search list: %m");
+                                return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for domain search list: %m");
                 }
 
                 if (link->network->dhcp_use_ntp) {
                         r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_NTP_SERVER);
                         if (r < 0)
-                                return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for NTP server: %m");
+                                return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for NTP server: %m");
                 }
 
                 if (link->network->dhcp_use_sip) {
                         r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_SIP_SERVER);
                         if (r < 0)
-                                return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for SIP server: %m");
+                                return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for SIP server: %m");
                 }
 
                 if (link->network->dhcp_use_timezone) {
                         r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_NEW_TZDB_TIMEZONE);
                         if (r < 0)
-                                return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for timezone: %m");
+                                return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for timezone: %m");
                 }
 
                 SET_FOREACH(request_options, link->network->dhcp_request_options) {
@@ -1550,7 +1540,7 @@ int dhcp4_configure(Link *link) {
 
                         r = sd_dhcp_client_set_request_option(link->dhcp_client, option);
                         if (r < 0)
-                                return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for '%u': %m", option);
+                                return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for '%u': %m", option);
                 }
 
                 ORDERED_HASHMAP_FOREACH(send_option, link->network->dhcp_client_send_options) {
@@ -1558,7 +1548,7 @@ int dhcp4_configure(Link *link) {
                         if (r == -EEXIST)
                                 continue;
                         if (r < 0)
-                                return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set send option: %m");
+                                return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set send option: %m");
                 }
 
                 ORDERED_HASHMAP_FOREACH(send_option, link->network->dhcp_client_send_vendor_options) {
@@ -1566,7 +1556,7 @@ int dhcp4_configure(Link *link) {
                         if (r == -EEXIST)
                                 continue;
                         if (r < 0)
-                                return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set send option: %m");
+                                return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set send option: %m");
                 }
 
                 r = dhcp4_set_hostname(link);
@@ -1577,49 +1567,49 @@ int dhcp4_configure(Link *link) {
                         r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client,
                                                                        link->network->dhcp_vendor_class_identifier);
                         if (r < 0)
-                                return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set vendor class identifier: %m");
+                                return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set vendor class identifier: %m");
                 }
 
                 if (link->network->dhcp_mudurl) {
                         r = sd_dhcp_client_set_mud_url(link->dhcp_client, link->network->dhcp_mudurl);
                         if (r < 0)
-                                return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set MUD URL: %m");
+                                return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set MUD URL: %m");
                 }
 
                 if (link->network->dhcp_user_class) {
                         r = sd_dhcp_client_set_user_class(link->dhcp_client, link->network->dhcp_user_class);
                         if (r < 0)
-                                return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set user class: %m");
+                                return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set user class: %m");
                 }
         }
 
         if (link->network->dhcp_client_port > 0) {
                 r = sd_dhcp_client_set_client_port(link->dhcp_client, link->network->dhcp_client_port);
                 if (r < 0)
-                        return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set listen port: %m");
+                        return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set listen port: %m");
         }
 
         if (link->network->dhcp_max_attempts > 0) {
                 r = sd_dhcp_client_set_max_attempts(link->dhcp_client, link->network->dhcp_max_attempts);
                 if (r < 0)
-                        return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set max attempts: %m");
+                        return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set max attempts: %m");
         }
 
         if (link->network->dhcp_ip_service_type > 0) {
                 r = sd_dhcp_client_set_service_type(link->dhcp_client, link->network->dhcp_ip_service_type);
                 if (r < 0)
-                        return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set IP service type: %m");
+                        return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set IP service type: %m");
         }
 
         if (link->network->dhcp_fallback_lease_lifetime > 0) {
                 r = sd_dhcp_client_set_fallback_lease_lifetime(link->dhcp_client, link->network->dhcp_fallback_lease_lifetime);
                 if (r < 0)
-                        return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed set to lease lifetime: %m");
+                        return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed set to lease lifetime: %m");
         }
 
         r = dhcp4_set_request_address(link);
         if (r < 0)
-                return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set initial DHCPv4 address: %m");
+                return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set initial DHCPv4 address: %m");
 
         return dhcp4_set_client_identifier(link);
 }
@@ -1642,17 +1632,83 @@ int dhcp4_update_mac(Link *link) {
 }
 
 int dhcp4_start(Link *link) {
+        int r;
+
         assert(link);
 
         if (!link->dhcp_client)
                 return 0;
 
+        if (!link_has_carrier(link))
+                return 0;
+
         if (sd_dhcp_client_is_running(link->dhcp_client) > 0)
                 return 0;
 
-        log_link_debug(link, "Acquiring DHCPv4 lease");
+        r = sd_dhcp_client_start(link->dhcp_client);
+        if (r < 0)
+                return r;
 
-        return sd_dhcp_client_start(link->dhcp_client);
+        return 1;
+}
+
+static int dhcp4_configure_duid(Link *link) {
+        assert(link);
+
+        if (!IN_SET(link->network->dhcp_client_identifier, DHCP_CLIENT_ID_DUID, DHCP_CLIENT_ID_DUID_ONLY))
+                return 1;
+
+        return dhcp_configure_duid(link, link_get_dhcp4_duid(link));
+}
+
+int request_process_dhcp4_client(Request *req) {
+        Link *link;
+        int r;
+
+        assert(req);
+        assert(req->link);
+        assert(req->type == REQUEST_TYPE_DHCP4_CLIENT);
+
+        link = req->link;
+
+        if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
+                return 0;
+
+        r = dhcp4_configure_duid(link);
+        if (r <= 0)
+                return r;
+
+        r = dhcp4_configure(req->link);
+        if (r < 0)
+                return log_link_warning_errno(link, r, "Failed to configure DHCPv4 client: %m");
+
+        r = dhcp4_start(link);
+        if (r < 0)
+                return log_link_warning_errno(link, r, "Failed to start DHCPv4 client: %m");
+
+        log_link_debug(link, "DHCPv4 client is configured%s.",
+                       r > 0 ? ", acquiring DHCPv4 lease" : "");
+
+        return 1;
+}
+
+int link_request_dhcp4_client(Link *link) {
+        int r;
+
+        assert(link);
+
+        if (!link_dhcp4_enabled(link))
+                return 0;
+
+        if (link->dhcp_client)
+                return 0;
+
+        r = link_queue_request(link, REQUEST_TYPE_DHCP4_CLIENT, NULL, false, NULL, NULL, NULL);
+        if (r < 0)
+                return log_link_warning_errno(link, r, "Failed to request configuring of the DHCPv4 client: %m");
+
+        log_link_debug(link, "Requested configuring of the DHCPv4 client.");
+        return 0;
 }
 
 int config_parse_dhcp_max_attempts(
@@ -1788,7 +1844,8 @@ int config_parse_dhcp_ip_service_type(
         return 0;
 }
 
-int config_parse_dhcp_fallback_lease_lifetime(const char *unit,
+int config_parse_dhcp_fallback_lease_lifetime(
+                const char *unit,
                 const char *filename,
                 unsigned line,
                 const char *section,
@@ -1798,6 +1855,7 @@ int config_parse_dhcp_fallback_lease_lifetime(const char *unit,
                 const char *rvalue,
                 void *data,
                 void *userdata) {
+
         Network *network = userdata;
         uint32_t k;
 
@@ -1826,6 +1884,39 @@ int config_parse_dhcp_fallback_lease_lifetime(const char *unit,
         return 0;
 }
 
+int config_parse_dhcp_label(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        char **label = data;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (isempty(rvalue)) {
+                *label = mfree(*label);
+                return 0;
+        }
+
+        if (!address_label_valid(rvalue)) {
+                log_syntax(unit, LOG_WARNING, filename, line, 0,
+                           "Address label is too long or invalid, ignoring assignment: %s", rvalue);
+                return 0;
+        }
+
+        return free_and_strdup_warn(label, rvalue);
+}
+
 static const char* const dhcp_client_identifier_table[_DHCP_CLIENT_ID_MAX] = {
         [DHCP_CLIENT_ID_MAC] = "mac",
         [DHCP_CLIENT_ID_DUID] = "duid",