summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-05-05 02:30:25 +0200
committerThomas Haller <thaller@redhat.com>2015-06-17 11:41:42 +0200
commit470bcefa5f259cb752660ac0069afe22dee8052e (patch)
tree506ca9188f4cc8dd07b8b30ce1a3f7daca11a909
parentf268dca0f1e3cc7acd06d3806b8668e99a9b6df1 (diff)
platform: use new platform caching
Switch platform caching implementation. Instead of caching libnl objects, cache our own types. Don't remove yet the now obsolete functions. Advantage: * Performance - as we now cache our native NMPlatformObject instances, we no longer have to convert libnl objects every time we access the platform cache. - for most cases, access is now O(1) because we can lookup the object in a hash table. Note that ip4_address_get_all() still has to create a copy of the result (O(n)), but as the caller is about to use those elements, he cannot do better then O(n) anyway. * We cache our own native types and have full control over them. We cannot extend the libnl objects, which has many short-commings: - _rtnl_addr_hack_lifetimes_rel_to_abs() to convert the timestamps to absolute values (and back). - hack_empty_master_iff_lower_up() would modify the internal flag, but it looses the original value. That means, we can only hack the state before putting a link into the cache, but we cannot revert that change, when a slave in the cache changes state. That was previously solved by always refetching the master when a slave changed. Now we can re-evaluate the connected state (DELAYED_ACTION_TYPE_MASTER_CONNECTED). - we implement functions like equality, to-string as most suitable for us. Before we needed hacks like nm_nl_object_diff(), nm_nl_cache_search(), route_search_cache(). - we can extend our objects with exactly those properties we care, and possibly additional properties that are not representable in the libnl objects. - we no longer cache RTM_F_CLONED routes and they get rejected early on as we receive them. - In the future, maybe it'd be interesting the make platform objects immutable (and ref-counted) and expose them directly. * Previous implementation did not order the refresh of objects but called check_cache_items(). Now, those actions are delayed and combined in an attempt to reduce the overall number of reloads. Realize how expensive a check_cache_items() for addresses and routes was: it would iterate all addresses/routes and call refresh_object(). The latter obtains a full dump of *all* objects again, and ignores all but the needle. Note that we probably still schedule some delayed actions that are not needed. Later we can optimize that further (related bug bgo #747985). While some of these points could also have been implemented with caching of libnl objects, that would have become hard to maintain. https://bugzilla.gnome.org/show_bug.cgi?id=747981
-rw-r--r--src/platform/nm-fake-platform.c58
-rw-r--r--src/platform/nm-linux-platform.c809
-rw-r--r--src/platform/tests/test-address.c4
-rw-r--r--src/platform/tests/test-link.c38
-rw-r--r--src/platform/tests/test-route.c8
-rw-r--r--src/tests/test-route-manager.c8
6 files changed, 410 insertions, 515 deletions
diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c
index 479e2fbf5c..4069650dbe 100644
--- a/src/platform/nm-fake-platform.c
+++ b/src/platform/nm-fake-platform.c
@@ -27,6 +27,7 @@
#include <linux/rtnetlink.h>
#include "gsystem-local-alloc.h"
+#include "nm-utils.h"
#include "NetworkManagerUtils.h"
#include "nm-fake-platform.h"
#include "nm-logging.h"
@@ -312,19 +313,23 @@ link_changed (NMPlatform *platform, NMFakePlatformLink *device)
g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_LINK_CHANGED, device->link.ifindex, &device->link, NM_PLATFORM_SIGNAL_CHANGED, NM_PLATFORM_REASON_INTERNAL);
if (device->link.master) {
+ gboolean connected = FALSE;
+
NMFakePlatformLink *master = link_get (platform, device->link.master);
- g_return_if_fail (master != device);
+ g_return_if_fail (master && master != device);
- master->link.connected = FALSE;
for (i = 0; i < priv->links->len; i++) {
NMFakePlatformLink *slave = &g_array_index (priv->links, NMFakePlatformLink, i);
if (slave && slave->link.master == master->link.ifindex && slave->link.connected)
- master->link.connected = TRUE;
+ connected = TRUE;
}
- link_changed (platform, master);
+ if (master->link.connected != connected) {
+ master->link.connected = connected;
+ link_changed (platform, master);
+ }
}
}
@@ -332,27 +337,33 @@ static gboolean
link_set_up (NMPlatform *platform, int ifindex)
{
NMFakePlatformLink *device = link_get (platform, ifindex);
+ gboolean up, connected;
if (!device)
return FALSE;
- device->link.up = TRUE;
+ up = TRUE;
+ connected = TRUE;
switch (device->link.type) {
case NM_LINK_TYPE_DUMMY:
case NM_LINK_TYPE_VLAN:
- device->link.connected = TRUE;
break;
case NM_LINK_TYPE_BRIDGE:
case NM_LINK_TYPE_BOND:
case NM_LINK_TYPE_TEAM:
- device->link.connected = FALSE;
+ connected = FALSE;
break;
default:
- device->link.connected = FALSE;
+ connected = FALSE;
g_error ("Unexpected device type: %d", device->link.type);
}
- link_changed (platform, device);
+ if ( device->link.up != up
+ || device->link.connected != connected) {
+ device->link.up = up;
+ device->link.connected = connected;
+ link_changed (platform, device);
+ }
return TRUE;
}
@@ -365,10 +376,12 @@ link_set_down (NMPlatform *platform, int ifindex)
if (!device)
return FALSE;
- device->link.up = FALSE;
- device->link.connected = FALSE;
+ if (device->link.up || device->link.connected) {
+ device->link.up = FALSE;
+ device->link.connected = FALSE;
- link_changed (platform, device);
+ link_changed (platform, device);
+ }
return TRUE;
}
@@ -566,12 +579,21 @@ static gboolean
link_enslave (NMPlatform *platform, int master, int slave)
{
NMFakePlatformLink *device = link_get (platform, slave);
+ NMFakePlatformLink *master_device = link_get (platform, master);
g_return_val_if_fail (device, FALSE);
+ g_return_val_if_fail (master_device, FALSE);
- device->link.master = master;
+ if (device->link.master != master) {
+ device->link.master = master;
- link_changed (platform, device);
+ if (NM_IN_SET (master_device->link.type, NM_LINK_TYPE_BOND, NM_LINK_TYPE_TEAM)) {
+ device->link.up = TRUE;
+ device->link.connected = TRUE;
+ }
+
+ link_changed (platform, device);
+ }
return TRUE;
}
@@ -1223,8 +1245,8 @@ ip4_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source,
break;
}
if (i == priv->ip4_routes->len) {
- nm_log_warn (LOGD_PLATFORM, "Fake platform: error adding %s: Network Unreachable",
- nm_platform_ip4_route_to_string (&route));
+ nm_log_warn (LOGD_PLATFORM, "Fake platform: failure adding ip4-route '%d: %s/%d %d': Network Unreachable",
+ route.ifindex, nm_utils_inet4_ntop (route.network, NULL), route.plen, route.metric);
return FALSE;
}
}
@@ -1290,8 +1312,8 @@ ip6_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source,
break;
}
if (i == priv->ip6_routes->len) {
- nm_log_warn (LOGD_PLATFORM, "Fake platform: error adding %s: Network Unreachable",
- nm_platform_ip6_route_to_string (&route));
+ nm_log_warn (LOGD_PLATFORM, "Fake platform: failure adding ip6-route '%d: %s/%d %d': Network Unreachable",
+ route.ifindex, nm_utils_inet6_ntop (&route.network, NULL), route.plen, route.metric);
return FALSE;
}
}
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index add4ac9493..c077d9cc03 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -909,15 +909,34 @@ read_devtype (const char *sysfs_path)
}
static NMLinkType
-link_extract_type (NMPlatform *platform, struct rtnl_link *rtnllink)
+link_extract_type (NMPlatform *platform, struct rtnl_link *rtnllink, gboolean complete_from_cache, const char **out_kind)
{
const char *rtnl_type, *ifname;
int i, arptype;
- if (!rtnllink)
+ if (!rtnllink) {
+ if (out_kind)
+ *out_kind = NULL;
return NM_LINK_TYPE_NONE;
+ }
rtnl_type = rtnl_link_get_type (rtnllink);
+ if (!rtnl_type && complete_from_cache) {
+ int ifindex = rtnl_link_get_ifindex (rtnllink);
+ const NMPObject *obj;
+
+ /* Sometimes we get netlink messages with the link type unset.
+ * In this case, look it up in the cache. */
+ if (ifindex > 0) {
+ obj = nmp_cache_lookup_link (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, ifindex);
+ if (obj && obj->_link.netlink.is_in_netlink && obj->link.kind) {
+ rtnl_type = obj->link.kind;
+ _LOGT ("link_extract_type(): complete kind from cache: ifindex=%d, kind=%s", ifindex, rtnl_type);
+ }
+ }
+ }
+ if (out_kind)
+ *out_kind = rtnl_type;
if (rtnl_type) {
for (i = 0; i < G_N_ELEMENTS (linktypes); i++) {
if (g_strcmp0 (rtnl_type, linktypes[i].rtnl_type) == 0)
@@ -1027,7 +1046,7 @@ init_link (NMPlatform *platform, NMPlatformLink *info, struct rtnl_link *rtnllin
g_strlcpy (info->name, name, sizeof (info->name));
else
info->name[0] = '\0';
- info->type = link_extract_type (platform, rtnllink);
+ info->type = link_extract_type (platform, rtnllink, FALSE, NULL);
info->kind = g_intern_string (rtnl_link_get_type (rtnllink));
info->flags = rtnl_link_get_flags (rtnllink);
info->up = NM_FLAGS_HAS (info->flags, IFF_UP);
@@ -1118,6 +1137,7 @@ _nmp_vt_cmd_plobj_init_from_nl_link (NMPlatform *platform, NMPlatformObject *_ob
struct rtnl_link *nlo = (struct rtnl_link *) _nlo;
const char *name;
struct nl_addr *nladdr;
+ const char *kind;
nm_assert (memcmp (obj, ((char [sizeof (NMPObjectLink)]) { 0 }), sizeof (NMPObjectLink)) == 0);
@@ -1129,8 +1149,8 @@ _nmp_vt_cmd_plobj_init_from_nl_link (NMPlatform *platform, NMPlatformObject *_ob
name = rtnl_link_get_name (nlo);
if (name)
g_strlcpy (obj->name, name, sizeof (obj->name));
- obj->type = link_extract_type (platform, nlo);
- obj->kind = g_intern_string (rtnl_link_get_type (nlo));
+ obj->type = link_extract_type (platform, nlo, complete_from_cache, &kind);
+ obj->kind = g_intern_string (kind);
obj->flags = rtnl_link_get_flags (nlo);
obj->up = NM_FLAGS_HAS (obj->flags, IFF_UP);
obj->connected = NM_FLAGS_HAS (obj->flags, IFF_LOWER_UP);
@@ -3208,120 +3228,30 @@ static int
event_notification (struct nl_msg *msg, gpointer user_data)
{
NMPlatform *platform = NM_PLATFORM (user_data);
- NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
- struct nl_cache *cache;
- auto_nl_object struct nl_object *object = NULL;
- auto_nl_object struct nl_object *cached_object = NULL;
- auto_nl_object struct nl_object *kernel_object = NULL;
+ auto_nl_object struct nl_object *nlo = NULL;
+ auto_nmp_obj NMPObject *obj = NULL;
int event;
- int nle;
- ObjectType type;
event = nlmsg_hdr (msg)->nlmsg_type;
if (_support_kernel_extended_ifa_flags_still_undecided () && event == RTM_NEWADDR)
_support_kernel_extended_ifa_flags_detect (msg);
- nl_msg_parse (msg, ref_object, &object);
- if (!object)
- return NL_OK;
-
- type = _nlo_get_object_type (object);
-
- if (type == OBJECT_TYPE_LINK)
- _support_user_ipv6ll_detect ((struct rtnl_link *) object);
-
- if (nm_logging_enabled (LOGL_DEBUG, LOGD_PLATFORM)) {
- if (type == OBJECT_TYPE_LINK) {
- const char *name = rtnl_link_get_name ((struct rtnl_link *) object);
-
- debug ("netlink event (type %d) for link: %s (%d, family %d)",
- event, name ? name : "(unknown)",
- rtnl_link_get_ifindex ((struct rtnl_link *) object),
- rtnl_link_get_family ((struct rtnl_link *) object));
- } else
- debug ("netlink event (type %d)", event);
- }
-
- cache = choose_cache_by_type (platform, type);
- cached_object = nm_nl_cache_search (cache, object);
- kernel_object = get_kernel_object (priv->nlh, object);
-
- hack_empty_master_iff_lower_up (platform, kernel_object);
-
- /* Removed object */
- switch (event) {
- case RTM_DELLINK:
- case RTM_DELADDR:
- case RTM_DELROUTE:
- /* Ignore inconsistent deletion
- *
- * Quick external deletion and addition can be occasionally
- * seen as just a change.
- */
- if (kernel_object)
- return NL_OK;
- /* Ignore internal deletion */
- if (!cached_object)
- return NL_OK;
-
- nl_cache_remove (cached_object);
- announce_object (platform, cached_object, NM_PLATFORM_SIGNAL_REMOVED, NM_PLATFORM_REASON_EXTERNAL);
- if (event == RTM_DELLINK) {
- int ifindex = rtnl_link_get_ifindex ((struct rtnl_link *) cached_object);
-
- g_hash_table_remove (priv->udev_devices, GINT_TO_POINTER (ifindex));
- }
-
+ nl_msg_parse (msg, ref_object, &nlo);
+ if (!nlo)
return NL_OK;
- case RTM_NEWLINK:
- case RTM_NEWADDR:
- case RTM_NEWROUTE:
- /* Ignore inconsistent addition or change (kernel will send a good one)
- *
- * Quick sequence of RTM_NEWLINK notifications can be occasionally
- * collapsed to just one addition or deletion, depending of whether we
- * already have the object in cache.
- */
- if (!kernel_object)
- return NL_OK;
- /* Ignore unsupported object types (e.g. AF_PHONET family addresses) */
- if (type == OBJECT_TYPE_UNKNOWN)
- return NL_OK;
+ obj = nmp_object_from_nl (platform, nlo, FALSE, TRUE);
- /* Handle external addition */
- if (!cached_object) {
- nle = nl_cache_add (cache, kernel_object);
- if (nle) {
- error ("netlink cache error: %s", nl_geterror (nle));
- return NL_OK;
- }
- announce_object (platform, kernel_object, NM_PLATFORM_SIGNAL_ADDED, NM_PLATFORM_REASON_EXTERNAL);
- return NL_OK;
- }
- /* Ignore non-change
- *
- * This also catches notifications for internal addition or change, unless
- * another action occured very soon after it.
- */
- if (!nm_nl_object_diff (type, kernel_object, cached_object))
- return NL_OK;
+ if ( (obj && NMP_OBJECT_GET_TYPE (obj) == OBJECT_TYPE_LINK)
+ || (!obj && _nlo_get_object_type (nlo) == OBJECT_TYPE_LINK))
+ _support_user_ipv6ll_detect ((struct rtnl_link *) nlo);
- /* Handle external change */
- nl_cache_remove (cached_object);
- nle = nl_cache_add (cache, kernel_object);
- if (nle) {
- error ("netlink cache error: %s", nl_geterror (nle));
- return NL_OK;
- }
- announce_object (platform, kernel_object, NM_PLATFORM_SIGNAL_CHANGED, NM_PLATFORM_REASON_EXTERNAL);
+ _LOGD ("event-notification: type %d: %s", event, nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0));
+ if (obj)
+ do_refresh_object (platform, obj, NM_PLATFORM_REASON_EXTERNAL, TRUE, NULL);
- return NL_OK;
- default:
- error ("Unknown netlink event: %d", event);
- return NL_OK;
- }
+ return NL_OK;
}
/******************************************************************/
@@ -3508,27 +3438,32 @@ static GArray *
link_get_all (NMPlatform *platform)
{
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
- GArray *links = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformLink), nl_cache_nitems (priv->link_cache));
- NMPlatformLink device;
- struct nl_object *object;
-
- for (object = nl_cache_get_first (priv->link_cache); object; object = nl_cache_get_next (object)) {
- if (init_link (platform, &device, (struct rtnl_link *) object))
- g_array_append_val (links, device);
- }
- return links;
+ return nmp_cache_lookup_multi_to_array (priv->cache,
+ OBJECT_TYPE_LINK,
+ nmp_cache_id_init_links (NMP_CACHE_ID_STATIC, TRUE));
}
static gboolean
_nm_platform_link_get (NMPlatform *platform, int ifindex, NMPlatformLink *l)
{
- NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
- auto_nl_object struct rtnl_link *rtnllink = NULL;
- NMPlatformLink tmp = { 0 };
+ const NMPObject *obj;
+
+ obj = cache_lookup_link (platform, ifindex);
+ if (obj && l)
+ *l = obj->link;
+ return !!obj;
+}
- rtnllink = rtnl_link_get (priv->link_cache, ifindex);
- return (rtnllink && init_link (platform, l ? l : &tmp, rtnllink));
+struct _nm_platform_link_get_by_address_data {
+ gconstpointer address;
+ guint8 length;
+};
+
+static gboolean
+_nm_platform_link_get_by_address_match_link (const NMPObject *obj, struct _nm_platform_link_get_by_address_data *d)
+{
+ return obj->link.addr.len == d->length && !memcmp (obj->link.addr.data, d->address, d->length);
}
static gboolean
@@ -3537,22 +3472,23 @@ _nm_platform_link_get_by_address (NMPlatform *platform,
size_t length,
NMPlatformLink *l)
{
- NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
- struct nl_object *object;
+ const NMPObject *obj;
+ struct _nm_platform_link_get_by_address_data d = {
+ .address = address,
+ .length = length,
+ };
- for (object = nl_cache_get_first (priv->link_cache); object; object = nl_cache_get_next (object)) {
- struct rtnl_link *rtnl_link = (struct rtnl_link *) object;
- struct nl_addr *nladdr;
- gconstpointer hwaddr;
+ if (length <= 0 || length > NM_UTILS_HWADDR_LEN_MAX)
+ return FALSE;
+ if (!address)
+ return FALSE;
- nladdr = rtnl_link_get_addr (rtnl_link);
- if (nladdr && (nl_addr_get_len (nladdr) == length)) {
- hwaddr = nl_addr_get_binary_addr (nladdr);
- if (hwaddr && memcmp (hwaddr, address, length) == 0)
- return init_link (platform, l, rtnl_link);
- }
- }
- return FALSE;
+ obj = nmp_cache_lookup_link_full (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache,
+ 0, NULL, TRUE, NM_LINK_TYPE_NONE,
+ (NMPObjectMatchFn) _nm_platform_link_get_by_address_match_link, &d);
+ if (obj && l)
+ *l = obj->link;
+ return !!obj;
}
static struct nl_object *
@@ -3731,7 +3667,7 @@ link_add (NMPlatform *platform,
size_t address_len,
NMPlatformLink *out_link)
{
- struct nl_object *l;
+ auto_nl_object struct nl_object *l = NULL;
if (type == NM_LINK_TYPE_BOND) {
/* When the kernel loads the bond module, either via explicit modprobe
@@ -3757,10 +3693,7 @@ link_add (NMPlatform *platform,
rtnl_link_set_addr ((struct rtnl_link *) l, nladdr);
}
- if (!add_object (platform, l))
- return FALSE;
-
- return link_get_by_name (platform, name, out_link);
+ return do_add_link_with_lookup (platform, name, (struct rtnl_link *) l, type, out_link);
}
static struct rtnl_link *
@@ -3819,71 +3752,80 @@ static gboolean
link_delete (NMPlatform *platform, int ifindex)
{
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
- auto_nl_object struct rtnl_link *rtnllink = rtnl_link_get (priv->link_cache, ifindex);
+ NMPObject obj_needle;
+ const NMPObject *obj;
- if (!rtnllink) {
+ obj = nmp_cache_lookup_link (priv->cache, ifindex);
+ if (!obj || !obj->_link.netlink.is_in_netlink) {
platform->error = NM_PLATFORM_ERROR_NOT_FOUND;
return FALSE;
}
- return delete_object (platform, build_rtnl_link (ifindex, NULL, NM_LINK_TYPE_NONE), TRUE);
+ nmp_object_stackinit_id_link (&obj_needle, ifindex);
+ return do_delete_object (platform, &obj_needle, NULL);
}
static int
link_get_ifindex (NMPlatform *platform, const char *ifname)
{
- NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
+ const NMPObject *obj;
+
+ g_return_val_if_fail (ifname, 0);
- return rtnl_link_name2i (priv->link_cache, ifname);
+ obj = nmp_cache_lookup_link_full (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache,
+ 0, ifname, TRUE, NM_LINK_TYPE_NONE, NULL, NULL);
+ if (!obj)
+ platform->error = NM_PLATFORM_ERROR_NOT_FOUND;
+ return obj ? obj->link.ifindex : 0;
}
static const char *
link_get_name (NMPlatform *platform, int ifindex)
{
- auto_nl_object struct rtnl_link *rtnllink = link_get (platform, ifindex);
+ const NMPObject *obj = cache_lookup_link (platform, ifindex);
- return rtnllink ? rtnl_link_get_name (rtnllink) : NULL;
+ return obj ? obj->link.name : NULL;
}
static NMLinkType
link_get_type (NMPlatform *platform, int ifindex)
{
- auto_nl_object struct rtnl_link *rtnllink = link_get (platform, ifindex);
+ const NMPObject *obj = cache_lookup_link (platform, ifindex);
- return link_extract_type (platform, rtnllink);
+ return obj ? obj->link.type : NM_LINK_TYPE_NONE;
}
static const char *
link_get_type_name (NMPlatform *platform, int ifindex)
{
- auto_nl_object struct rtnl_link *rtnllink = link_get (platform, ifindex);
- NMLinkType link_type;
- const char *l;
+ const NMPObject *obj = cache_lookup_link (platform, ifindex);
- if (!rtnllink)
+ if (!obj)
return NULL;
- link_type = link_extract_type (platform, rtnllink);
- if (link_type != NM_LINK_TYPE_UNKNOWN) {
+ if (obj->link.type != NM_LINK_TYPE_UNKNOWN) {
/* We could detect the @link_type. In this case the function returns
* our internel module names, which differs from rtnl_link_get_type():
* - NM_LINK_TYPE_INFINIBAND (gives "infiniband", instead of "ipoib")
* - NM_LINK_TYPE_TAP (gives "tap", instead of "tun").
* Note that this functions is only used by NMDeviceGeneric to
* set type_description. */
- return nm_link_type_to_string (link_type);
+ return nm_link_type_to_string (obj->link.type);
}
-
/* Link type not detected. Fallback to rtnl_link_get_type()/IFLA_INFO_KIND. */
- l = rtnl_link_get_type (rtnllink);
- return l ? g_intern_string (l) : "unknown";
+ return str_if_set (obj->link.kind, "unknown");
}
static gboolean
link_get_unmanaged (NMPlatform *platform, int ifindex, gboolean *managed)
{
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
- GUdevDevice *udev_device = g_hash_table_lookup (priv->udev_devices, GINT_TO_POINTER (ifindex));
+ const NMPObject *link;
+ GUdevDevice *udev_device = NULL;
+
+ link = nmp_cache_lookup_link (priv->cache, ifindex);
+ if (link)
+ udev_device = link->_link.udev.device;
if (udev_device && g_udev_device_get_property (udev_device, "NM_UNMANAGED")) {
*managed = g_udev_device_get_property_as_boolean (udev_device, "NM_UNMANAGED");
@@ -3896,20 +3838,19 @@ link_get_unmanaged (NMPlatform *platform, int ifindex, gboolean *managed)
static guint32
link_get_flags (NMPlatform *platform, int ifindex)
{
- auto_nl_object struct rtnl_link *rtnllink = link_get (platform, ifindex);
+ const NMPObject *obj = cache_lookup_link (platform, ifindex);
- if (!rtnllink)
- return IFF_NOARP;
-
- return rtnl_link_get_flags (rtnllink);
+ return obj ? obj->link.flags : IFF_NOARP;
}
static gboolean
link_refresh (NMPlatform *platform, int ifindex)
{
- auto_nl_object struct rtnl_link *rtnllink = _nm_rtnl_link_alloc (ifindex, NULL);
+ NMPObject obj_needle;
+ const NMPObject *obj_cache;
- return refresh_object (platform, (struct nl_object *) rtnllink, FALSE, NM_PLATFORM_REASON_EXTERNAL);
+ do_refresh_object (platform, nmp_object_stackinit_id_link (&obj_needle, ifindex), NM_PLATFORM_REASON_EXTERNAL, TRUE, &obj_cache);
+ return !!obj_cache;
}
static gboolean
@@ -3921,7 +3862,9 @@ link_is_up (NMPlatform *platform, int ifindex)
static gboolean
link_is_connected (NMPlatform *platform, int ifindex)
{
- return !!(link_get_flags (platform, ifindex) & IFF_LOWER_UP);
+ const NMPObject *obj = cache_lookup_link (platform, ifindex);
+
+ return obj ? obj->link.connected : FALSE;
}
static gboolean
@@ -3934,20 +3877,25 @@ static gboolean
link_change_flags (NMPlatform *platform, int ifindex, unsigned int flags, gboolean value)
{
auto_nl_object struct rtnl_link *change = _nm_rtnl_link_alloc (ifindex, NULL);
+ const NMPObject *obj_cache;
+ char buf[256];
+
+ obj_cache = cache_lookup_link (platform, ifindex);
+ if (!obj_cache)
+ return FALSE;
+ rtnl_link_set_flags (change, obj_cache->link.flags);
if (value)
rtnl_link_set_flags (change, flags);
else
rtnl_link_unset_flags (change, flags);
- if (nm_logging_enabled (LOGL_DEBUG, LOGD_PLATFORM)) {
- char buf[512];
+ _LOGD ("link: change %d: flags %s '%s' (%d)", ifindex,
+ value ? "set" : "unset",
+ rtnl_link_flags2str (flags, buf, sizeof (buf)),
+ flags);
- rtnl_link_flags2str (flags, buf, sizeof (buf));
- debug ("link: change %d: flags %s '%s' (%d)", ifindex, value ? "set" : "unset", buf, flags);
- }
-
- return link_change (platform, ifindex, change);
+ return do_change_link (platform, change, FALSE);
}
static gboolean
@@ -3977,52 +3925,26 @@ link_set_noarp (NMPlatform *platform, int ifindex)
static gboolean
link_get_ipv6_token (NMPlatform *platform, int ifindex, NMUtilsIPv6IfaceId *iid)
{
-#if HAVE_LIBNL_INET6_TOKEN
- auto_nl_object struct rtnl_link *rtnllink = link_get (platform, ifindex);
- struct nl_addr *nladdr;
- struct in6_addr *addr;
+ const NMPObject *obj = cache_lookup_link (platform, ifindex);
- if (rtnllink &&
- (rtnl_link_inet6_get_token (rtnllink, &nladdr)) == 0) {
- if (nl_addr_get_family (nladdr) != AF_INET6 ||
- nl_addr_get_len (nladdr) != sizeof (struct in6_addr)) {
- nl_addr_put (nladdr);
- return FALSE;
- }
+ /* Always lookup @obj, because it properly sets nm_platform_get_error().
+ * Otherwise, we could save this '#ifndef HAVE_LIBNL_INET6_TOKEN' */
+ if (!obj || !obj->link.inet6_token.is_valid)
+ return FALSE;
- addr = nl_addr_get_binary_addr (nladdr);
- iid->id_u8[7] = addr->s6_addr[15];
- iid->id_u8[6] = addr->s6_addr[14];
- iid->id_u8[5] = addr->s6_addr[13];
- iid->id_u8[4] = addr->s6_addr[12];
- iid->id_u8[3] = addr->s6_addr[11];
- iid->id_u8[2] = addr->s6_addr[10];
- iid->id_u8[1] = addr->s6_addr[9];
- iid->id_u8[0] = addr->s6_addr[8];
- nl_addr_put (nladdr);
- return TRUE;
- }
-#endif
- return FALSE;
+ *iid = obj->link.inet6_token.iid;
+ return TRUE;
}
static gboolean
link_get_user_ipv6ll_enabled (NMPlatform *platform, int ifindex)
{
-#if HAVE_LIBNL_INET6_ADDR_GEN_MODE
- if (_support_user_ipv6ll_get ()) {
- auto_nl_object struct rtnl_link *rtnllink = link_get (platform, ifindex);
- uint8_t mode = 0;
+ const NMPObject *obj = cache_lookup_link (platform, ifindex);
- if (rtnllink) {
- if (rtnl_link_inet6_get_addr_gen_mode (rtnllink, &mode) != 0) {
- /* Default to "disabled" on error */
- return FALSE;
- }
- return mode == IN6_ADDR_GEN_MODE_NONE;
- }
- }
-#endif
+ /* Always lookup @obj, because it properly sets nm_platform_get_error().
+ * Otherwise, we could save this '#ifndef HAVE_LIBNL_INET6_ADDR_GEN_MODE' */
+ if (obj && obj->link.inet6_addr_gen_mode_inv)
+ return (~obj->link.inet6_addr_gen_mode_inv) == IN6_ADDR_GEN_MODE_NONE;
return FALSE;
}
@@ -4031,14 +3953,14 @@ link_set_user_ipv6ll_enabled (NMPlatform *platform, int ifindex, gboolean enable
{
#if HAVE_LIBNL_INET6_ADDR_GEN_MODE
if (_support_user_ipv6ll_get ()) {
- auto_nl_object struct rtnl_link *change = _nm_rtnl_link_alloc (ifindex, NULL);
+ auto_nl_object struct rtnl_link *nlo = _nm_rtnl_link_alloc (ifindex, NULL);
guint8 mode = enabled ? IN6_ADDR_GEN_MODE_NONE : IN6_ADDR_GEN_MODE_EUI64;
char buf[32];
- rtnl_link_inet6_set_addr_gen_mode (change, mode);
+ rtnl_link_inet6_set_addr_gen_mode (nlo, mode);
debug ("link: change %d: set IPv6 address generation mode to %s",
ifindex, rtnl_link_inet6_addrgenmode2str (mode, buf, sizeof (buf)));
- return link_change (platform, ifindex, change);
+ return do_change_link (platform, nlo, TRUE);
}
#endif
return FALSE;
@@ -4062,13 +3984,15 @@ link_supports_carrier_detect (NMPlatform *platform, int ifindex)
static gboolean
link_supports_vlans (NMPlatform *platform, int ifindex)
{
- auto_nl_object struct rtnl_link *rtnllink = link_get (platform, ifindex);
+ const NMPObject *obj;
+
+ obj = cache_lookup_link (platform, ifindex);
/* Only ARPHRD_ETHER links can possibly support VLANs. */
- if (!rtnllink || rtnl_link_get_arptype (rtnllink) != ARPHRD_ETHER)
+ if (!obj || obj->link.arptype != ARPHRD_ETHER)
return FALSE;
- return nmp_utils_ethtool_supports_vlans (rtnl_link_get_name (rtnllink));
+ return nmp_utils_ethtool_supports_vlans (obj->link.name);
}
static gboolean
@@ -4076,36 +4000,31 @@ link_set_address (NMPlatform *platform, int ifindex, gconstpointer address, size
{
auto_nl_object struct rtnl_link *change = _nm_rtnl_link_alloc (ifindex, NULL);
auto_nl_addr struct nl_addr *nladdr = _nm_nl_addr_build (AF_LLC, address, length);
+ gs_free char *mac = NULL;
rtnl_link_set_addr (change, nladdr);
- if (nm_logging_enabled (LOGL_DEBUG, LOGD_PLATFORM)) {
- char *mac = nm_utils_hwaddr_ntoa (address, length);
-
- debug ("link: change %d: address %s (%lu bytes)", ifindex, mac, (unsigned long) length);
- g_free (mac);
- }
-
- return link_change (platform, ifindex, change);
+ _LOGD ("link: change %d: address %s (%lu bytes)", ifindex,
+ (mac = nm_utils_hwaddr_ntoa (address, length)),
+ (unsigned long) length);
+ return do_change_link (platform, change, TRUE);
}
static gconstpointer
link_get_address (NMPlatform *platform, int ifindex, size_t *length)
{
- auto_nl_object struct rtnl_link *rtnllink = link_get (platform, ifindex);
- struct nl_addr *nladdr;
- size_t l = 0;
+ const NMPObject *obj = cache_lookup_link (platform, ifindex);
gconstpointer a = NULL;
+ guint8 l = 0;
- if (rtnllink &&
- (nladdr = rtnl_link_get_addr (rtnllink))) {
- l = nl_addr_get_len (nladdr);
- if (l > NM_UTILS_HWADDR_LEN_MAX) {
+ if (obj && obj->link.addr.len > 0) {
+ if (obj->link.addr.len > NM_UTILS_HWADDR_LEN_MAX) {
if (length)
*length = 0;
g_return_val_if_reached (NULL);
- } else if (l > 0)
- a = nl_addr_get_binary_addr (nladdr);
+ }
+ a = obj->link.addr.data;
+ l = obj->link.addr.len;
}
if (length)
@@ -4130,15 +4049,15 @@ link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu)
rtnl_link_set_mtu (change, mtu);
debug ("link: change %d: mtu %lu", ifindex, (unsigned long)mtu);
- return link_change (platform, ifindex, change);
+ return do_change_link (platform, change, TRUE);
}
static guint32
link_get_mtu (NMPlatform *platform, int ifindex)
{
- auto_nl_object struct rtnl_link *rtnllink = link_get (platform, ifindex);
+ const NMPObject *obj = cache_lookup_link (platform, ifindex);
- return rtnllink ? rtnl_link_get_mtu (rtnllink) : 0;
+ return obj ? obj->link.mtu : 0;
}
static char *
@@ -4192,8 +4111,7 @@ vlan_add (NMPlatform *platform,
guint32 vlan_flags,
NMPlatformLink *out_link)
{
- struct nl_object *object = build_rtnl_link (0, name, NM_LINK_TYPE_VLAN);
- struct rtnl_link *rtnllink = (struct rtnl_link *) object;
+ auto_nl_object struct rtnl_link *rtnllink = (struct rtnl_link *) build_rtnl_link (0, name, NM_LINK_TYPE_VLAN);
unsigned int kernel_flags;
kernel_flags = 0;
@@ -4211,55 +4129,50 @@ vlan_add (NMPlatform *platform,
debug ("link: add vlan '%s', parent %d, vlan id %d, flags %X (native: %X)",
name, parent, vlan_id, (unsigned int) vlan_flags, kernel_flags);
- if (!add_object (platform, object))
- return FALSE;
-
- return link_get_by_name (platform, name, out_link);
+ return do_add_link_with_lookup (platform, name, rtnllink, NM_LINK_TYPE_VLAN, out_link);
}
static gboolean
vlan_get_info (NMPlatform *platform, int ifindex, int *parent, int *vlan_id)
{
- auto_nl_object struct rtnl_link *rtnllink = link_get (platform, ifindex);
+ const NMPObject *obj = cache_lookup_link (platform, ifindex);
+ int p = 0, v = 0;
+ if (obj) {
+ p = obj->link.parent;
+ v = obj->link.vlan_id;
+ }
if (parent)
- *parent = rtnllink ? rtnl_link_get_link (rtnllink) : 0;
+ *parent = p;
if (vlan_id)
- *vlan_id = rtnllink ? rtnl_link_vlan_get_id (rtnllink) : 0;
-
- return !!rtnllink;
+ *vlan_id = v;
+ return !!obj;
}
static gboolean
vlan_set_ingress_map (NMPlatform *platform, int ifindex, int from, int to)
{
- /* We have to use link_get() because a "blank" rtnl_link won't have the
- * right data structures to be able to call rtnl_link_vlan_set_ingress_map()
- * on it. (Likewise below in vlan_set_egress_map().)
- */
- auto_nl_object struct rtnl_link *change = link_get (platform, ifindex);
+ auto_nl_object struct rtnl_link *change = (struct rtnl_link *) build_rtnl_link (ifindex, NULL, NM_LINK_TYPE_VLAN);
- if (!change)
- return FALSE;
+ rtnl_link_set_type (change, "vlan");
rtnl_link_vlan_set_ingress_map (change, from, to);
debug ("link: change %d: vlan ingress map %d -> %d", ifindex, from, to);
- return link_change (platform, ifindex, change);
+ return do_change_link (platform, change, TRUE);
}
static gboolean
vlan_set_egress_map (NMPlatform *platform, int ifindex, int from, int to)
{
- auto_nl_object struct rtnl_link *change = link_get (platform, ifindex);
+ auto_nl_object struct rtnl_link *change = (struct rtnl_link *) build_rtnl_link (ifindex, NULL, NM_LINK_TYPE_VLAN);
- if (!change)
- return FALSE;
+ rtnl_link_set_type (change, "vlan");
rtnl_link_vlan_set_egress_map (change, from, to);
debug ("link: change %d: vlan egress map %d -> %d", ifindex, from, to);
- return link_change (platform, ifindex, change);
+ return do_change_link (platform, change, TRUE);
}
static gboolean
@@ -4270,7 +4183,7 @@ link_enslave (NMPlatform *platform, int master, int slave)
rtnl_link_set_master (change, master);
debug ("link: change %d: enslave to master %d", slave, master);
- return link_change (platform, slave, change);
+ return do_change_link (platform, change, TRUE);
}
static gboolean
@@ -4282,9 +4195,9 @@ link_release (NMPlatform *platform, int master, int slave)
static int
link_get_master (NMPlatform *platform, int slave)
{
- auto_nl_object struct rtnl_link *rtnllink = link_get (platform, slave);
+ const NMPObject *obj = cache_lookup_link (platform, slave);
- return rtnllink ? rtnl_link_get_master (rtnllink) : 0;
+ return obj ? obj->link.master : 0;
}
static char *
@@ -4377,30 +4290,36 @@ slave_get_option (NMPlatform *platform, int slave, const char *option)
static gboolean
infiniband_partition_add (NMPlatform *platform, int parent, int p_key, NMPlatformLink *out_link)
{
- const char *parent_name;
- char *path, *id;
- gboolean success;
+ NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
+ const NMPObject *obj_parent;
+ const NMPObject *obj;
+ NMPObject obj_needle;
+ gs_free char *path = NULL;
+ gs_free char *id = NULL;
+ gs_free char *ifname = NULL;
- parent_name = nm_platform_link_get_name (platform, parent);
- g_return_val_if_fail (parent_name != NULL, FALSE);
+ obj_parent = nmp_cache_lookup_link (priv->cache, parent);
+ if (!obj_parent || !obj_parent->link.name[0])
+ g_return_val_if_reached (FALSE);
- path = g_strdup_printf ("/sys/class/net/%s/create_child", ASSERT_VALID_PATH_COMPONENT (parent_name));
+ ifname = g_strdup_printf ("%s.%04x", obj_parent->link.name, p_key);
+
+ path = g_strdup_printf ("/sys/class/net/%s/create_child", ASSERT_VALID_PATH_COMPONENT (obj_parent->link.name));
id = g_strdup_printf ("0x%04x", p_key);
- success = nm_platform_sysctl_set (platform, path, id);
- g_free (id);
- g_free (path);
+ if (!nm_platform_sysctl_set (platform, path, id))
+ return FALSE;
+
+ nmp_object_stackinit_id_link (&obj_needle, 0);
+ g_strlcpy (obj_needle.link.name, ifname, sizeof (obj_needle.link.name));
- if (success) {
- gs_free char *ifname = g_strdup_printf ("%s.%04x", parent_name, p_key);
- auto_nl_object struct rtnl_link *rtnllink = NULL;
+ do_refresh_object (platform, &obj_needle, NM_PLATFORM_REASON_INTERNAL, TRUE, &obj);
- rtnllink = (struct rtnl_link *) build_rtnl_link (0, ifname, NM_LINK_TYPE_INFINIBAND);
- success = refresh_object (platform, (struct nl_object *) rtnllink, FALSE, NM_PLATFORM_REASON_INTERNAL);
- if (success)
- success = link_get_by_name (platform, ifname, out_link);
- }
+ if (!obj || obj->link.type != NM_LINK_TYPE_INFINIBAND)
+ return FALSE;
- return success;
+ if (out_link)
+ *out_link = obj->link;
+ return TRUE;
}
typedef struct {
@@ -4462,21 +4381,21 @@ static gboolean
infiniband_get_info (NMPlatform *platform, int ifindex, int *parent, int *p_key, const char **mode)
{
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
- auto_nl_object struct rtnl_link *rtnllink = NULL;
+ const NMPObject *obj;
IpoibInfo info = { -1, NULL };
- rtnllink = link_get (platform, ifindex);
- if (!rtnllink)
+ obj = cache_lookup_link (platform, ifindex);
+ if (!obj)
return FALSE;
if (parent)
- *parent = rtnl_link_get_link (rtnllink);
+ *parent = obj->link.parent;
if (nm_rtnl_link_parse_info_data (priv->nlh,
ifindex,
infiniband_info_data_parser,
&info) != 0) {
- const char *iface = rtnl_link_get_name (rtnllink);
+ const char *iface = obj->link.name;
char *path, *contents = NULL;
/* Fall back to reading sysfs */
@@ -4647,20 +4566,20 @@ static gboolean
macvlan_get_properties (NMPlatform *platform, int ifindex, NMPlatformMacvlanProperties *props)
{
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
- auto_nl_object struct rtnl_link *rtnllink = NULL;
int err;
+ const NMPObject *obj;
- rtnllink = link_get (platform, ifindex);
- if (!rtnllink)
+ obj = cache_lookup_link (platform, ifindex);
+ if (!obj)
return FALSE;
- props->parent_ifindex = rtnl_link_get_link (rtnllink);
+ props->parent_ifindex = obj->link.parent;
err = nm_rtnl_link_parse_info_data (priv->nlh, ifindex,
macvlan_info_data_parser, props);
if (err != 0) {
warning ("(%s) could not read properties: %s",
- rtnl_link_get_name (rtnllink), nl_geterror (err));
+ obj->link.name, nl_geterror (err));
}
return (err == 0);
}
@@ -5075,41 +4994,13 @@ ipx_address_get_all (NMPlatform *platform, int ifindex, gboolean is_v4)
static GArray *
ip4_address_get_all (NMPlatform *platform, int ifindex)
{
- NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
- GArray *addresses;
- NMPlatformIP4Address address;
- struct nl_object *object;
-
- addresses = g_array_new (FALSE, FALSE, sizeof (NMPlatformIP4Address));
-
- for (object = nl_cache_get_first (priv->address_cache); object; object = nl_cache_get_next (object)) {
- if (_address_match ((struct rtnl_addr *) object, AF_INET, ifindex)) {
- if (init_ip4_address (&address, (struct rtnl_addr *) object))
- g_array_append_val (addresses, address);
- }
- }
-
- return addresses;
+ return ipx_address_get_all (platform, ifindex, TRUE);
}
static GArray *
ip6_address_get_all (NMPlatform *platform, int ifindex)
{
- NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
- GArray *addresses;
- NMPlatformIP6Address address;
- struct nl_object *object;
-
- addresses = g_array_new (FALSE, FALSE, sizeof (NMPlatformIP6Address));
-
- for (object = nl_cache_get_first (priv->address_cache); object; object = nl_cache_get_next (object)) {
- if (_address_match ((struct rtnl_addr *) object, AF_INET6, ifindex)) {
- if (init_ip6_address (&address, (struct rtnl_addr *) object))
- g_array_append_val (addresses, address);
- }
- }
-
- return addresses;
+ return ipx_address_get_all (platform, ifindex, FALSE);
}
#define IPV4LL_NETWORK (htonl (0xA9FE0000L))
@@ -5249,10 +5140,16 @@ ip4_address_add (NMPlatform *platform,
guint32 preferred,
const char *label)
{
- return add_object (platform, build_rtnl_addr (platform, AF_INET, ifindex, &addr,
- peer_addr ? &peer_addr : NULL,
- plen, lifetime, preferred, 0,
- label));
+ NMPObject obj_needle;
+ auto_nl_object struct nl_object *nlo = NULL;
+
+ nlo = build_rtnl_addr (platform, AF_INET, ifindex, &addr,
+ peer_addr ? &peer_addr : NULL,
+ plen, lifetime, preferred, 0,
+ label);
+ return do_add_addrroute (platform,
+ nmp_object_stackinit_id_ip4_address (&obj_needle, ifindex, addr, plen),
+ nlo);
}
static gboolean
@@ -5265,22 +5162,35 @@ ip6_address_add (NMPlatform *platform,
guint32 preferred,
guint flags)
{
- return add_object (platform, build_rtnl_addr (platform, AF_INET6, ifindex, &addr,
- IN6_IS_ADDR_UNSPECIFIED (&peer_addr) ? NULL : &peer_addr,
- plen, lifetime, preferred, flags,
- NULL));
+ NMPObject obj_needle;
+ auto_nl_object struct nl_object *nlo = NULL;
+
+ nlo = build_rtnl_addr (platform, AF_INET6, ifindex, &addr,
+ IN6_IS_ADDR_UNSPECIFIED (&peer_addr) ? NULL : &peer_addr,
+ plen, lifetime, preferred, flags,
+ NULL);
+ return do_add_addrroute (platform,
+ nmp_object_stackinit_id_ip6_address (&obj_needle, ifindex, &addr, plen),
+ nlo);
}
static gboolean
ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, int plen, in_addr_t peer_address)
{
- return delete_object (platform, build_rtnl_addr (platform, AF_INET, ifindex, &addr, peer_address ? &peer_address : NULL, plen, 0, 0, 0, NULL), TRUE);
+ NMPObject obj_needle;
+
+ nmp_object_stackinit_id_ip4_address (&obj_needle, ifindex, addr, plen);
+ obj_needle.ip4_address.peer_address = peer_address;
+ return do_delete_object (platform, &obj_needle, NULL);
}
static gboolean
ip6_address_delete (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen)
{
- return delete_object (platform, build_rtnl_addr (platform, AF_INET6, ifindex, &addr, NULL, plen, 0, 0, 0, NULL), TRUE);
+ NMPObject obj_needle;
+
+ nmp_object_stackinit_id_ip6_address (&obj_needle, ifindex, &addr, plen);
+ return do_delete_object (platform, &obj_needle, NULL);
}
static gboolean
@@ -5295,53 +5205,47 @@ ip_address_exists (NMPlatform *platform, int family, int ifindex, gconstpointer
static gboolean
ip4_address_exists (NMPlatform *platform, int ifindex, in_addr_t addr, int plen)
{
- return ip_address_exists (platform, AF_INET, ifindex, &addr, plen);
+ NMPObject obj_needle;
+
+ nmp_object_stackinit_id_ip4_address (&obj_needle, ifindex, addr, plen);
+ return nmp_object_is_visible (nmp_cache_lookup_obj (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, &obj_needle));
}
static gboolean
ip6_address_exists (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen)
{
- return ip_address_exists (platform, AF_INET6, ifindex, &addr, plen);
+ NMPObject obj_needle;
+
+ nmp_object_stackinit_id_ip6_address (&obj_needle, ifindex, &addr, plen);
+ return nmp_object_is_visible (nmp_cache_lookup_obj (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, &obj_needle));
}
static gboolean
ip4_check_reinstall_device_route (NMPlatform *platform, int ifindex, const NMPlatformIP4Address *address, guint32 device_route_metric)
{
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
- NMPlatformIP4Address addr_candidate;
- NMPlatformIP4Route route_candidate;
- struct nl_object *object;
guint32 device_network;
+ NMPObject obj_needle;
- for (object = nl_cache_get_first (priv->address_cache); object; object = nl_cache_get_next (object)) {
- if (_address_match ((struct rtnl_addr *) object, AF_INET, 0)) {
- if (init_ip4_address (&addr_candidate, (struct rtnl_addr *) object))
- if ( addr_candidate.plen == address->plen
- && addr_candidate.address == address->address) {
- /* If we already have the same address installed on any interface,
- * we back off.
- * Perform this check first, as we expect to have significantly less
- * addresses to search. */
- return FALSE;
- }
- }
+ if (nmp_cache_lookup_obj (priv->cache,
+ nmp_object_stackinit_id_ip4_address (&obj_needle, ifindex, address->address, address->plen))) {
+ /* If we already have the same address installed on any interface,
+ * we back off. */
+ return FALSE;
}
device_network = nm_utils_ip4_address_clear_host_address (address->address, address->plen);
- for (object = nl_cache_get_first (priv->route_cache); object; object = nl_cache_get_next (object)) {
- if (_route_match ((struct rtnl_route *) object, AF_INET, 0, TRUE)) {
- if (init_ip4_route (&route_candidate, (struct rtnl_route *) object)) {
- if ( route_candidate.network == device_network
- && route_candidate.plen == address->plen
- && ( route_candidate.metric == 0
- || route_candidate.metric == device_route_metric)) {
- /* There is already any route with metric 0 or the metric we want to install
- * for the same subnet. */
- return FALSE;
- }
- }
- }
+check_for_route:
+ nmp_object_stackinit_id_ip4_route (&obj_needle, ifindex, device_network, address->plen, device_route_metric);
+ if (nmp_cache_lookup_obj (priv->cache, &obj_needle)) {
+ /* There is already a route with metric 0 or the metric we want to install
+ * for the same subnet. */
+ return FALSE;
+ }
+ if (device_route_metric != 0) {
+ device_route_metric = 0;
+ goto check_for_route;
}
return TRUE;
@@ -5395,59 +5299,13 @@ ipx_route_get_all (NMPlatform *platform, int ifindex, gboolean is_v4, NMPlatform
static GArray *
ip4_route_get_all (NMPlatform *platform, int ifindex, NMPlatformGetRouteMode mode)
{
- NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
- GArray *routes;
- NMPlatformIP4Route route;
- struct nl_object *object;
-
- g_return_val_if_fail (NM_IN_SET (mode, NM_PLATFORM_GET_ROUTE_MODE_ALL, NM_PLATFORM_GET_ROUTE_MODE_NO_DEFAULT, NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT), NULL);
-
- routes = g_array_new (FALSE, FALSE, sizeof (NMPlatformIP4Route));
-
- for (object = nl_cache_get_first (priv->route_cache); object; object = nl_cache_get_next (object)) {
- if (_route_match ((struct rtnl_route *) object, AF_INET, ifindex, FALSE)) {
- if (_rtnl_route_is_default ((struct rtnl_route *) object)) {
- if (mode == NM_PLATFORM_GET_ROUTE_MODE_NO_DEFAULT)
- continue;
- } else {
- if (mode == NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT)
- continue;
- }
- if (init_ip4_route (&route, (struct rtnl_route *) object))
- g_array_append_val (routes, route);
- }
- }
-
- return routes;
+ return ipx_route_get_all (platform, ifindex, TRUE, mode);
}
static GArray *
ip6_route_get_all (NMPlatform *platform, int ifindex, NMPlatformGetRouteMode mode)
{
- NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
- GArray *routes;
- NMPlatformIP6Route route;
- struct nl_object *object;
-
- g_return_val_if_fail (NM_IN_SET (mode, NM_PLATFORM_GET_ROUTE_MODE_ALL, NM_PLATFORM_GET_ROUTE_MODE_NO_DEFAULT, NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT), NULL);
-
- routes = g_array_new (FALSE, FALSE, sizeof (NMPlatformIP6Route));
-
- for (object = nl_cache_get_first (priv->route_cache); object; object = nl_cache_get_next (object)) {
- if (_route_match ((struct rtnl_route *) object, AF_INET6, ifindex, FALSE)) {
- if (_rtnl_route_is_default ((struct rtnl_route *) object)) {
- if (mode == NM_PLATFORM_GET_ROUTE_MODE_NO_DEFAULT)
- continue;
- } else {
- if (mode == NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT)
- continue;
- }
- if (init_ip6_route (&route, (struct rtnl_route *) object))
- g_array_append_val (routes, route);
- }
- }
-
- return routes;
+ return ipx_route_get_all (platform, ifindex, FALSE, mode);
}
static void
@@ -5550,7 +5408,13 @@ ip4_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source,
in_addr_t network, int plen, in_addr_t gateway,
guint32 pref_src, guint32 metric, guint32 mss)
{
- return add_object (platform, build_rtnl_route (AF_INET, ifindex, source, &network, plen, &gateway, pref_src ? &pref_src : NULL, metric, mss));
+ NMPObject obj_needle;
+ auto_nl_object struct nl_object *nlo = NULL;
+
+ nlo = build_rtnl_route (AF_INET, ifindex, source, &network, plen, &gateway, pref_src ? &pref_src : NULL, metric, mss);
+ return do_add_addrroute (platform,
+ nmp_object_stackinit_id_ip4_route (&obj_needle, ifindex, network, plen, metric),
+ nlo);
}
static gboolean
@@ -5558,9 +5422,15 @@ ip6_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source,
struct in6_addr network, int plen, struct in6_addr gateway,
guint32 metric, guint32 mss)
{
+ NMPObject obj_needle;
+ auto_nl_object struct nl_object *nlo = NULL;
+
metric = nm_utils_ip6_route_metric_normalize (metric);
- return add_object (platform, build_rtnl_route (AF_INET6, ifindex, source, &network, plen, &gateway, NULL, metric, mss));
+ nlo = build_rtnl_route (AF_INET6, ifindex, source, &network, plen, &gateway, NULL, metric, mss);
+ return do_add_addrroute (platform,
+ nmp_object_stackinit_id_ip6_route (&obj_needle, ifindex, &network, plen, metric),
+ nlo);
}
static struct rtnl_route *
@@ -5622,15 +5492,16 @@ refresh_route (NMPlatform *platform, int family, int ifindex, const void *networ
static gboolean
ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, int plen, guint32 metric)
{
+ NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
in_addr_t gateway = 0;
- struct rtnl_route *cached_object;
- struct nl_object *route = build_rtnl_route (AF_INET, ifindex, NM_IP_CONFIG_SOURCE_UNKNOWN, &network, plen, &gateway, NULL, metric, 0);
+ auto_nl_object struct nl_object *nlo = build_rtnl_route (AF_INET, ifindex, NM_IP_CONFIG_SOURCE_UNKNOWN, &network, plen, &gateway, NULL, metric, 0);
uint8_t scope = RT_SCOPE_NOWHERE;
- struct nl_cache *cache;
+ const NMPObject *obj;
+ NMPObject obj_needle;
- g_return_val_if_fail (route, FALSE);
+ g_return_val_if_fail (nlo, FALSE);
- cache = choose_cache_by_type (platform, OBJECT_TYPE_IP4_ROUTE);
+ nmp_object_stackinit_id_ip4_route (&obj_needle, ifindex, network, plen, metric);
if (metric == 0) {
/* Deleting an IPv4 route with metric 0 does not only delete an exectly matching route.
@@ -5639,17 +5510,12 @@ ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, int plen
*
* Instead, re-fetch the route from kernel, and if that fails, there is nothing to do.
* On success, there is still a race that we might end up deleting the wrong route. */
- if (!refresh_object (platform, (struct nl_object *) route, FALSE, _NM_PLATFORM_REASON_CACHE_CHECK_INTERNAL)) {
- rtnl_route_put ((struct rtnl_route *) route);
- return TRUE;
- }
- }
- /* when deleting an IPv4 route, several fields of the provided route must match.
- * Lookup in the cache so that we hopefully get the right values. */
- cached_object = (struct rtnl_route *) nl_cache_search (cache, route);
- if (!cached_object)
- cached_object = route_search_cache (cache, AF_INET, ifindex, &network, plen, metric);
+ do_refresh_object (platform, &obj_needle, NM_PLATFORM_REASON_INTERNAL, TRUE, &obj);
+ if (!obj)
+ return TRUE;
+ } else
+ obj = nmp_cache_lookup_obj (priv->cache, &obj_needle);
if (!_nl_has_capability (1 /* NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE */)) {
/* When searching for a matching IPv4 route to delete, the kernel
@@ -5666,8 +5532,8 @@ ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, int plen
* So, this workaround is only needed unless we have NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE.
**/
- if (cached_object)
- scope = rtnl_route_get_scope (cached_object);
+ if (obj)
+ scope = nm_platform_route_scope_inv (obj->ip4_route.scope_inv);
if (scope == RT_SCOPE_NOWHERE) {
/* If we would set the scope to RT_SCOPE_NOWHERE, libnl would guess the scope.
@@ -5676,7 +5542,7 @@ ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, int plen
scope = RT_SCOPE_UNIVERSE;
}
}
- rtnl_route_set_scope ((struct rtnl_route *) route, scope);
+ rtnl_route_set_scope ((struct rtnl_route *) nlo, scope);
/* we only support routes with TOS zero. As such, delete_route() is also only able to delete
* routes with tos==0. build_rtnl_route() already initializes tos properly. */
@@ -5688,19 +5554,23 @@ ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, int plen
* pref_src: NULL
*/
- rtnl_route_put (cached_object);
- return delete_object (platform, route, FALSE) && refresh_route (platform, AF_INET, ifindex, &network, plen, metric);
+ return do_delete_object (platform, &obj_needle, nlo);
}
static gboolean
ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, guint32 metric)
{
struct in6_addr gateway = IN6ADDR_ANY_INIT;
+ auto_nl_object struct nl_object *nlo = NULL;
+ NMPObject obj_needle;
metric = nm_utils_ip6_route_metric_normalize (metric);
- return delete_object (platform, build_rtnl_route (AF_INET6, ifindex, NM_IP_CONFIG_SOURCE_UNKNOWN ,&network, plen, &gateway, NULL, metric, 0), FALSE) &&
- refresh_route (platform, AF_INET6, ifindex, &network, plen, metric);
+ nlo = build_rtnl_route (AF_INET6, ifindex, NM_IP_CONFIG_SOURCE_UNKNOWN ,&network, plen, &gateway, NULL, metric, 0);
+
+ nmp_object_stackinit_id_ip6_route (&obj_needle, ifindex, &network, plen, metric);
+
+ return do_delete_object (platform, &obj_needle, nlo);
}
static gboolean
@@ -5720,15 +5590,21 @@ ip_route_exists (NMPlatform *platform, int family, int ifindex, gpointer network
static gboolean
ip4_route_exists (NMPlatform *platform, int ifindex, in_addr_t network, int plen, guint32 metric)
{
- return ip_route_exists (platform, AF_INET, ifindex, &network, plen, metric);
+ NMPObject obj_needle;
+
+ nmp_object_stackinit_id_ip4_route (&obj_needle, ifindex, network, plen, metric);
+ return nmp_object_is_visible (nmp_cache_lookup_obj (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, &obj_needle));
}
static gboolean
ip6_route_exists (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, guint32 metric)
{
+ NMPObject obj_needle;
+
metric = nm_utils_ip6_route_metric_normalize (metric);
- return ip_route_exists (platform, AF_INET6, ifindex, &network, plen, metric);
+ nmp_object_stackinit_id_ip6_route (&obj_needle, ifindex, &network, plen, metric);
+ return nmp_object_is_visible (nmp_cache_lookup_obj (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, &obj_needle));
}
/******************************************************************/
@@ -5918,7 +5794,8 @@ event_handler (GIOChannel *channel,
nle = -NLE_AGAIN;
} while (nle != -NLE_AGAIN);
nl_socket_modify_cb (priv->nlh_event, NL_CB_VALID, NL_CB_CUSTOM, event_notification, user_data);
- cache_repopulate_all (platform);
+ delayed_action_schedule (platform, DELAYED_ACTION_TYPE_REFRESH_ALL, NULL);
+ delayed_action_handle_all (platform);
break;
default:
error ("Failed to retrieve incoming events: %s (%d)", nl_geterror (nle), nle);
@@ -5978,8 +5855,6 @@ static void
udev_device_added (NMPlatform *platform,
GUdevDevice *udev_device)
{
- NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
- auto_nl_object struct rtnl_link *rtnllink = NULL;
const char *ifname;
int ifindex;
@@ -6005,49 +5880,37 @@ udev_device_added (NMPlatform *platform,
return;
}
- g_hash_table_insert (priv->udev_devices, GINT_TO_POINTER (ifindex),
- g_object_ref (udev_device));
-
- rtnllink = rtnl_link_get (priv->link_cache, ifindex);
- if (!rtnllink) {
- debug ("(%s): udev-add: interface not known via netlink; ignoring ifindex %d...", ifname, ifindex);
- return;
- }
+ cache_update_link_udev (platform, ifindex, udev_device);
+}
- announce_object (platform, (struct nl_object *) rtnllink, NM_PLATFORM_SIGNAL_CHANGED, NM_PLATFORM_REASON_EXTERNAL);
+static gboolean
+_udev_device_removed_match_link (const NMPObject *obj, gpointer udev_device)
+{
+ return obj->_link.udev.device == udev_device;
}
static void
udev_device_removed (NMPlatform *platform,
GUdevDevice *udev_device)
{
- NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
int ifindex = 0;
if (g_udev_device_get_property (udev_device, "IFINDEX"))
ifindex = g_udev_device_get_property_as_int (udev_device, "IFINDEX");
else {
- GHashTableIter iter;
- gpointer key, value;
+ const NMPObject *obj;
- /* This should not happen, but just to be sure.
- * If we can't get IFINDEX, go through the devices and
- * compare the pointers.
- */
- g_hash_table_iter_init (&iter, priv->udev_devices);
- while (g_hash_table_iter_next (&iter, &key, &value)) {
- if ((GUdevDevice *)value == udev_device) {
- ifindex = GPOINTER_TO_INT (key);
- break;
- }
- }
+ obj = nmp_cache_lookup_link_full (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache,
+ 0, NULL, FALSE, NM_LINK_TYPE_NONE, _udev_device_removed_match_link, udev_device);
+ if (obj)
+ ifindex = obj->link.ifindex;
}
debug ("udev-remove: IFINDEX=%d", ifindex);
if (ifindex <= 0)
return;
- g_hash_table_remove (priv->udev_devices, GINT_TO_POINTER (ifindex));
+ cache_update_link_udev (platform, ifindex, NULL);
}
static void
@@ -6136,21 +5999,9 @@ constructed (GObject *_object)
(EVENT_CONDITIONS | ERROR_CONDITIONS | DISCONNECT_CONDITIONS),
event_handler, platform);
- cache_repopulate_all (platform);
-
-#if HAVE_LIBNL_INET6_ADDR_GEN_MODE
- if (G_UNLIKELY (_support_user_ipv6ll == 0)) {
- struct nl_object *object;
-
- /* Initial check for user IPv6LL support once the link cache is allocated
- * and filled. If there are no links in the cache yet then we'll check
- * when a new link shows up in announce_object().
- */
- object = nl_cache_get_first (priv->link_cache);
- if (object)
- _support_user_ipv6ll_detect ((struct rtnl_link *) object);
- }
-#endif
+ _LOGD ("populate platform cache");
+ delayed_action_schedule (platform, DELAYED_ACTION_TYPE_REFRESH_ALL, NULL);
+ delayed_action_handle_all (platform);
/* Set up udev monitoring */
priv->udev_client = g_udev_client_new (udev_subsys);
diff --git a/src/platform/tests/test-address.c b/src/platform/tests/test-address.c
index c3bc0dcb2b..37a7c3bc58 100644
--- a/src/platform/tests/test-address.c
+++ b/src/platform/tests/test-address.c
@@ -75,7 +75,7 @@ test_ip4_address (void)
/* Add address again (aka update) */
g_assert (nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, addr, 0, IP4_PLEN, lifetime, preferred, NULL));
no_error ();
- accept_signal (address_changed);
+ accept_signals (address_changed, 0, 1);
/* Test address listing */
addresses = nm_platform_ip4_address_get_all (NM_PLATFORM_GET, ifindex);
@@ -131,7 +131,7 @@ test_ip6_address (void)
/* Add address again (aka update) */
g_assert (nm_platform_ip6_address_add (NM_PLATFORM_GET, ifindex, addr, in6addr_any, IP6_PLEN, lifetime, preferred, flags));
no_error ();
- accept_signal (address_changed);
+ accept_signals (address_changed, 0, 1);
/* Test address listing */
addresses = nm_platform_ip6_address_get_all (NM_PLATFORM_GET, ifindex);
diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c
index 102fe795f7..f2b82ae8c1 100644
--- a/src/platform/tests/test-link.c
+++ b/src/platform/tests/test-link.c
@@ -120,10 +120,15 @@ software_add (NMLinkType link_type, const char *name)
{
int parent_ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, PARENT_NAME);
+ gboolean was_up = nm_platform_link_is_up (NM_PLATFORM_GET, parent_ifindex);
parent_changed = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, link_callback, parent_ifindex);
g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, parent_ifindex));
- accept_signal (parent_changed);
+ if (was_up) {
+ /* when NM is running in the background, it will mess with addrgenmode which might cause additional signals. */
+ accept_signals (parent_changed, 0, 1);
+ } else
+ accept_signal (parent_changed);
free_signal (parent_changed);
return nm_platform_vlan_add (NM_PLATFORM_GET, name, parent_ifindex, VLAN_ID, 0, NULL);
@@ -142,6 +147,9 @@ test_slave (int master, int type, SignalData *master_changed)
SignalData *link_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, SLAVE_NAME);
SignalData *link_changed, *link_removed;
char *value;
+ NMLinkType link_type = nm_platform_link_get_type (NM_PLATFORM_GET, master);
+
+ g_assert (NM_IN_SET (link_type, NM_LINK_TYPE_TEAM, NM_LINK_TYPE_BOND, NM_LINK_TYPE_BRIDGE));
g_assert (software_add (type, SLAVE_NAME));
ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, SLAVE_NAME);
@@ -154,19 +162,28 @@ test_slave (int master, int type, SignalData *master_changed)
*
* See https://bugzilla.redhat.com/show_bug.cgi?id=910348
*/
+ g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex));
g_assert (nm_platform_link_set_down (NM_PLATFORM_GET, ifindex));
g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex));
- accept_signal (link_changed);
+ ensure_no_signal (link_changed);
/* Enslave */
link_changed->ifindex = ifindex;
g_assert (nm_platform_link_enslave (NM_PLATFORM_GET, master, ifindex)); no_error ();
g_assert_cmpint (nm_platform_link_get_master (NM_PLATFORM_GET, ifindex), ==, master); no_error ();
+
accept_signal (link_changed);
- accept_signal (master_changed);
+ accept_signals (master_changed, 0, 1);
+
+ /* enslaveing brings put the slave */
+ if (NM_IN_SET (link_type, NM_LINK_TYPE_BOND, NM_LINK_TYPE_TEAM))
+ g_assert (nm_platform_link_is_up (NM_PLATFORM_GET, ifindex));
+ else
+ g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex));
/* Set master up */
g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, master));
+ g_assert (nm_platform_link_is_up (NM_PLATFORM_GET, master));
accept_signal (master_changed);
/* Master with a disconnected slave is disconnected
@@ -179,7 +196,7 @@ test_slave (int master, int type, SignalData *master_changed)
case NM_LINK_TYPE_TEAM:
g_assert (nm_platform_link_set_down (NM_PLATFORM_GET, ifindex));
accept_signal (link_changed);
- accept_signal (master_changed);
+ accept_signals (master_changed, 0, 2);
break;
default:
break;
@@ -206,15 +223,16 @@ test_slave (int master, int type, SignalData *master_changed)
g_assert (nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex));
g_assert (nm_platform_link_is_connected (NM_PLATFORM_GET, master));
accept_signal (link_changed);
- accept_signal (master_changed);
+ /* NM running, can cause additional change of addrgenmode */
+ accept_signals (master_changed, 1, 2);
/* Enslave again
*
* Gracefully succeed if already enslaved.
*/
g_assert (nm_platform_link_enslave (NM_PLATFORM_GET, master, ifindex)); no_error ();
- accept_signal (link_changed);
- accept_signal (master_changed);
+ ensure_no_signal (link_changed);
+ ensure_no_signal (master_changed);
/* Set slave option */
switch (type) {
@@ -236,7 +254,10 @@ test_slave (int master, int type, SignalData *master_changed)
g_assert (nm_platform_link_release (NM_PLATFORM_GET, master, ifindex));
g_assert_cmpint (nm_platform_link_get_master (NM_PLATFORM_GET, ifindex), ==, 0); no_error ();
accept_signal (link_changed);
- accept_signal (master_changed);
+ if (link_type != NM_LINK_TYPE_TEAM)
+ accept_signals (master_changed, 1, 2);
+ else
+ accept_signals (master_changed, 1, 1);
/* Release again */
g_assert (!nm_platform_link_release (NM_PLATFORM_GET, master, ifindex));
@@ -539,6 +560,7 @@ test_external (void)
run_command ("ip link del %s", DEVICE_NAME);
wait_signal (link_removed);
+ accept_signals (link_changed, 0, 1);
g_assert (!nm_platform_link_exists (NM_PLATFORM_GET, DEVICE_NAME));
free_signal (link_added);
diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c
index fd86719958..90406f8ed7 100644
--- a/src/platform/tests/test-route.c
+++ b/src/platform/tests/test-route.c
@@ -153,7 +153,7 @@ test_ip4_route (void)
/* Add route again */
g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, 0, metric, mss));
no_error ();
- accept_signal (route_changed);
+ accept_signals (route_changed, 0, 1);
/* Add default route */
assert_ip4_route_exists (FALSE, DEVICE_NAME, 0, 0, metric);
@@ -167,7 +167,7 @@ test_ip4_route (void)
/* Add default route again */
g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, 0, 0, gateway, 0, metric, mss));
no_error ();
- accept_signal (route_changed);
+ accept_signals (route_changed, 0, 1);
/* Test route listing */
routes = nm_platform_ip4_route_get_all (NM_PLATFORM_GET, ifindex, NM_PLATFORM_GET_ROUTE_MODE_ALL);
@@ -251,7 +251,7 @@ test_ip6_route (void)
/* Add route again */
g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, metric, mss));
no_error ();
- accept_signal (route_changed);
+ accept_signals (route_changed, 0, 1);
/* Add default route */
g_assert (!nm_platform_ip6_route_exists (NM_PLATFORM_GET, ifindex, in6addr_any, 0, metric));
@@ -265,7 +265,7 @@ test_ip6_route (void)
/* Add default route again */
g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, in6addr_any, 0, gateway, metric, mss));
no_error ();
- accept_signal (route_changed);
+ accept_signals (route_changed, 0, 1);
/* Test route listing */
routes = nm_platform_ip6_route_get_all (NM_PLATFORM_GET, ifindex, NM_PLATFORM_GET_ROUTE_MODE_ALL);
diff --git a/src/tests/test-route-manager.c b/src/tests/test-route-manager.c
index 5b1c5f9d5a..9b5f187232 100644
--- a/src/tests/test-route-manager.c
+++ b/src/tests/test-route-manager.c
@@ -250,7 +250,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
};
setup_dev0_ip4 (fixture->ifindex0, 1000, 21021);
- g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*error adding 8.0.0.0/8 via 6.6.6.2 dev *");
+ g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure adding ip4-route '*: 8.0.0.0/8 22': *");
setup_dev1_ip4 (fixture->ifindex1);
g_test_assert_expected_messages ();
@@ -262,7 +262,7 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
nmtst_platform_ip4_routes_equal ((NMPlatformIP4Route *) routes->data, state1, routes->len, TRUE);
g_array_free (routes, TRUE);
- g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*error adding 8.0.0.0/8 via 6.6.6.2 dev *");
+ g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure adding ip4-route '*: 8.0.0.0/8 22': *");
setup_dev1_ip4 (fixture->ifindex1);
g_test_assert_expected_messages ();
@@ -584,7 +584,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data)
};
setup_dev0_ip6 (fixture->ifindex0);
- g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*error adding 2001:db8:d34d::/64 via 2001:db8:8086::2 dev *");
+ g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure adding ip6-route '*: 2001:db8:d34d::/64 20': *");
setup_dev1_ip6 (fixture->ifindex1);
g_test_assert_expected_messages ();
@@ -598,7 +598,7 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data)
g_array_free (routes, TRUE);
- g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*error adding 2001:db8:d34d::/64 via 2001:db8:8086::2 dev *");
+ g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*failure adding ip6-route '*: 2001:db8:d34d::/64 20': *");
setup_dev1_ip6 (fixture->ifindex1);
g_test_assert_expected_messages ();
setup_dev0_ip6 (fixture->ifindex0);