summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2015-12-08 18:14:53 +0100
committerLubomir Rintel <lkundrak@v3.sk>2015-12-08 18:14:53 +0100
commite68619df061aca91ffac5ae4dd9cb95810da329b (patch)
tree829eb4107db4bf8b2a4fe0075380ccaa1d526384
parent5201c3d8f96a03a8b8de1211ed9a10e59446c2ea (diff)
parent1762d58a8cf7fbd21b6940fb2a15c136952a9603 (diff)
downloadNetworkManager-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.c1
-rw-r--r--src/devices/nm-device-bridge.c1
-rw-r--r--src/devices/nm-device-ethernet.c1
-rw-r--r--src/devices/nm-device-infiniband.c2
-rw-r--r--src/devices/nm-device-ip-tunnel.c25
-rw-r--r--src/devices/nm-device-macvlan.c3
-rw-r--r--src/devices/nm-device-tun.c24
-rw-r--r--src/devices/nm-device-veth.c1
-rw-r--r--src/devices/nm-device-vlan.c1
-rw-r--r--src/devices/nm-device-vxlan.c1
-rw-r--r--src/devices/nm-device.c73
-rw-r--r--src/devices/nm-device.h2
-rw-r--r--src/devices/team/nm-device-team.c1
-rw-r--r--src/devices/wifi/nm-device-olpc-mesh.c1
-rw-r--r--src/devices/wifi/nm-device-wifi.c1
-rw-r--r--src/nm-manager.c25
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",