summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-03-04 13:01:21 +0100
committerThomas Haller <thaller@redhat.com>2019-03-13 09:03:59 +0100
commitac4a1deba02708e7538bd6fbf1c88c7245342ae2 (patch)
treea243e249ab35e62b0d108c616d6f7f1bb18b557c
parent667aa52f89616129ee953a1dd55235790ac9b54c (diff)
downloadNetworkManager-ac4a1deba02708e7538bd6fbf1c88c7245342ae2.tar.gz
platform: add NMPlatformObjWithIfindex helper structure for handling NMPObject types
Until now, all implemented NMPObject types have an ifindex field (from links, addresses, routes, qdisc to tfilter). The NMPObject structure contains a union of all available types, that makes it easier to down-case from an NMPObject pointer to the actual content. The "object" field of NMPObject of type NMPlatformObject is the lowest common denominator. We will add NMPlatformRoutingRules (for policy routing rules). That type won't have an ifindex field. Hence, drop the "ifindex" field from NMPlatformObject type. But also add a new type NMPlatformObjWithIfindex, that can represent all types that have an ifindex.
-rw-r--r--src/nm-ip4-config.c6
-rw-r--r--src/nm-types.h19
-rw-r--r--src/platform/nm-fake-platform.c2
-rw-r--r--src/platform/nm-platform.c12
-rw-r--r--src/platform/nm-platform.h28
-rw-r--r--src/platform/nmp-object.c37
-rw-r--r--src/platform/nmp-object.h56
-rw-r--r--src/platform/tests/test-nmp-object.c2
8 files changed, 115 insertions, 47 deletions
diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c
index 1c06a42ce9..2f9db03b66 100644
--- a/src/nm-ip4-config.c
+++ b/src/nm-ip4-config.c
@@ -115,13 +115,13 @@ _nm_ip_config_add_obj (NMDedupMultiIndex *multi_idx,
if (!obj_new) {
nm_assert (pl_new);
obj_new = nmp_object_stackinit (&obj_new_stackinit, idx_type->obj_type, pl_new);
- obj_new_stackinit.object.ifindex = ifindex;
+ NMP_OBJECT_CAST_OBJ_WITH_IFINDEX (&obj_new_stackinit)->ifindex = ifindex;
} else {
nm_assert (!pl_new);
nm_assert (NMP_OBJECT_GET_TYPE (obj_new) == idx_type->obj_type);
- if (obj_new->object.ifindex != ifindex) {
+ if (NMP_OBJECT_CAST_OBJ_WITH_IFINDEX (obj_new)->ifindex != ifindex) {
obj_new = nmp_object_stackinit_obj (&obj_new_stackinit, obj_new);
- obj_new_stackinit.object.ifindex = ifindex;
+ NMP_OBJECT_CAST_OBJ_WITH_IFINDEX (&obj_new_stackinit)->ifindex = ifindex;
}
}
nm_assert (NMP_OBJECT_GET_TYPE (obj_new) == idx_type->obj_type);
diff --git a/src/nm-types.h b/src/nm-types.h
index b6b49028ca..f30cc19920 100644
--- a/src/nm-types.h
+++ b/src/nm-types.h
@@ -119,15 +119,16 @@ NM_IS_IP_CONFIG_SOURCE_RTPROT (NMIPConfigSource source)
}
/* platform */
-typedef struct _NMPlatform NMPlatform;
-typedef struct _NMPlatformObject NMPlatformObject;
-typedef struct _NMPlatformIP4Address NMPlatformIP4Address;
-typedef struct _NMPlatformIP4Route NMPlatformIP4Route;
-typedef struct _NMPlatformIP6Address NMPlatformIP6Address;
-typedef struct _NMPlatformIP6Route NMPlatformIP6Route;
-typedef struct _NMPlatformLink NMPlatformLink;
-typedef struct _NMPNetns NMPNetns;
-typedef struct _NMPObject NMPObject;
+typedef struct _NMPlatform NMPlatform;
+typedef struct _NMPlatformObject NMPlatformObject;
+typedef struct _NMPlatformObjWithIfindex NMPlatformObjWithIfindex;
+typedef struct _NMPlatformIP4Address NMPlatformIP4Address;
+typedef struct _NMPlatformIP4Route NMPlatformIP4Route;
+typedef struct _NMPlatformIP6Address NMPlatformIP6Address;
+typedef struct _NMPlatformIP6Route NMPlatformIP6Route;
+typedef struct _NMPlatformLink NMPlatformLink;
+typedef struct _NMPNetns NMPNetns;
+typedef struct _NMPObject NMPObject;
typedef enum {
/* Please don't interpret type numbers outside nm-platform and use functions
diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c
index 3046615954..9dad647cfb 100644
--- a/src/platform/nm-fake-platform.c
+++ b/src/platform/nm-fake-platform.c
@@ -1119,7 +1119,7 @@ ipx_route_delete (NMPlatform *platform,
g_assert (NM_IN_SET (NMP_OBJECT_GET_TYPE (obj), NMP_OBJECT_TYPE_IP4_ROUTE,
NMP_OBJECT_TYPE_IP6_ROUTE));
g_assert (ifindex == -1);
- ifindex = obj->object.ifindex;
+ ifindex = NMP_OBJECT_CAST_IP_ROUTE (obj)->ifindex;
obj_type = NMP_OBJECT_GET_TYPE (obj);
} else {
g_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6));
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
index 1f7814f178..6aefcd5027 100644
--- a/src/platform/nm-platform.c
+++ b/src/platform/nm-platform.c
@@ -4577,7 +4577,7 @@ _ip_route_add (NMPlatform *self,
nm_assert (route);
nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6));
- ifindex = ((NMPlatformObject *)route)->ifindex;
+ ifindex = ((const NMPlatformIPRoute *) route)->ifindex;
_LOG3D ("route: %-10s IPv%c route: %s",
_nmp_nlm_flag_to_string (flags & NMP_NLM_FLAG_FMASK),
nm_utils_addr_family_to_char (addr_family),
@@ -4629,7 +4629,8 @@ gboolean
nm_platform_object_delete (NMPlatform *self,
const NMPObject *obj)
{
- int ifindex = obj->object.ifindex;
+ int ifindex;
+
_CHECK_SELF (self, klass, FALSE);
if (!NM_IN_SET (NMP_OBJECT_GET_TYPE (obj), NMP_OBJECT_TYPE_IP4_ROUTE,
@@ -4638,6 +4639,8 @@ nm_platform_object_delete (NMPlatform *self,
NMP_OBJECT_TYPE_TFILTER))
g_return_val_if_reached (FALSE);
+ ifindex = NMP_OBJECT_CAST_OBJ_WITH_IFINDEX (obj)->ifindex;
+
_LOG3D ("%s: delete %s",
NMP_OBJECT_GET_CLASS (obj)->obj_type_name,
nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0));
@@ -7195,7 +7198,8 @@ nm_platform_cache_update_emit_signal (NMPlatform *self,
return;
}
- ifindex = o->object.ifindex;
+ ifindex = NMP_OBJECT_CAST_OBJ_WITH_IFINDEX (o)->ifindex;
+
klass = NMP_OBJECT_GET_CLASS (o);
if ( klass->obj_type == NMP_OBJECT_TYPE_IP4_ROUTE
@@ -7213,7 +7217,7 @@ nm_platform_cache_update_emit_signal (NMPlatform *self,
_nm_platform_signal_id_get (klass->signal_type_id),
0,
(int) klass->obj_type,
- o->object.ifindex,
+ ifindex,
&o->object,
(int) cache_op);
nmp_object_unref (o);
diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h
index 665864a8e5..c9898603e2 100644
--- a/src/platform/nm-platform.h
+++ b/src/platform/nm-platform.h
@@ -181,12 +181,22 @@ typedef enum {
#define NM_PLATFORM_LINK_OTHER_NETNS (-1)
-#define __NMPlatformObject_COMMON \
+struct _NMPlatformObject {
+ /* the object type has no fields of its own, it is only used to having
+ * a special pointer type that can be used to indicate "any" type. */
+ char _dummy_don_t_use_me;
+};
+
+#define __NMPlatformObjWithIfindex_COMMON \
int ifindex; \
;
+struct _NMPlatformObjWithIfindex {
+ __NMPlatformObjWithIfindex_COMMON;
+};
+
struct _NMPlatformLink {
- __NMPlatformObject_COMMON;
+ __NMPlatformObjWithIfindex_COMMON;
char name[NMP_IFNAMSIZ];
NMLinkType type;
@@ -260,15 +270,11 @@ typedef enum {
NM_PLATFORM_SIGNAL_REMOVED,
} NMPlatformSignalChangeType;
-struct _NMPlatformObject {
- __NMPlatformObject_COMMON;
-};
-
#define NM_PLATFORM_IP_ADDRESS_CAST(address) \
NM_CONSTCAST (NMPlatformIPAddress, (address), NMPlatformIPXAddress, NMPlatformIP4Address, NMPlatformIP6Address)
#define __NMPlatformIPAddress_COMMON \
- __NMPlatformObject_COMMON; \
+ __NMPlatformObjWithIfindex_COMMON; \
NMIPConfigSource addr_source; \
\
/* Timestamp in seconds in the reference system of nm_utils_get_monotonic_timestamp_*().
@@ -370,7 +376,7 @@ typedef union {
#define NM_PLATFORM_ROUTE_METRIC_IP4_DEVICE_ROUTE 0
#define __NMPlatformIPRoute_COMMON \
- __NMPlatformObject_COMMON; \
+ __NMPlatformObjWithIfindex_COMMON; \
\
/* The NMIPConfigSource. For routes that we receive from cache this corresponds
* to the rtm_protocol field (and is one of the NM_IP_CONFIG_SOURCE_RTPROT_* values).
@@ -540,7 +546,7 @@ typedef union {
#undef __NMPlatformIPRoute_COMMON
typedef struct {
- __NMPlatformObject_COMMON;
+ __NMPlatformObjWithIfindex_COMMON;
const char *kind;
int addr_family;
guint32 handle;
@@ -562,7 +568,7 @@ typedef struct {
#define NM_PLATFORM_ACTION_KIND_SIMPLE "simple"
typedef struct {
- __NMPlatformObject_COMMON;
+ __NMPlatformObjWithIfindex_COMMON;
const char *kind;
int addr_family;
guint32 handle;
@@ -571,7 +577,7 @@ typedef struct {
NMPlatformAction action;
} NMPlatformTfilter;
-#undef __NMPlatformObject_COMMON
+#undef __NMPlatformObjWithIfindex_COMMON
typedef struct {
gboolean is_ip4;
diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c
index 97c2db3ec0..e3563d716f 100644
--- a/src/platform/nmp-object.c
+++ b/src/platform/nmp-object.c
@@ -389,16 +389,16 @@ _idx_obj_part (const DedupMultiIdxType *idx_type,
nm_hash_update_val (h, obj_a);
return 0;
}
- nm_assert (obj_a->object.ifindex > 0);
+ nm_assert (NMP_OBJECT_CAST_OBJ_WITH_IFINDEX (obj_a)->ifindex > 0);
if (obj_b) {
return NMP_OBJECT_GET_TYPE (obj_a) == NMP_OBJECT_GET_TYPE (obj_b)
- && obj_a->object.ifindex == obj_b->object.ifindex
+ && NMP_OBJECT_CAST_OBJ_WITH_IFINDEX (obj_a)->ifindex == NMP_OBJECT_CAST_OBJ_WITH_IFINDEX (obj_b)->ifindex
&& nmp_object_is_visible (obj_b);
}
if (h) {
nm_hash_update_vals (h,
idx_type->cache_id_type,
- obj_a->object.ifindex);
+ NMP_OBJECT_CAST_OBJ_WITH_IFINDEX (obj_a)->ifindex);
}
return 1;
@@ -406,14 +406,14 @@ _idx_obj_part (const DedupMultiIdxType *idx_type,
obj_type = NMP_OBJECT_GET_TYPE (obj_a);
if ( !NM_IN_SET (obj_type, NMP_OBJECT_TYPE_IP4_ROUTE,
NMP_OBJECT_TYPE_IP6_ROUTE)
- || obj_a->object.ifindex <= 0) {
+ || NMP_OBJECT_CAST_IP_ROUTE (obj_a)->ifindex <= 0) {
if (h)
nm_hash_update_val (h, obj_a);
return 0;
}
if (obj_b) {
return obj_type == NMP_OBJECT_GET_TYPE (obj_b)
- && obj_b->object.ifindex > 0
+ && NMP_OBJECT_CAST_IP_ROUTE (obj_b)->ifindex > 0
&& (obj_type == NMP_OBJECT_TYPE_IP4_ROUTE
? (nm_platform_ip4_route_cmp (&obj_a->ip4_route, &obj_b->ip4_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID) == 0)
: (nm_platform_ip6_route_cmp (&obj_a->ip6_route, &obj_b->ip6_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID) == 0));
@@ -1564,13 +1564,14 @@ nmp_object_is_alive (const NMPObject *obj)
static gboolean
_vt_cmd_obj_is_alive_link (const NMPObject *obj)
{
- return obj->object.ifindex > 0 && (obj->_link.netlink.is_in_netlink || obj->_link.udev.device);
+ return NMP_OBJECT_CAST_LINK (obj)->ifindex > 0
+ && (obj->_link.netlink.is_in_netlink || obj->_link.udev.device);
}
static gboolean
_vt_cmd_obj_is_alive_ipx_address (const NMPObject *obj)
{
- return obj->object.ifindex > 0;
+ return NMP_OBJECT_CAST_IP_ADDRESS (obj)->ifindex > 0;
}
static gboolean
@@ -1591,20 +1592,20 @@ _vt_cmd_obj_is_alive_ipx_route (const NMPObject *obj)
* Instead we create a dead object, and nmp_cache_update_netlink()
* will remove the old version of the update.
**/
- return obj->object.ifindex > 0
+ return NMP_OBJECT_CAST_IP_ROUTE (obj)->ifindex > 0
&& !NM_FLAGS_HAS (obj->ip_route.r_rtm_flags, RTM_F_CLONED);
}
static gboolean
_vt_cmd_obj_is_alive_qdisc (const NMPObject *obj)
{
- return obj->object.ifindex > 0;
+ return NMP_OBJECT_CAST_QDISC (obj)->ifindex > 0;
}
static gboolean
_vt_cmd_obj_is_alive_tfilter (const NMPObject *obj)
{
- return obj->object.ifindex > 0;
+ return NMP_OBJECT_CAST_TFILTER (obj)->ifindex > 0;
}
gboolean
@@ -1988,7 +1989,7 @@ nmp_lookup_init_object (NMPLookup *lookup,
}
o = _nmp_object_stackinit_from_type (&lookup->selector_obj, obj_type);
- o->object.ifindex = ifindex;
+ o->obj_with_ifindex.ifindex = ifindex;
lookup->cache_id_type = NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX;
return _L (lookup);
}
@@ -2004,7 +2005,7 @@ nmp_lookup_init_route_default (NMPLookup *lookup,
NMP_OBJECT_TYPE_IP6_ROUTE));
o = _nmp_object_stackinit_from_type (&lookup->selector_obj, obj_type);
- o->object.ifindex = 1;
+ o->ip_route.ifindex = 1;
lookup->cache_id_type = NMP_CACHE_ID_TYPE_DEFAULT_ROUTES;
return _L (lookup);
}
@@ -2052,9 +2053,9 @@ nmp_lookup_init_ip4_route_by_weak_id (NMPLookup *lookup,
nm_assert (lookup);
o = _nmp_object_stackinit_from_type (&lookup->selector_obj, NMP_OBJECT_TYPE_IP4_ROUTE);
- o->object.ifindex = 1;
- o->ip_route.plen = plen;
- o->ip_route.metric = metric;
+ o->ip4_route.ifindex = 1;
+ o->ip4_route.plen = plen;
+ o->ip4_route.metric = metric;
if (network)
o->ip4_route.network = network;
o->ip4_route.tos = tos;
@@ -2075,9 +2076,9 @@ nmp_lookup_init_ip6_route_by_weak_id (NMPLookup *lookup,
nm_assert (lookup);
o = _nmp_object_stackinit_from_type (&lookup->selector_obj, NMP_OBJECT_TYPE_IP6_ROUTE);
- o->object.ifindex = 1;
- o->ip_route.plen = plen;
- o->ip_route.metric = metric;
+ o->ip6_route.ifindex = 1;
+ o->ip6_route.plen = plen;
+ o->ip6_route.metric = metric;
if (network)
o->ip6_route.network = *network;
if (src)
diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h
index 3241573c27..7d64b094ce 100644
--- a/src/platform/nmp-object.h
+++ b/src/platform/nmp-object.h
@@ -340,6 +340,8 @@ struct _NMPObject {
union {
NMPlatformObject object;
+ NMPlatformObjWithIfindex obj_with_ifindex;
+
NMPlatformLink link;
NMPObjectLink _link;
@@ -467,6 +469,60 @@ NMP_OBJECT_GET_TYPE (const NMPObject *obj)
return obj ? obj->_class->obj_type : NMP_OBJECT_TYPE_UNKNOWN;
}
+static inline gboolean
+_NMP_OBJECT_TYPE_IS_OBJ_WITH_IFINDEX (NMPObjectType obj_type)
+{
+ switch (obj_type) {
+ case NMP_OBJECT_TYPE_LINK:
+ case NMP_OBJECT_TYPE_IP4_ADDRESS:
+ case NMP_OBJECT_TYPE_IP6_ADDRESS:
+ case NMP_OBJECT_TYPE_IP4_ROUTE:
+ case NMP_OBJECT_TYPE_IP6_ROUTE:
+
+ case NMP_OBJECT_TYPE_QDISC:
+
+ case NMP_OBJECT_TYPE_TFILTER:
+
+ case NMP_OBJECT_TYPE_LNK_GRE:
+ case NMP_OBJECT_TYPE_LNK_GRETAP:
+ case NMP_OBJECT_TYPE_LNK_INFINIBAND:
+ case NMP_OBJECT_TYPE_LNK_IP6TNL:
+ case NMP_OBJECT_TYPE_LNK_IP6GRE:
+ case NMP_OBJECT_TYPE_LNK_IP6GRETAP:
+ case NMP_OBJECT_TYPE_LNK_IPIP:
+ case NMP_OBJECT_TYPE_LNK_MACSEC:
+ case NMP_OBJECT_TYPE_LNK_MACVLAN:
+ case NMP_OBJECT_TYPE_LNK_MACVTAP:
+ case NMP_OBJECT_TYPE_LNK_SIT:
+ case NMP_OBJECT_TYPE_LNK_TUN:
+ case NMP_OBJECT_TYPE_LNK_VLAN:
+ case NMP_OBJECT_TYPE_LNK_VXLAN:
+ case NMP_OBJECT_TYPE_LNK_WIREGUARD:
+ return TRUE;
+ default:
+ nm_assert (nmp_class_from_type (obj_type));
+ return FALSE;
+ }
+}
+
+#define NMP_OBJECT_CAST_OBJECT(obj) \
+ ({ \
+ typeof (obj) _obj = (obj); \
+ \
+ nm_assert ( !_obj \
+ || nmp_class_from_type (NMP_OBJECT_GET_TYPE (_obj)))); \
+ _obj ? &NM_CONSTCAST (NMPObject, _obj)->object : NULL; \
+ })
+
+#define NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj) \
+ ({ \
+ typeof (obj) _obj = (obj); \
+ \
+ nm_assert ( !_obj \
+ || _NMP_OBJECT_TYPE_IS_OBJ_WITH_IFINDEX (NMP_OBJECT_GET_TYPE (_obj))); \
+ _obj ? &NM_CONSTCAST (NMPObject, _obj)->obj_with_ifindex : NULL; \
+ })
+
#define NMP_OBJECT_CAST_LINK(obj) \
({ \
typeof (obj) _obj = (obj); \
diff --git a/src/platform/tests/test-nmp-object.c b/src/platform/tests/test-nmp-object.c
index 12acf4a544..280ed5208f 100644
--- a/src/platform/tests/test-nmp-object.c
+++ b/src/platform/tests/test-nmp-object.c
@@ -223,7 +223,7 @@ _nmp_cache_update_netlink (NMPCache *cache, NMPObject *obj, const NMPObject **ou
g_assert (cache);
g_assert (NMP_OBJECT_IS_VALID (obj));
- obj_prev = nmp_cache_lookup_link (cache, obj->object.ifindex);
+ obj_prev = nmp_cache_lookup_link (cache, NMP_OBJECT_CAST_LINK (obj)->ifindex);
obj_new_expected = nmp_object_clone (obj, FALSE);
if (obj_prev && obj_prev->_link.udev.device)
obj_new_expected->_link.udev.device = udev_device_ref (obj_prev->_link.udev.device);