From dc9b25f1612daf1b5492d737cb448c40a6b06028 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 18 Apr 2015 12:53:45 +0200 Subject: [PATCH 01/10] platform: initialize NMLinuxPlatform in constructed() method setup() can be used to initialize a NMPlatform instance that is registered as singleton via nm_platform_setup(). It should not be used to initialize the object. Prior to c6529a9d748ad3c8ee37431d020a7b9223992a23, this change was not possible because constructed() will call back into nm_platform_*() functions, without having the singleton instance setup. --- src/platform/nm-linux-platform.c | 10 +++++----- src/platform/nm-platform.c | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index f3d25e2532..32b551b936 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -4476,9 +4476,10 @@ nm_linux_platform_init (NMLinuxPlatform *platform) { } -static gboolean -setup (NMPlatform *platform) +static void +constructed (GObject *_object) { + NMPlatform *platform = NM_PLATFORM (_object); NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); const char *udev_subsys[] = { "net", NULL }; GUdevEnumerator *enumerator; @@ -4575,7 +4576,7 @@ setup (NMPlatform *platform) priv->wifi_data = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) wifi_utils_deinit); - return TRUE; + G_OBJECT_CLASS (nm_linux_platform_parent_class)->constructed (_object); } static void @@ -4610,10 +4611,9 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass) g_type_class_add_private (klass, sizeof (NMLinuxPlatformPrivate)); /* virtual methods */ + object_class->constructed = constructed; object_class->finalize = nm_linux_platform_finalize; - platform_class->setup = setup; - platform_class->sysctl_set = sysctl_set; platform_class->sysctl_get = sysctl_get; diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 1bc907b667..feb8204991 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -100,7 +100,6 @@ static NMPlatform *singleton_instance = NULL; void nm_platform_setup (GType type) { - gboolean status; NMPlatformClass *klass; g_assert (singleton_instance == NULL); @@ -109,10 +108,11 @@ nm_platform_setup (GType type) g_assert (NM_IS_PLATFORM (singleton_instance)); klass = NM_PLATFORM_GET_CLASS (singleton_instance); - g_assert (klass->setup); - status = klass->setup (singleton_instance); - g_assert (status); + if (klass->setup) { + if (!klass->setup (singleton_instance)) + g_assert_not_reached (); + } } /** From a50d77d952b3c183d53a304ae0ae386f6694eca2 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 18 Apr 2015 13:37:36 +0200 Subject: [PATCH 02/10] platform: pass singleton instance to nm_platform_setup() We have two hooks to modify setup of the platform singleton: nm_linux_platform_setup() and the virtual setup() function. On the other hand, nm_platform_setup() limits us by accepting only a GType, instead of a prepeared platform instance. Make the nm_platform_setup() method more flexible, so that we can later drop the setup() hook. --- src/platform/nm-fake-platform.c | 2 +- src/platform/nm-linux-platform.c | 2 +- src/platform/nm-platform.c | 14 +++++--------- src/platform/nm-platform.h | 2 +- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index 09e1d37cc7..75ffbd3efb 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -63,7 +63,7 @@ G_DEFINE_TYPE (NMFakePlatform, nm_fake_platform, NM_TYPE_PLATFORM) void nm_fake_platform_setup (void) { - nm_platform_setup (NM_TYPE_FAKE_PLATFORM); + nm_platform_setup (g_object_new (NM_TYPE_FAKE_PLATFORM, NULL)); } /******************************************************************/ diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 32b551b936..5112538296 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -488,7 +488,7 @@ static gboolean _route_match (struct rtnl_route *rtnlroute, int family, int ifin void nm_linux_platform_setup (void) { - nm_platform_setup (NM_TYPE_LINUX_PLATFORM); + nm_platform_setup (g_object_new (NM_TYPE_LINUX_PLATFORM, NULL)); } /******************************************************************/ diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index feb8204991..4dfc086b7b 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -82,11 +82,7 @@ static NMPlatform *singleton_instance = NULL; /** * nm_platform_setup: - * @type: The #GType for a subclass of #NMPlatform - * - * Do not use this function directly, it is intended to be called by - * NMPlatform subclasses. For the linux platform initialization use - * nm_linux_platform_setup() instead. + * @instance: the #NMPlatform instance * * Failing to set up #NMPlatform singleton results in a fatal error, * as well as trying to initialize it multiple times without freeing @@ -98,14 +94,14 @@ static NMPlatform *singleton_instance = NULL; * nm_*_platform_setup(). */ void -nm_platform_setup (GType type) +nm_platform_setup (NMPlatform *instance) { NMPlatformClass *klass; - g_assert (singleton_instance == NULL); + g_return_if_fail (NM_IS_PLATFORM (instance)); + g_return_if_fail (!singleton_instance); - singleton_instance = g_object_new (type, NULL); - g_assert (NM_IS_PLATFORM (singleton_instance)); + singleton_instance = instance; klass = NM_PLATFORM_GET_CLASS (singleton_instance); diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index aee1ee8160..08bceb3d88 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -490,7 +490,7 @@ typedef struct { GType nm_platform_get_type (void); -void nm_platform_setup (GType type); +void nm_platform_setup (NMPlatform *instance); NMPlatform *nm_platform_get (void); void nm_platform_free (void); From fe2608c9032932e1a731dfeb6fb3196bd15a1cbf Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 18 Apr 2015 13:44:22 +0200 Subject: [PATCH 03/10] platform: drop virtual setup() initalization function We already have nm_*_platform_setup() that gets specified via -DSETUP. This SETUP() hook gives us all the flexiblity we need to customize our singleton, so just do any required setup there. Also, it would be easier to add an alternative (hypotetical) nm_fake_platform_setup_custom() to customize the singleton then to parametrize the NMPlatform:setup() implementation. So this virtual function is less flexible and redundant. --- src/platform/nm-fake-platform.c | 22 ++++++++-------------- src/platform/nm-platform.c | 9 --------- src/platform/nm-platform.h | 2 -- 3 files changed, 8 insertions(+), 25 deletions(-) diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index 75ffbd3efb..c9785b0035 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -60,14 +60,6 @@ G_DEFINE_TYPE (NMFakePlatform, nm_fake_platform, NM_TYPE_PLATFORM) /******************************************************************/ -void -nm_fake_platform_setup (void) -{ - nm_platform_setup (g_object_new (NM_TYPE_FAKE_PLATFORM, NULL)); -} - -/******************************************************************/ - static gboolean sysctl_set (NMPlatform *platform, const char *path, const char *value) { @@ -1336,9 +1328,15 @@ nm_fake_platform_init (NMFakePlatform *fake_platform) priv->ip6_routes = g_array_new (TRUE, TRUE, sizeof (NMPlatformIP6Route)); } -static gboolean -setup (NMPlatform *platform) +void +nm_fake_platform_setup (void) { + NMPlatform *platform; + + platform = g_object_new (NM_TYPE_FAKE_PLATFORM, NULL); + + nm_platform_setup (platform); + /* skip zero element */ link_add (platform, NULL, NM_LINK_TYPE_NONE, NULL, 0); @@ -1349,8 +1347,6 @@ setup (NMPlatform *platform) link_add (platform, "eth0", NM_LINK_TYPE_ETHERNET, NULL, 0); link_add (platform, "eth1", NM_LINK_TYPE_ETHERNET, NULL, 0); link_add (platform, "eth2", NM_LINK_TYPE_ETHERNET, NULL, 0); - - return TRUE; } static void @@ -1386,8 +1382,6 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass) /* virtual methods */ object_class->finalize = nm_fake_platform_finalize; - platform_class->setup = setup; - platform_class->sysctl_set = sysctl_set; platform_class->sysctl_get = sysctl_get; diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 4dfc086b7b..bb2a8c970e 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -96,19 +96,10 @@ static NMPlatform *singleton_instance = NULL; void nm_platform_setup (NMPlatform *instance) { - NMPlatformClass *klass; - g_return_if_fail (NM_IS_PLATFORM (instance)); g_return_if_fail (!singleton_instance); singleton_instance = instance; - - klass = NM_PLATFORM_GET_CLASS (singleton_instance); - - if (klass->setup) { - if (!klass->setup (singleton_instance)) - g_assert_not_reached (); - } } /** diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 08bceb3d88..d0273910e9 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -357,8 +357,6 @@ struct _NMPlatform { typedef struct { GObjectClass parent; - gboolean (*setup) (NMPlatform *); - gboolean (*sysctl_set) (NMPlatform *, const char *path, const char *value); char * (*sysctl_get) (NMPlatform *, const char *path); From 04ed48e5a06bed9d2eba20ca92488c7d8836ed97 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 18 Apr 2015 14:00:45 +0200 Subject: [PATCH 04/10] platform: drop nm_platform_free() and register weak-ref Instead of having a nm_platform_free() function, use NM_DEFINE_SINGLETON_WEAK_REF() and register a weak reference. That way, users who want to free the platform instance can just unref it. --- src/platform/nm-platform.c | 24 +++++++----------------- src/platform/nm-platform.h | 1 - src/platform/tests/test-common.c | 2 +- 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index bb2a8c970e..55a08ebc43 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -58,7 +58,9 @@ static guint signals[LAST_SIGNAL] = { 0 }; /******************************************************************/ /* Singleton NMPlatform subclass instance and cached class object */ -static NMPlatform *singleton_instance = NULL; +NM_DEFINE_SINGLETON_INSTANCE (NMPlatform); + +NM_DEFINE_SINGLETON_WEAK_REF (NMPlatform); /* Just always initialize a @klass instance. NM_PLATFORM_GET_CLASS() * is only a plain read on the self instance, which the compiler @@ -90,8 +92,7 @@ static NMPlatform *singleton_instance = NULL; * * NetworkManager will typically use only one platform object during * its run. Test programs might want to switch platform implementations, - * though. This is done with a combination of nm_platform_free() and - * nm_*_platform_setup(). + * though. */ void nm_platform_setup (NMPlatform *instance) @@ -100,20 +101,10 @@ nm_platform_setup (NMPlatform *instance) g_return_if_fail (!singleton_instance); singleton_instance = instance; -} -/** - * nm_platform_free: - * - * Free #NMPlatform singleton created by nm_*_platform_setup(). - */ -void -nm_platform_free (void) -{ - g_assert (singleton_instance); + nm_singleton_instance_weak_ref_register (); - g_object_unref (singleton_instance); - singleton_instance = NULL; + nm_log_dbg (LOGD_CORE, "setup NMPlatform singleton (%p, %s)", instance, G_OBJECT_TYPE_NAME (instance)); } /** @@ -121,8 +112,7 @@ nm_platform_free (void) * @self: platform instance * * Retrieve #NMPlatform singleton. Use this whenever you want to connect to - * #NMPlatform signals. It is an error to call it before nm_*_platform_setup() - * or after nm_platform_free(). + * #NMPlatform signals. It is an error to call it before nm_platform_setup(). * * Returns: (transfer none): The #NMPlatform singleton reference. */ diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index d0273910e9..66b132e2dc 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -490,7 +490,6 @@ GType nm_platform_get_type (void); void nm_platform_setup (NMPlatform *instance); NMPlatform *nm_platform_get (void); -void nm_platform_free (void); #define NM_PLATFORM_GET (nm_platform_get ()) diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c index cedbc518e6..d1627058e9 100644 --- a/src/platform/tests/test-common.c +++ b/src/platform/tests/test-common.c @@ -287,6 +287,6 @@ main (int argc, char **argv) nm_platform_link_delete (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME)); - nm_platform_free (); + g_object_unref (nm_platform_get ()); return result; } From 90caa93582384e204ba473d6e2502a5fce94efea Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 18 Apr 2015 14:02:24 +0200 Subject: [PATCH 05/10] platform: add nm_platform_try_get() function --- src/platform/nm-platform.c | 6 ++++++ src/platform/nm-platform.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 55a08ebc43..1a7b9bc182 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -124,6 +124,12 @@ nm_platform_get () return singleton_instance; } +NMPlatform * +nm_platform_try_get (void) +{ + return singleton_instance; +} + /******************************************************************/ /** diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 66b132e2dc..c3423ef5dd 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -490,6 +490,7 @@ GType nm_platform_get_type (void); void nm_platform_setup (NMPlatform *instance); NMPlatform *nm_platform_get (void); +NMPlatform *nm_platform_try_get (void); #define NM_PLATFORM_GET (nm_platform_get ()) From 7db9306aa3a6e4a9ed028bae326246a83be0fd0b Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 18 Apr 2015 14:21:54 +0200 Subject: [PATCH 06/10] platform: add _LOG() logging macros to linux platform --- src/platform/nm-linux-platform.c | 42 ++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 5112538296..089e15a0f0 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -67,10 +67,52 @@ /* This is only included for the translation of VLAN flags */ #include "nm-setting-vlan.h" +/*********************************************************************************************/ + +#define _LOG_DOMAIN LOGD_PLATFORM +#define _LOG_PREFIX_NAME "platform-linux" + +#define _LOG(level, domain, self, ...) \ + G_STMT_START { \ + const NMLogLevel __level = (level); \ + const NMLogDomain __domain = (domain); \ + \ + if (nm_logging_enabled (__level, __domain)) { \ + char __prefix[32]; \ + const char *__p_prefix = _LOG_PREFIX_NAME; \ + const void *const __self = (self); \ + \ + if (__self && __self != nm_platform_try_get ()) { \ + g_snprintf (__prefix, sizeof (__prefix), "%s[%p]", _LOG_PREFIX_NAME, __self); \ + __p_prefix = __prefix; \ + } \ + _nm_log (__level, __domain, 0, \ + "%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ + __p_prefix _NM_UTILS_MACRO_REST (__VA_ARGS__)); \ + } \ + } G_STMT_END +#define _LOG_LEVEL_ENABLED(level, domain) \ + ( nm_logging_enabled ((level), (domain)) ) + +#ifdef NM_MORE_LOGGING +#define _LOGT_ENABLED() _LOG_LEVEL_ENABLED (LOGL_TRACE, _LOG_DOMAIN) +#define _LOGT(...) _LOG (LOGL_TRACE, _LOG_DOMAIN, platform, __VA_ARGS__) +#else +#define _LOGT_ENABLED() FALSE +#define _LOGT(...) G_STMT_START { (void) 0; } G_STMT_END +#endif + +#define _LOGD(...) _LOG (LOGL_DEBUG, _LOG_DOMAIN, platform, __VA_ARGS__) +#define _LOGI(...) _LOG (LOGL_INFO , _LOG_DOMAIN, platform, __VA_ARGS__) +#define _LOGW(...) _LOG (LOGL_WARN , _LOG_DOMAIN, platform, __VA_ARGS__) +#define _LOGE(...) _LOG (LOGL_ERR , _LOG_DOMAIN, platform, __VA_ARGS__) + #define debug(...) nm_log_dbg (LOGD_PLATFORM, __VA_ARGS__) #define warning(...) nm_log_warn (LOGD_PLATFORM, __VA_ARGS__) #define error(...) nm_log_err (LOGD_PLATFORM, __VA_ARGS__) +/******************************************************************/ + #define return_type(t, name) \ G_STMT_START { \ if (out_name) \ From 0c03db4e8e9f717edb3d1d2be45ba71ca277024b Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 21 Apr 2015 18:27:13 +0200 Subject: [PATCH 07/10] platform: use new _LOG() logging macros in nm-linux-platform.c --- src/platform/nm-linux-platform.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 089e15a0f0..19db6bd71d 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -107,9 +107,9 @@ #define _LOGW(...) _LOG (LOGL_WARN , _LOG_DOMAIN, platform, __VA_ARGS__) #define _LOGE(...) _LOG (LOGL_ERR , _LOG_DOMAIN, platform, __VA_ARGS__) -#define debug(...) nm_log_dbg (LOGD_PLATFORM, __VA_ARGS__) -#define warning(...) nm_log_warn (LOGD_PLATFORM, __VA_ARGS__) -#define error(...) nm_log_err (LOGD_PLATFORM, __VA_ARGS__) +#define debug(...) _LOG (LOGL_DEBUG, _LOG_DOMAIN, NULL, __VA_ARGS__) +#define warning(...) _LOG (LOGL_WARN , _LOG_DOMAIN, NULL, __VA_ARGS__) +#define error(...) _LOG (LOGL_ERR , _LOG_DOMAIN, NULL, __VA_ARGS__) /******************************************************************/ From a319aea9f42db7fd88981704473726588382810f Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 14 Apr 2015 17:54:36 +0200 Subject: [PATCH 08/10] platform: don't assert against success of nl_msg_parse() --- src/platform/nm-linux-platform.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 19db6bd71d..27e9b39b08 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -1998,7 +1998,8 @@ event_notification (struct nl_msg *msg, gpointer user_data) } nl_msg_parse (msg, ref_object, &object); - g_return_val_if_fail (object, NL_OK); + if (!object) + return NL_OK; type = _nlo_get_object_type (object); From f15a27f9c1635808268f9aa1d7a3b9da95438259 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 13 Apr 2015 18:21:55 +0200 Subject: [PATCH 09/10] platform: refactor detection of support_user_ipv6ll Move detection of @support_user_ipv6ll to a separate function _support_user_ipv6ll_detect() and call it immediately after the places where we receive libnl objects from kernel, i.e. get_kernel_object(), event_notification(), and cache_repopulate_all(). Also, whether we have support depends on the kernel and is per-system, not per-platform-instance. Make @_support_user_ipv6ll a global variable. This way, we don't need to pass around a NMLinuxPlatform instance. --- src/platform/nm-linux-platform.c | 101 +++++++++++++++++-------------- 1 file changed, 57 insertions(+), 44 deletions(-) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 27e9b39b08..da804804d8 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -328,6 +328,47 @@ _rtnl_addr_hack_lifetimes_rel_to_abs (struct rtnl_addr *rtnladdr) rtnl_addr_set_preferred_lifetime (rtnladdr, _get_expiry (now, a_preferred)); } +/******************************************************************/ + +#if HAVE_LIBNL_INET6_ADDR_GEN_MODE +static int _support_user_ipv6ll = 0; +#endif + +static gboolean +_support_user_ipv6ll_get () +{ +#if HAVE_LIBNL_INET6_ADDR_GEN_MODE + if (G_UNLIKELY (_support_user_ipv6ll == 0)) { + _support_user_ipv6ll = -1; + nm_log_warn (LOGD_PLATFORM, "kernel support for IFLA_INET6_ADDR_GEN_MODE %s", "failed to detect; assume no support"); + } else + return _support_user_ipv6ll > 0; +#endif + + return FALSE; +} + +static void +_support_user_ipv6ll_detect (const struct rtnl_link *rtnl_link) +{ +#if HAVE_LIBNL_INET6_ADDR_GEN_MODE + /* If we ever see a link with valid IPv6 link-local address + * generation modes, the kernel supports it. + */ + if (G_UNLIKELY (_support_user_ipv6ll == 0)) { + uint8_t mode; + + if (rtnl_link_inet6_get_addr_gen_mode ((struct rtnl_link *) rtnl_link, &mode) == 0) { + _support_user_ipv6ll = 1; + nm_log_dbg (LOGD_PLATFORM, "kernel support for IFLA_INET6_ADDR_GEN_MODE %s", "detected"); + } else { + _support_user_ipv6ll = -1; + nm_log_dbg (LOGD_PLATFORM, "kernel support for IFLA_INET6_ADDR_GEN_MODE %s", "not detected"); + } + } +#endif +} + /****************************************************************** * ethtool ******************************************************************/ @@ -516,7 +557,6 @@ typedef struct { GHashTable *wifi_data; int support_kernel_extended_ifa_flags; - int support_user_ipv6ll; } NMLinuxPlatformPrivate; #define NM_LINUX_PLATFORM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_LINUX_PLATFORM, NMLinuxPlatformPrivate)) @@ -625,6 +665,7 @@ get_kernel_object (struct nl_sock *sock, struct nl_object *needle) nle = rtnl_link_get_kernel (sock, ifindex, name, (struct rtnl_link **) &object); switch (nle) { case -NLE_SUCCESS: + _support_user_ipv6ll_detect ((struct rtnl_link *) object); if (nm_logging_enabled (LOGL_DEBUG, LOGD_PLATFORM)) { name = rtnl_link_get_name ((struct rtnl_link *) object); debug ("get_kernel_object for link: %s (%d, family %d)", @@ -829,21 +870,11 @@ check_support_kernel_extended_ifa_flags (NMPlatform *platform) static gboolean check_support_user_ipv6ll (NMPlatform *platform) { - NMLinuxPlatformPrivate *priv; - g_return_val_if_fail (NM_IS_LINUX_PLATFORM (platform), FALSE); - priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); - - if (priv->support_user_ipv6ll == 0) { - nm_log_warn (LOGD_PLATFORM, "Unable to detect kernel support for IFLA_INET6_ADDR_GEN_MODE. Assume no kernel support."); - priv->support_user_ipv6ll = -1; - } - - return priv->support_user_ipv6ll > 0; + return _support_user_ipv6ll_get (); } - /* Object type specific utilities */ static const char * @@ -1583,18 +1614,6 @@ announce_object (NMPlatform *platform, const struct nl_object *object, NMPlatfor struct rtnl_link *rtnl_link = (struct rtnl_link *) object; NMPlatformLink device; -#if HAVE_LIBNL_INET6_ADDR_GEN_MODE - /* If we ever see a link with valid IPv6 link-local address - * generation modes, the kernel supports it. - */ - if (priv->support_user_ipv6ll == 0) { - uint8_t mode; - - if (rtnl_link_inet6_get_addr_gen_mode (rtnl_link, &mode) == 0) - priv->support_user_ipv6ll = 1; - } -#endif - if (!init_link (platform, &device, rtnl_link)) return; @@ -2003,6 +2022,9 @@ event_notification (struct nl_msg *msg, gpointer user_data) 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); @@ -2584,9 +2606,7 @@ static gboolean link_get_user_ipv6ll_enabled (NMPlatform *platform, int ifindex) { #if HAVE_LIBNL_INET6_ADDR_GEN_MODE - NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); - - if (priv->support_user_ipv6ll > 0) { + if (_support_user_ipv6ll_get ()) { auto_nl_object struct rtnl_link *rtnllink = link_get (platform, ifindex); uint8_t mode = 0; @@ -2606,7 +2626,7 @@ static gboolean link_set_user_ipv6ll_enabled (NMPlatform *platform, int ifindex, gboolean enabled) { #if HAVE_LIBNL_INET6_ADDR_GEN_MODE - if (check_support_user_ipv6ll (platform)) { + if (_support_user_ipv6ll_get ()) { auto_nl_object struct rtnl_link *change = _nm_rtnl_link_alloc (ifindex, NULL); guint8 mode = enabled ? IN6_ADDR_GEN_MODE_NONE : IN6_ADDR_GEN_MODE_EUI64; char buf[32]; @@ -4530,9 +4550,6 @@ constructed (GObject *_object) int channel_flags; gboolean status; int nle; -#if HAVE_LIBNL_INET6_ADDR_GEN_MODE - struct nl_object *object; -#endif /* Initialize netlink socket for requests */ priv->nlh = setup_socket (FALSE, platform); @@ -4571,21 +4588,17 @@ constructed (GObject *_object) cache_repopulate_all (platform); #if HAVE_LIBNL_INET6_ADDR_GEN_MODE - /* 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) { - uint8_t mode; + if (G_UNLIKELY (_support_user_ipv6ll == 0)) { + struct nl_object *object; - if (rtnl_link_inet6_get_addr_gen_mode ((struct rtnl_link *) object, &mode) == 0) - priv->support_user_ipv6ll = 1; - else - priv->support_user_ipv6ll = -1; + /* 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); } -#else - priv->support_user_ipv6ll = -1; #endif /* Set up udev monitoring */ From ea5865cf456b407e0e9627868e2af7154a574ad1 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 13 Apr 2015 18:55:59 +0200 Subject: [PATCH 10/10] platform: add NM_PLATFORM_SIGNAL_NONE enum value --- src/platform/nm-platform.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index c3423ef5dd..5cd5ae8e0c 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -97,6 +97,7 @@ struct _NMPlatformLink { }; typedef enum { + NM_PLATFORM_SIGNAL_NONE, NM_PLATFORM_SIGNAL_ADDED, NM_PLATFORM_SIGNAL_CHANGED, NM_PLATFORM_SIGNAL_REMOVED,