summaryrefslogtreecommitdiff
path: root/src/network/networkd-dhcp4.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/networkd-dhcp4.c')
-rw-r--r--src/network/networkd-dhcp4.c185
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);
}