diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c index d35e3e2ce1..b3b134d650 100644 --- a/src/libsystemd-network/network-internal.c +++ b/src/libsystemd-network/network-internal.c @@ -371,36 +371,6 @@ int config_parse_hwaddrs(const char *unit, return 0; } -int config_parse_iaid(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) { - uint32_t iaid; - int r; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - r = safe_atou32(rvalue, &iaid); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, - "Unable to read IAID, ignoring assignment: %s", rvalue); - return 0; - } - - *((uint32_t *)data) = iaid; - - return 0; -} - int config_parse_bridge_port_priority( const char *unit, const char *filename, diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h index 45020c2bcf..0c8da848c1 100644 --- a/src/libsystemd-network/network-internal.h +++ b/src/libsystemd-network/network-internal.h @@ -35,7 +35,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_hwaddr); CONFIG_PARSER_PROTOTYPE(config_parse_hwaddrs); CONFIG_PARSER_PROTOTYPE(config_parse_ifnames); CONFIG_PARSER_PROTOTYPE(config_parse_ifalias); -CONFIG_PARSER_PROTOTYPE(config_parse_iaid); CONFIG_PARSER_PROTOTYPE(config_parse_bridge_port_priority); int net_get_unique_predictable_data(sd_device *device, uint64_t *result); diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 842aeaa6b1..3bdd584bb5 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -345,8 +345,9 @@ int sd_dhcp_client_set_client_id( */ static int dhcp_client_set_iaid_duid_internal( sd_dhcp_client *client, + bool iaid_append, + bool iaid_set, uint32_t iaid, - bool append_iaid, uint16_t duid_type, const void *duid, size_t duid_len, @@ -368,17 +369,17 @@ static int dhcp_client_set_iaid_duid_internal( zero(client->client_id); client->client_id.type = 255; - if (append_iaid) { - /* If IAID is not configured, generate it. */ - if (iaid == 0) { + if (iaid_append) { + if (iaid_set) + client->client_id.ns.iaid = htobe32(iaid); + else { r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len, true, &client->client_id.ns.iaid); if (r < 0) return r; - } else - client->client_id.ns.iaid = htobe32(iaid); + } } if (duid != NULL) { @@ -418,10 +419,10 @@ static int dhcp_client_set_iaid_duid_internal( } client->client_id_len = sizeof(client->client_id.type) + len + - (append_iaid ? sizeof(client->client_id.ns.iaid) : 0); + (iaid_append ? sizeof(client->client_id.ns.iaid) : 0); if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) { - log_dhcp_client(client, "Configured %sDUID, restarting.", append_iaid ? "IAID+" : ""); + log_dhcp_client(client, "Configured %sDUID, restarting.", iaid_append ? "IAID+" : ""); client_stop(client, SD_DHCP_CLIENT_EVENT_STOP); sd_dhcp_client_start(client); } @@ -431,18 +432,20 @@ static int dhcp_client_set_iaid_duid_internal( int sd_dhcp_client_set_iaid_duid( sd_dhcp_client *client, + bool iaid_set, uint32_t iaid, uint16_t duid_type, const void *duid, size_t duid_len) { - return dhcp_client_set_iaid_duid_internal(client, iaid, true, duid_type, duid, duid_len, 0); + return dhcp_client_set_iaid_duid_internal(client, true, iaid_set, iaid, duid_type, duid, duid_len, 0); } int sd_dhcp_client_set_iaid_duid_llt( sd_dhcp_client *client, + bool iaid_set, uint32_t iaid, usec_t llt_time) { - return dhcp_client_set_iaid_duid_internal(client, iaid, true, DUID_TYPE_LLT, NULL, 0, llt_time); + return dhcp_client_set_iaid_duid_internal(client, true, iaid_set, iaid, DUID_TYPE_LLT, NULL, 0, llt_time); } int sd_dhcp_client_set_duid( @@ -450,13 +453,13 @@ int sd_dhcp_client_set_duid( uint16_t duid_type, const void *duid, size_t duid_len) { - return dhcp_client_set_iaid_duid_internal(client, 0, false, duid_type, duid, duid_len, 0); + return dhcp_client_set_iaid_duid_internal(client, false, false, 0, duid_type, duid, duid_len, 0); } int sd_dhcp_client_set_duid_llt( sd_dhcp_client *client, usec_t llt_time) { - return dhcp_client_set_iaid_duid_internal(client, 0, false, DUID_TYPE_LLT, NULL, 0, llt_time); + return dhcp_client_set_iaid_duid_internal(client, false, false, 0, DUID_TYPE_LLT, NULL, 0, llt_time); } int sd_dhcp_client_set_hostname( diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 555ae5f5ec..8ff4585f63 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -56,7 +56,7 @@ struct sd_dhcp6_client { struct sd_dhcp6_lease *lease; int fd; bool information_request; - bool has_iaid; + bool iaid_set; be16_t *req_opts; size_t req_opts_allocated; size_t req_opts_len; @@ -268,7 +268,7 @@ int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid) { client->ia_na.ia_na.id = htobe32(iaid); client->ia_pd.ia_pd.id = htobe32(iaid); - client->has_iaid = true; + client->iaid_set = true; return 0; } @@ -792,7 +792,7 @@ static int client_ensure_iaid(sd_dhcp6_client *client) { assert(client); - if (client->has_iaid) + if (client->iaid_set) return 0; r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len, true, &iaid); @@ -801,7 +801,7 @@ static int client_ensure_iaid(sd_dhcp6_client *client) { client->ia_na.ia_na.id = iaid; client->ia_pd.ia_pd.id = iaid; - client->has_iaid = true; + client->iaid_set = true; return 0; } diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 31dbea9420..980d49e4ff 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -670,10 +670,12 @@ int dhcp4_set_client_identifier(Link *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, diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 4b5c4b8b4b..ed6b9df72b 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -655,9 +655,11 @@ int dhcp6_configure(Link *link) { if (r < 0) return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set MAC address: %m"); - r = sd_dhcp6_client_set_iaid(client, link->network->iaid); - if (r < 0) - return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set IAID: %m"); + if (link->network->iaid_set) { + r = sd_dhcp6_client_set_iaid(client, link->network->iaid); + if (r < 0) + return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set IAID: %m"); + } duid = link_get_duid(link); if (duid->type == DUID_TYPE_LLT && duid->raw_data_len == 0) diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index d575740e83..d73e85cf25 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -3637,10 +3637,12 @@ int link_update(Link *link, sd_netlink_message *m) { if (r < 0) return log_link_warning_errno(link, r, "Could not update MAC address in DHCPv6 client: %m"); - r = sd_dhcp6_client_set_iaid(link->dhcp6_client, - link->network->iaid); - if (r < 0) - return log_link_warning_errno(link, r, "Could not update DHCPv6 IAID: %m"); + if (link->network->iaid_set) { + r = sd_dhcp6_client_set_iaid(link->dhcp6_client, + link->network->iaid); + if (r < 0) + return log_link_warning_errno(link, r, "Could not update DHCPv6 IAID: %m"); + } r = sd_dhcp6_client_set_duid(link->dhcp6_client, duid->type, diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 00605c0b92..48d8ae52fa 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -141,7 +141,7 @@ DHCP.DUIDRawData, config_parse_duid_rawdata, DHCP.RouteMetric, config_parse_unsigned, 0, offsetof(Network, dhcp_route_metric) DHCP.RouteTable, config_parse_dhcp_route_table, 0, 0 DHCP.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone) -DHCP.IAID, config_parse_iaid, 0, offsetof(Network, iaid) +DHCP.IAID, config_parse_iaid, 0, 0 DHCP.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port) DHCP.RapidCommit, config_parse_bool, 0, offsetof(Network, rapid_commit) DHCP.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 6f14fb270e..62dc6a0bf7 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -1473,3 +1473,35 @@ static const char* const lldp_mode_table[_LLDP_MODE_MAX] = { }; DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode, LLDPMode, LLDP_MODE_YES); + +int config_parse_iaid(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; + uint32_t iaid; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(network); + + r = safe_atou32(rvalue, &iaid); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Unable to read IAID, ignoring assignment: %s", rvalue); + return 0; + } + + network->iaid = iaid; + network->iaid_set = true; + + return 0; +} diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 7f64c38839..3a72c5bd9a 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -227,6 +227,8 @@ struct Network { uint32_t iaid; DUID duid; + bool iaid_set; + bool required_for_online; /* Is this network required to be considered online? */ LLDPMode lldp_mode; /* LLDP reception */ @@ -306,6 +308,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_lldp_mode); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_route_table); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_user_class); CONFIG_PARSER_PROTOTYPE(config_parse_ntp); +CONFIG_PARSER_PROTOTYPE(config_parse_iaid); /* Legacy IPv4LL support */ CONFIG_PARSER_PROTOTYPE(config_parse_ipv4ll); diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h index e388552064..bd0d429df6 100644 --- a/src/systemd/sd-dhcp-client.h +++ b/src/systemd/sd-dhcp-client.h @@ -23,6 +23,7 @@ #include #include #include +#include #include "sd-dhcp-lease.h" #include "sd-event.h" @@ -127,12 +128,14 @@ int sd_dhcp_client_set_client_id( size_t data_len); int sd_dhcp_client_set_iaid_duid( sd_dhcp_client *client, + bool iaid_set, uint32_t iaid, uint16_t duid_type, const void *duid, size_t duid_len); int sd_dhcp_client_set_iaid_duid_llt( sd_dhcp_client *client, + bool iaid_set, uint32_t iaid, uint64_t llt_time); int sd_dhcp_client_set_duid(