summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dhcp/nm-dhcp-client.c13
-rw-r--r--src/dhcp/nm-dhcp-client.h3
-rw-r--r--src/dhcp/nm-dhcp-systemd.c32
3 files changed, 39 insertions, 9 deletions
diff --git a/src/dhcp/nm-dhcp-client.c b/src/dhcp/nm-dhcp-client.c
index 6e4c28c122..6eec21a9c2 100644
--- a/src/dhcp/nm-dhcp-client.c
+++ b/src/dhcp/nm-dhcp-client.c
@@ -805,6 +805,15 @@ maybe_add_option (NMDhcpClient *self,
}
}
+void
+nm_dhcp_client_emit_ipv6_prefix_delegated (NMDhcpClient *self,
+ const NMPlatformIP6Address *prefix)
+{
+ g_signal_emit (G_OBJECT (self),
+ signals[SIGNAL_PREFIX_DELEGATED], 0,
+ prefix);
+}
+
gboolean
nm_dhcp_client_handle_event (gpointer unused,
const char *iface,
@@ -876,9 +885,7 @@ nm_dhcp_client_handle_event (gpointer unused,
/* If we got an IPv6 prefix to delegate, we don't change the state
* of the DHCP client instance. Instead, we just signal the prefix
* to the device. */
- g_signal_emit (G_OBJECT (self),
- signals[SIGNAL_PREFIX_DELEGATED], 0,
- &prefix);
+ nm_dhcp_client_emit_ipv6_prefix_delegated (self, &prefix);
} else {
/* Fail if no valid IP config was received */
if ( new_state == NM_DHCP_STATE_BOUND
diff --git a/src/dhcp/nm-dhcp-client.h b/src/dhcp/nm-dhcp-client.h
index 9263565192..ea74c8b3e3 100644
--- a/src/dhcp/nm-dhcp-client.h
+++ b/src/dhcp/nm-dhcp-client.h
@@ -189,6 +189,9 @@ void nm_dhcp_client_set_client_id_bin (NMDhcpClient *self,
const guint8 *client_id,
gsize len);
+void nm_dhcp_client_emit_ipv6_prefix_delegated (NMDhcpClient *self,
+ const NMPlatformIP6Address *prefix);
+
/*****************************************************************************
* Client data
*****************************************************************************/
diff --git a/src/dhcp/nm-dhcp-systemd.c b/src/dhcp/nm-dhcp-systemd.c
index b943bead06..7f0cd3325e 100644
--- a/src/dhcp/nm-dhcp-systemd.c
+++ b/src/dhcp/nm-dhcp-systemd.c
@@ -709,6 +709,7 @@ lease_to_ip6_config (NMDedupMultiIndex *multi_idx,
sd_dhcp6_lease *lease,
gboolean info_only,
GHashTable **out_options,
+ gint32 ts,
GError **error)
{
gs_unref_object NMIP6Config *ip6_config = NULL;
@@ -719,7 +720,6 @@ lease_to_ip6_config (NMDedupMultiIndex *multi_idx,
char **domains;
nm_auto_free_gstring GString *str = NULL;
int num, i;
- const gint32 ts = nm_utils_get_monotonic_timestamp_s ();
g_return_val_if_fail (lease, NULL);
@@ -794,10 +794,12 @@ static void
bound6_handle (NMDhcpSystemd *self)
{
NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self);
+ const gint32 ts = nm_utils_get_monotonic_timestamp_s ();
const char *iface = nm_dhcp_client_get_iface (NM_DHCP_CLIENT (self));
gs_unref_object NMIP6Config *ip6_config = NULL;
gs_unref_hashtable GHashTable *options = NULL;
gs_free_error GError *error = NULL;
+ NMPlatformIP6Address prefix = { 0 };
sd_dhcp6_lease *lease;
if ( sd_dhcp6_client_get_lease (priv->client6, &lease) < 0
@@ -815,6 +817,7 @@ bound6_handle (NMDhcpSystemd *self)
lease,
nm_dhcp_client_get_info_only (NM_DHCP_CLIENT (self)),
&options,
+ ts,
&error);
if (!ip6_config) {
@@ -827,6 +830,16 @@ bound6_handle (NMDhcpSystemd *self)
NM_DHCP_STATE_BOUND,
NM_IP_CONFIG_CAST (ip6_config),
options);
+
+ sd_dhcp6_lease_reset_pd_prefix_iter (lease);
+ while (!sd_dhcp6_lease_get_pd (lease,
+ &prefix.address,
+ &prefix.plen,
+ &prefix.preferred,
+ &prefix.lifetime)) {
+ prefix.timestamp = ts;
+ nm_dhcp_client_emit_ipv6_prefix_delegated (NM_DHCP_CLIENT (self), &prefix);
+ }
}
static void
@@ -895,11 +908,6 @@ ip6_start (NMDhcpClient *client,
return FALSE;
}
- if (needed_prefixes > 0) {
- _LOGW ("dhcp-client6: prefix delegation not yet supported, won't supply %d prefixes",
- needed_prefixes);
- }
-
_LOGT ("dhcp-client6: set %p", sd_client);
if (nm_dhcp_client_get_info_only (client))
@@ -962,6 +970,18 @@ ip6_start (NMDhcpClient *client,
}
}
+ if (needed_prefixes > 0) {
+ if (needed_prefixes > 1)
+ _LOGW ("dhcp-client6: only one prefix request is supported");
+ /* FIXME: systemd-networkd API only allows to request a
+ * single prefix */
+ r = sd_dhcp6_client_set_prefix_delegation (sd_client, TRUE);
+ if (r < 0) {
+ nm_utils_error_set_errno (error, r, "failed to enable prefix delegation: %s");
+ return FALSE;
+ }
+ }
+
r = sd_dhcp6_client_set_local_address (sd_client, ll_addr);
if (r < 0) {
nm_utils_error_set_errno (error, r, "failed to set local address: %s");