diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2015-12-08 18:14:53 +0100 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2015-12-08 18:14:53 +0100 |
commit | e68619df061aca91ffac5ae4dd9cb95810da329b (patch) | |
tree | 829eb4107db4bf8b2a4fe0075380ccaa1d526384 | |
parent | 5201c3d8f96a03a8b8de1211ed9a10e59446c2ea (diff) | |
parent | 1762d58a8cf7fbd21b6940fb2a15c136952a9603 (diff) | |
download | NetworkManager-e68619df061aca91ffac5ae4dd9cb95810da329b.tar.gz |
merge: branch 'lr/device-link-type'
Avoids a mismatch of incompatible devices of the same class. Consider two
devices of tap class, one of tun mode and one of tap mode.
-rw-r--r-- | src/devices/nm-device-bond.c | 1 | ||||
-rw-r--r-- | src/devices/nm-device-bridge.c | 1 | ||||
-rw-r--r-- | src/devices/nm-device-ethernet.c | 1 | ||||
-rw-r--r-- | src/devices/nm-device-infiniband.c | 2 | ||||
-rw-r--r-- | src/devices/nm-device-ip-tunnel.c | 25 | ||||
-rw-r--r-- | src/devices/nm-device-macvlan.c | 3 | ||||
-rw-r--r-- | src/devices/nm-device-tun.c | 24 | ||||
-rw-r--r-- | src/devices/nm-device-veth.c | 1 | ||||
-rw-r--r-- | src/devices/nm-device-vlan.c | 1 | ||||
-rw-r--r-- | src/devices/nm-device-vxlan.c | 1 | ||||
-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 | 1 | ||||
-rw-r--r-- | src/devices/wifi/nm-device-olpc-mesh.c | 1 | ||||
-rw-r--r-- | src/devices/wifi/nm-device-wifi.c | 1 | ||||
-rw-r--r-- | src/nm-manager.c | 25 |
16 files changed, 137 insertions, 26 deletions
diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c index 6510065d55..6471d3e4a2 100644 --- a/src/devices/nm-device-bond.c +++ b/src/devices/nm-device-bond.c @@ -523,6 +523,7 @@ create_device (NMDeviceFactory *factory, NM_DEVICE_DRIVER, "bonding", NM_DEVICE_TYPE_DESC, "Bond", NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BOND, + NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_BOND, NM_DEVICE_IS_MASTER, TRUE, NULL); } diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c index e43ce858b6..39d41ae4d4 100644 --- a/src/devices/nm-device-bridge.c +++ b/src/devices/nm-device-bridge.c @@ -471,6 +471,7 @@ create_device (NMDeviceFactory *factory, NM_DEVICE_DRIVER, "bridge", NM_DEVICE_TYPE_DESC, "Bridge", NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BRIDGE, + NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_BRIDGE, NM_DEVICE_IS_MASTER, TRUE, NULL); } diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index 68e16f20b2..9aec4ca66f 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -1776,6 +1776,7 @@ create_device (NMDeviceFactory *factory, NM_DEVICE_IFACE, iface, NM_DEVICE_TYPE_DESC, "Ethernet", NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_ETHERNET, + NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_ETHERNET, NULL); } diff --git a/src/devices/nm-device-infiniband.c b/src/devices/nm-device-infiniband.c index 95f69c93c3..50b7f1bb8f 100644 --- a/src/devices/nm-device-infiniband.c +++ b/src/devices/nm-device-infiniband.c @@ -385,6 +385,8 @@ create_device (NMDeviceFactory *factory, NM_DEVICE_IFACE, iface, NM_DEVICE_TYPE_DESC, "InfiniBand", NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_INFINIBAND, + NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_INFINIBAND, + /* XXX: Partition should probably be a different link type! */ NM_DEVICE_INFINIBAND_IS_PARTITION, is_partition, NULL); } diff --git a/src/devices/nm-device-ip-tunnel.c b/src/devices/nm-device-ip-tunnel.c index 84ab7cd69d..0e3e53d877 100644 --- a/src/devices/nm-device-ip-tunnel.c +++ b/src/devices/nm-device-ip-tunnel.c @@ -570,6 +570,24 @@ platform_link_to_tunnel_mode (const NMPlatformLink *link) } } +static NMLinkType +tunnel_mode_to_link_type (NMIPTunnelMode tunnel_mode) +{ + switch (tunnel_mode) { + case NM_IP_TUNNEL_MODE_GRE: + return NM_LINK_TYPE_GRE; + case NM_IP_TUNNEL_MODE_IPIP6: + case NM_IP_TUNNEL_MODE_IP6IP6: + return NM_LINK_TYPE_IP6TNL; + case NM_IP_TUNNEL_MODE_IPIP: + return NM_LINK_TYPE_IPIP; + case NM_IP_TUNNEL_MODE_SIT: + return NM_LINK_TYPE_SIT; + default: + g_return_val_if_reached (NM_LINK_TYPE_UNKNOWN); + } +} + /**************************************************************/ static void @@ -957,12 +975,16 @@ create_device (NMDeviceFactory *factory, { NMSettingIPTunnel *s_ip_tunnel; NMIPTunnelMode mode; + NMLinkType link_type; if (connection) { s_ip_tunnel = nm_connection_get_setting_ip_tunnel (connection); mode = nm_setting_ip_tunnel_get_mode (s_ip_tunnel); - } else + link_type = tunnel_mode_to_link_type (mode); + } else { + link_type = plink->type; mode = platform_link_to_tunnel_mode (plink); + } if (mode == NM_IP_TUNNEL_MODE_UKNOWN) return NULL; @@ -971,6 +993,7 @@ create_device (NMDeviceFactory *factory, NM_DEVICE_IFACE, iface, NM_DEVICE_TYPE_DESC, "IPTunnel", NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_IP_TUNNEL, + NM_DEVICE_LINK_TYPE, link_type, NM_DEVICE_IP_TUNNEL_MODE, mode, NULL); } diff --git a/src/devices/nm-device-macvlan.c b/src/devices/nm-device-macvlan.c index aed28816ff..ab650acab7 100644 --- a/src/devices/nm-device-macvlan.c +++ b/src/devices/nm-device-macvlan.c @@ -189,10 +189,13 @@ create_device (NMDeviceFactory *factory, NMConnection *connection, gboolean *out_ignore) { + g_return_val_if_fail (plink, NULL); + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_MACVLAN, NM_DEVICE_IFACE, iface, NM_DEVICE_TYPE_DESC, "Macvlan", NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC, + NM_DEVICE_LINK_TYPE, plink->type, NULL); } diff --git a/src/devices/nm-device-tun.c b/src/devices/nm-device-tun.c index 60d9d7bba2..a170fe6533 100644 --- a/src/devices/nm-device-tun.c +++ b/src/devices/nm-device-tun.c @@ -449,10 +449,34 @@ create_device (NMDeviceFactory *factory, NMConnection *connection, gboolean *out_ignore) { + NMSettingTun *s_tun; + NMLinkType link_type = NM_LINK_TYPE_UNKNOWN; + + if (plink) { + link_type = plink->type; + } else if (connection) { + s_tun = nm_connection_get_setting_tun (connection); + if (!s_tun) + return NULL; + switch (nm_setting_tun_get_mode (s_tun)) { + case NM_SETTING_TUN_MODE_TUN: + link_type = NM_LINK_TYPE_TUN; + break; + case NM_SETTING_TUN_MODE_TAP: + link_type = NM_LINK_TYPE_TAP; + break; + case NM_SETTING_TUN_MODE_UNKNOWN: + g_return_val_if_reached (NULL); + } + } + + g_return_val_if_fail (link_type != NM_LINK_TYPE_UNKNOWN, NULL); + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_TUN, NM_DEVICE_IFACE, iface, NM_DEVICE_TYPE_DESC, "Tun", NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_TUN, + NM_DEVICE_LINK_TYPE, link_type, NULL); } diff --git a/src/devices/nm-device-veth.c b/src/devices/nm-device-veth.c index 1fd2a5a834..07187205fb 100644 --- a/src/devices/nm-device-veth.c +++ b/src/devices/nm-device-veth.c @@ -189,6 +189,7 @@ create_device (NMDeviceFactory *factory, NM_DEVICE_IFACE, iface, NM_DEVICE_TYPE_DESC, "Veth", NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_ETHERNET, + NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_VETH, NULL); } diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index 7861cf2b4d..63938c8968 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -727,6 +727,7 @@ create_device (NMDeviceFactory *factory, NM_DEVICE_DRIVER, "8021q", NM_DEVICE_TYPE_DESC, "VLAN", NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_VLAN, + NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_VLAN, NULL); } diff --git a/src/devices/nm-device-vxlan.c b/src/devices/nm-device-vxlan.c index ad2f2ba44f..beee9f2c6c 100644 --- a/src/devices/nm-device-vxlan.c +++ b/src/devices/nm-device-vxlan.c @@ -386,6 +386,7 @@ create_device (NMDeviceFactory *factory, NM_DEVICE_IFACE, iface, NM_DEVICE_TYPE_DESC, "Vxlan", NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC, + NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_VXLAN, NULL); } diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 7bf55a77f0..3a4e7cc946 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -114,6 +114,7 @@ enum { PROP_STATE_REASON, PROP_ACTIVE_CONNECTION, PROP_DEVICE_TYPE, + PROP_LINK_TYPE, PROP_MANAGED, PROP_AUTOCONNECT, PROP_FIRMWARE_MISSING, @@ -215,6 +216,7 @@ typedef struct _NMDevicePrivate { NMDeviceType type; char * type_desc; char * type_description; + NMLinkType link_type; NMDeviceCapabilities capabilities; char * driver; char * driver_version; @@ -710,6 +712,14 @@ nm_device_get_device_type (NMDevice *self) return NM_DEVICE_GET_PRIVATE (self)->type; } +NMLinkType +nm_device_get_link_type (NMDevice *self) +{ + g_return_val_if_fail (NM_IS_DEVICE (self), NM_LINK_TYPE_UNKNOWN); + + return NM_DEVICE_GET_PRIVATE (self)->link_type; +} + /** * nm_device_get_metered: * @setting: the #NMDevice @@ -1646,9 +1656,14 @@ link_type_compatible (NMDevice *self, gboolean *out_compatible, GError **error) { - NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self); + NMDeviceClass *klass; + NMLinkType device_type; guint i = 0; + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + + klass = NM_DEVICE_GET_CLASS (self); + if (!klass->link_types) { NM_SET_OUT (out_compatible, FALSE); g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, @@ -1656,6 +1671,14 @@ link_type_compatible (NMDevice *self, return FALSE; } + device_type = self->priv->link_type; + if (device_type > NM_LINK_TYPE_UNKNOWN && device_type != link_type) { + g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, + "Needed link type 0x%x does not match the platform link type 0x%X", + device_type, link_type); + return FALSE; + } + for (i = 0; klass->link_types[i] > NM_LINK_TYPE_UNKNOWN; i++) { if (klass->link_types[i] == link_type) return TRUE; @@ -10064,12 +10087,25 @@ constructed (GObject *object) NMDevice *self = NM_DEVICE (object); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMPlatform *platform; + const NMPlatformLink *pllink; + + platform = nm_platform_get (); + + if (priv->iface) { + pllink = nm_platform_link_get_by_ifname (platform, priv->iface); + + nm_assert (pllink->type != NM_LINK_TYPE_NONE); + + if (pllink && link_type_compatible (self, pllink->type, NULL, NULL)) { + priv->ifindex = pllink->ifindex; + priv->up = NM_FLAGS_HAS (pllink->flags, IFF_UP); + } + } if (NM_DEVICE_GET_CLASS (self)->get_generic_capabilities) priv->capabilities |= NM_DEVICE_GET_CLASS (self)->get_generic_capabilities (self); /* Watch for external IP config changes */ - platform = nm_platform_get (); g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, G_CALLBACK (device_ipx_changed), self); g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, G_CALLBACK (device_ipx_changed), self); g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, G_CALLBACK (device_ipx_changed), self); @@ -10214,7 +10250,6 @@ 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: @@ -10224,20 +10259,9 @@ set_property (GObject *object, guint prop_id, } break; case PROP_IFACE: - p = g_value_get_string (value); - if (p) { - - g_free (priv->iface); - 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); - } - } - } + /* construct only */ + g_return_if_fail (!priv->iface); + priv->iface = g_value_dup_string (value); break; case PROP_DRIVER: if (g_value_get_string (value)) { @@ -10280,6 +10304,11 @@ set_property (GObject *object, guint prop_id, g_return_if_fail (priv->type == NM_DEVICE_TYPE_UNKNOWN); priv->type = g_value_get_uint (value); break; + case PROP_LINK_TYPE: + /* construct only */ + g_return_if_fail (priv->link_type == NM_LINK_TYPE_NONE); + priv->link_type = g_value_get_uint (value); + break; case PROP_TYPE_DESC: g_free (priv->type_desc); priv->type_desc = g_value_dup_string (value); @@ -10396,6 +10425,9 @@ get_property (GObject *object, guint prop_id, case PROP_DEVICE_TYPE: g_value_set_uint (value, priv->type); break; + case PROP_LINK_TYPE: + g_value_set_uint (value, priv->link_type); + break; case PROP_MANAGED: g_value_set_boolean (value, nm_device_get_managed (self)); break; @@ -10649,6 +10681,13 @@ nm_device_class_init (NMDeviceClass *klass) G_PARAM_STATIC_STRINGS)); g_object_class_install_property + (object_class, PROP_LINK_TYPE, + g_param_spec_uint (NM_DEVICE_LINK_TYPE, "", "", + 0, G_MAXUINT32, NM_LINK_TYPE_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_MANAGED, g_param_spec_boolean (NM_DEVICE_MANAGED, "", "", FALSE, diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 6f9e0462e0..48398faf05 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -49,6 +49,7 @@ #define NM_DEVICE_STATE_REASON "state-reason" #define NM_DEVICE_ACTIVE_CONNECTION "active-connection" #define NM_DEVICE_DEVICE_TYPE "device-type" /* ugh */ +#define NM_DEVICE_LINK_TYPE "link-type" #define NM_DEVICE_MANAGED "managed" #define NM_DEVICE_AUTOCONNECT "autoconnect" #define NM_DEVICE_FIRMWARE_MISSING "firmware-missing" @@ -372,6 +373,7 @@ const char * nm_device_get_driver_version (NMDevice *dev); const char * nm_device_get_type_desc (NMDevice *dev); const char * nm_device_get_type_description (NMDevice *dev); NMDeviceType nm_device_get_device_type (NMDevice *dev); +NMLinkType nm_device_get_link_type (NMDevice *dev); NMMetered nm_device_get_metered (NMDevice *dev); int nm_device_get_priority (NMDevice *dev); diff --git a/src/devices/team/nm-device-team.c b/src/devices/team/nm-device-team.c index 9ab848dedf..c91e2c404b 100644 --- a/src/devices/team/nm-device-team.c +++ b/src/devices/team/nm-device-team.c @@ -702,6 +702,7 @@ nm_device_team_new (const char *iface) NM_DEVICE_DRIVER, "team", NM_DEVICE_TYPE_DESC, "Team", NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_TEAM, + NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_TEAM, NM_DEVICE_IS_MASTER, TRUE, NULL); } diff --git a/src/devices/wifi/nm-device-olpc-mesh.c b/src/devices/wifi/nm-device-olpc-mesh.c index 585c7022ad..9642e0955a 100644 --- a/src/devices/wifi/nm-device-olpc-mesh.c +++ b/src/devices/wifi/nm-device-olpc-mesh.c @@ -421,6 +421,7 @@ nm_device_olpc_mesh_new (const char *iface) NM_DEVICE_IFACE, iface, NM_DEVICE_TYPE_DESC, "802.11 OLPC Mesh", NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_OLPC_MESH, + NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_OLPC_MESH, NULL); } diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index 8f3630c84a..6febd10b55 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -2927,6 +2927,7 @@ nm_device_wifi_new (const char *iface) NM_DEVICE_IFACE, iface, NM_DEVICE_TYPE_DESC, "802.11 WiFi", NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_WIFI, + NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_WIFI, NM_DEVICE_RFKILL_TYPE, RFKILL_TYPE_WLAN, NULL); } diff --git a/src/nm-manager.c b/src/nm-manager.c index ed556fd66d..27aa603e79 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -58,7 +58,7 @@ #include "nmdbus-manager.h" #include "nmdbus-device.h" -static void add_device (NMManager *self, NMDevice *device); +static gboolean add_device (NMManager *self, NMDevice *device, GError **error); static NMActiveConnection *_new_active_connection (NMManager *self, NMConnection *connection, @@ -1056,7 +1056,10 @@ system_create_virtual_device (NMManager *self, NMConnection *connection, GError if (!device) return NULL; - add_device (self, device); + if (!add_device (self, device, error)) { + g_object_unref (device); + return NULL; + } /* Add device takes a reference that NMManager still owns, so it's * safe to unref here and still return @device. @@ -1748,12 +1751,13 @@ device_realized (NMDevice *device, * add_device: * @self: the #NMManager * @device: the #NMDevice to add + * @error: (out): the #GError * * If successful, this function will increase the references count of @device. * Callers should decrease the reference count. */ -static void -add_device (NMManager *self, NMDevice *device) +static gboolean +add_device (NMManager *self, NMDevice *device, GError **error) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); const char *iface, *type_desc; @@ -1765,8 +1769,11 @@ add_device (NMManager *self, NMDevice *device) /* No duplicates */ ifindex = nm_device_get_ifindex (device); - if (ifindex > 0 && nm_manager_get_device_by_ifindex (self, ifindex)) - return; + if (ifindex > 0 && nm_manager_get_device_by_ifindex (self, ifindex)) { + g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED, + "A device with ifindex %d already exits", ifindex); + return FALSE; + } /* Remove existing devices owned by the new device; eg remove ethernet * ports that are owned by a WWAN modem, since udev may announce them @@ -1861,6 +1868,8 @@ add_device (NMManager *self, NMDevice *device) if (d != device) nm_device_notify_new_device_added (d, device); } + + return TRUE; } /*******************************************************************/ @@ -1873,7 +1882,7 @@ factory_device_added_cb (NMDeviceFactory *factory, GError *error = NULL; if (nm_device_realize (device, NULL, NULL, &error)) { - add_device (NM_MANAGER (user_data), device); + add_device (NM_MANAGER (user_data), device, NULL); nm_device_setup_finish (device, NULL); } else { nm_log_warn (LOGD_DEVICE, "(%s): failed to realize device: %s", @@ -1994,7 +2003,7 @@ platform_link_added (NMManager *self, if (nm_plugin_missing) nm_device_set_nm_plugin_missing (device, TRUE); if (nm_device_realize (device, plink, NULL, &error)) { - add_device (self, device); + add_device (self, device, NULL); nm_device_setup_finish (device, plink); } else { nm_log_warn (LOGD_DEVICE, "%s: failed to realize device: %s", |