mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-10-27 01:55:32 +03:00
network: fix handling of uninitialized and zero IAID setting
An earlier commit0e408b82b
(dhcp6-client: handle IAID with value zero) introduced a flag to sd_dhcp6_client to distinguish between an unset IAID and a value set to zero. However, that was not sufficient and broke leaving the setting uninitialized in networkd configuration. The configuration parsing also must distinguish between the default, unset value and an explict zero configuration. Fixes:0e408b82b8
This commit is contained in:
parent
1d4c6f5bef
commit
8217ed5ec3
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <net/ethernet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#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(
|
||||
|
Loading…
Reference in New Issue
Block a user