platform: refactor fake platform to use NMPCache for addresses

And move some code from NMLinuxPlatform to NMPlatform, where it belongs.

The advantage is that we reuse (and test!) the NMPCache implementation for
tracking addresses.

Also, we now always expose proper NMPObjects from both linux and fake
platform.

For example,

  obj = NMP_OBJECT_UP_CAST (nm_platform_ip4_address_get (...));

will work as expected. Also, the caller is now by NMPlatform API
allowed to take and keep a reference to the returned objects.
This commit is contained in:
Thomas Haller
2017-07-04 12:49:47 +02:00
parent 8b3b148fda
commit 71cf60e852
5 changed files with 144 additions and 270 deletions

View File

@@ -50,8 +50,6 @@ typedef struct {
typedef struct { typedef struct {
GHashTable *options; GHashTable *options;
GArray *links; GArray *links;
GArray *ip4_addresses;
GArray *ip6_addresses;
} NMFakePlatformPrivate; } NMFakePlatformPrivate;
struct _NMFakePlatform { struct _NMFakePlatform {
@@ -97,6 +95,13 @@ G_DEFINE_TYPE (NMFakePlatform, nm_fake_platform, NM_TYPE_PLATFORM)
static void link_changed (NMPlatform *platform, NMFakePlatformLink *device, gboolean raise_signal); static void link_changed (NMPlatform *platform, NMFakePlatformLink *device, gboolean raise_signal);
static gboolean ipx_address_delete (NMPlatform *platform,
int addr_family,
int ifindex,
gconstpointer addr,
const guint8 *plen,
gconstpointer peer_addr);
static gboolean ipx_route_delete (NMPlatform *platform, static gboolean ipx_route_delete (NMPlatform *platform,
int addr_family, int addr_family,
int ifindex, int ifindex,
@@ -116,14 +121,6 @@ static gboolean ip6_address_delete (NMPlatform *platform, int ifindex, struct in
/*****************************************************************************/ /*****************************************************************************/
static gboolean
_ip4_address_equal_peer_net (in_addr_t peer1, in_addr_t peer2, guint8 plen)
{
return ((peer1 ^ peer2) & nm_utils_ip4_prefix_to_netmask (plen)) == 0;
}
/*****************************************************************************/
#define ASSERT_SYSCTL_ARGS(pathid, dirfd, path) \ #define ASSERT_SYSCTL_ARGS(pathid, dirfd, path) \
G_STMT_START { \ G_STMT_START { \
const char *const _pathid = (pathid); \ const char *const _pathid = (pathid); \
@@ -379,10 +376,8 @@ link_add (NMPlatform *platform,
static gboolean static gboolean
link_delete (NMPlatform *platform, int ifindex) link_delete (NMPlatform *platform, int ifindex)
{ {
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE ((NMFakePlatform *) platform);
NMFakePlatformLink *device = link_get (platform, ifindex); NMFakePlatformLink *device = link_get (platform, ifindex);
NMPlatformLink deleted_device; NMPlatformLink deleted_device;
int i;
if (!device || !device->link.ifindex) if (!device || !device->link.ifindex)
return FALSE; return FALSE;
@@ -393,18 +388,8 @@ link_delete (NMPlatform *platform, int ifindex)
g_clear_pointer (&device->udi, g_free); g_clear_pointer (&device->udi, g_free);
/* Remove addresses and routes which belong to the deleted interface */ /* Remove addresses and routes which belong to the deleted interface */
for (i = 0; i < priv->ip4_addresses->len; i++) { ipx_address_delete (platform, AF_INET, ifindex, NULL, NULL, NULL);
NMPlatformIP4Address *address = &g_array_index (priv->ip4_addresses, NMPlatformIP4Address, i); ipx_address_delete (platform, AF_INET6, ifindex, NULL, NULL, NULL);
if (address->ifindex == ifindex)
memset (address, 0, sizeof (*address));
}
for (i = 0; i < priv->ip6_addresses->len; i++) {
NMPlatformIP6Address *address = &g_array_index (priv->ip6_addresses, NMPlatformIP6Address, i);
if (address->ifindex == ifindex)
memset (address, 0, sizeof (*address));
}
ipx_route_delete (platform, AF_INET, ifindex, NULL, NULL, NULL); ipx_route_delete (platform, AF_INET, ifindex, NULL, NULL, NULL);
ipx_route_delete (platform, AF_INET6, ifindex, NULL, NULL, NULL); ipx_route_delete (platform, AF_INET6, ifindex, NULL, NULL, NULL);
@@ -907,59 +892,25 @@ mesh_set_ssid (NMPlatform *platform, int ifindex, const guint8 *ssid, gsize len)
/*****************************************************************************/ /*****************************************************************************/
static GArray * static gboolean
ip4_address_get_all (NMPlatform *platform, int ifindex) ipx_address_add (NMPlatform *platform, int addr_family, const NMPlatformObject *address)
{ {
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE ((NMFakePlatform *) platform); nm_auto_nmpobj NMPObject *obj = NULL;
GArray *addresses; NMPCacheOpsType cache_op;
NMPlatformIP4Address *address; nm_auto_nmpobj const NMPObject *obj_old = NULL;
int count = 0, i; nm_auto_nmpobj const NMPObject *obj_new = NULL;
NMPCache *cache = nm_platform_get_cache (platform);
/* Count addresses */ g_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6));
for (i = 0; i < priv->ip4_addresses->len; i++) {
address = &g_array_index (priv->ip4_addresses, NMPlatformIP4Address, i);
if (address && address->ifindex == ifindex)
count++;
}
addresses = g_array_sized_new (TRUE, TRUE, sizeof (NMPlatformIP4Address), count); obj = nmp_object_new (addr_family == AF_INET
? NMP_OBJECT_TYPE_IP4_ADDRESS
: NMP_OBJECT_TYPE_IP6_ADDRESS,
address);
/* Fill addresses */ cache_op = nmp_cache_update_netlink (cache, obj, &obj_old, &obj_new);
for (i = 0; i < priv->ip4_addresses->len; i++) { nm_platform_cache_update_emit_signal (platform, cache_op, obj_old, obj_new);
address = &g_array_index (priv->ip4_addresses, NMPlatformIP4Address, i); return TRUE;
if (address && address->ifindex == ifindex)
g_array_append_val (addresses, *address);
}
return addresses;
}
static GArray *
ip6_address_get_all (NMPlatform *platform, int ifindex)
{
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE ((NMFakePlatform *) platform);
GArray *addresses;
NMPlatformIP6Address *address;
int count = 0, i;
/* Count addresses */
for (i = 0; i < priv->ip6_addresses->len; i++) {
address = &g_array_index (priv->ip6_addresses, NMPlatformIP6Address, i);
if (address && address->ifindex == ifindex)
count++;
}
addresses = g_array_sized_new (TRUE, TRUE, sizeof (NMPlatformIP6Address), count);
/* Fill addresses */
count = 0;
for (i = 0; i < priv->ip6_addresses->len; i++) {
address = &g_array_index (priv->ip6_addresses, NMPlatformIP6Address, i);
if (address && address->ifindex == ifindex)
g_array_append_val (addresses, *address);
}
return addresses;
} }
static gboolean static gboolean
@@ -973,9 +924,7 @@ ip4_address_add (NMPlatform *platform,
guint32 flags, guint32 flags,
const char *label) const char *label)
{ {
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE ((NMFakePlatform *) platform);
NMPlatformIP4Address address; NMPlatformIP4Address address;
int i;
memset (&address, 0, sizeof (address)); memset (&address, 0, sizeof (address));
address.addr_source = NM_IP_CONFIG_SOURCE_KERNEL; address.addr_source = NM_IP_CONFIG_SOURCE_KERNEL;
@@ -990,28 +939,7 @@ ip4_address_add (NMPlatform *platform,
if (label) if (label)
g_strlcpy (address.label, label, sizeof (address.label)); g_strlcpy (address.label, label, sizeof (address.label));
for (i = 0; i < priv->ip4_addresses->len; i++) { return ipx_address_add (platform, AF_INET, (const NMPlatformObject *) &address);
NMPlatformIP4Address *item = &g_array_index (priv->ip4_addresses, NMPlatformIP4Address, i);
gboolean changed;
if ( item->ifindex != address.ifindex
|| item->address != address.address
|| item->plen != address.plen
|| !_ip4_address_equal_peer_net (item->peer_address, address.peer_address, address.plen))
continue;
changed = !nm_platform_ip4_address_cmp (item, &address);
memcpy (item, &address, sizeof (address));
if (changed)
g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, (int) NMP_OBJECT_TYPE_IP4_ADDRESS, ifindex, &address, (int) NM_PLATFORM_SIGNAL_CHANGED);
return TRUE;
}
g_array_append_val (priv->ip4_addresses, address);
g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, (int) NMP_OBJECT_TYPE_IP4_ADDRESS, ifindex, &address, (int) NM_PLATFORM_SIGNAL_ADDED);
return TRUE;
} }
static gboolean static gboolean
@@ -1024,9 +952,7 @@ ip6_address_add (NMPlatform *platform,
guint32 preferred, guint32 preferred,
guint32 flags) guint32 flags)
{ {
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE ((NMFakePlatform *) platform);
NMPlatformIP6Address address; NMPlatformIP6Address address;
int i;
memset (&address, 0, sizeof (address)); memset (&address, 0, sizeof (address));
address.addr_source = NM_IP_CONFIG_SOURCE_KERNEL; address.addr_source = NM_IP_CONFIG_SOURCE_KERNEL;
@@ -1039,111 +965,83 @@ ip6_address_add (NMPlatform *platform,
address.preferred = preferred; address.preferred = preferred;
address.n_ifa_flags = flags; address.n_ifa_flags = flags;
for (i = 0; i < priv->ip6_addresses->len; i++) { return ipx_address_add (platform, AF_INET6, (const NMPlatformObject *) &address);
NMPlatformIP6Address *item = &g_array_index (priv->ip6_addresses, NMPlatformIP6Address, i); }
gboolean changed;
if ( item->ifindex != address.ifindex static gboolean
|| !IN6_ARE_ADDR_EQUAL (&item->address, &address.address)) ipx_address_delete (NMPlatform *platform,
continue; int addr_family,
int ifindex,
gconstpointer addr,
const guint8 *plen,
gconstpointer peer_addr)
{
gs_unref_ptrarray GPtrArray *objs = g_ptr_array_new_with_free_func ((GDestroyNotify) nmp_object_unref);
NMDedupMultiIter iter;
const NMPObject *o = NULL;
guint i;
guint32 peer_addr_i;
changed = !nm_platform_ip6_address_cmp (item, &address); g_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6));
memcpy (item, &address, sizeof (address)); peer_addr_i = peer_addr ? *((guint32 *) peer_addr) : 0;
if (changed)
g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, (int) NMP_OBJECT_TYPE_IP6_ADDRESS, ifindex, &address, (int) NM_PLATFORM_SIGNAL_CHANGED); nmp_cache_iter_for_each (&iter,
return TRUE; nm_platform_lookup_addrroute (platform,
addr_family == AF_INET
? NMP_OBJECT_TYPE_IP4_ADDRESS
: NMP_OBJECT_TYPE_IP6_ADDRESS,
0),
&o) {
const NMPObject *obj_old = NULL;
if (addr_family == AF_INET) {
const NMPlatformIP4Address *address = NMP_OBJECT_CAST_IP4_ADDRESS (o);
if ( address->ifindex != ifindex
|| (addr && address->address != *((guint32 *) addr))
|| (plen && address->plen != *plen)
|| ( peer_addr
&& (((peer_addr_i ^ address->peer_address) & nm_utils_ip4_prefix_to_netmask (address->plen)) != 0)))
continue;
} else {
const NMPlatformIP6Address *address = NMP_OBJECT_CAST_IP6_ADDRESS (o);
g_assert (!peer_addr);
if ( address->ifindex != ifindex
|| (addr && !IN6_ARE_ADDR_EQUAL (&address->address, addr))
|| (plen && address->plen != *plen))
continue;
}
if (nmp_cache_remove (nm_platform_get_cache (platform),
o,
TRUE,
&obj_old) != NMP_CACHE_OPS_REMOVED)
g_assert_not_reached ();
g_assert (obj_old);
g_ptr_array_add (objs, (gpointer) obj_old);
} }
g_array_append_val (priv->ip6_addresses, address); for (i = 0; i < objs->len; i++) {
g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, (int) NMP_OBJECT_TYPE_IP6_ADDRESS, ifindex, &address, (int) NM_PLATFORM_SIGNAL_ADDED); nm_platform_cache_update_emit_signal (platform,
NMP_CACHE_OPS_REMOVED,
objs->pdata[i],
NULL);
}
return TRUE; return TRUE;
} }
static gboolean static gboolean
ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, guint8 plen, in_addr_t peer_address) ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, guint8 plen, in_addr_t peer_address)
{ {
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE ((NMFakePlatform *) platform); return ipx_address_delete (platform, AF_INET, ifindex, &addr, &plen, &peer_address);
int i;
for (i = 0; i < priv->ip4_addresses->len; i++) {
NMPlatformIP4Address *address = &g_array_index (priv->ip4_addresses, NMPlatformIP4Address, i);
if ( address->ifindex == ifindex
&& address->plen == plen
&& address->address == addr
&& ((peer_address ^ address->peer_address) & nm_utils_ip4_prefix_to_netmask (plen)) == 0) {
NMPlatformIP4Address deleted_address;
memcpy (&deleted_address, address, sizeof (deleted_address));
memset (address, 0, sizeof (*address));
g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, (int) NMP_OBJECT_TYPE_IP4_ADDRESS, ifindex, &deleted_address, (int) NM_PLATFORM_SIGNAL_REMOVED);
return TRUE;
}
}
return TRUE;
} }
static gboolean static gboolean
ip6_address_delete (NMPlatform *platform, int ifindex, struct in6_addr addr, guint8 plen) ip6_address_delete (NMPlatform *platform, int ifindex, struct in6_addr addr, guint8 plen)
{ {
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE ((NMFakePlatform *) platform); return ipx_address_delete (platform, AF_INET6, ifindex, &addr, &plen, NULL);
int i;
for (i = 0; i < priv->ip6_addresses->len; i++) {
NMPlatformIP6Address *address = &g_array_index (priv->ip6_addresses, NMPlatformIP6Address, i);
if ( address->ifindex == ifindex
&& address->plen == plen
&& IN6_ARE_ADDR_EQUAL (&address->address, &addr)) {
NMPlatformIP6Address deleted_address;
memcpy (&deleted_address, address, sizeof (deleted_address));
memset (address, 0, sizeof (*address));
g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, (int) NMP_OBJECT_TYPE_IP6_ADDRESS, ifindex, &deleted_address, (int) NM_PLATFORM_SIGNAL_REMOVED);
return TRUE;
}
}
return TRUE;
}
static const NMPlatformIP4Address *
ip4_address_get (NMPlatform *platform, int ifindex, in_addr_t addr, guint8 plen, in_addr_t peer_address)
{
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE ((NMFakePlatform *) platform);
int i;
for (i = 0; i < priv->ip4_addresses->len; i++) {
NMPlatformIP4Address *address = &g_array_index (priv->ip4_addresses, NMPlatformIP4Address, i);
if ( address->ifindex == ifindex
&& address->plen == plen
&& address->address == addr
&& _ip4_address_equal_peer_net (address->peer_address, peer_address, plen))
return address;
}
return NULL;
}
static const NMPlatformIP6Address *
ip6_address_get (NMPlatform *platform, int ifindex, struct in6_addr addr)
{
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE ((NMFakePlatform *) platform);
int i;
for (i = 0; i < priv->ip6_addresses->len; i++) {
NMPlatformIP6Address *address = &g_array_index (priv->ip6_addresses, NMPlatformIP6Address, i);
if ( address->ifindex == ifindex
&& IN6_ARE_ADDR_EQUAL (&address->address, &addr))
return address;
}
return NULL;
} }
/*****************************************************************************/ /*****************************************************************************/
@@ -1325,8 +1223,6 @@ nm_fake_platform_init (NMFakePlatform *fake_platform)
priv->options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); priv->options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
priv->links = g_array_new (TRUE, TRUE, sizeof (NMFakePlatformLink)); priv->links = g_array_new (TRUE, TRUE, sizeof (NMFakePlatformLink));
priv->ip4_addresses = g_array_new (TRUE, TRUE, sizeof (NMPlatformIP4Address));
priv->ip6_addresses = g_array_new (TRUE, TRUE, sizeof (NMPlatformIP6Address));
} }
void void
@@ -1366,8 +1262,6 @@ finalize (GObject *object)
g_clear_pointer (&device->lnk, nmp_object_unref); g_clear_pointer (&device->lnk, nmp_object_unref);
} }
g_array_unref (priv->links); g_array_unref (priv->links);
g_array_unref (priv->ip4_addresses);
g_array_unref (priv->ip6_addresses);
G_OBJECT_CLASS (nm_fake_platform_parent_class)->finalize (object); G_OBJECT_CLASS (nm_fake_platform_parent_class)->finalize (object);
} }
@@ -1435,10 +1329,6 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass)
platform_class->mesh_set_channel = mesh_set_channel; platform_class->mesh_set_channel = mesh_set_channel;
platform_class->mesh_set_ssid = mesh_set_ssid; platform_class->mesh_set_ssid = mesh_set_ssid;
platform_class->ip4_address_get = ip4_address_get;
platform_class->ip6_address_get = ip6_address_get;
platform_class->ip4_address_get_all = ip4_address_get_all;
platform_class->ip6_address_get_all = ip6_address_get_all;
platform_class->ip4_address_add = ip4_address_add; platform_class->ip4_address_add = ip4_address_add;
platform_class->ip6_address_add = ip6_address_add; platform_class->ip6_address_add = ip6_address_add;
platform_class->ip4_address_delete = ip4_address_delete; platform_class->ip4_address_delete = ip4_address_delete;

