diff options
author | Thomas Haller <thaller@redhat.com> | 2015-04-13 18:21:55 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2015-04-22 11:27:41 +0200 |
commit | 1033352a8ef519927f85f0a55bfa749d49ed2ec1 (patch) | |
tree | 4163c6e2540005a7004a144e445720a38a2985d0 | |
parent | 793eadf7486f381f8611d274a1b07cc078a1f89c (diff) | |
download | NetworkManager-1033352a8ef519927f85f0a55bfa749d49ed2ec1.tar.gz |
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
two places where we receive libnl objects from kernel,
i.e. get_kernel_object() and event_notification().
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.
-rw-r--r-- | src/platform/nm-linux-platform.c | 99 |
1 files changed, 55 insertions, 44 deletions
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 8163ffaad1..278c596d9b 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -328,6 +328,45 @@ _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 (gboolean freeze_result) +{ +#if HAVE_LIBNL_INET6_ADDR_GEN_MODE + if (_support_user_ipv6ll == 0) { + if (!freeze_result) + return FALSE; + nm_log_warn (LOGD_PLATFORM, "Unable to detect kernel support for IFLA_INET6_ADDR_GEN_MODE. Assume no kernel support."); + _support_user_ipv6ll = -1; + } + + return _support_user_ipv6ll > 0; +#else + return FALSE; +#endif +} + +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 (_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; + } +#endif +} + /****************************************************************** * ethtool ******************************************************************/ @@ -516,7 +555,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 +663,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 +868,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 (TRUE); } - /* Object type specific utilities */ static const char * @@ -1583,18 +1612,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 +2020,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 +2604,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 (FALSE)) { auto_nl_object struct rtnl_link *rtnllink = link_get (platform, ifindex); uint8_t mode = 0; @@ -2606,7 +2624,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 (TRUE)) { 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 +4548,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 +4586,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 (_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 */ |