mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-08 22:58:16 +02:00
core: handle externally added IPv6 adresses and routes on IP change
Cache externally added IP details and represent them via the D-Bus interface, and also merge them into the final device config to ensure they aren't lost if DHCP renews or RA changes occur.
This commit is contained in:
parent
d8c9828a4d
commit
fa0112c0ca
1 changed files with 34 additions and 18 deletions
|
|
@ -260,6 +260,7 @@ typedef struct {
|
||||||
NMIP6Config * ip6_config;
|
NMIP6Config * ip6_config;
|
||||||
IpState ip6_state;
|
IpState ip6_state;
|
||||||
NMIP6Config * vpn6_config; /* routes added by a VPN which uses this device */
|
NMIP6Config * vpn6_config; /* routes added by a VPN which uses this device */
|
||||||
|
NMIP6Config * ext_ip6_config; /* Stuff added outside NM */
|
||||||
|
|
||||||
NMRDisc * rdisc;
|
NMRDisc * rdisc;
|
||||||
gulong rdisc_config_changed_sigid;
|
gulong rdisc_config_changed_sigid;
|
||||||
|
|
@ -2807,6 +2808,7 @@ dhcp6_add_option_cb (gpointer key, gpointer value, gpointer user_data)
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
ip6_config_merge_and_apply (NMDevice *self,
|
ip6_config_merge_and_apply (NMDevice *self,
|
||||||
|
gboolean commit,
|
||||||
NMDeviceStateReason *out_reason)
|
NMDeviceStateReason *out_reason)
|
||||||
{
|
{
|
||||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
|
|
@ -2814,9 +2816,6 @@ ip6_config_merge_and_apply (NMDevice *self,
|
||||||
gboolean success;
|
gboolean success;
|
||||||
NMIP6Config *composite;
|
NMIP6Config *composite;
|
||||||
|
|
||||||
connection = nm_device_get_connection (self);
|
|
||||||
g_assert (connection);
|
|
||||||
|
|
||||||
/* If no config was passed in, create a new one */
|
/* If no config was passed in, create a new one */
|
||||||
composite = nm_ip6_config_new ();
|
composite = nm_ip6_config_new ();
|
||||||
g_assert (composite);
|
g_assert (composite);
|
||||||
|
|
@ -2828,11 +2827,15 @@ ip6_config_merge_and_apply (NMDevice *self,
|
||||||
nm_ip6_config_merge (composite, priv->dhcp6_ip6_config);
|
nm_ip6_config_merge (composite, priv->dhcp6_ip6_config);
|
||||||
if (priv->vpn6_config)
|
if (priv->vpn6_config)
|
||||||
nm_ip6_config_merge (composite, priv->vpn6_config);
|
nm_ip6_config_merge (composite, priv->vpn6_config);
|
||||||
|
if (priv->ext_ip6_config)
|
||||||
|
nm_ip6_config_merge (composite, priv->ext_ip6_config);
|
||||||
|
|
||||||
/* Merge user overrides into the composite config */
|
/* Merge user overrides into the composite config */
|
||||||
nm_ip6_config_merge_setting (composite, nm_connection_get_setting_ip6_config (connection));
|
connection = nm_device_get_connection (self);
|
||||||
|
if (connection)
|
||||||
|
nm_ip6_config_merge_setting (composite, nm_connection_get_setting_ip6_config (connection));
|
||||||
|
|
||||||
success = nm_device_set_ip6_config (self, composite, TRUE, out_reason);
|
success = nm_device_set_ip6_config (self, composite, commit, out_reason);
|
||||||
g_object_unref (composite);
|
g_object_unref (composite);
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
@ -2857,7 +2860,7 @@ dhcp6_lease_change (NMDevice *device)
|
||||||
g_assert (connection);
|
g_assert (connection);
|
||||||
|
|
||||||
/* Apply the updated config */
|
/* Apply the updated config */
|
||||||
if (ip6_config_merge_and_apply (device, &reason) == FALSE) {
|
if (ip6_config_merge_and_apply (device, TRUE, &reason) == FALSE) {
|
||||||
nm_log_warn (LOGD_DHCP6, "(%s): failed to update IPv6 config in response to DHCP event.",
|
nm_log_warn (LOGD_DHCP6, "(%s): failed to update IPv6 config in response to DHCP event.",
|
||||||
nm_device_get_ip_iface (device));
|
nm_device_get_ip_iface (device));
|
||||||
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
|
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
|
||||||
|
|
@ -4003,7 +4006,7 @@ nm_device_activate_ip6_config_commit (gpointer user_data)
|
||||||
if (NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit)
|
if (NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit)
|
||||||
NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit (self);
|
NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit (self);
|
||||||
|
|
||||||
if (ip6_config_merge_and_apply (self, &reason)) {
|
if (ip6_config_merge_and_apply (self, TRUE, &reason)) {
|
||||||
/* Enter the IP_CHECK state if this is the first method to complete */
|
/* Enter the IP_CHECK state if this is the first method to complete */
|
||||||
priv->ip6_state = IP_DONE;
|
priv->ip6_state = IP_DONE;
|
||||||
if (nm_device_get_state (self) == NM_DEVICE_STATE_IP_CONFIG)
|
if (nm_device_get_state (self) == NM_DEVICE_STATE_IP_CONFIG)
|
||||||
|
|
@ -4340,6 +4343,7 @@ nm_device_deactivate (NMDevice *self, NMDeviceStateReason reason)
|
||||||
g_clear_object (&priv->ext_ip4_config);
|
g_clear_object (&priv->ext_ip4_config);
|
||||||
g_clear_object (&priv->vpn4_config);
|
g_clear_object (&priv->vpn4_config);
|
||||||
g_clear_object (&priv->vpn6_config);
|
g_clear_object (&priv->vpn6_config);
|
||||||
|
g_clear_object (&priv->ext_ip6_config);
|
||||||
|
|
||||||
/* Clear legacy IPv4 address property */
|
/* Clear legacy IPv4 address property */
|
||||||
priv->ip4_address = 0;
|
priv->ip4_address = 0;
|
||||||
|
|
@ -4684,7 +4688,7 @@ nm_device_set_vpn6_config (NMDevice *device, NMIP6Config *config)
|
||||||
priv->vpn6_config = g_object_ref (config);
|
priv->vpn6_config = g_object_ref (config);
|
||||||
|
|
||||||
/* NULL to use existing configs */
|
/* NULL to use existing configs */
|
||||||
if (!ip6_config_merge_and_apply (device, NULL)) {
|
if (!ip6_config_merge_and_apply (device, TRUE, NULL)) {
|
||||||
nm_log_warn (LOGD_IP6, "(%s): failed to set VPN routes for device",
|
nm_log_warn (LOGD_IP6, "(%s): failed to set VPN routes for device",
|
||||||
nm_device_get_ip_iface (device));
|
nm_device_get_ip_iface (device));
|
||||||
}
|
}
|
||||||
|
|
@ -5045,6 +5049,7 @@ dispose (GObject *object)
|
||||||
g_clear_object (&priv->ac_ip6_config);
|
g_clear_object (&priv->ac_ip6_config);
|
||||||
g_clear_object (&priv->dhcp6_ip6_config);
|
g_clear_object (&priv->dhcp6_ip6_config);
|
||||||
g_clear_object (&priv->vpn6_config);
|
g_clear_object (&priv->vpn6_config);
|
||||||
|
g_clear_object (&priv->ext_ip6_config);
|
||||||
|
|
||||||
/* On dispose, do a final check whether we should delete_link */
|
/* On dispose, do a final check whether we should delete_link */
|
||||||
delete_on_deactivate_check_and_schedule (self, nm_device_get_ip_ifindex (self));
|
delete_on_deactivate_check_and_schedule (self, nm_device_get_ip_ifindex (self));
|
||||||
|
|
@ -6165,26 +6170,37 @@ static void
|
||||||
update_ip_config (NMDevice *self)
|
update_ip_config (NMDevice *self)
|
||||||
{
|
{
|
||||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
NMDeviceStateReason ignored = NM_DEVICE_STATE_REASON_NONE;
|
|
||||||
NMIP6Config *ip6_config = NULL;
|
|
||||||
int ifindex;
|
int ifindex;
|
||||||
|
|
||||||
ifindex = nm_device_get_ip_ifindex (self);
|
ifindex = nm_device_get_ip_ifindex (self);
|
||||||
if (!ifindex)
|
if (!ifindex)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* IPv4 */
|
||||||
g_clear_object (&priv->ext_ip4_config);
|
g_clear_object (&priv->ext_ip4_config);
|
||||||
priv->ext_ip4_config = nm_ip4_config_capture (ifindex);
|
priv->ext_ip4_config = nm_ip4_config_capture (ifindex);
|
||||||
if (priv->dev_ip4_config)
|
if (priv->ext_ip4_config) {
|
||||||
nm_ip4_config_subtract (priv->ext_ip4_config, priv->dev_ip4_config);
|
if (priv->dev_ip4_config)
|
||||||
if (priv->vpn4_config)
|
nm_ip4_config_subtract (priv->ext_ip4_config, priv->dev_ip4_config);
|
||||||
nm_ip4_config_subtract (priv->ext_ip4_config, priv->vpn4_config);
|
if (priv->vpn4_config)
|
||||||
|
nm_ip4_config_subtract (priv->ext_ip4_config, priv->vpn4_config);
|
||||||
|
|
||||||
ip4_config_merge_and_apply (self, NULL, FALSE, NULL);
|
ip4_config_merge_and_apply (self, NULL, FALSE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
ip6_config = nm_ip6_config_capture (ifindex);
|
/* IPv6 */
|
||||||
nm_device_set_ip6_config (self, ip6_config, FALSE, &ignored);
|
g_clear_object (&priv->ext_ip6_config);
|
||||||
g_clear_object (&ip6_config);
|
priv->ext_ip6_config = nm_ip6_config_capture (ifindex);
|
||||||
|
if (priv->ext_ip6_config) {
|
||||||
|
if (priv->ac_ip6_config)
|
||||||
|
nm_ip6_config_subtract (priv->ext_ip6_config, priv->ac_ip6_config);
|
||||||
|
if (priv->dhcp6_ip6_config)
|
||||||
|
nm_ip6_config_subtract (priv->ext_ip6_config, priv->dhcp6_ip6_config);
|
||||||
|
if (priv->vpn6_config)
|
||||||
|
nm_ip6_config_subtract (priv->ext_ip6_config, priv->vpn6_config);
|
||||||
|
|
||||||
|
ip6_config_merge_and_apply (self, FALSE, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue