about summary refs log tree commit diff
path: root/src/platform
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2016-08-03 22:59:23 +0200
committerMichael Biebl <biebl@debian.org>2016-08-03 22:59:23 +0200
commitd6201f5d8daada3d64a0a3e0038e14eebec683ce (patch)
tree035500728cc23e7ee5368c3fd605270265a077f7 /src/platform
parent73e152af6e3fb4f5848bfb8394484026ff119003 (diff)
Imported Upstream version 1.2.4 upstream/1.2.4
Diffstat (limited to 'src/platform')
-rw-r--r--src/platform/Makefile.in1
-rw-r--r--src/platform/nm-linux-platform.c80
-rw-r--r--src/platform/nm-platform.h2
-rw-r--r--src/platform/tests/Makefile.in1
-rw-r--r--src/platform/wifi/wifi-utils.c16
-rw-r--r--src/platform/wifi/wifi-utils.h4
6 files changed, 82 insertions, 22 deletions
diff --git a/src/platform/Makefile.in b/src/platform/Makefile.in
index 854c6712..a528da66 100644
--- a/src/platform/Makefile.in
+++ b/src/platform/Makefile.in
@@ -324,6 +324,7 @@ NEWT_LIBS = @NEWT_LIBS@
 NM = @NM@
 NMEDIT = @NMEDIT@
 NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@
+NM_CONFIG_DEFAULT_DNS_RC_MANAGER = @NM_CONFIG_DEFAULT_DNS_RC_MANAGER@
 NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT = @NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT@
 NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT = @NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT@
 NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index c5045503..f6f7be80 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -1439,6 +1439,8 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
 	gboolean *completed_from_cache = cache ? &completed_from_cache_val : NULL;
 	const NMPObject *link_cached = NULL;
 	NMPObject *lnk_data = NULL;
+	gboolean address_complete_from_cache = TRUE;
+	gboolean lnk_data_complete_from_cache = TRUE;
 
 	if (!nlmsg_valid_hdr (nlh, sizeof (*ifi)))
 		return NULL;
@@ -1503,6 +1505,7 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
 			memcpy (obj->link.addr.data, nla_data (tb[IFLA_ADDRESS]), l);
 			obj->link.addr.len = l;
 		}
+		address_complete_from_cache = FALSE;
 	}
 
 	if (tb[IFLA_AF_SPEC]) {
@@ -1552,28 +1555,34 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
 		lnk_data = _parse_lnk_vxlan (nl_info_kind, nl_info_data);
 		break;
 	default:
-		goto lnk_data_handled;
+		lnk_data_complete_from_cache = FALSE;
+		break;
 	}
 
