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/devices | |
| parent | 288a08a3672a89a9bfdb8354b6863cc039759fc2 (diff) | |
Imported Upstream version 1.2.0 upstream/1.2.0
Diffstat (limited to 'src/devices')
| -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 |
7 files changed, 162 insertions, 65 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 |