mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-28 11:00:09 +01: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;
|
||||
IpState ip6_state;
|
||||
NMIP6Config * vpn6_config; /* routes added by a VPN which uses this device */
|
||||
NMIP6Config * ext_ip6_config; /* Stuff added outside NM */
|
||||
|
||||
NMRDisc * rdisc;
|
||||
gulong rdisc_config_changed_sigid;
|
||||
|
|
@ -2807,6 +2808,7 @@ dhcp6_add_option_cb (gpointer key, gpointer value, gpointer user_data)
|
|||
|
||||
static gboolean
|
||||
ip6_config_merge_and_apply (NMDevice *self,
|
||||
gboolean commit,
|
||||
NMDeviceStateReason *out_reason)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
|
@ -2814,9 +2816,6 @@ ip6_config_merge_and_apply (NMDevice *self,
|
|||
gboolean success;
|
||||
NMIP6Config *composite;
|
||||
|
||||
connection = nm_device_get_connection (self);
|
||||
g_assert (connection);
|
||||
|
||||
/* If no config was passed in, create a new one */
|
||||
composite = nm_ip6_config_new ();
|
||||
g_assert (composite);
|
||||
|
|
@ -2828,11 +2827,15 @@ ip6_config_merge_and_apply (NMDevice *self,
|
|||
nm_ip6_config_merge (composite, priv->dhcp6_ip6_config);
|
||||
if (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 */
|
||||
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);
|
||||
return success;
|
||||
}
|
||||
|
|
@ -2857,7 +2860,7 @@ dhcp6_lease_change (NMDevice *device)
|
|||
g_assert (connection);
|
||||
|
||||
/* 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_device_get_ip_iface (device));
|
||||
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)
|
||||
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 */
|
||||
priv->ip6_state = IP_DONE;
|
||||
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->vpn4_config);
|
||||
g_clear_object (&priv->vpn6_config);
|
||||
g_clear_object (&priv->ext_ip6_config);
|
||||
|
||||
/* Clear legacy IPv4 address property */
|
||||
priv->ip4_address = 0;
|
||||
|
|
@ -4684,7 +4688,7 @@ nm_device_set_vpn6_config (NMDevice *device, NMIP6Config *config)
|
|||
priv->vpn6_config = g_object_ref (config);
|
||||
|
||||
/* 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_device_get_ip_iface (device));
|
||||
}
|
||||
|
|
@ -5045,6 +5049,7 @@ dispose (GObject *object)
|
|||
g_clear_object (&priv->ac_ip6_config);
|
||||
g_clear_object (&priv->dhcp6_ip6_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 */
|
||||
delete_on_deactivate_check_and_schedule (self, nm_device_get_ip_ifindex (self));
|
||||
|
|
@ -6165,26 +6170,37 @@ static void
|
|||
update_ip_config (NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
NMDeviceStateReason ignored = NM_DEVICE_STATE_REASON_NONE;
|
||||
NMIP6Config *ip6_config = NULL;
|
||||
int ifindex;
|
||||
|
||||
ifindex = nm_device_get_ip_ifindex (self);
|
||||
if (!ifindex)
|
||||
return;
|
||||
|
||||
/* IPv4 */
|
||||
g_clear_object (&priv->ext_ip4_config);
|
||||
priv->ext_ip4_config = nm_ip4_config_capture (ifindex);
|
||||
if (priv->dev_ip4_config)
|
||||
nm_ip4_config_subtract (priv->ext_ip4_config, priv->dev_ip4_config);
|
||||
if (priv->vpn4_config)
|
||||
nm_ip4_config_subtract (priv->ext_ip4_config, priv->vpn4_config);
|
||||
if (priv->ext_ip4_config) {
|
||||
if (priv->dev_ip4_config)
|
||||
nm_ip4_config_subtract (priv->ext_ip4_config, priv->dev_ip4_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);
|
||||
nm_device_set_ip6_config (self, ip6_config, FALSE, &ignored);
|
||||
g_clear_object (&ip6_config);
|
||||
/* IPv6 */
|
||||
g_clear_object (&priv->ext_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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue