diff options
| author | Michael Biebl <biebl@debian.org> | 2016-04-20 21:11:10 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2016-04-20 21:11:10 +0200 |
| commit | 78c3b8801ecf4975e5da1af3b10ae20dd2d876de (patch) | |
| tree | 19b80fbe9429f554a48ed126911026d4fa8a4b3f /src | |
| parent | 288a08a3672a89a9bfdb8354b6863cc039759fc2 (diff) | |
Imported Upstream version 1.2.0 upstream/1.2.0
Diffstat (limited to 'src')
| -rw-r--r-- | src/devices/nm-device-factory.c | 5 | ||||
| -rw-r--r-- | src/devices/nm-device-infiniband.c | 67 | ||||
| -rw-r--r-- | src/devices/nm-device-macvlan.c | 9 | ||||
| -rw-r--r-- | src/devices/nm-device-vlan.c | 57 | ||||
| -rw-r--r-- | src/devices/nm-device.c | 76 | ||||
| -rw-r--r-- | src/devices/nm-device.h | 10 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem.c | 3 | ||||
| -rw-r--r-- | src/nm-config.c | 2 | ||||
| -rw-r--r-- | src/nm-core-utils.c | 34 | ||||
| -rw-r--r-- | src/nm-core-utils.h | 5 | ||||
| -rw-r--r-- | src/nm-manager.c | 16 | ||||
| -rw-r--r-- | src/platform/nm-fake-platform.c | 14 | ||||
| -rw-r--r-- | src/platform/nm-linux-platform.c | 38 | ||||
| -rw-r--r-- | src/platform/nm-platform.c | 50 | ||||
| -rw-r--r-- | src/platform/nm-platform.h | 4 | ||||
| -rw-r--r-- | src/vpn-manager/nm-vpn-connection.c | 19 |
16 files changed, 274 insertions, 135 deletions
diff --git a/src/devices/nm-device-factory.c b/src/devices/nm-device-factory.c index 9dfa9bcb..482eb185 100644 --- a/src/devices/nm-device-factory.c +++ b/src/devices/nm-device-factory.c @@ -187,10 +187,9 @@ nm_device_factory_get_connection_iface (NMDeviceFactory *factory, klass = NM_DEVICE_FACTORY_GET_INTERFACE (factory); - if (klass->get_connection_iface) + ifname = g_strdup (nm_connection_get_interface_name (connection)); + if (!ifname && klass->get_connection_iface) ifname = klass->get_connection_iface (factory, connection, parent_iface); - else - ifname = g_strdup (nm_connection_get_interface_name (connection)); if (!ifname) { g_set_error (error, diff --git a/src/devices/nm-device-infiniband.c b/src/devices/nm-device-infiniband.c index a27af314..ae9543e4 100644 --- a/src/devices/nm-device-infiniband.c +++ b/src/devices/nm-device-infiniband.c @@ -42,6 +42,7 @@ G_DEFINE_TYPE (NMDeviceInfiniband, nm_device_infiniband, NM_TYPE_DEVICE) typedef struct { gboolean is_partition; + int parent_ifindex, p_key; } NMDeviceInfinibandPrivate; enum { @@ -235,36 +236,43 @@ create_and_realize (NMDevice *device, const NMPlatformLink **out_plink, GError **error) { + NMDeviceInfinibandPrivate *priv = NM_DEVICE_INFINIBAND_GET_PRIVATE (device); NMSettingInfiniband *s_infiniband; - int parent_ifindex, p_key; NMPlatformError plerr; - if (!NM_IS_DEVICE_INFINIBAND (parent)) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, - "Parent interface %s must be an InfiniBand interface", - nm_device_get_iface (parent)); - return FALSE; - } - s_infiniband = nm_connection_get_setting_infiniband (connection); + g_assert (s_infiniband); /* Can only create partitions at this time */ - p_key = nm_setting_infiniband_get_p_key (s_infiniband); - if (p_key < 0) { - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, + priv->p_key = nm_setting_infiniband_get_p_key (s_infiniband); + if (priv->p_key < 0) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "only InfiniBand partitions can be created"); return FALSE; } - parent_ifindex = nm_device_get_ifindex (parent); - if (parent_ifindex <= 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, + if (!parent) { + g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, + "InfiniBand partitions can not be created without a parent interface"); + return FALSE; + } + + if (!NM_IS_DEVICE_INFINIBAND (parent)) { + g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, + "Parent interface %s must be an InfiniBand interface", + nm_device_get_iface (parent)); + return FALSE; + } + + priv->parent_ifindex = nm_device_get_ifindex (parent); + if (priv->parent_ifindex <= 0) { + g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "failed to get InfiniBand parent %s ifindex", nm_device_get_iface (parent)); return FALSE; } - plerr = nm_platform_link_infiniband_add (NM_PLATFORM_GET, parent_ifindex, p_key, out_plink); + plerr = nm_platform_link_infiniband_add (NM_PLATFORM_GET, priv->parent_ifindex, priv->p_key, out_plink); if (plerr != NM_PLATFORM_ERROR_SUCCESS) { g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, "Failed to create InfiniBand P_Key interface '%s' for '%s': %s", @@ -274,7 +282,33 @@ create_and_realize (NMDevice *device, return FALSE; } - NM_DEVICE_INFINIBAND_GET_PRIVATE (device)->is_partition = TRUE; + priv->is_partition = TRUE; + return TRUE; +} + +static gboolean +unrealize (NMDevice *device, GError **error) +{ + NMDeviceInfinibandPrivate *priv = NM_DEVICE_INFINIBAND_GET_PRIVATE (device); + NMPlatformError plerr; + + g_return_val_if_fail (NM_IS_DEVICE_INFINIBAND (device), FALSE); + + if (priv->p_key < 0) { + g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, + "Only InfiniBand partitions can be removed"); + return FALSE; + } + + plerr = nm_platform_link_infiniband_delete (NM_PLATFORM_GET, priv->parent_ifindex, priv->p_key); + if (plerr != NM_PLATFORM_ERROR_SUCCESS) { + g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, + "Failed to remove InfiniBand P_Key interface '%s': %s", + nm_device_get_iface (device), + nm_platform_error_to_string (plerr)); + return FALSE; + } + return TRUE; } @@ -328,6 +362,7 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass) object_class->set_property = set_property; parent_class->create_and_realize = create_and_realize; + parent_class->unrealize = unrealize; parent_class->get_generic_capabilities = get_generic_capabilities; parent_class->check_connection_compatible = check_connection_compatible; parent_class->complete_connection = complete_connection; diff --git a/src/devices/nm-device-macvlan.c b/src/devices/nm-device-macvlan.c index cd02cb8e..c431fe89 100644 --- a/src/devices/nm-device-macvlan.c +++ b/src/devices/nm-device-macvlan.c @@ -223,12 +223,19 @@ create_and_realize (NMDevice *device, s_macvlan = nm_connection_get_setting_macvlan (connection); g_assert (s_macvlan); + if (!parent) { + g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, + "MACVLAN devices can not be created without a parent interface"); + return FALSE; + } + parent_ifindex = nm_device_get_ifindex (parent); g_warn_if_fail (parent_ifindex > 0); lnk.mode = setting_mode_to_platform (nm_setting_macvlan_get_mode (s_macvlan)); if (!lnk.mode) { - nm_log_info (LOGD_DEVICE, "unsupported MACVLAN mode %u in connection %s", + g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, + "unsupported MACVLAN mode %u in connection %s", nm_setting_macvlan_get_mode (s_macvlan), nm_connection_get_uuid (connection)); return FALSE; diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index 4d606e9d..eb6527de 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -80,14 +80,14 @@ parent_state_changed (NMDevice *parent, } static void -parent_hwaddr_changed (NMDevice *parent, - GParamSpec *pspec, - gpointer user_data) +parent_hwaddr_maybe_changed (NMDevice *parent, + GParamSpec *pspec, + gpointer user_data) { NMDeviceVlan *self = NM_DEVICE_VLAN (user_data); NMConnection *connection; NMSettingWired *s_wired; - const char *cloned_mac = NULL, *new_mac; + const char *new_mac, *old_mac; NMSettingIPConfig *s_ip6; /* Never touch assumed devices */ @@ -100,23 +100,26 @@ parent_hwaddr_changed (NMDevice *parent, /* Update the VLAN MAC only if configuration does not specify one */ s_wired = nm_connection_get_setting_wired (connection); - if (s_wired) - cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); + if (s_wired) { + if (nm_setting_wired_get_cloned_mac_address (s_wired)) + return; + } - if (!cloned_mac) { - new_mac = nm_device_get_hw_address (parent); - _LOGD (LOGD_VLAN, "parent hardware address changed to %s%s%s", - NM_PRINT_FMT_QUOTE_STRING (new_mac)); - if (new_mac) { - nm_device_set_hw_addr (self, nm_device_get_hw_address (parent), - "set", LOGD_VLAN); - /* When changing the hw address the interface is taken down, - * removing the IPv6 configuration; reapply it. - */ - s_ip6 = nm_connection_get_setting_ip6_config (connection); - if (s_ip6) - nm_device_reactivate_ip6_config (NM_DEVICE (self), s_ip6, s_ip6); - } + old_mac = nm_device_get_hw_address (self); + new_mac = nm_device_get_hw_address (parent); + if (nm_streq0 (old_mac, new_mac)) + return; + + _LOGD (LOGD_VLAN, "parent hardware address changed to %s%s%s", + NM_PRINT_FMT_QUOTE_STRING (new_mac)); + if (new_mac) { + nm_device_set_hw_addr (self, new_mac, "set", LOGD_VLAN); + /* When changing the hw address the interface is taken down, + * removing the IPv6 configuration; reapply it. + */ + s_ip6 = nm_connection_get_setting_ip6_config (connection); + if (s_ip6) + nm_device_reactivate_ip6_config (NM_DEVICE (self), s_ip6, s_ip6); } } @@ -141,7 +144,8 @@ nm_device_vlan_set_parent (NMDeviceVlan *self, NMDevice *parent) device); priv->parent_hwaddr_id = g_signal_connect (priv->parent, "notify::" NM_DEVICE_HW_ADDRESS, - G_CALLBACK (parent_hwaddr_changed), device); + G_CALLBACK (parent_hwaddr_maybe_changed), device); + parent_hwaddr_maybe_changed (parent, NULL, self); /* Set parent-dependent unmanaged flag */ nm_device_set_unmanaged_by_flags (device, @@ -218,6 +222,12 @@ create_and_realize (NMDevice *device, s_vlan = nm_connection_get_setting_vlan (connection); g_assert (s_vlan); + if (!parent) { + g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, + "VLAN devices can not be created without a parent interface"); + return FALSE; + } + if (!nm_device_supports_vlans (parent)) { g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "no support for VLANs on interface %s of type %s", @@ -537,6 +547,7 @@ update_connection (NMDevice *device, NMConnection *connection) static NMActStageReturn act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) { + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (dev); NMSettingVlan *s_vlan; NMSettingWired *s_wired; const char *cloned_mac; @@ -555,6 +566,10 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) nm_device_set_hw_addr (dev, cloned_mac, "set", LOGD_VLAN); } + /* Change MAC address to parent's one if needed */ + if (priv->parent) + parent_hwaddr_maybe_changed (priv->parent, NULL, dev); + s_vlan = (NMSettingVlan *) nm_device_get_applied_setting (dev, NM_TYPE_SETTING_VLAN); if (s_vlan) { gs_free NMVlanQosMapping *ingress_map = NULL; diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 3d949ec2..08cf6dce 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -280,11 +280,11 @@ typedef struct _NMDevicePrivate { NMIP4Config * wwan_ip4_config; /* WWAN configuration */ GSList * vpn4_configs; /* VPNs which use this device */ struct { - gboolean v4_has; - gboolean v4_is_assumed; + bool v4_has; + bool v4_is_assumed; + bool v6_has; + bool v6_is_assumed; NMPlatformIP4Route v4; - gboolean v6_has; - gboolean v6_is_assumed; NMPlatformIP6Route v6; } default_route; @@ -878,6 +878,34 @@ nm_device_get_ip6_route_metric (NMDevice *self) return _get_ipx_route_metric (self, FALSE); } +static void +_update_default_route (NMDevice *self, int addr_family, gboolean has, gboolean is_assumed) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + bool *p_has, *p_is_assumed; + + nm_assert (NM_IN_SET (addr_family, 0, AF_INET, AF_INET6)); + + if (addr_family == AF_INET) { + p_has = &priv->default_route.v4_has; + p_is_assumed = &priv->default_route.v4_is_assumed; + } else { + p_has = &priv->default_route.v6_has; + p_is_assumed = &priv->default_route.v6_is_assumed; + } + + if (*p_has == has && *p_is_assumed == is_assumed) + return; + + *p_has = has; + *p_is_assumed = is_assumed; + + if (addr_family == AF_INET) + nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), self); + else + nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), self); +} + const NMPlatformIP4Route * nm_device_get_ip4_default_route (NMDevice *self, gboolean *out_is_assumed) { @@ -2067,8 +2095,12 @@ nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error) _LOGD (LOGD_DEVICE, "unrealize (ifindex %d)", ifindex > 0 ? ifindex : 0); if (remove_resources) { - if (ifindex > 0) + if (NM_DEVICE_GET_CLASS (self)->unrealize) { + if (!NM_DEVICE_GET_CLASS (self)->unrealize (self, error)) + return FALSE; + } else if (ifindex > 0) { nm_platform_link_delete (NM_PLATFORM_GET, ifindex); + } } NM_DEVICE_GET_CLASS (self)->unrealize_notify (self); @@ -2568,12 +2600,14 @@ nm_device_get_enslaved (NMDevice *self) /** * nm_device_removed: * @self: the #NMDevice + * @unconfigure_ip_config: whether to clear the IP config objects + * of the device (provided, it is still not cleared at this point). * * Called by the manager when the device was removed. Releases the device from * the master in case it's enslaved. */ void -nm_device_removed (NMDevice *self) +nm_device_removed (NMDevice *self, gboolean unconfigure_ip_config) { NMDevicePrivate *priv; @@ -2586,16 +2620,19 @@ nm_device_removed (NMDevice *self) nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); } + if (!unconfigure_ip_config) + return; + /* Clean up IP configs; this does not actually deconfigure the * interface, it just clears the configuration to which policy * is reacting via NM_DEVICE_IP4_CONFIG_CHANGED/NM_DEVICE_IP6_CONFIG_CHANGED * signal. As NMPolicy registered the NMIPxConfig instances in NMDnsManager, * these would be leaked otherwise. */ - priv->default_route.v4_has = FALSE; - priv->default_route.v4_is_assumed = TRUE; + _update_default_route (self, AF_INET, priv->default_route.v4_has, TRUE); + _update_default_route (self, AF_INET6, priv->default_route.v6_has, TRUE); + _update_default_route (self, AF_INET, FALSE, TRUE); + _update_default_route (self, AF_INET6, FALSE, TRUE); nm_device_set_ip4_config (self, NULL, 0, FALSE, FALSE, NULL); - priv->default_route.v6_has = FALSE; - priv->default_route.v6_is_assumed = TRUE; nm_device_set_ip6_config (self, NULL, FALSE, FALSE, NULL); } @@ -9994,20 +10031,15 @@ _cleanup_generic_post (NMDevice *self, CleanupType cleanup_type) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - priv->default_route.v4_has = FALSE; - priv->default_route.v6_has = FALSE; - if (cleanup_type == CLEANUP_TYPE_DECONFIGURE) { - priv->default_route.v4_is_assumed = FALSE; - priv->default_route.v6_is_assumed = FALSE; - nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), self); - nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), self); + _update_default_route (self, AF_INET, FALSE, FALSE); + _update_default_route (self, AF_INET6, FALSE, FALSE); + } else { + _update_default_route (self, AF_INET, priv->default_route.v4_has, TRUE); + _update_default_route (self, AF_INET6, priv->default_route.v6_has, TRUE); } - - priv->default_route.v4_is_assumed = TRUE; - priv->default_route.v6_is_assumed = TRUE; - nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), self); - nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), self); + _update_default_route (self, AF_INET, FALSE, TRUE); + _update_default_route (self, AF_INET6, FALSE, TRUE); priv->v4_commit_first_time = TRUE; priv->v6_commit_first_time = TRUE; diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 368e77f7..9f689850 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -180,6 +180,14 @@ typedef struct { void (*realize_start_notify) (NMDevice *self, const NMPlatformLink *plink); /** + * unrealize(): + * @self: the #NMDevice + * + * Remove the device backing resources. + */ + gboolean (*unrealize) (NMDevice *self, GError **error); + + /** * unrealize_notify(): * @self: the #NMDevice * @@ -377,7 +385,7 @@ gboolean nm_device_has_unmodified_applied_connection (NMDevice *self, NMSettingCompareFlags compare_flags); NMSetting * nm_device_get_applied_setting (NMDevice *dev, GType setting_type); -void nm_device_removed (NMDevice *dev); +void nm_device_removed (NMDevice *self, gboolean unconfigure_ip_config); gboolean nm_device_is_available (NMDevice *dev, NMDeviceCheckDevAvailableFlags flags); gboolean nm_device_has_carrier (NMDevice *dev); diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c index 2a8a9d1e..804a6d9c 100644 --- a/src/devices/wwan/nm-modem.c +++ b/src/devices/wwan/nm-modem.c @@ -742,7 +742,8 @@ cancel_get_secrets (NMModem *self) { NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - nm_act_request_cancel_secrets (priv->act_request, priv->secrets_id); + if (priv->secrets_id) + nm_act_request_cancel_secrets (priv->act_request, priv->secrets_id); } static void diff --git a/src/nm-config.c b/src/nm-config.c index 58fd96cb..8bca6870 100644 --- a/src/nm-config.c +++ b/src/nm-config.c @@ -125,7 +125,7 @@ gint nm_config_parse_boolean (const char *str, gint default_value) { - return nm_utils_ascii_str_to_bool (str, default_value); + return _nm_utils_ascii_str_to_bool (str, default_value); } gint diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index 714aaa92..bbe46654 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -154,40 +154,6 @@ _nm_singleton_instance_register_destruction (GObject *instance) /*****************************************************************************/ -gint -nm_utils_ascii_str_to_bool (const char *str, - gint default_value) -{ - gsize len; - char *s = NULL; - - if (!str) - return default_value; - - while (str[0] && g_ascii_isspace (str[0])) - str++; - - if (!str[0]) - return default_value; - - len = strlen (str); - if (g_ascii_isspace (str[len - 1])) { - s = g_strdup (str); - g_strchomp (s); - str = s; - } - - if (!g_ascii_strcasecmp (str, "true") || !g_ascii_strcasecmp (str, "yes") || !g_ascii_strcasecmp (str, "on") || !g_ascii_strcasecmp (str, "1")) - default_value = TRUE; - else if (!g_ascii_strcasecmp (str, "false") || !g_ascii_strcasecmp (str, "no") || !g_ascii_strcasecmp (str, "off") || !g_ascii_strcasecmp (str, "0")) - default_value = FALSE; - if (s) - g_free (s); - return default_value; -} - -/*****************************************************************************/ - /* * nm_ethernet_address_is_valid: * @addr: pointer to a binary or ASCII Ethernet address diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h index 280be047..528288c3 100644 --- a/src/nm-core-utils.h +++ b/src/nm-core-utils.h @@ -91,11 +91,6 @@ GETTER (void) \ /*****************************************************************************/ -gint nm_utils_ascii_str_to_bool (const char *str, - gint default_value); - -/*****************************************************************************/ - gboolean nm_ethernet_address_is_valid (gconstpointer addr, gssize len); in_addr_t nm_utils_ip4_address_clear_host_address (in_addr_t addr, guint8 plen); diff --git a/src/nm-manager.c b/src/nm-manager.c index 289a91d6..e64c68af 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -833,13 +833,13 @@ remove_device (NMManager *self, gboolean allow_unmanage) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + gboolean unmanage = FALSE; _LOGD (LOGD_DEVICE, "(%s): removing device (allow_unmanage %d, managed %d)", nm_device_get_iface (device), allow_unmanage, nm_device_get_managed (device, FALSE)); if (allow_unmanage && nm_device_get_managed (device, FALSE)) { NMActRequest *req = nm_device_get_act_request (device); - gboolean unmanage = FALSE; /* Leave activated interfaces up when quitting so their configuration * can be taken over when NM restarts. This ensures connectivity while @@ -869,7 +869,18 @@ remove_device (NMManager *self, priv->devices = g_slist_remove (priv->devices, device); if (nm_device_is_real (device)) { - nm_device_removed (device); + gboolean unconfigure_ip_config = !quitting || unmanage; + + /* When we don't unmanage the device on shutdown, we want to preserve the DNS + * configuration in resolv.conf. For that, we must leak the configuration + * in NMPolicy/NMDnsManager. We do that, by emitting the device-removed signal + * with device's ip-config object still uncleared. In that case, NMPolicy + * never learns to unconfigure the ip-config objects and does not remove them + * from DNS on shutdown (which is ugly, because we don't cleanup the memory + * properly). + * + * Control that by passing @unconfigure_ip_config. */ + nm_device_removed (device, unconfigure_ip_config); g_signal_emit (self, signals[DEVICE_REMOVED], 0, device); _notify (self, PROP_DEVICES); @@ -3512,7 +3523,6 @@ activation_add_done (NMSettings *settings, FALSE, nm_active_connection_get_subject (active), error->message); - g_object_unref (active); g_clear_error (&local); } diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index 15d9c543..7b545076 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -731,6 +731,19 @@ infiniband_partition_add (NMPlatform *platform, int parent, int p_key, const NMP } static gboolean +infiniband_partition_delete (NMPlatform *platform, int parent, int p_key) +{ + NMFakePlatformLink *parent_device; + gs_free char *name = NULL; + + parent_device = link_get (platform, parent); + g_return_val_if_fail (parent_device != NULL, FALSE); + + name = g_strdup_printf ("%s.%04x", parent_device->link.name, p_key); + return link_delete (platform, nm_platform_link_get_ifindex (platform, name)); +} + +static gboolean wifi_get_capabilities (NMPlatform *platform, int ifindex, NMDeviceWifiCapabilities *caps) { NMFakePlatformLink *device = link_get (platform, ifindex); @@ -1460,6 +1473,7 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass) platform_class->link_vxlan_add = link_vxlan_add; platform_class->infiniband_partition_add = infiniband_partition_add; + platform_class->infiniband_partition_delete = infiniband_partition_delete; platform_class->wifi_get_capabilities = wifi_get_capabilities; platform_class->wifi_get_bssid = wifi_get_bssid; diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index ded019e6..254f9c85 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -1562,6 +1562,7 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr _lookup_cached_link (cache, obj->link.ifindex, completed_from_cache, &link_cached); if ( link_cached && link_cached->link.type == obj->link.type + && link_cached->_link.netlink.lnk && ( !lnk_data || nmp_object_equal (lnk_data, link_cached->_link.netlink.lnk))) { nmp_object_unref (lnk_data); @@ -5077,24 +5078,35 @@ link_release (NMPlatform *platform, int master, int slave) /******************************************************************/ static gboolean -infiniband_partition_add (NMPlatform *platform, int parent, int p_key, const NMPlatformLink **out_link) +_infiniband_partition_action (NMPlatform *platform, int parent, int p_key, const char *action, char **ifname) { NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); const NMPObject *obj_parent; - const NMPObject *obj; gs_free char *path = NULL; gs_free char *id = NULL; - gs_free char *ifname = NULL; obj_parent = nmp_cache_lookup_link (priv->cache, parent); if (!obj_parent || !obj_parent->link.name[0]) g_return_val_if_reached (FALSE); - ifname = g_strdup_printf ("%s.%04x", obj_parent->link.name, p_key); + *ifname = g_strdup_printf ("%s.%04x", obj_parent->link.name, p_key); - path = g_strdup_printf ("/sys/class/net/%s/create_child", NM_ASSERT_VALID_PATH_COMPONENT (obj_parent->link.name)); + path = g_strdup_printf ("/sys/class/net/%s/%s", + NM_ASSERT_VALID_PATH_COMPONENT (obj_parent->link.name), + action); id = g_strdup_printf ("0x%04x", p_key); - if (!nm_platform_sysctl_set (platform, path, id)) + + return nm_platform_sysctl_set (platform, path, id); +} + + +static gboolean +infiniband_partition_add (NMPlatform *platform, int parent, int p_key, const NMPlatformLink **out_link) +{ + const NMPObject *obj; + gs_free char *ifname = NULL; + + if (!_infiniband_partition_action (platform, parent, p_key, "create_child", &ifname)) return FALSE; do_request_link (platform, 0, ifname); @@ -5106,6 +5118,19 @@ infiniband_partition_add (NMPlatform *platform, int parent, int p_key, const NMP return !!obj; } +static gboolean +infiniband_partition_delete (NMPlatform *platform, int parent, int p_key) +{ + gs_free char *ifname = NULL; + + if (!_infiniband_partition_action (platform, parent, p_key, "delete_child", &ifname)) { + if (errno != ENODEV) + return FALSE; + } + + return TRUE; +} + /******************************************************************/ static WifiData * @@ -6380,6 +6405,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass) platform_class->tun_add = tun_add; platform_class->infiniband_partition_add = infiniband_partition_add; + platform_class->infiniband_partition_delete = infiniband_partition_delete; platform_class->wifi_get_capabilities = wifi_get_capabilities; platform_class->wifi_get_bssid = wifi_get_bssid; diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 69b0d420..26ac766d 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -1888,11 +1888,12 @@ nm_platform_link_gre_add (NMPlatform *self, return NM_PLATFORM_ERROR_SUCCESS; } -NMPlatformError -nm_platform_link_infiniband_add (NMPlatform *self, - int parent, - int p_key, - const NMPlatformLink **out_link) +static NMPlatformError +_infiniband_add_add_or_delete (NMPlatform *self, + int parent, + int p_key, + gboolean add, + const NMPlatformLink **out_link) { gs_free char *parent_name = NULL; gs_free char *name = NULL; @@ -1909,17 +1910,42 @@ nm_platform_link_infiniband_add (NMPlatform *self, return NM_PLATFORM_ERROR_WRONG_TYPE; name = g_strdup_printf ("%s.%04x", parent_name, p_key); - plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_INFINIBAND, out_link); - if (plerr != NM_PLATFORM_ERROR_SUCCESS) - return plerr; - _LOGD ("link: adding infiniband partition %s for parent '%s' (%d), key %d", - name, parent_name, parent, p_key); - if (!klass->infiniband_partition_add (self, parent, p_key, out_link)) - return NM_PLATFORM_ERROR_UNSPECIFIED; + if (add) { + plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_INFINIBAND, out_link); + if (plerr != NM_PLATFORM_ERROR_SUCCESS) + return plerr; + + _LOGD ("link: adding infiniband partition %s for parent '%s' (%d), key %d", + name, parent_name, parent, p_key); + if (!klass->infiniband_partition_add (self, parent, p_key, out_link)) + return NM_PLATFORM_ERROR_UNSPECIFIED; + } else { + if (!klass->infiniband_partition_delete (self, parent, p_key)) + return NM_PLATFORM_ERROR_UNSPECIFIED; + } + return NM_PLATFORM_ERROR_SUCCESS; } +NMPlatformError +nm_platform_link_infiniband_add (NMPlatform *self, + int parent, + int p_key, + const NMPlatformLink **out_link) +{ + return _infiniband_add_add_or_delete (self, parent, p_key, TRUE, out_link); +} + +NMPlatformError +nm_platform_link_infiniband_delete (NMPlatform *self, + int parent, + int p_key) +{ + return _infiniband_add_add_or_delete (self, parent, p_key, FALSE, NULL); +} + + gboolean nm_platform_link_infiniband_get_properties (NMPlatform *self, int ifindex, diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 9f055b04..658b709a 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -570,6 +570,7 @@ typedef struct { const NMPlatformLink **out_link); gboolean (*infiniband_partition_add) (NMPlatform *, int parent, int p_key, const NMPlatformLink **out_link); + gboolean (*infiniband_partition_delete) (NMPlatform *, int parent, int p_key); gboolean (*tun_add) (NMPlatform *platform, const char *name, gboolean tap, gint64 owner, gint64 group, gboolean pi, gboolean vnet_hdr, gboolean multi_queue, const NMPlatformLink **out_link); @@ -815,6 +816,9 @@ NMPlatformError nm_platform_link_infiniband_add (NMPlatform *self, int parent, int p_key, const NMPlatformLink **out_link); +NMPlatformError nm_platform_link_infiniband_delete (NMPlatform *self, + int parent, + int p_key); gboolean nm_platform_link_infiniband_get_properties (NMPlatform *self, int ifindex, int *parent, int *p_key, const char **mode); gboolean nm_platform_link_veth_get_properties (NMPlatform *self, int ifindex, int *out_peer_ifindex); diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 2945ad34..a1cd0c32 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -1210,7 +1210,7 @@ process_generic_config (NMVpnConnection *self, GVariant *dict) const char *str; GVariant *v; guint32 u32; - gboolean b, success = FALSE; + gboolean b; if (g_variant_lookup (dict, NM_VPN_PLUGIN_CAN_PERSIST, "b", &b) && b) { /* Defaults to FALSE, so only let service indicate TRUE */ @@ -1246,17 +1246,15 @@ process_generic_config (NMVpnConnection *self, GVariant *dict) if (g_variant_lookup (dict, NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY, "u", &u32)) { priv->ip4_external_gw = u32; - success = TRUE; } else if (g_variant_lookup (dict, NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY, "@ay", &v)) { priv->ip6_external_gw = ip6_addr_dup_from_variant (v); - success = !!priv->ip6_external_gw; g_variant_unref (v); - } - if (!success) { - _LOGE ("VPN gateway is neither IPv4 nor IPv6"); - nm_vpn_connection_config_maybe_complete (self, FALSE); - return FALSE; + if (!priv->ip6_external_gw) { + _LOGE ("Invalid IPv6 VPN gateway address received"); + nm_vpn_connection_config_maybe_complete (self, FALSE); + return FALSE; + } } priv->mtu = 0; @@ -2021,7 +2019,10 @@ nm_vpn_connection_activate (NMVpnConnection *self, s_vpn = nm_connection_get_setting_vpn (_get_applied_connection (self)); g_return_if_fail (s_vpn); - service = nm_setting_vpn_get_service_type (s_vpn); + service = nm_vpn_plugin_info_lookup_property (plugin_info, + NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION, + "service"); + g_return_if_fail (service); if (nm_vpn_plugin_info_supports_multiple (plugin_info)) { const char *path; |