summaryrefslogtreecommitdiffstats
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.c107
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",