summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-10-29 11:27:55 +0100
committerThomas Haller <thaller@redhat.com>2015-11-02 13:57:02 +0100
commit4b1e1f8aabcc61337b04ebd5ce956327b2e7ce03 (patch)
tree8fcc4594e4a551b217e378f078230961561e09d4
parentf8fa4a0970464c0a6851dbc60d28c55aef81d403 (diff)
downloadNetworkManager-4b1e1f8aabcc61337b04ebd5ce956327b2e7ce03.tar.gz
platform: promise that the link lnk is an immutable NMPObject and expose it
Expose internal lnk object and promise in the API that the object will not be modified (which allows the user to ref it).
-rw-r--r--src/nm-types.h2
-rw-r--r--src/platform/nm-fake-platform.c35
-rw-r--r--src/platform/nm-linux-platform.c34
-rw-r--r--src/platform/nm-platform.c44
-rw-r--r--src/platform/nm-platform.h4
-rw-r--r--src/platform/nmp-object.c5
-rw-r--r--src/platform/nmp-object.h3
-rw-r--r--src/platform/tests/test-link.c20
8 files changed, 91 insertions, 56 deletions
diff --git a/src/nm-types.h b/src/nm-types.h
index 517316cdbc..6dbd3b3b45 100644
--- a/src/nm-types.h
+++ b/src/nm-types.h
@@ -79,6 +79,8 @@ typedef struct _NMPlatformIP6Address NMPlatformIP6Address;
typedef struct _NMPlatformIP6Route NMPlatformIP6Route;
typedef struct _NMPlatformLink NMPlatformLink;
+typedef struct _NMPObject NMPObject;
+
typedef enum {
/* Please don't interpret type numbers outside nm-platform and use functions
* like nm_platform_link_is_software() and nm_platform_supports_slaves().
diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c
index d1080d47ec..663930ebac 100644
--- a/src/platform/nm-fake-platform.c
+++ b/src/platform/nm-fake-platform.c
@@ -27,6 +27,7 @@
#include <linux/rtnetlink.h>
#include "nm-utils.h"
+#include "nmp-object.h"
#include "NetworkManagerUtils.h"
#include "nm-fake-platform.h"
#include "nm-default.h"
@@ -74,8 +75,7 @@ typedef struct {
NMPlatformLink link;
char *udi;
- NMPlatformLnkVlan lnk_vlan;
- NMPlatformLnkInfiniband lnk_infiniband;
+ NMPObject *lnk;
struct in6_addr ip6_lladdr;
} NMFakePlatformLink;
@@ -260,7 +260,7 @@ _nm_platform_link_get_by_address (NMPlatform *platform,
return NULL;
}
-static gconstpointer
+static const NMPObject *
link_get_lnk (NMPlatform *platform,
int ifindex,
NMLinkType link_type,
@@ -273,17 +273,17 @@ link_get_lnk (NMPlatform *platform,
NM_SET_OUT (out_link, &device->link);
- if (link_type != device->link.type)
+ if (!device->lnk)
return NULL;
- switch (link_type) {
- case NM_LINK_TYPE_VLAN:
- return &device->lnk_vlan;
- case NM_LINK_TYPE_INFINIBAND:
- return &device->lnk_infiniband;
- default:
+ if (link_type == NM_LINK_TYPE_NONE)
+ return device->lnk;
+
+ if ( link_type != device->link.type
+ || link_type != NMP_OBJECT_GET_CLASS (device->lnk)->lnk_link_type)
return NULL;
- }
+
+ return device->lnk;
}
static gboolean
@@ -331,6 +331,8 @@ link_delete (NMPlatform *platform, int ifindex)
memcpy (&deleted_device, &device->link, sizeof (deleted_device));
memset (&device->link, 0, sizeof (device->link));
+ g_clear_pointer (&device->lnk, nmp_object_unref);
+ g_clear_pointer (&device->udi, g_free);
/* Remove addresses and routes which belong to the deleted interface */
for (i = 0; i < priv->ip4_addresses->len; i++) {
@@ -671,8 +673,10 @@ vlan_add (NMPlatform *platform, const char *name, int parent, int vlan_id, guint
device = link_get (platform, nm_platform_link_get_ifindex (platform, name));
g_return_val_if_fail (device, FALSE);
+ g_return_val_if_fail (!device->lnk, FALSE);
- device->lnk_vlan.id = vlan_id;
+ device->lnk = nmp_object_new (NMP_OBJECT_TYPE_LNK_VLAN, NULL);
+ device->lnk->lnk_vlan.id = vlan_id;
device->link.parent = parent;
if (out_link)
@@ -707,9 +711,11 @@ infiniband_partition_add (NMPlatform *platform, int parent, int p_key, NMPlatfor
device = link_get (platform, nm_platform_link_get_ifindex (platform, name));
g_return_val_if_fail (device, FALSE);
+ g_return_val_if_fail (!device->lnk, FALSE);
- device->lnk_infiniband.p_key = p_key;
- device->lnk_infiniband.mode = "datagram";
+ device->lnk = nmp_object_new (NMP_OBJECT_TYPE_LNK_VLAN, NULL);
+ device->lnk->lnk_infiniband.p_key = p_key;
+ device->lnk->lnk_infiniband.mode = "datagram";
device->link.parent = parent;
return TRUE;
@@ -1381,6 +1387,7 @@ nm_fake_platform_finalize (GObject *object)
NMFakePlatformLink *device = &g_array_index (priv->links, NMFakePlatformLink, i);
g_free (device->udi);
+ g_clear_pointer (&device->lnk, nmp_object_unref);
}
g_array_unref (priv->links);
g_array_unref (priv->ip4_addresses);
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index f82806e8e7..21b565564b 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -3252,7 +3252,7 @@ _nm_platform_link_get_by_address (NMPlatform *platform,
/*****************************************************************************/
-static gconstpointer
+static const NMPObject *
link_get_lnk (NMPlatform *platform, int ifindex, NMLinkType link_type, const NMPlatformLink **out_link)
{
const NMPObject *obj = cache_lookup_link (platform, ifindex);
@@ -3262,34 +3262,14 @@ link_get_lnk (NMPlatform *platform, int ifindex, NMLinkType link_type, const NMP
NM_SET_OUT (out_link, &obj->link);
- if (link_type != obj->link.type)
+ if (!obj->_link.netlink.lnk)
+ return NULL;
+ if ( link_type != NM_LINK_TYPE_NONE
+ && ( link_type != obj->link.type
+ || link_type != NMP_OBJECT_GET_CLASS (obj->_link.netlink.lnk)->lnk_link_type))
return NULL;
- switch (link_type) {
- case NM_LINK_TYPE_GRE:
- if (NMP_OBJECT_GET_TYPE (obj->_link.netlink.lnk) == NMP_OBJECT_TYPE_LNK_GRE)
- return &obj->_link.netlink.lnk->lnk_gre;
- break;
- case NM_LINK_TYPE_INFINIBAND:
- if (NMP_OBJECT_GET_TYPE (obj->_link.netlink.lnk) == NMP_OBJECT_TYPE_LNK_INFINIBAND)
- return &obj->_link.netlink.lnk->lnk_infiniband;
- break;
- case NM_LINK_TYPE_MACVLAN:
- if (NMP_OBJECT_GET_TYPE (obj->_link.netlink.lnk) == NMP_OBJECT_TYPE_LNK_MACVLAN)
- return &obj->_link.netlink.lnk->lnk_macvlan;
- break;
- case NM_LINK_TYPE_VLAN:
- if (NMP_OBJECT_GET_TYPE (obj->_link.netlink.lnk) == NMP_OBJECT_TYPE_LNK_VLAN)
- return &obj->_link.netlink.lnk->lnk_vlan;
- break;
- case NM_LINK_TYPE_VXLAN:
- if (NMP_OBJECT_GET_TYPE (obj->_link.netlink.lnk) == NMP_OBJECT_TYPE_LNK_VXLAN)
- return &obj->_link.netlink.lnk->lnk_vxlan;
- break;
- default:
- break;
- }
- return NULL;
+ return obj->_link.netlink.lnk;
}
/*****************************************************************************/
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
index 12f12b9f30..55794c1c54 100644
--- a/src/platform/nm-platform.c
+++ b/src/platform/nm-platform.c
@@ -36,6 +36,7 @@
#include "nm-utils.h"
#include "nm-platform.h"
#include "nm-platform-utils.h"
+#include "nmp-object.h"
#include "NetworkManagerUtils.h"
#include "nm-default.h"
#include "nm-enum-types.h"
@@ -1369,7 +1370,29 @@ nm_platform_link_get_master (NMPlatform *self, int slave)
/*****************************************************************************/
-gconstpointer
+/**
+ * nm_platform_link_get_lnk:
+ * @self: the platform instance
+ * @ifindex: the link ifindex to lookup
+ * @link_type: filter by link-type.
+ * @out_link: (allow-none): returns the platform link instance
+ *
+ * If the function returns %NULL, that could mean that no such ifindex
+ * exists, of that the link has no lnk data. You can find that out
+ * by checking @out_link. @out_link will always be set if a link
+ * with @ifindex exists.
+ *
+ * If @link_type is %NM_LINK_TYPE_NONE, the function returns the lnk
+ * object if it is present. If you set link-type, you can be sure
+ * that only a link type of the matching type is returned (or %NULL).
+ *
+ * Returns: the internal link lnk object. The returned object
+ * is owned by the platform cache and must not be modified. Note
+ * however, that the object is guaranteed to be immutable, so
+ * you can savely take a reference and keep it for yourself
+ * (but don't modify it).
+ */
+const NMPObject *
nm_platform_link_get_lnk (NMPlatform *self, int ifindex, NMLinkType link_type, const NMPlatformLink **out_link)
{
_CHECK_SELF (self, klass, FALSE);
@@ -1381,34 +1404,43 @@ nm_platform_link_get_lnk (NMPlatform *self, int ifindex, NMLinkType link_type, c
return klass->link_get_lnk (self, ifindex, link_type, out_link);
}
+static gconstpointer
+_link_get_lnk (NMPlatform *self, int ifindex, NMLinkType link_type, const NMPlatformLink **out_link)
+{
+ const NMPObject *lnk;
+
+ lnk = nm_platform_link_get_lnk (self, ifindex, link_type, out_link);
+ return lnk ? &lnk->object : NULL;
+}
+
const NMPlatformLnkGre *
nm_platform_link_get_lnk_gre (NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
{
- return nm_platform_link_get_lnk (self, ifindex, NM_LINK_TYPE_GRE, out_link);
+ return _link_get_lnk (self, ifindex, NM_LINK_TYPE_GRE, out_link);
}
const NMPlatformLnkInfiniband *
nm_platform_link_get_lnk_infiniband (NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
{
- return nm_platform_link_get_lnk (self, ifindex, NM_LINK_TYPE_INFINIBAND, out_link);
+ return _link_get_lnk (self, ifindex, NM_LINK_TYPE_INFINIBAND, out_link);
}
const NMPlatformLnkMacvlan *
nm_platform_link_get_lnk_macvlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
{
- return nm_platform_link_get_lnk (self, ifindex, NM_LINK_TYPE_MACVLAN, out_link);
+ return _link_get_lnk (self, ifindex, NM_LINK_TYPE_MACVLAN, out_link);
}
const NMPlatformLnkVlan *
nm_platform_link_get_lnk_vlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
{
- return nm_platform_link_get_lnk (self, ifindex, NM_LINK_TYPE_VLAN, out_link);
+ return _link_get_lnk (self, ifindex, NM_LINK_TYPE_VLAN, out_link);
}
const NMPlatformLnkVxlan *
nm_platform_link_get_lnk_vxlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
{
- return nm_platform_link_get_lnk (self, ifindex, NM_LINK_TYPE_VXLAN, out_link);
+ return _link_get_lnk (self, ifindex, NM_LINK_TYPE_VXLAN, out_link);
}
/*****************************************************************************/
diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h
index 31b28700a4..fa53792fc9 100644
--- a/src/platform/nm-platform.h
+++ b/src/platform/nm-platform.h
@@ -457,7 +457,7 @@ typedef struct {
const NMPlatformLink *(*link_get_by_ifname) (NMPlatform *platform, const char *ifname);
const NMPlatformLink *(*link_get_by_address) (NMPlatform *platform, gconstpointer address, size_t length);
- gconstpointer (*link_get_lnk) (NMPlatform *platform, int ifindex, NMLinkType link_type, const NMPlatformLink **out_link);
+ const NMPObject *(*link_get_lnk) (NMPlatform *platform, int ifindex, NMLinkType link_type, const NMPlatformLink **out_link);
GArray *(*link_get_all) (NMPlatform *);
gboolean (*link_add) (NMPlatform *,
@@ -696,7 +696,7 @@ char *nm_platform_master_get_option (NMPlatform *self, int ifindex, const char *
gboolean nm_platform_slave_set_option (NMPlatform *self, int ifindex, const char *option, const char *value);
char *nm_platform_slave_get_option (NMPlatform *self, int ifindex, const char *option);
-gconstpointer nm_platform_link_get_lnk (NMPlatform *self, int ifindex, NMLinkType link_type, const NMPlatformLink **out_link);
+const NMPObject *nm_platform_link_get_lnk (NMPlatform *self, int ifindex, NMLinkType link_type, const NMPlatformLink **out_link);
const NMPlatformLnkGre *nm_platform_link_get_lnk_gre (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
const NMPlatformLnkInfiniband *nm_platform_link_get_lnk_infiniband (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
const NMPlatformLnkMacvlan *nm_platform_link_get_lnk_macvlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c
index 1eec649320..0e5222f459 100644
--- a/src/platform/nmp-object.c
+++ b/src/platform/nmp-object.c
@@ -1891,6 +1891,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
.sizeof_data = sizeof (NMPObjectLnkGre),
.sizeof_public = sizeof (NMPlatformLnkGre),
.obj_type_name = "gre",
+ .lnk_link_type = NM_LINK_TYPE_GRE,
.cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_gre_to_string,
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_gre_cmp,
},
@@ -1899,6 +1900,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
.sizeof_data = sizeof (NMPObjectLnkInfiniband),
.sizeof_public = sizeof (NMPlatformLnkInfiniband),
.obj_type_name = "infiniband",
+ .lnk_link_type = NM_LINK_TYPE_INFINIBAND,
.cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_infiniband_to_string,
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_infiniband_cmp,
},
@@ -1907,6 +1909,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
.sizeof_data = sizeof (NMPObjectLnkMacvlan),
.sizeof_public = sizeof (NMPlatformLnkMacvlan),
.obj_type_name = "macvlan",
+ .lnk_link_type = NM_LINK_TYPE_MACVLAN,
.cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_macvlan_to_string,
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_macvlan_cmp,
},
@@ -1915,6 +1918,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
.sizeof_data = sizeof (NMPObjectLnkVlan),
.sizeof_public = sizeof (NMPlatformLnkVlan),
.obj_type_name = "vlan",
+ .lnk_link_type = NM_LINK_TYPE_VLAN,
.cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_vlan_to_string,
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_vlan_cmp,
},
@@ -1923,6 +1927,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
.sizeof_data = sizeof (NMPObjectLnkVxlan),
.sizeof_public = sizeof (NMPlatformLnkVxlan),
.obj_type_name = "vxlan",
+ .lnk_link_type = NM_LINK_TYPE_VXLAN,
.cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_vxlan_to_string,
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_vxlan_cmp,
},
diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h
index e92fabcb1f..efced61879 100644
--- a/src/platform/nmp-object.h
+++ b/src/platform/nmp-object.h
@@ -119,6 +119,9 @@ typedef struct {
const char *obj_type_name;
const char *signal_type;
+ /* Only for NMPObjectLnk* types. */
+ NMLinkType lnk_link_type;
+
/* returns %FALSE, if the obj type would never have an entry for index type @id_type. If @obj has an index,
* initialize @id and set @out_id to it. Otherwise, @out_id is NULL. */
gboolean (*cmd_obj_init_cache_id) (const NMPObject *obj, NMPCacheIdType id_type, NMPCacheId *id, const NMPCacheId **out_id);
diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c
index b059bb1816..645d9f6342 100644
--- a/src/platform/tests/test-link.c
+++ b/src/platform/tests/test-link.c
@@ -1,5 +1,7 @@
#include "config.h"
+#include "nmp-object.h"
+
#include "test-common.h"
#include "nm-test-utils.h"
@@ -640,7 +642,7 @@ test_software_detect (gconstpointer user_data)
const TestAddSoftwareDetectData *test_data = user_data;
int ifindex, ifindex_parent;
const NMPlatformLink *plink;
- gconstpointer plnk_void;
+ const NMPObject *lnk;
guint i_step;
int exit_code;
@@ -708,15 +710,16 @@ test_software_detect (gconstpointer user_data)
nmtstp_link_set_updown (-1, ifindex, set_up);
}
- plnk_void = nm_platform_link_get_lnk (NM_PLATFORM_GET, ifindex, test_data->link_type, &plink);
+ lnk = nm_platform_link_get_lnk (NM_PLATFORM_GET, ifindex, test_data->link_type, &plink);
g_assert (plink);
g_assert_cmpint (plink->ifindex, ==, ifindex);
- g_assert (plnk_void);
+ g_assert (lnk);
switch (test_data->link_type) {
case NM_LINK_TYPE_GRE: {
- const NMPlatformLnkGre *plnk = plnk_void;
+ const NMPlatformLnkGre *plnk = &lnk->lnk_gre;
+ g_assert (plnk == nm_platform_link_get_lnk_gre (NM_PLATFORM_GET, ifindex, NULL));
g_assert_cmpint (plnk->parent_ifindex, ==, 0);
g_assert_cmpint (plnk->input_flags, ==, 0);
g_assert_cmpint (plnk->output_flags, ==, 0);
@@ -730,21 +733,24 @@ test_software_detect (gconstpointer user_data)
break;
}
case NM_LINK_TYPE_MACVLAN: {
- const NMPlatformLnkMacvlan *plnk = plnk_void;
+ const NMPlatformLnkMacvlan *plnk = &lnk->lnk_macvlan;
+ g_assert (plnk == nm_platform_link_get_lnk_macvlan (NM_PLATFORM_GET, ifindex, NULL));
g_assert_cmpint (plnk->no_promisc, ==, FALSE);
g_assert_cmpstr (plnk->mode, ==, "vepa");
break;
}
case NM_LINK_TYPE_VLAN: {
- const NMPlatformLnkVlan *plnk = plnk_void;
+ const NMPlatformLnkVlan *plnk = &lnk->lnk_vlan;
+ g_assert (plnk == nm_platform_link_get_lnk_vlan (NM_PLATFORM_GET, ifindex, NULL));
g_assert_cmpint (plnk->id, ==, 1242);
break;
}
case NM_LINK_TYPE_VXLAN: {
- const NMPlatformLnkVxlan *plnk = plnk_void;
+ const NMPlatformLnkVxlan *plnk = &lnk->lnk_vxlan;
+ g_assert (plnk == nm_platform_link_get_lnk_vxlan (NM_PLATFORM_GET, ifindex, NULL));
g_assert_cmpint (plnk->parent_ifindex, !=, 0);
g_assert_cmpint (plnk->tos, ==, 0);
g_assert_cmpint (plnk->ttl, ==, 0);