diff options
Diffstat (limited to 'src/network/networkd-dhcp4.c')
-rw-r--r-- | src/network/networkd-dhcp4.c | 185 |
1 files changed, 106 insertions, 79 deletions
diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 34c1f63568..980d49e4ff 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -4,7 +4,6 @@ #include <linux/if.h> #include "alloc-util.h" -#include "dhcp-lease-internal.h" #include "hostname-util.h" #include "parse-util.h" #include "netdev/vrf.h" @@ -15,9 +14,7 @@ #include "string-util.h" #include "sysctl-util.h" -static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m, - void *userdata) { - _cleanup_(link_unrefp) Link *link = userdata; +static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { int r; assert(link); @@ -81,15 +78,20 @@ static int link_set_dhcp_routes(Link *link) { return log_link_warning_errno(link, r, "DHCP error: could not get address: %m"); n = sd_dhcp_lease_get_routes(link->dhcp_lease, &static_routes); - if (n < 0) + 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"); for (i = 0; i < n; i++) { - if (static_routes[i]->option == SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE) + switch (sd_dhcp_route_get_option(static_routes[i])) { + case SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE: classless_route = true; - - if (static_routes[i]->option == SD_DHCP_OPTION_STATIC_ROUTE) + break; + case SD_DHCP_OPTION_STATIC_ROUTE: static_route = true; + break; + } } for (i = 0; i < n; i++) { @@ -97,7 +99,8 @@ static int link_set_dhcp_routes(Link *link) { /* if the DHCP server returns both a Classless Static Routes option and a Static Routes option, the DHCP client MUST ignore the Static Routes option. */ - if (classless_route && static_routes[i]->option == SD_DHCP_OPTION_STATIC_ROUTE) + if (classless_route && + sd_dhcp_route_get_option(static_routes[i]) != SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE) continue; r = route_new(&route); @@ -122,7 +125,7 @@ static int link_set_dhcp_routes(Link *link) { r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway); if (r == -ENODATA) - log_link_info_errno(link, r, "DHCP: No routes received from DHCP server: %m"); + log_link_info_errno(link, r, "DHCP: No gateway received from DHCP server: %m"); else if (r < 0) log_link_warning_errno(link, r, "DHCP error: could not get gateway: %m"); @@ -211,8 +214,7 @@ static int dhcp_lease_lost(Link *link) { assert_se(sd_dhcp_route_get_destination(routes[i], &route->dst.in) >= 0); assert_se(sd_dhcp_route_get_destination_prefix_length(routes[i], &route->dst_prefixlen) >= 0); - route_remove(route, link, - link_route_remove_handler); + route_remove(route, link, NULL); } } } @@ -232,8 +234,7 @@ static int dhcp_lease_lost(Link *link) { route_gw->dst_prefixlen = 32; route_gw->scope = RT_SCOPE_LINK; - route_remove(route_gw, link, - link_route_remove_handler); + route_remove(route_gw, link, NULL); } r = route_new(&route); @@ -241,8 +242,7 @@ static int dhcp_lease_lost(Link *link) { route->family = AF_INET; route->gw.in = gateway; - route_remove(route, link, - link_route_remove_handler); + route_remove(route, link, NULL); } } @@ -256,7 +256,7 @@ static int dhcp_lease_lost(Link *link) { address->in_addr.in = addr; address->prefixlen = prefixlen; - address_remove(address, link, link_address_remove_handler); + address_remove(address, link, NULL); } } @@ -298,9 +298,7 @@ static int dhcp_lease_lost(Link *link) { return 0; } -static int dhcp4_address_handler(sd_netlink *rtnl, sd_netlink_message *m, - void *userdata) { - _cleanup_(link_unrefp) Link *link = userdata; +static int dhcp4_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { int r; assert(link); @@ -501,10 +499,8 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) { if (!link->network->dhcp_critical) { r = sd_dhcp_lease_get_lifetime(link->dhcp_lease, &lifetime); - if (r < 0) { - log_link_warning_errno(link, r, "DHCP error: no lifetime: %m"); - return r; - } + if (r < 0) + return log_link_warning_errno(link, r, "DHCP error: no lifetime: %m"); } r = dhcp4_update_address(link, &address, &netmask, lifetime); @@ -597,7 +593,14 @@ static int dhcp4_set_hostname(Link *link) { hn = hostname; } - return sd_dhcp_client_set_hostname(link->dhcp_client, hn); + 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_warning_errno(link, r, "DHCP4 CLIENT: Failed to set hostname from kernel hostname, ignoring: %m"); + else if (r < 0) + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set hostname: %m"); + + return 0; } static bool promote_secondaries_enabled(const char *ifname) { @@ -653,6 +656,65 @@ int dhcp4_set_promote_secondaries(Link *link) { return 0; } +int dhcp4_set_client_identifier(Link *link) { + int r; + + assert(link); + assert(link->network); + assert(link->dhcp_client); + + switch (link->network->dhcp_client_identifier) { + case DHCP_CLIENT_ID_DUID: { + /* If configured, apply user specified DUID and IAID */ + const DUID *duid = link_get_duid(link); + + if (duid->type == DUID_TYPE_LLT && duid->raw_data_len == 0) + r = sd_dhcp_client_set_iaid_duid_llt(link->dhcp_client, + link->network->iaid_set, + link->network->iaid, + duid->llt_time); + else + r = sd_dhcp_client_set_iaid_duid(link->dhcp_client, + link->network->iaid_set, + link->network->iaid, + duid->type, + duid->raw_data_len > 0 ? duid->raw_data : NULL, + duid->raw_data_len); + if (r < 0) + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set IAID+DUID: %m"); + break; + } + case DHCP_CLIENT_ID_DUID_ONLY: { + /* If configured, apply user specified DUID */ + const DUID *duid = link_get_duid(link); + + if (duid->type == DUID_TYPE_LLT && duid->raw_data_len == 0) + r = sd_dhcp_client_set_duid_llt(link->dhcp_client, + duid->llt_time); + else + r = sd_dhcp_client_set_duid(link->dhcp_client, + duid->type, + duid->raw_data_len > 0 ? duid->raw_data : NULL, + duid->raw_data_len); + if (r < 0) + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set DUID: %m"); + break; + } + case DHCP_CLIENT_ID_MAC: + r = sd_dhcp_client_set_client_id(link->dhcp_client, + ARPHRD_ETHER, + (const uint8_t *) &link->mac, + sizeof(link->mac)); + if (r < 0) + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set client ID: %m"); + break; + default: + assert_not_reached("Unknown client identifier type."); + } + + return 0; +} + int dhcp4_configure(Link *link) { int r; @@ -662,44 +724,46 @@ int dhcp4_configure(Link *link) { if (!link->dhcp_client) { r = sd_dhcp_client_new(&link->dhcp_client, link->network->dhcp_anonymize); + if (r == -ENOMEM) + return log_oom(); if (r < 0) - return r; + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to create DHCP4 client: %m"); } r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0); if (r < 0) - return r; + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to attach event: %m"); r = sd_dhcp_client_set_mac(link->dhcp_client, (const uint8_t *) &link->mac, sizeof (link->mac), ARPHRD_ETHER); if (r < 0) - return r; + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set MAC address: %m"); r = sd_dhcp_client_set_ifindex(link->dhcp_client, link->ifindex); if (r < 0) - return r; + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set ifindex: %m"); r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp4_handler, link); if (r < 0) - return r; + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set callback: %m"); r = sd_dhcp_client_set_request_broadcast(link->dhcp_client, link->network->dhcp_broadcast); if (r < 0) - return r; + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for broadcast: %m"); if (link->mtu) { r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu); if (r < 0) - return r; + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set MTU: %m"); } 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 r; + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for MTU: %m"); } /* NOTE: even if this variable is called "use", it also "sends" PRL @@ -711,23 +775,24 @@ int dhcp4_configure(Link *link) { r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_STATIC_ROUTE); if (r < 0) - return r; + return log_link_error_errno(link, r, "DHCP4 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 r; + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for classless static route: %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 r; + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for NTP 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 r; + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for timezone: %m"); } r = dhcp4_set_hostname(link); @@ -738,58 +803,20 @@ 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 r; + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set vendor class identifier: %m"); } if (link->network->dhcp_user_class) { r = sd_dhcp_client_set_user_class(link->dhcp_client, (const char **) link->network->dhcp_user_class); if (r < 0) - return r; + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set user class: %m"); } if (link->network->dhcp_client_port) { r = sd_dhcp_client_set_client_port(link->dhcp_client, link->network->dhcp_client_port); if (r < 0) - return r; + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set listen port: %m"); } - switch (link->network->dhcp_client_identifier) { - case DHCP_CLIENT_ID_DUID: { - /* If configured, apply user specified DUID and/or IAID */ - const DUID *duid = link_duid(link); - - r = sd_dhcp_client_set_iaid_duid(link->dhcp_client, - link->network->iaid, - duid->type, - duid->raw_data_len > 0 ? duid->raw_data : NULL, - duid->raw_data_len); - if (r < 0) - return r; - break; - } - case DHCP_CLIENT_ID_DUID_ONLY: { - /* If configured, apply user specified DUID */ - const DUID *duid = link_duid(link); - - r = sd_dhcp_client_set_duid(link->dhcp_client, - duid->type, - duid->raw_data_len > 0 ? duid->raw_data : NULL, - duid->raw_data_len); - if (r < 0) - return r; - break; - } - case DHCP_CLIENT_ID_MAC: - r = sd_dhcp_client_set_client_id(link->dhcp_client, - ARPHRD_ETHER, - (const uint8_t *) &link->mac, - sizeof(link->mac)); - if (r < 0) - return r; - break; - default: - assert_not_reached("Unknown client identifier type."); - } - - return 0; + return dhcp4_set_client_identifier(link); } |