diff options
Diffstat (limited to 'src/platform')
| -rw-r--r-- | src/platform/Makefile.in | 1 | ||||
| -rw-r--r-- | src/platform/nm-linux-platform.c | 80 | ||||
| -rw-r--r-- | src/platform/nm-platform.h | 2 | ||||
| -rw-r--r-- | src/platform/tests/Makefile.in | 1 | ||||
| -rw-r--r-- | src/platform/wifi/wifi-utils.c | 16 | ||||
| -rw-r--r-- | src/platform/wifi/wifi-utils.h | 4 |
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); |