summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2022-12-12 20:29:30 +0100
committerThomas Haller <thaller@redhat.com>2022-12-19 11:29:11 +0100
commitbea72c3d6de5a294a89fc659e475fe9db0abf6ac (patch)
tree0ece4cbbb6745823ae8b0b6d462cde470ff3ecaf
parent28d7f9b7c4787db101e30a549c6b05aad2ce89c3 (diff)
downloadNetworkManager-bea72c3d6de5a294a89fc659e475fe9db0abf6ac.tar.gz
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. Commit 58287cbcc0c8 ('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: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
-rw-r--r--src/core/dhcp/nm-dhcp-dhclient-utils.c2
-rw-r--r--src/core/dhcp/nm-dhcp-dhclient.c29
2 files changed, 23 insertions, 8 deletions
diff --git a/src/core/dhcp/nm-dhcp-dhclient-utils.c b/src/core/dhcp/nm-dhcp-dhclient-utils.c
index 74e6b90507..72dbc7885e 100644
--- a/src/core/dhcp/nm-dhcp-dhclient-utils.c
+++ b/src/core/dhcp/nm-dhcp-dhclient-utils.c
@@ -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);
diff --git a/src/core/dhcp/nm-dhcp-dhclient.c b/src/core/dhcp/nm-dhcp-dhclient.c
index 92b4332a74..34aa7d44e0 100644
--- a/src/core/dhcp/nm-dhcp-dhclient.c
+++ b/src/core/dhcp/nm-dhcp-dhclient.c
@@ -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,18 +633,18 @@ 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);
- NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE(self);
+ NMDhcpClient *client = NM_DHCP_CLIENT(self);
+ NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE(self);
const NMDhcpClientConfig *client_config;
GBytes *duid = NULL;
gs_free char *leasefile = NULL;