View File

@@ -5722,32 +5722,6 @@ link_get_driver_info (NMPlatform *platform,
/*****************************************************************************/ /*****************************************************************************/
static GArray *
ipx_address_get_all (NMPlatform *platform, int ifindex, NMPObjectType obj_type)
{
NMPLookup lookup;
nm_assert (NM_IN_SET (obj_type, NMP_OBJECT_TYPE_IP4_ADDRESS, NMP_OBJECT_TYPE_IP6_ADDRESS));
nmp_lookup_init_addrroute (&lookup,
obj_type,
ifindex);
return nmp_cache_lookup_to_array (nmp_cache_lookup (nm_platform_get_cache (platform), &lookup),
obj_type,
FALSE /*addresses are always visible. */);
}
static GArray *
ip4_address_get_all (NMPlatform *platform, int ifindex)
{
return ipx_address_get_all (platform, ifindex, NMP_OBJECT_TYPE_IP4_ADDRESS);
}
static GArray *
ip6_address_get_all (NMPlatform *platform, int ifindex)
{
return ipx_address_get_all (platform, ifindex, NMP_OBJECT_TYPE_IP6_ADDRESS);
}
static gboolean static gboolean
ip4_address_add (NMPlatform *platform, ip4_address_add (NMPlatform *platform,
int ifindex, int ifindex,
@@ -5859,32 +5833,6 @@ ip6_address_delete (NMPlatform *platform, int ifindex, struct in6_addr addr, gui
return do_delete_object (platform, &obj_id, nlmsg); return do_delete_object (platform, &obj_id, nlmsg);
} }
static const NMPlatformIP4Address *
ip4_address_get (NMPlatform *platform, int ifindex, in_addr_t addr, guint8 plen, in_addr_t peer_address)
{
NMPObject obj_id;
const NMPObject *obj;
nmp_object_stackinit_id_ip4_address (&obj_id, ifindex, addr, plen, peer_address);
obj = nmp_cache_lookup_obj (nm_platform_get_cache (platform), &obj_id);
if (nmp_object_is_visible (obj))
return &obj->ip4_address;
return NULL;
}
static const NMPlatformIP6Address *
ip6_address_get (NMPlatform *platform, int ifindex, struct in6_addr addr)
{
NMPObject obj_id;
const NMPObject *obj;
nmp_object_stackinit_id_ip6_address (&obj_id, ifindex, &addr);
obj = nmp_cache_lookup_obj (nm_platform_get_cache (platform), &obj_id);
if (nmp_object_is_visible (obj))
return &obj->ip6_address;
return NULL;
}
/*****************************************************************************/ /*****************************************************************************/
static guint32 static guint32
@@ -6807,10 +6755,6 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
platform_class->link_ipip_add = link_ipip_add; platform_class->link_ipip_add = link_ipip_add;
platform_class->link_sit_add = link_sit_add; platform_class->link_sit_add = link_sit_add;
platform_class->ip4_address_get = ip4_address_get;
platform_class->ip6_address_get = ip6_address_get;
platform_class->ip4_address_get_all = ip4_address_get_all;
platform_class->ip6_address_get_all = ip6_address_get_all;
platform_class->ip4_address_add = ip4_address_add; platform_class->ip4_address_add = ip4_address_add;
platform_class->ip6_address_add = ip6_address_add; platform_class->ip6_address_add = ip6_address_add;
platform_class->ip4_address_delete = ip4_address_delete; platform_class->ip4_address_delete = ip4_address_delete;

View File

@@ -2652,10 +2652,10 @@ nm_platform_ethtool_get_link_settings (NMPlatform *self, int ifindex, gboolean *
/*****************************************************************************/ /*****************************************************************************/
const NMDedupMultiHeadEntry * const NMDedupMultiHeadEntry *
nm_platform_lookup (NMPlatform *platform, nm_platform_lookup (NMPlatform *self,
const NMPLookup *lookup) const NMPLookup *lookup)
{ {
return nmp_cache_lookup (nm_platform_get_cache (platform), return nmp_cache_lookup (nm_platform_get_cache (self),
lookup); lookup);
} }
@@ -2670,7 +2670,7 @@ nm_platform_lookup_predicate_routes_skip_rtprot_kernel (const NMPObject *obj,
/** /**
* nm_platform_lookup_clone: * nm_platform_lookup_clone:
* @platform: * @self:
* @lookup: * @lookup:
* @predicate: if given, only objects for which @predicate returns %TRUE are included * @predicate: if given, only objects for which @predicate returns %TRUE are included
* in the result. * in the result.
@@ -2687,12 +2687,12 @@ nm_platform_lookup_predicate_routes_skip_rtprot_kernel (const NMPObject *obj,
* Returns: the result of the lookup. * Returns: the result of the lookup.
*/ */
GPtrArray * GPtrArray *
nm_platform_lookup_clone (NMPlatform *platform, nm_platform_lookup_clone (NMPlatform *self,
const NMPLookup *lookup, const NMPLookup *lookup,
gboolean (*predicate) (const NMPObject *obj, gpointer user_data), gboolean (*predicate) (const NMPObject *obj, gpointer user_data),
gpointer user_data) gpointer user_data)
{ {
return nm_dedup_multi_objs_to_ptr_array_head (nm_platform_lookup (platform, lookup), return nm_dedup_multi_objs_to_ptr_array_head (nm_platform_lookup (self, lookup),
(NMDedupMultiFcnSelectPredicate) predicate, (NMDedupMultiFcnSelectPredicate) predicate,
user_data); user_data);
} }
@@ -2716,6 +2716,20 @@ nm_platform_ip6_address_get_peer (const NMPlatformIP6Address *addr)
return &addr->peer_address; return &addr->peer_address;
} }
static GArray *
ipx_address_get_all (NMPlatform *self, int ifindex, NMPObjectType obj_type)
{
NMPLookup lookup;
nm_assert (NM_IN_SET (obj_type, NMP_OBJECT_TYPE_IP4_ADDRESS, NMP_OBJECT_TYPE_IP6_ADDRESS));
nmp_lookup_init_addrroute (&lookup,
obj_type,
ifindex);
return nmp_cache_lookup_to_array (nmp_cache_lookup (nm_platform_get_cache (self), &lookup),
obj_type,
FALSE /*addresses are always visible. */);
}
GArray * GArray *
nm_platform_ip4_address_get_all (NMPlatform *self, int ifindex) nm_platform_ip4_address_get_all (NMPlatform *self, int ifindex)
{ {
@@ -2723,7 +2737,7 @@ nm_platform_ip4_address_get_all (NMPlatform *self, int ifindex)
g_return_val_if_fail (ifindex > 0, NULL); g_return_val_if_fail (ifindex > 0, NULL);
return klass->ip4_address_get_all (self, ifindex); return ipx_address_get_all (self, ifindex, NMP_OBJECT_TYPE_IP4_ADDRESS);
} }
GArray * GArray *
@@ -2733,7 +2747,7 @@ nm_platform_ip6_address_get_all (NMPlatform *self, int ifindex)
g_return_val_if_fail (ifindex > 0, NULL); g_return_val_if_fail (ifindex > 0, NULL);
return klass->ip6_address_get_all (self, ifindex); return ipx_address_get_all (self, ifindex, NMP_OBJECT_TYPE_IP6_ADDRESS);
} }
gboolean gboolean
@@ -2848,19 +2862,31 @@ nm_platform_ip6_address_delete (NMPlatform *self, int ifindex, struct in6_addr a
const NMPlatformIP4Address * const NMPlatformIP4Address *
nm_platform_ip4_address_get (NMPlatform *self, int ifindex, in_addr_t address, guint8 plen, guint32 peer_address) nm_platform_ip4_address_get (NMPlatform *self, int ifindex, in_addr_t address, guint8 plen, guint32 peer_address)
{ {
NMPObject obj_id;
const NMPObject *obj;
_CHECK_SELF (self, klass, NULL); _CHECK_SELF (self, klass, NULL);
g_return_val_if_fail (plen <= 32, NULL); g_return_val_if_fail (plen <= 32, NULL);
return klass->ip4_address_get (self, ifindex, address, plen, peer_address); nmp_object_stackinit_id_ip4_address (&obj_id, ifindex, address, plen, peer_address);
obj = nmp_cache_lookup_obj (nm_platform_get_cache (self), &obj_id);
nm_assert (nmp_object_is_visible (obj));
return &obj->ip4_address;
} }
const NMPlatformIP6Address * const NMPlatformIP6Address *
nm_platform_ip6_address_get (NMPlatform *self, int ifindex, struct in6_addr address) nm_platform_ip6_address_get (NMPlatform *self, int ifindex, struct in6_addr address)
{ {
NMPObject obj_id;
const NMPObject *obj;
_CHECK_SELF (self, klass, NULL); _CHECK_SELF (self, klass, NULL);
return klass->ip6_address_get (self, ifindex, address); nmp_object_stackinit_id_ip6_address (&obj_id, ifindex, &address);
obj = nmp_cache_lookup_obj (nm_platform_get_cache (self), &obj_id);
nm_assert (nmp_object_is_visible (obj));
return &obj->ip6_address;
} }
static const NMPlatformIP4Address * static const NMPlatformIP4Address *
@@ -4920,17 +4946,17 @@ nm_platform_netns_get (NMPlatform *self)
} }
gboolean gboolean
nm_platform_netns_push (NMPlatform *platform, NMPNetns **netns) nm_platform_netns_push (NMPlatform *self, NMPNetns **netns)
{ {
g_return_val_if_fail (NM_IS_PLATFORM (platform), FALSE); g_return_val_if_fail (NM_IS_PLATFORM (self), FALSE);
if ( platform->_netns if ( self->_netns
&& !nmp_netns_push (platform->_netns)) { && !nmp_netns_push (self->_netns)) {
NM_SET_OUT (netns, NULL); NM_SET_OUT (netns, NULL);
return FALSE; return FALSE;
} }
NM_SET_OUT (netns, platform->_netns); NM_SET_OUT (netns, self->_netns);
return TRUE; return TRUE;
} }

