From 0b1ffdbdb599ecd53f4b0cdead4f64296ac3ad49 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Fri, 21 Sep 2018 18:30:49 +0200 Subject: [PATCH 1/4] 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) --- src/nm-ip4-config.c | 121 +++++++++++++++++++++++++------------------- src/nm-ip4-config.h | 6 ++- src/nm-ip6-config.c | 47 ----------------- src/nm-ip6-config.h | 1 - 4 files changed, 75 insertions(+), 100 deletions(-) diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index 573c479a92..1fec20d51f 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -1971,71 +1971,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; + 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; - g_message ("--------- NMIP4Config %p (%s)", self, detail); + if (self) { + addr_family = nm_ip_config_get_addr_family (self); + addr_family_char = nm_utils_addr_family_to_char (addr_family); + } - if (self == NULL) { - g_message (" (null)"); + nm_log (level, domain, NULL, NULL, + "---- NMIP%cConfig %p (%s)", + addr_family_char, + self, + detail); + + if (!self) return; + + path = nm_dbus_object_get_path (NM_DBUS_OBJECT (self)); + if (path) + nm_log (level, domain, NULL, NULL, " path : %s", path); + + 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)); + } } - 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)); - - /* 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)); + 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)); } - /* 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)); + 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)); - /* domains */ - for (i = 0; i < nm_ip4_config_get_num_domains (self); i++) - g_message (" domain: %s", nm_ip4_config_get_domain (self, i)); + 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)); - /* 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)); + 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)); - /* 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)); + nm_log (level, domain, NULL, NULL, " dns-prio : %d", nm_ip_config_get_dns_priority (self)); - g_message (" dnspri: %d", nm_ip4_config_get_dns_priority (self)); - - g_message (" mtu: %"G_GUINT32_FORMAT" (source: %d)", nm_ip4_config_get_mtu (self), (int) nm_ip4_config_get_mtu_source (self)); - - /* 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)); + 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 (" nisdmn: %s", nm_ip4_config_get_nis_domain (self) ?: "(none)"); - - /* 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)); - } - - 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 d9ac969cb2..4983ca7add 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -194,7 +194,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); @@ -297,6 +296,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 378b76d6ba..382512945e 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -1483,53 +1483,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 425b20496c..d796c33996 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); From 81aaf0ff93c002dafd5198d677b802c1b161f757 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Tue, 25 Sep 2018 09:51:06 +0200 Subject: [PATCH 2/4] 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) --- 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 b6ff6b5d96..cd9600ef73 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -3578,6 +3578,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; @@ -3592,7 +3593,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); From bd79e67c55a5c9d7736f9e0a43d557f26e54ab72 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Fri, 21 Sep 2018 17:55:46 +0200 Subject: [PATCH 3/4] 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) --- 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 cd9600ef73..1ab419d394 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -12540,7 +12540,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; @@ -12557,10 +12559,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); } } @@ -12592,14 +12595,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 @@ -12643,15 +12647,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 1fec20d51f..6604711c3d 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -1511,6 +1511,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) { @@ -1555,6 +1556,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) { @@ -1595,6 +1599,7 @@ _nm_ip4_config_intersect_helper (NMIP4Config *dst, _notify (dst, PROP_GATEWAY); } +skip_routes: if (changed) { _notify_routes (dst); result = TRUE; @@ -1625,9 +1630,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); } /** @@ -1648,14 +1654,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 4983ca7add..07fb7f12a2 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -189,9 +189,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); @@ -541,11 +543,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); } @@ -587,18 +591,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 382512945e..a8c4aecdf2 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -1084,6 +1084,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) { @@ -1128,6 +1129,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) { @@ -1172,6 +1176,7 @@ _nm_ip6_config_intersect_helper (NMIP6Config *dst, result = TRUE; } +skip_routes: /* ignore domains */ /* ignore dns searches */ /* ignore dns options */ @@ -1194,9 +1199,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); } /** @@ -1217,14 +1223,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 d796c33996..862f237de0 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); From ce2d403530451a60357dcd1ce815977079f539f6 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Mon, 24 Sep 2018 16:35:25 +0200 Subject: [PATCH 4/4] 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) --- 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 1ab419d394..30318f9dcd 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -12574,6 +12574,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); @@ -12581,6 +12582,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); @@ -12595,15 +12598,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 @@ -12647,16 +12650,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))