You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
769 lines
30 KiB
769 lines
30 KiB
From 51dd0ac4b8b7b13e3d26c2ab7d35e9451bbcd4c5 Mon Sep 17 00:00:00 2001 |
|
From: Beniamino Galvani <bgalvani@redhat.com> |
|
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 <bgalvani@redhat.com> |
|
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 <bgalvani@redhat.com> |
|
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 <bgalvani@redhat.com> |
|
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 <bgalvani@redhat.com> |
|
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 |
|
|
|
|