
3 changed files with 912 additions and 0 deletions
@ -0,0 +1,769 @@
@@ -0,0 +1,769 @@
|
||||
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 |
||||
|
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
From 14990584112a3740acb404f7085f1b5ed0cfb4f9 Mon Sep 17 00:00:00 2001 |
||||
From: Beniamino Galvani <bgalvani@redhat.com> |
||||
Date: Tue, 26 Feb 2019 10:07:36 +0100 |
||||
Subject: [PATCH] manager: ignore ovs-system master when assuming |
||||
connections |
||||
|
||||
This change allows to assume after restart a device that has been |
||||
enslaved externally to an ovs bridge. |
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1676551 |
||||
(cherry picked from commit 23b0f943b7408da77b51e83a16de604b52704a1d) |
||||
--- |
||||
src/nm-manager.c | 7 ++++++- |
||||
1 file changed, 6 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/src/nm-manager.c b/src/nm-manager.c |
||||
index 289dcf838..225eb1f70 100644 |
||||
--- a/src/nm-manager.c |
||||
+++ b/src/nm-manager.c |
||||
@@ -2405,7 +2405,12 @@ get_existing_connection (NMManager *self, |
||||
if (ifindex) { |
||||
int master_ifindex = nm_platform_link_get_master (priv->platform, ifindex); |
||||
|
||||
- if (master_ifindex) { |
||||
+ /* Check that the master is activating before assuming a |
||||
+ * slave connection. However, ignore ovs-system master as |
||||
+ * we never manage it. |
||||
+ */ |
||||
+ if ( master_ifindex |
||||
+ && nm_platform_link_get_type (priv->platform, master_ifindex) != NM_LINK_TYPE_OPENVSWITCH) { |
||||
master = nm_manager_get_device_by_ifindex (self, master_ifindex); |
||||
if (!master) { |
||||
_LOG2D (LOGD_DEVICE, device, "assume: don't assume because " |
||||
-- |
||||
2.20.1 |
||||
|
@ -0,0 +1,107 @@
@@ -0,0 +1,107 @@
|
||||
From 17612d182004af4045b7e55654f231114e311f12 Mon Sep 17 00:00:00 2001 |
||||
From: Beniamino Galvani <bgalvani@redhat.com> |
||||
Date: Thu, 21 Feb 2019 16:18:48 +0100 |
||||
Subject: [PATCH] device: do ARP announcements only after masters have a slave |
||||
|
||||
Delay ARP announcements for masters until the first interfaces gets |
||||
enslaved. There is no point in doing it before as the ARP packets |
||||
would be dropped in most cases; also, if the first slave is added when |
||||
we already started announcing, the MAC of the master is going to |
||||
change and so the remaining ARPs will have a wrong "sender mac |
||||
address" field. |
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1678796 |
||||
|
||||
https://github.com/NetworkManager/NetworkManager/pull/301 |
||||
(cherry picked from commit de1022285a6c09763d878cf60ef7e200343ae373) |
||||
--- |
||||
src/devices/nm-device.c | 38 +++++++++++++++++++++++++++++++++++--- |
||||
1 file changed, 35 insertions(+), 3 deletions(-) |
||||
|
||||
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c |
||||
index a81541c87..a150442d3 100644 |
||||
--- a/src/devices/nm-device.c |
||||
+++ b/src/devices/nm-device.c |
||||
@@ -2849,6 +2849,7 @@ find_slave_info (NMDevice *self, NMDevice *slave) |
||||
static gboolean |
||||
nm_device_master_enslave_slave (NMDevice *self, NMDevice *slave, NMConnection *connection) |
||||
{ |
||||
+ NMDevicePrivate *priv; |
||||
SlaveInfo *info; |
||||
gboolean success = FALSE; |
||||
gboolean configure; |
||||
@@ -2857,6 +2858,7 @@ nm_device_master_enslave_slave (NMDevice *self, NMDevice *slave, NMConnection *c |
||||
g_return_val_if_fail (slave != NULL, FALSE); |
||||
g_return_val_if_fail (NM_DEVICE_GET_CLASS (self)->enslave_slave != NULL, FALSE); |
||||
|
||||
+ priv = NM_DEVICE_GET_PRIVATE (self); |
||||
info = find_slave_info (self, slave); |
||||
if (!info) |
||||
return FALSE; |
||||
@@ -2879,15 +2881,20 @@ nm_device_master_enslave_slave (NMDevice *self, NMDevice *slave, NMConnection *c |
||||
*/ |
||||
nm_device_update_hw_address (self); |
||||
|
||||
+ /* Send ARP announcements if did not yet and have addresses. */ |
||||
+ if ( priv->ip4_state == IP_DONE |
||||
+ && !priv->acd.announcing) |
||||
+ nm_device_arp_announce (self); |
||||
+ |
||||
/* Restart IP configuration if we're waiting for slaves. Do this |
||||
* after updating the hardware address as IP config may need the |
||||
* new address. |
||||
*/ |
||||
if (success) { |
||||
- if (NM_DEVICE_GET_PRIVATE (self)->ip4_state == IP_WAIT) |
||||
+ if (priv->ip4_state == IP_WAIT) |
||||
nm_device_activate_stage3_ip4_start (self); |
||||
|
||||
- if (NM_DEVICE_GET_PRIVATE (self)->ip6_state == IP_WAIT) |
||||
+ if (priv->ip6_state == IP_WAIT) |
||||
nm_device_activate_stage3_ip6_start (self); |
||||
} |
||||
|
||||
@@ -9795,6 +9802,7 @@ activate_stage5_ip4_config_result (NMDevice *self) |
||||
const char *method; |
||||
NMConnection *connection; |
||||
int ip_ifindex; |
||||
+ gboolean do_announce = FALSE; |
||||
|
||||
req = nm_device_get_act_request (self); |
||||
g_assert (req); |
||||
@@ -9840,7 +9848,31 @@ activate_stage5_ip4_config_result (NMDevice *self) |
||||
NULL, NULL, NULL); |
||||
} |
||||
|
||||
- nm_device_arp_announce (self); |
||||
+ /* Send ARP announcements */ |
||||
+ |
||||
+ if (nm_device_is_master (self)) { |
||||
+ CList *iter; |
||||
+ SlaveInfo *info; |
||||
+ |
||||
+ /* Skip announcement if there are no device enslaved, for two reasons: |
||||
+ * 1) the master has a temporary MAC address until the first slave comes |
||||
+ * 2) announcements are going to be dropped anyway without slaves |
||||
+ */ |
||||
+ do_announce = FALSE; |
||||
+ |
||||
+ c_list_for_each (iter, &priv->slaves) { |
||||
+ info = c_list_entry (iter, SlaveInfo, lst_slave); |
||||
+ if (info->slave_is_enslaved) { |
||||
+ do_announce = TRUE; |
||||
+ break; |
||||
+ } |
||||
+ } |
||||
+ } else |
||||
+ do_announce = TRUE; |
||||
+ |
||||
+ if (do_announce) |
||||
+ nm_device_arp_announce (self); |
||||
+ |
||||
nm_device_remove_pending_action (self, NM_PENDING_ACTION_DHCP4, FALSE); |
||||
|
||||
/* Enter the IP_CHECK state if this is the first method to complete */ |
||||
-- |
||||
2.20.1 |
||||
|
Loading…
Reference in new issue