diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/devices/nm-device-bond.c | 2 | ||||
-rw-r--r-- | src/devices/nm-device-bridge.c | 2 | ||||
-rw-r--r-- | src/devices/nm-device-ethernet.c | 2 | ||||
-rw-r--r-- | src/devices/nm-device-generic.c | 2 | ||||
-rw-r--r-- | src/devices/nm-device-infiniband.c | 2 | ||||
-rw-r--r-- | src/devices/nm-device-ip-tunnel.c | 7 | ||||
-rw-r--r-- | src/devices/nm-device-macvlan.c | 2 | ||||
-rw-r--r-- | src/devices/nm-device-private.h | 7 | ||||
-rw-r--r-- | src/devices/nm-device-tun.c | 2 | ||||
-rw-r--r-- | src/devices/nm-device-veth.c | 2 | ||||
-rw-r--r-- | src/devices/nm-device-vlan.c | 2 | ||||
-rw-r--r-- | src/devices/nm-device-vxlan.c | 2 | ||||
-rw-r--r-- | src/devices/nm-device.c | 73 | ||||
-rw-r--r-- | src/devices/nm-device.h | 2 | ||||
-rw-r--r-- | src/devices/team/nm-device-team.c | 2 | ||||
-rw-r--r-- | src/devices/wifi/nm-device-olpc-mesh.c | 2 | ||||
-rw-r--r-- | src/devices/wifi/nm-device-wifi.c | 2 | ||||
-rw-r--r-- | src/nm-manager.c | 37 | ||||
-rw-r--r-- | src/nm-types.h | 2 |
19 files changed, 125 insertions, 29 deletions
diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c index 359b3c4abf..033c57214f 100644 --- a/src/devices/nm-device-bond.c +++ b/src/devices/nm-device-bond.c @@ -529,7 +529,7 @@ nm_device_bond_class_init (NMDeviceBondClass *klass) g_type_class_add_private (object_class, sizeof (NMDeviceBondPrivate)); - parent_class->connection_type = NM_SETTING_BOND_SETTING_NAME; + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_BOND_SETTING_NAME, NM_LINK_TYPE_BOND) /* virtual methods */ object_class->get_property = get_property; diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c index 2a2f234c16..e152bb38b9 100644 --- a/src/devices/nm-device-bridge.c +++ b/src/devices/nm-device-bridge.c @@ -475,7 +475,7 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *klass) g_type_class_add_private (object_class, sizeof (NMDeviceBridgePrivate)); - parent_class->connection_type = NM_SETTING_BRIDGE_SETTING_NAME; + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_BRIDGE_SETTING_NAME, NM_LINK_TYPE_BRIDGE) /* virtual methods */ object_class->get_property = get_property; diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index 6f0c3e8881..65f8716d8e 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -1706,7 +1706,7 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass) g_type_class_add_private (object_class, sizeof (NMDeviceEthernetPrivate)); - parent_class->connection_type = NM_SETTING_WIRED_SETTING_NAME; + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_WIRED_SETTING_NAME, NM_LINK_TYPE_ETHERNET) /* virtual methods */ object_class->constructor = constructor; diff --git a/src/devices/nm-device-generic.c b/src/devices/nm-device-generic.c index 70ae48c678..0be55d54f0 100644 --- a/src/devices/nm-device-generic.c +++ b/src/devices/nm-device-generic.c @@ -196,7 +196,7 @@ nm_device_generic_class_init (NMDeviceGenericClass *klass) g_type_class_add_private (klass, sizeof (NMDeviceGenericPrivate)); - parent_class->connection_type = NM_SETTING_GENERIC_SETTING_NAME; + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_GENERIC_SETTING_NAME, NM_LINK_TYPE_ANY) object_class->constructor = constructor; object_class->dispose = dispose; diff --git a/src/devices/nm-device-infiniband.c b/src/devices/nm-device-infiniband.c index e0c3c62d76..95f69c93c3 100644 --- a/src/devices/nm-device-infiniband.c +++ b/src/devices/nm-device-infiniband.c @@ -327,6 +327,8 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass) g_type_class_add_private (object_class, sizeof (NMDeviceInfinibandPrivate)); + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_INFINIBAND_SETTING_NAME, NM_LINK_TYPE_INFINIBAND) + /* virtual methods */ object_class->get_property = get_property; object_class->set_property = set_property; diff --git a/src/devices/nm-device-ip-tunnel.c b/src/devices/nm-device-ip-tunnel.c index 64c3a52146..84ab7cd69d 100644 --- a/src/devices/nm-device-ip-tunnel.c +++ b/src/devices/nm-device-ip-tunnel.c @@ -852,7 +852,12 @@ nm_device_ip_tunnel_class_init (NMDeviceIPTunnelClass *klass) device_class->setup_start = setup_start; device_class->unrealize = unrealize; - device_class->connection_type = NM_SETTING_IP_TUNNEL_SETTING_NAME; + NM_DEVICE_CLASS_DECLARE_TYPES (klass, + NM_SETTING_IP_TUNNEL_SETTING_NAME, + NM_LINK_TYPE_GRE, + NM_LINK_TYPE_IP6TNL, + NM_LINK_TYPE_IPIP, + NM_LINK_TYPE_SIT); /* properties */ g_object_class_install_property diff --git a/src/devices/nm-device-macvlan.c b/src/devices/nm-device-macvlan.c index e2dd891c1a..aed28816ff 100644 --- a/src/devices/nm-device-macvlan.c +++ b/src/devices/nm-device-macvlan.c @@ -143,6 +143,8 @@ nm_device_macvlan_class_init (NMDeviceMacvlanClass *klass) g_type_class_add_private (klass, sizeof (NMDeviceMacvlanPrivate)); + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NULL, NM_LINK_TYPE_MACVLAN, NM_LINK_TYPE_MACVTAP) + object_class->constructed = constructed; object_class->get_property = get_property; diff --git a/src/devices/nm-device-private.h b/src/devices/nm-device-private.h index 33f51bfb6e..5010e90655 100644 --- a/src/devices/nm-device-private.h +++ b/src/devices/nm-device-private.h @@ -106,4 +106,11 @@ void nm_device_set_wwan_ip6_config (NMDevice *device, NMIP6Config *config); gboolean nm_device_ipv6_sysctl_set (NMDevice *self, const char *property, const char *value); +#define NM_DEVICE_CLASS_DECLARE_TYPES(klass, conn_type, ...) \ + NM_DEVICE_CLASS (klass)->connection_type = conn_type; \ + { \ + static const NMLinkType link_types[] = { __VA_ARGS__, NM_LINK_TYPE_NONE }; \ + NM_DEVICE_CLASS (klass)->link_types = link_types; \ + } + #endif /* NM_DEVICE_PRIVATE_H */ diff --git a/src/devices/nm-device-tun.c b/src/devices/nm-device-tun.c index 46d4d391e8..af37c3184d 100644 --- a/src/devices/nm-device-tun.c +++ b/src/devices/nm-device-tun.c @@ -364,6 +364,8 @@ nm_device_tun_class_init (NMDeviceTunClass *klass) g_type_class_add_private (klass, sizeof (NMDeviceTunPrivate)); + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NULL, NM_LINK_TYPE_TUN, NM_LINK_TYPE_TAP) + object_class->get_property = get_property; object_class->set_property = set_property; diff --git a/src/devices/nm-device-veth.c b/src/devices/nm-device-veth.c index 9c22ad1e5c..1fd2a5a834 100644 --- a/src/devices/nm-device-veth.c +++ b/src/devices/nm-device-veth.c @@ -153,6 +153,8 @@ nm_device_veth_class_init (NMDeviceVethClass *klass) g_type_class_add_private (klass, sizeof (NMDeviceVethPrivate)); + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NULL, NM_LINK_TYPE_VETH) + object_class->get_property = get_property; object_class->dispose = dispose; diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index 58263c5d0c..734a483bdc 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -667,7 +667,7 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); - parent_class->connection_type = NM_SETTING_VLAN_SETTING_NAME; + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_VLAN_SETTING_NAME, NM_LINK_TYPE_VLAN) g_type_class_add_private (object_class, sizeof (NMDeviceVlanPrivate)); diff --git a/src/devices/nm-device-vxlan.c b/src/devices/nm-device-vxlan.c index 65b3950dd4..ad2f2ba44f 100644 --- a/src/devices/nm-device-vxlan.c +++ b/src/devices/nm-device-vxlan.c @@ -244,6 +244,8 @@ nm_device_vxlan_class_init (NMDeviceVxlanClass *klass) g_type_class_add_private (klass, sizeof (NMDeviceVxlanPrivate)); + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NULL, NM_LINK_TYPE_VXLAN) + object_class->get_property = get_property; device_class->link_changed = link_changed; diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 63df7b71aa..5435440e2d 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -1634,20 +1634,69 @@ link_changed (NMDevice *self, NMPlatformLink *info) nm_device_set_carrier (self, info->connected); } +static gboolean +link_type_compatible (NMDevice *self, + NMLinkType link_type, + gboolean *out_compatible, + GError **error) +{ + NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self); + guint i = 0; + + if (!klass->link_types) { + NM_SET_OUT (out_compatible, FALSE); + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, + "Device does not support platform links"); + return FALSE; + } + + for (i = 0; klass->link_types[i] > NM_LINK_TYPE_UNKNOWN; i++) { + if (klass->link_types[i] == link_type) + return TRUE; + if (klass->link_types[i] == NM_LINK_TYPE_ANY) + return TRUE; + } + + NM_SET_OUT (out_compatible, FALSE); + g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, + "Device does not support platform link type 0x%X", + link_type); + return FALSE; +} + /** * nm_device_realize(): * @self: the #NMDevice * @plink: an existing platform link or %NULL + * @out_compatible: %TRUE on return if @self is compatible with @plink * @error: location to store error, or %NULL * * Initializes and sets up the device using existing backing resources. Before * the device is ready for use nm_device_setup_finish() must be called. + * @out_compatible will only be set if @plink is not %NULL, and * * Returns: %TRUE on success, %FALSE on error */ gboolean -nm_device_realize (NMDevice *self, NMPlatformLink *plink, GError **error) +nm_device_realize (NMDevice *self, + NMPlatformLink *plink, + gboolean *out_compatible, + GError **error) { + NM_SET_OUT (out_compatible, TRUE); + + if (plink) { + if (g_strcmp0 (nm_device_get_iface (self), plink->name) != 0) { + NM_SET_OUT (out_compatible, FALSE); + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, + "Device interface name does not match platform link"); + return FALSE; + } + + if (!link_type_compatible (self, plink->type, out_compatible, error)) + return FALSE; + } + /* Try to realize the device from existing resources */ if (NM_DEVICE_GET_CLASS (self)->realize) { if (!NM_DEVICE_GET_CLASS (self)->realize (self, plink, error)) @@ -1766,7 +1815,7 @@ setup_start (NMDevice *self, NMPlatformLink *plink) g_object_freeze_notify (G_OBJECT (self)); if (plink) { - g_return_if_fail (priv->iface == NULL || strcmp (plink->name, priv->iface) == 0); + g_return_if_fail (link_type_compatible (self, plink->type, NULL, NULL)); update_device_from_platform_link (self, plink); } @@ -1871,6 +1920,8 @@ setup_finish (NMDevice *self, NMPlatformLink *plink) void nm_device_setup_finish (NMDevice *self, NMPlatformLink *plink) { + g_return_if_fail (!plink || link_type_compatible (self, plink->type, NULL, NULL)); + NM_DEVICE_GET_CLASS (self)->setup_finish (self, plink); NM_DEVICE_GET_PRIVATE (self)->real = TRUE; @@ -10073,6 +10124,7 @@ set_property (GObject *object, guint prop_id, const char *hw_addr, *p; guint count; gboolean val_bool; + const NMPlatformLink *pllink; switch (prop_id) { case PROP_UDI: @@ -10082,12 +10134,19 @@ set_property (GObject *object, guint prop_id, } break; case PROP_IFACE: - if (g_value_get_string (value)) { + p = g_value_get_string (value); + if (p) { + g_free (priv->iface); - priv->iface = g_value_dup_string (value); - priv->ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, priv->iface); - if (priv->ifindex > 0) - priv->up = nm_platform_link_is_up (NM_PLATFORM_GET, priv->ifindex); + priv->iface = g_strdup (p); + + pllink = nm_platform_link_get_by_ifname (NM_PLATFORM_GET, priv->iface); + if (pllink) { + if (link_type_compatible (self, pllink->type, NULL, NULL)) { + priv->ifindex = pllink->ifindex; + priv->up = nm_platform_link_is_up (NM_PLATFORM_GET, priv->ifindex); + } + } } break; case PROP_DRIVER: diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 268ed06294..55f05c4fab 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -123,6 +123,7 @@ typedef struct { NMExportedObjectClass parent; const char *connection_type; + const NMLinkType *link_types; void (*state_changed) (NMDevice *device, NMDeviceState new_state, @@ -485,6 +486,7 @@ gboolean nm_device_has_capability (NMDevice *self, NMDeviceCapabilities caps); gboolean nm_device_realize (NMDevice *device, NMPlatformLink *plink, + gboolean *out_compatible, GError **error); gboolean nm_device_create_and_realize (NMDevice *self, NMConnection *connection, diff --git a/src/devices/team/nm-device-team.c b/src/devices/team/nm-device-team.c index 4bbe4c9ce7..fdc603364d 100644 --- a/src/devices/team/nm-device-team.c +++ b/src/devices/team/nm-device-team.c @@ -802,7 +802,7 @@ nm_device_team_class_init (NMDeviceTeamClass *klass) g_type_class_add_private (object_class, sizeof (NMDeviceTeamPrivate)); - parent_class->connection_type = NM_SETTING_TEAM_SETTING_NAME; + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_TEAM_SETTING_NAME, NM_LINK_TYPE_TEAM) /* virtual methods */ object_class->constructed = constructed; diff --git a/src/devices/wifi/nm-device-olpc-mesh.c b/src/devices/wifi/nm-device-olpc-mesh.c index 38f1f88dd4..8898c59cd6 100644 --- a/src/devices/wifi/nm-device-olpc-mesh.c +++ b/src/devices/wifi/nm-device-olpc-mesh.c @@ -511,6 +511,8 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass) g_type_class_add_private (object_class, sizeof (NMDeviceOlpcMeshPrivate)); + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_OLPC_MESH_SETTING_NAME, NM_LINK_TYPE_OLPC_MESH) + object_class->constructor = constructor; object_class->get_property = get_property; object_class->set_property = set_property; diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index bb73e8c456..72540efed4 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -3034,6 +3034,8 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) g_type_class_add_private (object_class, sizeof (NMDeviceWifiPrivate)); + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_WIRELESS_SETTING_NAME, NM_LINK_TYPE_WIFI) + object_class->constructor = constructor; object_class->get_property = get_property; object_class->set_property = set_property; diff --git a/src/nm-manager.c b/src/nm-manager.c index eb0ec6fffc..ba926157f8 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1818,7 +1818,7 @@ factory_device_added_cb (NMDeviceFactory *factory, { GError *error = NULL; - if (nm_device_realize (device, NULL, &error)) { + if (nm_device_realize (device, NULL, NULL, &error)) { add_device (NM_MANAGER (user_data), device); nm_device_setup_finish (device, NULL); } else { @@ -1878,22 +1878,29 @@ platform_link_added (NMManager *self, device = find_device_by_iface (self, plink->name); if (device) { - if (!nm_device_is_real (device)) { - if (nm_device_realize (device, plink, &error)) - nm_device_setup_finish (device, plink); - else { - nm_log_warn (LOGD_DEVICE, "(%s): %s", plink->name, error->message); - g_clear_error (&error); - remove_device (self, device, FALSE, FALSE); - } + gboolean compatible = FALSE; + + if (nm_device_is_real (device)) return; - } else if (!nm_device_realize (device, plink, &error)) { - nm_log_warn (LOGD_HW, "%s: factory failed to create device: %s", - plink->name, error->message); - g_clear_error (&error); + + if (nm_device_realize (device, plink, &compatible, &error)) { + /* Success */ + nm_device_setup_finish (device, plink); return; } - return; + + nm_log_warn (LOGD_DEVICE, "(%s): %s", plink->name, error->message); + remove_device (self, device, FALSE, FALSE); + g_clear_error (&error); + + if (compatible) { + /* Device compatible with platform link, but some other fatal error + * happened during realization. + */ + return; + } + + /* Fall through and create new compatible device for the link */ } /* Try registered device factories */ @@ -1932,7 +1939,7 @@ platform_link_added (NMManager *self, if (device) { if (nm_plugin_missing) nm_device_set_nm_plugin_missing (device, TRUE); - if (nm_device_realize (device, plink, &error)) { + if (nm_device_realize (device, plink, NULL, &error)) { add_device (self, device); nm_device_setup_finish (device, plink); } else { diff --git a/src/nm-types.h b/src/nm-types.h index 16ae6fa7b4..65d6193be2 100644 --- a/src/nm-types.h +++ b/src/nm-types.h @@ -126,6 +126,8 @@ typedef enum { NM_LINK_TYPE_BRIDGE = 0x10000 | 0x20000, NM_LINK_TYPE_BOND, NM_LINK_TYPE_TEAM, + + NM_LINK_TYPE_ANY = G_MAXUINT32, } NMLinkType; typedef enum { |