diff options
Diffstat (limited to 'src/network/networkd-dhcp4.c')
-rw-r--r-- | src/network/networkd-dhcp4.c | 107 |
1 files changed, 100 insertions, 7 deletions
diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 19743d2037..3911753c1c 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -2,6 +2,7 @@ #include <netinet/in.h> #include <linux/if.h> +#include <linux/if_arp.h> #include "alloc-util.h" #include "hostname-util.h" @@ -210,7 +211,7 @@ static int link_set_dhcp_routes(Link *link) { * the addresses now, let's not configure the routes either. */ return 0; - r = set_ensure_allocated(&link->dhcp_routes, &route_full_hash_ops); + r = set_ensure_allocated(&link->dhcp_routes, &route_hash_ops); if (r < 0) return log_oom(); @@ -252,7 +253,7 @@ static int link_set_dhcp_routes(Link *link) { if (n == -ENODATA) log_link_debug_errno(link, n, "DHCP: No routes received from DHCP server: %m"); else if (n < 0) - log_link_debug_errno(link, n, "DHCP error: could not get routes: %m"); + log_link_debug_errno(link, n, "DHCP: could not get routes: %m"); for (i = 0; i < n; i++) { switch (sd_dhcp_route_get_option(static_routes[i])) { @@ -632,7 +633,7 @@ static int dhcp_lease_lost(Link *link) { assert(link); assert(link->dhcp_lease); - log_link_warning(link, "DHCP lease lost"); + log_link_info(link, "DHCP lease lost"); link->dhcp4_configured = false; @@ -968,10 +969,10 @@ static int dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) { return 0; } - if (link->network->dhcp_send_release) - (void) sd_dhcp_client_send_release(client); - if (link->dhcp_lease) { + if (link->network->dhcp_send_release) + (void) sd_dhcp_client_send_release(client); + r = dhcp_lease_lost(link); if (r < 0) { link_enter_failed(link); @@ -1182,6 +1183,8 @@ int dhcp4_set_client_identifier(Link *link) { } int dhcp4_configure(Link *link) { + void *request_options; + Iterator i; int r; assert(link); @@ -1261,12 +1264,31 @@ int dhcp4_configure(Link *link) { return log_link_error_errno(link, r, "DHCP4 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_error_errno(link, r, "DHCP4 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_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for timezone: %m"); } + SET_FOREACH(request_options, link->network->dhcp_request_options, i) { + uint32_t option = PTR_TO_UINT32(request_options); + + r = sd_dhcp_client_set_request_option(link->dhcp_client, option); + if (r == -EEXIST) { + log_link_debug(link, "DHCP4 CLIENT: Failed to set request flag for '%u' already exists, ignoring.", option); + continue; + } + + if (r < 0) + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for '%u': %m", option); + } + r = dhcp4_set_hostname(link); if (r < 0) return r; @@ -1296,7 +1318,12 @@ int dhcp4_configure(Link *link) { return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set max attempts: %m"); } - return dhcp4_set_client_identifier(link); + if (link->network->ip_service_type > 0) { + r = sd_dhcp_client_set_service_type(link->dhcp_client, link->network->ip_service_type); + if (r < 0) + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set ip service type: %m"); + } + return dhcp4_set_client_identifier(link); } int config_parse_dhcp_max_attempts( @@ -1461,6 +1488,72 @@ int config_parse_dhcp_user_class( return 0; } +int config_parse_dhcp_request_options( + 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) { + + Network *network = data; + const char *p; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (isempty(rvalue)) { + network->dhcp_request_options = set_free(network->dhcp_request_options); + return 0; + } + + for (p = rvalue;;) { + _cleanup_free_ char *n = NULL; + uint32_t i; + + r = extract_first_word(&p, &n, NULL, 0); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to parse DHCP request option, ignoring assignment: %s", + rvalue); + return 0; + } + if (r == 0) + return 0; + + r = safe_atou32(n, &i); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "DHCP request option is invalid, ignoring assignment: %s", n); + continue; + } + + if (i < 1 || i >= 255) { + log_syntax(unit, LOG_ERR, filename, line, r, + "DHCP request option is invalid, valid range is 1-254, ignoring assignment: %s", n); + continue; + } + + r = set_ensure_allocated(&network->dhcp_request_options, NULL); + if (r < 0) + return log_oom(); + + r = set_put(network->dhcp_request_options, UINT32_TO_PTR(i)); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to store DHCP request option '%s', ignoring assignment: %m", n); + } + + return 0; +} + static const char* const dhcp_client_identifier_table[_DHCP_CLIENT_ID_MAX] = { [DHCP_CLIENT_ID_MAC] = "mac", [DHCP_CLIENT_ID_DUID] = "duid", |