View File

@@ -631,8 +631,6 @@ typedef struct {
gboolean (*mesh_set_channel) (NMPlatform *, int ifindex, guint32 channel); gboolean (*mesh_set_channel) (NMPlatform *, int ifindex, guint32 channel);
gboolean (*mesh_set_ssid) (NMPlatform *, int ifindex, const guint8 *ssid, gsize len); gboolean (*mesh_set_ssid) (NMPlatform *, int ifindex, const guint8 *ssid, gsize len);
GArray * (*ip4_address_get_all) (NMPlatform *, int ifindex);
GArray * (*ip6_address_get_all) (NMPlatform *, int ifindex);
gboolean (*ip4_address_add) (NMPlatform *, gboolean (*ip4_address_add) (NMPlatform *,
int ifindex, int ifindex,
in_addr_t address, in_addr_t address,
@@ -652,8 +650,6 @@ typedef struct {
guint32 flags); guint32 flags);
gboolean (*ip4_address_delete) (NMPlatform *, int ifindex, in_addr_t address, guint8 plen, in_addr_t peer_address); gboolean (*ip4_address_delete) (NMPlatform *, int ifindex, in_addr_t address, guint8 plen, in_addr_t peer_address);
gboolean (*ip6_address_delete) (NMPlatform *, int ifindex, struct in6_addr address, guint8 plen); gboolean (*ip6_address_delete) (NMPlatform *, int ifindex, struct in6_addr address, guint8 plen);
const NMPlatformIP4Address *(*ip4_address_get) (NMPlatform *, int ifindex, in_addr_t address, guint8 plen, in_addr_t peer_address);
const NMPlatformIP6Address *(*ip6_address_get) (NMPlatform *, int ifindex, struct in6_addr address);
gboolean (*ip4_route_add) (NMPlatform *, const NMPlatformIP4Route *route); gboolean (*ip4_route_add) (NMPlatform *, const NMPlatformIP4Route *route);
gboolean (*ip6_route_add) (NMPlatform *, const NMPlatformIP6Route *route); gboolean (*ip6_route_add) (NMPlatform *, const NMPlatformIP6Route *route);

View File

@@ -337,6 +337,24 @@ NMP_OBJECT_GET_TYPE (const NMPObject *obj)
return obj ? obj->_class->obj_type : NMP_OBJECT_TYPE_UNKNOWN; return obj ? obj->_class->obj_type : NMP_OBJECT_TYPE_UNKNOWN;
} }
#define NMP_OBJECT_CAST_IP4_ADDRESS(obj) \
({ \
typeof (*(obj)) *_obj = (obj); \
_nm_unused const NMPObject *_obj_type_check = _obj; \
\
nm_assert (NMP_OBJECT_GET_TYPE (_obj) == NMP_OBJECT_TYPE_IP4_ADDRESS); \
&_obj->ip4_address; \
})
#define NMP_OBJECT_CAST_IP6_ADDRESS(obj) \
({ \
typeof (*(obj)) *_obj = (obj); \
_nm_unused const NMPObject *_obj_type_check = _obj; \
\
nm_assert (NMP_OBJECT_GET_TYPE (_obj) == NMP_OBJECT_TYPE_IP6_ADDRESS); \
&_obj->ip6_address; \
})
#define NMP_OBJECT_CAST_IPX_ROUTE(obj) \ #define NMP_OBJECT_CAST_IPX_ROUTE(obj) \
({ \ ({ \
typeof (*(obj)) *_obj = (obj); \ typeof (*(obj)) *_obj = (obj); \