From 51dd0ac4b8b7b13e3d26c2ab7d35e9451bbcd4c5 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Fri, 21 Sep 2018 18:30:49 +0200 Subject: [PATCH 1/5] core: improve nm_ip_config_dump() Previously we had nm_ip{4,6}_config_dump() for debugging purposes, but they were inconveniently printing to stdout and so the output was not ordered in the journal. Implement a unified nm_ip_config_dump() that logs through the usual logging mechanism. (cherry picked from commit 3b49d1075daa084edd7541a0915a97b3afd643e9) (cherry picked from commit 0b1ffdbdb599ecd53f4b0cdead4f64296ac3ad49) (cherry picked from commit 33aae9b8c4953c0bb2910cf792eece792ba4ba53) --- src/nm-ip4-config.c | 119 +++++++++++++++++++++++++------------------- src/nm-ip4-config.h | 6 ++- src/nm-ip6-config.c | 47 ----------------- src/nm-ip6-config.h | 1 - 4 files changed, 74 insertions(+), 99 deletions(-) diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index 6ae81b573..ed6b712ea 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -1918,71 +1918,90 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev } void -nm_ip4_config_dump (const NMIP4Config *self, const char *detail) +nm_ip_config_dump (const NMIPConfig *self, + const char *detail, + NMLogLevel level, + NMLogDomain domain) { - guint32 tmp; - guint i; - const char *str; NMDedupMultiIter ipconf_iter; - const NMPlatformIP4Address *address; - const NMPlatformIP4Route *route; - - g_message ("--------- NMIP4Config %p (%s)", self, detail); + const NMPlatformIP4Address *addr4; + const NMPlatformIP6Address *addr6; + const NMPlatformIP4Route *route4; + const NMPlatformIP6Route *route6; + const NMIP4Config *ip4; + const NMIP6Config *ip6; + int addr_family = AF_UNSPEC; + char addr_family_char = '?'; + const char *path; + gconstpointer ptr; + guint i; - if (self == NULL) { - g_message (" (null)"); - return; + if (self) { + addr_family = nm_ip_config_get_addr_family (self); + addr_family_char = nm_utils_addr_family_to_char (addr_family); } - str = nm_dbus_object_get_path (NM_DBUS_OBJECT (self)); - if (str) - g_message (" path: %s", str); - - /* addresses */ - nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, self, &address) - g_message (" a: %s", nm_platform_ip4_address_to_string (address, NULL, 0)); + nm_log (level, domain, NULL, NULL, + "---- NMIP%cConfig %p (%s)", + addr_family_char, + self, + detail); - /* nameservers */ - for (i = 0; i < nm_ip4_config_get_num_nameservers (self); i++) { - tmp = nm_ip4_config_get_nameserver (self, i); - g_message (" ns: %s", nm_utils_inet4_ntop (tmp, NULL)); - } - - /* routes */ - nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, self, &route) - g_message (" rt: %s", nm_platform_ip4_route_to_string (route, NULL, 0)); + if (!self) + return; - /* domains */ - for (i = 0; i < nm_ip4_config_get_num_domains (self); i++) - g_message (" domain: %s", nm_ip4_config_get_domain (self, i)); + path = nm_dbus_object_get_path (NM_DBUS_OBJECT (self)); + if (path) + nm_log (level, domain, NULL, NULL, " path : %s", path); - /* dns searches */ - for (i = 0; i < nm_ip4_config_get_num_searches (self); i++) - g_message (" search: %s", nm_ip4_config_get_search (self, i)); + if (addr_family == AF_INET) { + ip4 = NM_IP4_CONFIG (self); + nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, ip4, &addr4) { + nm_log (level, domain, NULL, NULL, " address : %s", + nm_platform_ip4_address_to_string (addr4, NULL, 0)); + } + nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &route4) { + nm_log (level, domain, NULL, NULL, " route : %s", + nm_platform_ip4_route_to_string (route4, NULL, 0)); + } + } else { + ip6 = NM_IP6_CONFIG (self); + nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, ip6, &addr6) { + nm_log (level, domain, NULL, NULL, " address : %s", + nm_platform_ip6_address_to_string (addr6, NULL, 0)); + } + nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, ip6, &route6) { + nm_log (level, domain, NULL, NULL, " route : %s", + nm_platform_ip6_route_to_string (route6, NULL, 0)); + } + } - /* dns options */ - for (i = 0; i < nm_ip4_config_get_num_dns_options (self); i++) - g_message (" dnsopt: %s", nm_ip4_config_get_dns_option (self, i)); + for (i = 0; i < nm_ip_config_get_num_nameservers (self); i++) { + ptr = nm_ip_config_get_nameserver (self, i); + nm_log (level, domain, NULL, NULL, " dns : %s", + nm_utils_inet_ntop (addr_family, ptr, NULL)); + } - g_message (" dnspri: %d", nm_ip4_config_get_dns_priority (self)); + for (i = 0; i < nm_ip_config_get_num_domains (self); i++) + nm_log (level, domain, NULL, NULL, " domain : %s", nm_ip_config_get_domain (self, i)); - g_message (" mtu: %"G_GUINT32_FORMAT" (source: %d)", nm_ip4_config_get_mtu (self), (int) nm_ip4_config_get_mtu_source (self)); + for (i = 0; i < nm_ip_config_get_num_searches (self); i++) + nm_log (level, domain, NULL, NULL, " search : %s", nm_ip_config_get_search (self, i)); - /* NIS */ - for (i = 0; i < nm_ip4_config_get_num_nis_servers (self); i++) { - tmp = nm_ip4_config_get_nis_server (self, i); - g_message (" nis: %s", nm_utils_inet4_ntop (tmp, NULL)); - } + for (i = 0; i < nm_ip_config_get_num_dns_options (self); i++) + nm_log (level, domain, NULL, NULL, "dns-option: %s", nm_ip_config_get_dns_option (self, i)); - g_message (" nisdmn: %s", nm_ip4_config_get_nis_domain (self) ?: "(none)"); + nm_log (level, domain, NULL, NULL, " dns-prio : %d", nm_ip_config_get_dns_priority (self)); - /* WINS */ - for (i = 0; i < nm_ip4_config_get_num_wins (self); i++) { - tmp = nm_ip4_config_get_wins (self, i); - g_message (" wins: %s", nm_utils_inet4_ntop (tmp, NULL)); + if (addr_family == AF_INET) { + ip4 = NM_IP4_CONFIG (self); + nm_log (level, domain, NULL, NULL, + " mtu : %"G_GUINT32_FORMAT" (source: %d)", + nm_ip4_config_get_mtu (ip4), + (int) nm_ip4_config_get_mtu_source (ip4)); + nm_log (level, domain, NULL, NULL, " metered : %d", + (int) nm_ip4_config_get_metered (ip4)); } - - g_message (" mtrd: %d", (int) nm_ip4_config_get_metered (self)); } /*****************************************************************************/ diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h index 78aca14e4..728b64ac6 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -191,7 +191,6 @@ NMIP4Config *nm_ip4_config_intersect_alloc (const NMIP4Config *a, const NMIP4Config *b, guint32 default_route_metric_penalty); gboolean nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relevant_changes); -void nm_ip4_config_dump (const NMIP4Config *self, const char *detail); const NMPObject *nm_ip4_config_best_default_route_get (const NMIP4Config *self); const NMPObject *_nm_ip4_config_best_default_route_find (const NMIP4Config *self); @@ -290,6 +289,11 @@ gboolean nm_ip4_config_equal (const NMIP4Config *a, const NMIP4Config *b); gboolean _nm_ip_config_check_and_add_domain (GPtrArray *array, const char *domain); +void nm_ip_config_dump (const NMIPConfig *self, + const char *detail, + NMLogLevel level, + NMLogDomain domain); + /*****************************************************************************/ #include "nm-ip6-config.h" diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index 9807d3882..86b687e10 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -1452,53 +1452,6 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev return has_relevant_changes || has_minor_changes; } -void -nm_ip6_config_dump (const NMIP6Config *self, const char *detail) -{ - const struct in6_addr *tmp; - guint32 i; - const char *str; - NMDedupMultiIter ipconf_iter; - const NMPlatformIP6Address *address; - const NMPlatformIP6Route *route; - - g_return_if_fail (self != NULL); - - g_message ("--------- NMIP6Config %p (%s)", self, detail); - - str = nm_dbus_object_get_path (NM_DBUS_OBJECT (self)); - if (str) - g_message (" path: %s", str); - - /* addresses */ - nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, self, &address) - g_message (" a: %s", nm_platform_ip6_address_to_string (address, NULL, 0)); - - /* nameservers */ - for (i = 0; i < nm_ip6_config_get_num_nameservers (self); i++) { - tmp = nm_ip6_config_get_nameserver (self, i); - g_message (" ns: %s", nm_utils_inet6_ntop (tmp, NULL)); - } - - /* routes */ - nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, self, &route) - g_message (" rt: %s", nm_platform_ip6_route_to_string (route, NULL, 0)); - - /* domains */ - for (i = 0; i < nm_ip6_config_get_num_domains (self); i++) - g_message (" domain: %s", nm_ip6_config_get_domain (self, i)); - - /* dns searches */ - for (i = 0; i < nm_ip6_config_get_num_searches (self); i++) - g_message (" search: %s", nm_ip6_config_get_search (self, i)); - - /* dns options */ - for (i = 0; i < nm_ip6_config_get_num_dns_options (self); i++) - g_message (" dnsopt: %s", nm_ip6_config_get_dns_option (self, i)); - - g_message (" dnspri: %d", nm_ip6_config_get_dns_priority (self)); -} - /*****************************************************************************/ void diff --git a/src/nm-ip6-config.h b/src/nm-ip6-config.h index 9762ef48b..d4fed853c 100644 --- a/src/nm-ip6-config.h +++ b/src/nm-ip6-config.h @@ -135,7 +135,6 @@ NMIP6Config *nm_ip6_config_intersect_alloc (const NMIP6Config *a, const NMIP6Config *b, guint32 default_route_metric_penalty); gboolean nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relevant_changes); -void nm_ip6_config_dump (const NMIP6Config *self, const char *detail); const NMPObject *nm_ip6_config_best_default_route_get (const NMIP6Config *self); const NMPObject *_nm_ip6_config_best_default_route_find (const NMIP6Config *self); -- 2.20.1 From 70e7474bff0ea9b57300804b9952c50bfaf3100c Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Tue, 25 Sep 2018 09:51:06 +0200 Subject: [PATCH 2/5] device: fix updating device information after link change device_link_changed() can't use nm_device_update_from_platform_link() to update the device private fields because the latter overwrites priv->iface and priv->up, and so the checks below as: if (info.name[0] && strcmp (priv->iface, info.name) != 0) { and: was_up = priv->up; priv->up = NM_FLAGS_HAS (info.n_ifi_flags, IFF_UP); ... if (priv->up && !was_up) { never succeed. Fixes: d7f7725ae8c965756902bd492bf2cf0834319548 (cherry picked from commit 46ed756112f38f30f996bb7425514bc59b6f5360) (cherry picked from commit 81aaf0ff93c002dafd5198d677b802c1b161f757) (cherry picked from commit 4775b1dff20781340c05d09888b56b654aea0d1d) --- src/devices/nm-device.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index ac9e1da08..76474c2c3 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -3382,6 +3382,7 @@ device_link_changed (NMDevice *self) gboolean ip_ifname_changed = FALSE; nm_auto_nmpobj const NMPObject *pllink_keep_alive = NULL; const NMPlatformLink *pllink; + const char *str; int ifindex; gboolean was_up; gboolean update_unmanaged_specs = FALSE; @@ -3396,7 +3397,23 @@ device_link_changed (NMDevice *self) pllink_keep_alive = nmp_object_ref (NMP_OBJECT_UP_CAST (pllink)); - nm_device_update_from_platform_link (self, pllink); + str = nm_platform_link_get_udi (nm_device_get_platform (self), pllink->ifindex); + if (!nm_streq0 (str, priv->udi)) { + g_free (priv->udi); + priv->udi = g_strdup (str); + _notify (self, PROP_UDI); + } + + if (!nm_streq0 (pllink->driver, priv->driver)) { + g_free (priv->driver); + priv->driver = g_strdup (pllink->driver); + _notify (self, PROP_DRIVER); + } + + _set_mtu (self, pllink->mtu); + + if (ifindex == nm_device_get_ip_ifindex (self)) + _stats_update_counters_from_pllink (self, pllink); had_hw_addr = (priv->hw_addr != NULL); nm_device_update_hw_address (self); -- 2.20.1 From 5a0ce5c98883f4812a1506ab4ac58758e19c5aab Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Fri, 21 Sep 2018 17:55:46 +0200 Subject: [PATCH 3/5] ip-config: add @intersect_routes argument to intersect functions In some cases we want to intersect two IP configurations without considering routes. (cherry picked from commit 8f07b3ac4f6878b3cb1e24c8f272e1bbfa26ba2f) (cherry picked from commit bd79e67c55a5c9d7736f9e0a43d557f26e54ab72) (cherry picked from commit da46fcaffdea2530f24fc697938ffe59e9e8d3c4) --- src/devices/nm-device.c | 23 ++++++++++++++--------- src/nm-ip4-config.c | 13 +++++++++++-- src/nm-ip4-config.h | 7 +++++++ src/nm-ip6-config.c | 13 +++++++++++-- src/nm-ip6-config.h | 2 ++ 5 files changed, 45 insertions(+), 13 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 76474c2c3..2fad467a7 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -12059,7 +12059,9 @@ nm_device_get_firmware_missing (NMDevice *self) } static void -intersect_ext_config (NMDevice *self, AppliedConfig *config) +intersect_ext_config (NMDevice *self, + AppliedConfig *config, + gboolean intersect_routes) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMIPConfig *ext; @@ -12076,10 +12078,11 @@ intersect_ext_config (NMDevice *self, AppliedConfig *config) : (NMIPConfig *) priv->ext_ip_config_6; if (config->current) - nm_ip_config_intersect (config->current, ext, penalty); + nm_ip_config_intersect (config->current, ext, intersect_routes, penalty); else { config->current = nm_ip_config_intersect_alloc (config->orig, ext, + intersect_routes, penalty); } } @@ -12111,14 +12114,15 @@ update_ext_ip_config (NMDevice *self, int addr_family, gboolean intersect_config * by the user. */ if (priv->con_ip_config_4) { nm_ip4_config_intersect (priv->con_ip_config_4, priv->ext_ip_config_4, + TRUE, default_route_metric_penalty_get (self, AF_INET)); } - intersect_ext_config (self, &priv->dev_ip4_config); - intersect_ext_config (self, &priv->wwan_ip_config_4); + intersect_ext_config (self, &priv->dev_ip4_config, TRUE); + intersect_ext_config (self, &priv->wwan_ip_config_4, TRUE); for (iter = priv->vpn_configs_4; iter; iter = iter->next) - nm_ip4_config_intersect (iter->data, priv->ext_ip_config_4, 0); + nm_ip4_config_intersect (iter->data, priv->ext_ip_config_4, TRUE, 0); } /* Remove parts from ext_ip_config_4 to only contain the information that @@ -12162,15 +12166,16 @@ update_ext_ip_config (NMDevice *self, int addr_family, gboolean intersect_config * by the user. */ if (priv->con_ip_config_6) { nm_ip6_config_intersect (priv->con_ip_config_6, priv->ext_ip_config_6, + TRUE, default_route_metric_penalty_get (self, AF_INET6)); } - intersect_ext_config (self, &priv->ac_ip6_config); - intersect_ext_config (self, &priv->dhcp6.ip6_config); - intersect_ext_config (self, &priv->wwan_ip_config_6); + intersect_ext_config (self, &priv->ac_ip6_config, TRUE); + intersect_ext_config (self, &priv->dhcp6.ip6_config, TRUE); + intersect_ext_config (self, &priv->wwan_ip_config_6, TRUE); for (iter = priv->vpn_configs_6; iter; iter = iter->next) - nm_ip6_config_intersect (iter->data, priv->ext_ip_config_6, 0); + nm_ip6_config_intersect (iter->data, priv->ext_ip_config_6, TRUE, 0); if ( priv->ipv6ll_has && !nm_ip6_config_lookup_address (priv->ext_ip_config_6, &priv->ipv6ll_addr)) diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index ed6b712ea..45f0861a8 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -1467,6 +1467,7 @@ nm_ip4_config_subtract (NMIP4Config *dst, static gboolean _nm_ip4_config_intersect_helper (NMIP4Config *dst, const NMIP4Config *src, + gboolean intersect_routes, guint32 default_route_metric_penalty, gboolean update_dst) { @@ -1511,6 +1512,9 @@ _nm_ip4_config_intersect_helper (NMIP4Config *dst, /* ignore nameservers */ /* routes */ + if (!intersect_routes) + goto skip_routes; + changed = FALSE; new_best_default_route = NULL; nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, dst, &r) { @@ -1551,6 +1555,7 @@ _nm_ip4_config_intersect_helper (NMIP4Config *dst, _notify (dst, PROP_GATEWAY); } +skip_routes: if (changed) { _notify_routes (dst); result = TRUE; @@ -1580,9 +1585,10 @@ _nm_ip4_config_intersect_helper (NMIP4Config *dst, void nm_ip4_config_intersect (NMIP4Config *dst, const NMIP4Config *src, + gboolean intersect_routes, guint32 default_route_metric_penalty) { - _nm_ip4_config_intersect_helper (dst, src, default_route_metric_penalty, TRUE); + _nm_ip4_config_intersect_helper (dst, src, intersect_routes, default_route_metric_penalty, TRUE); } /** @@ -1603,14 +1609,17 @@ nm_ip4_config_intersect (NMIP4Config *dst, NMIP4Config * nm_ip4_config_intersect_alloc (const NMIP4Config *a, const NMIP4Config *b, + gboolean intersect_routes, guint32 default_route_metric_penalty) { NMIP4Config *a_copy; if (_nm_ip4_config_intersect_helper ((NMIP4Config *) a, b, + intersect_routes, default_route_metric_penalty, FALSE)) { a_copy = nm_ip4_config_clone (a); - _nm_ip4_config_intersect_helper (a_copy, b, default_route_metric_penalty, TRUE); + _nm_ip4_config_intersect_helper (a_copy, b, intersect_routes, + default_route_metric_penalty, TRUE); return a_copy; } else return NULL; diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h index 728b64ac6..5806c81da 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -186,9 +186,11 @@ void nm_ip4_config_subtract (NMIP4Config *dst, guint32 default_route_metric_penalty); void nm_ip4_config_intersect (NMIP4Config *dst, const NMIP4Config *src, + gboolean intersect_routes, guint32 default_route_metric_penalty); NMIP4Config *nm_ip4_config_intersect_alloc (const NMIP4Config *a, const NMIP4Config *b, + gboolean intersect_routes, guint32 default_route_metric_penalty); gboolean nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relevant_changes); @@ -534,11 +536,13 @@ nm_ip_config_best_default_route_get (const NMIPConfig *self) static inline void nm_ip_config_intersect (NMIPConfig *dst, const NMIPConfig *src, + gboolean intersect_routes, guint32 default_route_metric_penalty) { _NM_IP_CONFIG_DISPATCH_SET_OP (, dst, src, nm_ip4_config_intersect, nm_ip6_config_intersect, + intersect_routes, default_route_metric_penalty); } @@ -580,18 +584,21 @@ nm_ip_config_replace (NMIPConfig *dst, static inline NMIPConfig * nm_ip_config_intersect_alloc (const NMIPConfig *a, const NMIPConfig *b, + gboolean intersect_routes, guint32 default_route_metric_penalty) { if (NM_IS_IP4_CONFIG (a)) { nm_assert (NM_IS_IP4_CONFIG (b)); return (NMIPConfig *) nm_ip4_config_intersect_alloc ((const NMIP4Config *) a, (const NMIP4Config *) b, + intersect_routes, default_route_metric_penalty); } else { nm_assert (NM_IS_IP6_CONFIG (a)); nm_assert (NM_IS_IP6_CONFIG (b)); return (NMIPConfig *) nm_ip6_config_intersect_alloc ((const NMIP6Config *) a, (const NMIP6Config *) b, + intersect_routes, default_route_metric_penalty); } } diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index 86b687e10..f2125659c 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -1053,6 +1053,7 @@ nm_ip6_config_subtract (NMIP6Config *dst, static gboolean _nm_ip6_config_intersect_helper (NMIP6Config *dst, const NMIP6Config *src, + gboolean intersect_routes, guint32 default_route_metric_penalty, gboolean update_dst) { @@ -1097,6 +1098,9 @@ _nm_ip6_config_intersect_helper (NMIP6Config *dst, /* ignore nameservers */ /* routes */ + if (!intersect_routes) + goto skip_routes; + changed = FALSE; new_best_default_route = NULL; nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, dst, &r) { @@ -1141,6 +1145,7 @@ _nm_ip6_config_intersect_helper (NMIP6Config *dst, result = TRUE; } +skip_routes: /* ignore domains */ /* ignore dns searches */ /* ignore dns options */ @@ -1163,9 +1168,10 @@ _nm_ip6_config_intersect_helper (NMIP6Config *dst, void nm_ip6_config_intersect (NMIP6Config *dst, const NMIP6Config *src, + gboolean intersect_routes, guint32 default_route_metric_penalty) { - _nm_ip6_config_intersect_helper (dst, src, default_route_metric_penalty, TRUE); + _nm_ip6_config_intersect_helper (dst, src, intersect_routes, default_route_metric_penalty, TRUE); } /** @@ -1186,14 +1192,17 @@ nm_ip6_config_intersect (NMIP6Config *dst, NMIP6Config * nm_ip6_config_intersect_alloc (const NMIP6Config *a, const NMIP6Config *b, + gboolean intersect_routes, guint32 default_route_metric_penalty) { NMIP6Config *a_copy; if (_nm_ip6_config_intersect_helper ((NMIP6Config *) a, b, + intersect_routes, default_route_metric_penalty, FALSE)) { a_copy = nm_ip6_config_clone (a); - _nm_ip6_config_intersect_helper (a_copy, b, default_route_metric_penalty, TRUE); + _nm_ip6_config_intersect_helper (a_copy, b, intersect_routes, + default_route_metric_penalty, TRUE); return a_copy; } else return NULL; diff --git a/src/nm-ip6-config.h b/src/nm-ip6-config.h index d4fed853c..4f1778060 100644 --- a/src/nm-ip6-config.h +++ b/src/nm-ip6-config.h @@ -130,9 +130,11 @@ void nm_ip6_config_subtract (NMIP6Config *dst, guint32 default_route_metric_penalty); void nm_ip6_config_intersect (NMIP6Config *dst, const NMIP6Config *src, + gboolean intersect_routes, guint32 default_route_metric_penalty); NMIP6Config *nm_ip6_config_intersect_alloc (const NMIP6Config *a, const NMIP6Config *b, + gboolean intersect_routes, guint32 default_route_metric_penalty); gboolean nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relevant_changes); -- 2.20.1 From 5078529926c6b634dc8af7dedb50d054c17c7558 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Mon, 24 Sep 2018 16:35:25 +0200 Subject: [PATCH 4/5] device: don't remove routes when the interface is down In update update_ext_ip_config() we remove from various internal configurations those addresses and routes that were removed externally by users. When the interface is brought down, the kernel automatically removes routes associated with it and so we should not consider them as "removed by users". Instead, keep them so that they can be restored when the interface comes up again. (cherry picked from commit f069c98cc95494891215ddf261661afb742744ba) (cherry picked from commit ce2d403530451a60357dcd1ce815977079f539f6) (cherry picked from commit 4fc6f5f3177903a23deda1384d9bb88fc5c933f4) --- src/devices/nm-device.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 2fad467a7..e1bfe44e2 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -12093,6 +12093,7 @@ update_ext_ip_config (NMDevice *self, int addr_family, gboolean intersect_config NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); int ifindex; GSList *iter; + gboolean is_up; nm_assert_addr_family (addr_family); @@ -12100,6 +12101,8 @@ update_ext_ip_config (NMDevice *self, int addr_family, gboolean intersect_config if (!ifindex) return FALSE; + is_up = nm_platform_link_is_up (nm_device_get_platform (self), ifindex); + if (addr_family == AF_INET) { g_clear_object (&priv->ext_ip_config_4); @@ -12114,15 +12117,15 @@ update_ext_ip_config (NMDevice *self, int addr_family, gboolean intersect_config * by the user. */ if (priv->con_ip_config_4) { nm_ip4_config_intersect (priv->con_ip_config_4, priv->ext_ip_config_4, - TRUE, + is_up, default_route_metric_penalty_get (self, AF_INET)); } - intersect_ext_config (self, &priv->dev_ip4_config, TRUE); - intersect_ext_config (self, &priv->wwan_ip_config_4, TRUE); + intersect_ext_config (self, &priv->dev_ip4_config, is_up); + intersect_ext_config (self, &priv->wwan_ip_config_4, is_up); for (iter = priv->vpn_configs_4; iter; iter = iter->next) - nm_ip4_config_intersect (iter->data, priv->ext_ip_config_4, TRUE, 0); + nm_ip4_config_intersect (iter->data, priv->ext_ip_config_4, is_up, 0); } /* Remove parts from ext_ip_config_4 to only contain the information that @@ -12166,16 +12169,16 @@ update_ext_ip_config (NMDevice *self, int addr_family, gboolean intersect_config * by the user. */ if (priv->con_ip_config_6) { nm_ip6_config_intersect (priv->con_ip_config_6, priv->ext_ip_config_6, - TRUE, + is_up, default_route_metric_penalty_get (self, AF_INET6)); } - intersect_ext_config (self, &priv->ac_ip6_config, TRUE); - intersect_ext_config (self, &priv->dhcp6.ip6_config, TRUE); - intersect_ext_config (self, &priv->wwan_ip_config_6, TRUE); + intersect_ext_config (self, &priv->ac_ip6_config, is_up); + intersect_ext_config (self, &priv->dhcp6.ip6_config, is_up); + intersect_ext_config (self, &priv->wwan_ip_config_6, is_up); for (iter = priv->vpn_configs_6; iter; iter = iter->next) - nm_ip6_config_intersect (iter->data, priv->ext_ip_config_6, TRUE, 0); + nm_ip6_config_intersect (iter->data, priv->ext_ip_config_6, is_up, 0); if ( priv->ipv6ll_has && !nm_ip6_config_lookup_address (priv->ext_ip_config_6, &priv->ipv6ll_addr)) -- 2.20.1 From 79a55db94360c87add82e82f7b59818959d7e583 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Thu, 20 Dec 2018 09:35:34 +0100 Subject: [PATCH 5/5] device: ensure IP configuration is restored when link goes up When the link is up and goes down link_changed_cb() schedules device_link_changed() to be run later. If the function is dispatched when the link is already up again, it does not detect that the link was down. Fix this by storing in the device state that we saw the link down so that device_link_changed() can properly restore the IP configuration. https://bugzilla.redhat.com/show_bug.cgi?id=1636715 https://github.com/NetworkManager/NetworkManager/pull/264 (cherry picked from commit 7bd193ef30fb2a1d4c328bb61412e35a5bccfced) (cherry picked from commit 710406e74635ec03776dc49aa2de6d2bc0f6ff5f) (cherry picked from commit c941b6fa101b2b6bceef86d2d5dac8342ba9065e) --- src/devices/nm-device.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index e1bfe44e2..a81541c87 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -382,6 +382,7 @@ typedef struct _NMDevicePrivate { bool ipv6ll_handle:1; /* TRUE if NM handles the device's IPv6LL address */ bool ipv6ll_has:1; + bool device_link_changed_down:1; /* Generic DHCP stuff */ char * dhcp_anycast_address; @@ -3387,8 +3388,10 @@ device_link_changed (NMDevice *self) gboolean was_up; gboolean update_unmanaged_specs = FALSE; gboolean got_hw_addr = FALSE, had_hw_addr; + gboolean seen_down = priv->device_link_changed_down; priv->device_link_changed_id = 0; + priv->device_link_changed_down = FALSE; ifindex = nm_device_get_ifindex (self); pllink = nm_platform_link_get (nm_device_get_platform (self), ifindex); @@ -3498,7 +3501,7 @@ device_link_changed (NMDevice *self) device_recheck_slave_status (self, pllink); - if (priv->up && !was_up) { + if (priv->up && (!was_up || seen_down)) { /* the link was down and just came up. That happens for example, while changing MTU. * We must restore IP configuration. */ if (priv->ip4_state == IP_DONE) { @@ -3574,6 +3577,8 @@ link_changed_cb (NMPlatform *platform, priv = NM_DEVICE_GET_PRIVATE (self); if (ifindex == nm_device_get_ifindex (self)) { + if (!(info->n_ifi_flags & IFF_UP)) + priv->device_link_changed_down = TRUE; if (!priv->device_link_changed_id) { priv->device_link_changed_id = g_idle_add ((GSourceFunc) device_link_changed, self); _LOGD (LOGD_DEVICE, "queued link change for ifindex %d", ifindex); -- 2.20.1