dhcp: fix "ipv6.dhcp-duid=lease" for dhclient DHCPv6 client
The "lease" mode is unusual, because it means to prefer the DUID configuration from the DHCP plugin over the explicit configuration in NetworkManager. It is only for the DHCPv6 DUID and not for the IPv4 client-id. It also is only special for the "dhclient" plugin, because with the internal plugin, this always corresponds to a generated, stable DUID. Commit58287cbcc0
('core: rework IP configuration in NetworkManager using layer 3 configuration') broke this. The commit refactored the code to track the effective-client-id separately. Previously, the client-id which was read from the dhclient lease, was overwriting NMDhcpClient.client_id. But with the refactor, it broke because nm_dhcp_client_get_effective_client_id() was never called. Fix that. Fixes:58287cbcc0
('core: rework IP configuration in NetworkManager using layer 3 configuration')
This commit is contained in:
@@ -399,6 +399,7 @@ nm_dhcp_dhclient_create_config(const char *interface,
|
||||
if (out_new_client_id)
|
||||
nm_clear_pointer(out_new_client_id, g_bytes_unref);
|
||||
NM_SET_OUT(out_new_client_id, read_client_id(p));
|
||||
/* fall-through. We keep the line... */
|
||||
}
|
||||
|
||||
/* Override config file hostname and use one from the connection */
|
||||
@@ -656,6 +657,7 @@ nm_dhcp_dhclient_save_duid(const char *leasefile, GBytes *duid, GError **error)
|
||||
gsize len = 0;
|
||||
|
||||
g_return_val_if_fail(leasefile != NULL, FALSE);
|
||||
|
||||
if (!duid) {
|
||||
nm_utils_error_set_literal(error, NM_UTILS_ERROR_UNKNOWN, "missing duid");
|
||||
g_return_val_if_reached(FALSE);
|
||||
|
@@ -82,6 +82,10 @@ G_DEFINE_TYPE(NMDhcpDhclient, nm_dhcp_dhclient, NM_TYPE_DHCP_CLIENT)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static GBytes *read_duid_from_lease(NMDhcpDhclient *self);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static const char *
|
||||
nm_dhcp_dhclient_get_path(void)
|
||||
{
|
||||
@@ -332,6 +336,7 @@ static gboolean
|
||||
dhclient_start(NMDhcpClient *client,
|
||||
gboolean set_mode,
|
||||
gboolean release,
|
||||
gboolean set_duid,
|
||||
pid_t *out_pid,
|
||||
GError **error)
|
||||
{
|
||||
@@ -410,8 +415,10 @@ dhclient_start(NMDhcpClient *client,
|
||||
}
|
||||
|
||||
/* Save the DUID to the leasefile dhclient will actually use */
|
||||
if (addr_family == AF_INET6) {
|
||||
if (!nm_dhcp_dhclient_save_duid(priv->lease_file, client_config->client_id, &local)) {
|
||||
if (set_duid && addr_family == AF_INET6) {
|
||||
if (!nm_dhcp_dhclient_save_duid(priv->lease_file,
|
||||
nm_dhcp_client_get_effective_client_id(client),
|
||||
&local)) {
|
||||
nm_utils_error_set(error,
|
||||
NM_UTILS_ERROR_UNKNOWN,
|
||||
"failed to save DUID to '%s': %s",
|
||||
@@ -560,6 +567,7 @@ ip6_start(NMDhcpClient *client, const struct in6_addr *ll_addr, GError **error)
|
||||
NMDhcpDhclient *self = NM_DHCP_DHCLIENT(client);
|
||||
NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE(self);
|
||||
const NMDhcpClientConfig *config;
|
||||
gs_unref_bytes GBytes *effective_client_id = NULL;
|
||||
|
||||
config = nm_dhcp_client_get_config(client);
|
||||
|
||||
@@ -586,7 +594,12 @@ ip6_start(NMDhcpClient *client, const struct in6_addr *ll_addr, GError **error)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return dhclient_start(client, TRUE, FALSE, NULL, error);
|
||||
nm_assert(config->client_id);
|
||||
if (!config->v6.enforce_duid)
|
||||
effective_client_id = read_duid_from_lease(self);
|
||||
nm_dhcp_client_set_effective_client_id(client, effective_client_id ?: config->client_id);
|
||||
|
||||
return dhclient_start(client, TRUE, FALSE, TRUE, NULL, error);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -620,17 +633,17 @@ stop(NMDhcpClient *client, gboolean release)
|
||||
if (release) {
|
||||
pid_t rpid = -1;
|
||||
|
||||
if (dhclient_start(client, FALSE, TRUE, &rpid, NULL)) {
|
||||
if (dhclient_start(client, FALSE, TRUE, FALSE, &rpid, NULL)) {
|
||||
/* Wait a few seconds for the release to happen */
|
||||
nm_dhcp_client_stop_pid(rpid, nm_dhcp_client_get_iface(client));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_nm_unused static GBytes *
|
||||
get_duid(NMDhcpClient *client)
|
||||
static GBytes *
|
||||
read_duid_from_lease(NMDhcpDhclient *self)
|
||||
{
|
||||
NMDhcpDhclient *self = NM_DHCP_DHCLIENT(client);
|
||||
NMDhcpClient *client = NM_DHCP_CLIENT(self);
|
||||
NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE(self);
|
||||
const NMDhcpClientConfig *client_config;
|
||||
GBytes *duid = NULL;
|
||||
|
Reference in New Issue
Block a user