-	/* We always try to look into the cache and reuse the object there.
-	 * We do that, because we consider the lnk object as immutable and don't
-	 * modify it after creating. Hence we can share it and reuse.
-	 *
-	 * Also, sometimes the info-data is missing for updates. In this case
-	 * we want to keep the previously received lnk_data. */
-	if (completed_from_cache) {
+	if (   completed_from_cache
+	    && (   lnk_data_complete_from_cache
+	        || address_complete_from_cache)) {
 		_lookup_cached_link (cache, obj->link.ifindex, completed_from_cache, &link_cached);
-		if (   link_cached
-		    && link_cached->link.type == obj->link.type
-		    && link_cached->_link.netlink.lnk
-		    && (   !lnk_data
-		        || nmp_object_equal (lnk_data, link_cached->_link.netlink.lnk))) {
-			nmp_object_unref (lnk_data);
-			lnk_data = nmp_object_ref (link_cached->_link.netlink.lnk);
+		if (link_cached) {
+			if (   lnk_data_complete_from_cache
+			    && link_cached->link.type == obj->link.type
+			    && link_cached->_link.netlink.lnk
+			    && (   !lnk_data
+			        || nmp_object_equal (lnk_data, link_cached->_link.netlink.lnk))) {
+				/* We always try to look into the cache and reuse the object there.
+				 * We do that, because we consider the lnk object as immutable and don't
+				 * modify it after creating. Hence we can share it and reuse.
+				 *
+				 * Also, sometimes the info-data is missing for updates. In this case
+				 * we want to keep the previously received lnk_data. */
+				nmp_object_unref (lnk_data);
+				lnk_data = nmp_object_ref (link_cached->_link.netlink.lnk);
+			}
+			if (address_complete_from_cache)
+				obj->link.addr = link_cached->link.addr;
 		}
 	}
 
-lnk_data_handled:
 	obj->_link.netlink.lnk = lnk_data;
 
 	obj->_link.netlink.is_in_netlink = TRUE;
@@ -3283,9 +3292,14 @@ cache_pre_hook (NMPCache *cache, const NMPObject *old, const NMPObject *new, NMP
 			if (   ops_type == NMP_CACHE_OPS_UPDATED
 			    && old && new /* <-- nonsensical, make coverity happy */
 			    && old->_link.netlink.is_in_netlink
-			    && NM_FLAGS_HAS (old->link.n_ifi_flags, IFF_LOWER_UP)
 			    && new->_link.netlink.is_in_netlink
-			    && !NM_FLAGS_HAS (new->link.n_ifi_flags, IFF_LOWER_UP)) {
+			    && (   (   NM_FLAGS_HAS (old->link.n_ifi_flags, IFF_UP)
+			            && !NM_FLAGS_HAS (new->link.n_ifi_flags, IFF_UP))
+			        || (   NM_FLAGS_HAS (old->link.n_ifi_flags, IFF_LOWER_UP)
+			            && !NM_FLAGS_HAS (new->link.n_ifi_flags, IFF_LOWER_UP)))) {
+				/* FIXME: I suspect that IFF_LOWER_UP must not be considered, and I
+				 * think kernel does send RTM_DELROUTE events for IPv6 routes, so
+				 * we might not need to refresh IPv6 routes. */
 				delayed_action_schedule (platform,
 				                         DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES |
 				                         DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES,
@@ -5140,13 +5154,30 @@ static WifiData *
 wifi_get_wifi_data (NMPlatform *platform, int ifindex)
 {
 	NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
+	const NMPlatformLink *pllink;
 	WifiData *wifi_data;
 
 	wifi_data = g_hash_table_lookup (priv->wifi_data, GINT_TO_POINTER (ifindex));
-	if (!wifi_data) {
-		const NMPlatformLink *pllink;
+	pllink = nm_platform_link_get (platform, ifindex);
 
-		pllink = nm_platform_link_get (platform, ifindex);
+	/* @wifi_data contains an interface name which is used for WEXT queries. If
+	 * the interface name changes we should at least replace the name in the
+	 * existing structure; but probably a complete reinitialization is better
+	 * because during the initial creation there can be race conditions while
+	 * the interface is renamed by udev.
+	 */
+	if (wifi_data && pllink) {
+		if (!nm_streq (wifi_utils_get_iface (wifi_data), pllink->name)) {
+			_LOGD ("wifi: interface %s renamed to %s, dropping old data for ifindex %d",
+			       wifi_utils_get_iface (wifi_data),
+			       pllink->name,
+			       ifindex);
+			g_hash_table_remove (priv->wifi_data, GINT_TO_POINTER (ifindex));
+			wifi_data = NULL;
+		}
+	}
+
+	if (!wifi_data) {
 		if (pllink) {
 			if (pllink->type == NM_LINK_TYPE_WIFI)
 				wifi_data = wifi_utils_init (pllink->name, ifindex, TRUE);
@@ -5778,6 +5809,13 @@ continue_reading:
 	errno = 0;
 	n = nl_recv (sk, &nla, &buf, &creds);
 
+	if (n <= 0) {
+		/* workaround libnl3 <= 3.2.15 returning danling pointers in case nl_recv()
+		 * fails. Fixed by libnl3 69468517d0de1675d80f24661ff57a5dbac7275c. */
+		buf = NULL;
+		creds = NULL;
+	}
+
 	switch (n) {
 	case 0:
 		/* Work around a libnl bug fixed in 3.2.22 (375a6294) */
diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h
index 658b709a..19724f1c 100644
--- a/src/platform/nm-platform.h
+++ b/src/platform/nm-platform.h
@@ -138,7 +138,7 @@ struct _NMPlatformLink {
 	/* rtnl_link_get_arptype(), ifinfomsg.ifi_type. */
 	guint32 arptype;
 
-	/* rtnl_link_get_addr() */
+	/* rtnl_link_get_addr(), IFLA_ADDRESS */
 	struct {
 		guint8 data[20]; /* NM_UTILS_HWADDR_LEN_MAX */
 		guint8 len;
diff --git a/src/platform/tests/Makefile.in b/src/platform/tests/Makefile.in
index 60cd6d82..49f2fa09 100644
--- a/src/platform/tests/Makefile.in
+++ b/src/platform/tests/Makefile.in
@@ -621,6 +621,7 @@ NEWT_LIBS = @NEWT_LIBS@
 NM = @NM@
 NMEDIT = @NMEDIT@
 NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@
+NM_CONFIG_DEFAULT_DNS_RC_MANAGER = @NM_CONFIG_DEFAULT_DNS_RC_MANAGER@
 NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT = @NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT@
 NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT = @NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT@
 NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
diff --git a/src/platform/wifi/wifi-utils.c b/src/platform/wifi/wifi-utils.c
index 38e5a054..4f04041a 100644
--- a/src/platform/wifi/wifi-utils.c
+++ b/src/platform/wifi/wifi-utils.c
@@ -70,6 +70,22 @@ wifi_utils_init (const char *iface, int ifindex, gboolean check_scan)
 	return ret;
 }
 
+int
+wifi_utils_get_ifindex (WifiData *data)
+{
+	g_return_val_if_fail (data != NULL, -1);
+
+	return data->ifindex;
+}
+
+const char *
+wifi_utils_get_iface (WifiData *data)
+{
+	g_return_val_if_fail (data != NULL, NULL);
+
+	return data->iface;
+}
+
 NMDeviceWifiCapabilities
 wifi_utils_get_caps (WifiData *data)
 {
diff --git a/src/platform/wifi/wifi-utils.h b/src/platform/wifi/wifi-utils.h
index 21dac9e9..9555bbee 100644
--- a/src/platform/wifi/wifi-utils.h
+++ b/src/platform/wifi/wifi-utils.h
@@ -33,6 +33,10 @@ gboolean wifi_utils_is_wifi (const char *iface, const char *sysfs_path);
 
 WifiData *wifi_utils_init (const char *iface, int ifindex, gboolean check_scan);
 
+int wifi_utils_get_ifindex (WifiData *data);
+
+const char *wifi_utils_get_iface (WifiData *data);
+
 void wifi_utils_deinit (WifiData *data);
 
 NMDeviceWifiCapabilities wifi_utils_get_caps (WifiData *data);