summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-04-13 18:21:55 +0200
committerThomas Haller <thaller@redhat.com>2015-04-22 11:27:41 +0200
commit1033352a8ef519927f85f0a55bfa749d49ed2ec1 (patch)
tree4163c6e2540005a7004a144e445720a38a2985d0
parent793eadf7486f381f8611d274a1b07cc078a1f89c (diff)
downloadNetworkManager-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.c99
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 */