summary refs log tree commit diff
path: root/src/platform
diff options
context:
space:
mode:
Diffstat (limited to 'src/platform')
-rw-r--r--src/platform/nm-fake-platform.c14
-rw-r--r--src/platform/nm-linux-platform.c38
-rw-r--r--src/platform/nm-platform.c50
-rw-r--r--src/platform/nm-platform.h4
4 files changed, 88 insertions, 18 deletions
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);