mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-07-22 10:46:59 +00:00
dhcp: systemd: support DHCPv6 prefix delegation
Add support to the internal DHCP client for requesting a prefix and distributing it to interfaces with 'shared' IPv6 mode. The systemd-networkd API currently allows to request only a single prefix and so there will be issues when the number of downstream interfaces is greater than the number of /64 subnets available in the returned prefix; but this is still an improvement over the previous situation when no prefix was requested at all. https://gitlab.freedesktop.org/NetworkManager/NetworkManager/issues/247
This commit is contained in:
parent
ad68f3f402
commit
3c4f70c5c2
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*****************************************************************************/
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in a new issue