diff options
Diffstat (limited to 'src/devices/nm-device.c')
| -rw-r--r-- | src/devices/nm-device.c | 93 |
1 files changed, 62 insertions, 31 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 33dd5e50..f0d747e5 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -3306,7 +3306,8 @@ ndisc_set_router_config (NMNDisc *ndisc, NMDevice *self) guint32 lifetime, preferred; gint32 base; - if (IN6_IS_ADDR_LINKLOCAL (&addr->address)) + if ( IN6_IS_ADDR_UNSPECIFIED (&addr->address) + || IN6_IS_ADDR_LINKLOCAL (&addr->address)) continue; if ( addr->n_ifa_flags & IFA_F_TENTATIVE @@ -10362,8 +10363,10 @@ nm_device_reactivate_ip4_config (NMDevice *self, nm_ip4_config_update_routes_metric ((NMIP4Config *) priv->wwan_ip_config_4.orig, nm_device_get_route_metric (self, AF_INET)); } - if (priv->dhcp4.client) - nm_dhcp_client_set_route_metric (priv->dhcp4.client, metric_new); + if (priv->dhcp4.client) { + nm_dhcp_client_set_route_metric (priv->dhcp4.client, + nm_device_get_route_metric (self, AF_INET)); + } } } @@ -10433,8 +10436,10 @@ nm_device_reactivate_ip6_config (NMDevice *self, nm_ip6_config_update_routes_metric ((NMIP6Config *) priv->wwan_ip_config_6.orig, nm_device_get_route_metric (self, AF_INET6)); } - if (priv->dhcp6.client) - nm_dhcp_client_set_route_metric (priv->dhcp6.client, metric_new); + if (priv->dhcp6.client) { + nm_dhcp_client_set_route_metric (priv->dhcp6.client, + nm_device_get_route_metric (self, AF_INET6)); + } } } @@ -14770,7 +14775,8 @@ _hw_addr_set (NMDevice *self, NMPlatformError plerr; guint8 addr_bytes[NM_UTILS_HWADDR_LEN_MAX]; gsize addr_len; - gboolean was_up; + gboolean was_taken_down; + gboolean retry_down; nm_assert (NM_IS_DEVICE (self)); nm_assert (addr); @@ -14793,21 +14799,30 @@ _hw_addr_set (NMDevice *self, _LOGT (LOGD_DEVICE, "set-hw-addr: setting MAC address to '%s' (%s, %s)...", addr, operation, detail); - was_up = nm_device_is_up (self); - if (was_up) { - /* Can't change MAC address while device is up */ - nm_device_take_down (self, FALSE); - } + was_taken_down = FALSE; +again: plerr = nm_platform_link_set_address (nm_device_get_platform (self), nm_device_get_ip_ifindex (self), addr_bytes, addr_len); success = (plerr == NM_PLATFORM_ERROR_SUCCESS); - if (success) { - /* MAC address succesfully changed; update the current MAC to match */ + if (!success) { + retry_down = !was_taken_down + && plerr != NM_PLATFORM_ERROR_NOT_FOUND + && nm_platform_link_is_up (nm_device_get_platform (self), + nm_device_get_ip_ifindex (self)); + _NMLOG ( retry_down + || plerr == NM_PLATFORM_ERROR_NOT_FOUND + ? LOGL_DEBUG + : LOGL_WARN, + LOGD_DEVICE, + "set-hw-addr: failed to %s MAC address to %s (%s) (%s)%s", + operation, addr, detail, + nm_platform_error_to_string_a (plerr), + retry_down ? " (retry with taking down)" : ""); + } else { + /* MAC address successfully changed; update the current MAC to match */ nm_device_update_hw_address (self); - if (_hw_addr_matches (self, addr_bytes, addr_len)) { - _LOGI (LOGD_DEVICE, "set-hw-addr: %s MAC address to %s (%s)", - operation, addr, detail); - } else { + + if (!_hw_addr_matches (self, addr_bytes, addr_len)) { gint64 poll_end, now; _LOGD (LOGD_DEVICE, @@ -14848,24 +14863,40 @@ handle_fail: success = FALSE; break; } + } - if (success) { - _LOGI (LOGD_DEVICE, "set-hw-addr: %s MAC address to %s (%s)", - operation, addr, detail); - } else { - _LOGW (LOGD_DEVICE, - "set-hw-addr: new MAC address %s not successfully %s (%s)", - addr, operation, detail); - } + if (success) { + retry_down = FALSE; + _LOGI (LOGD_DEVICE, "set-hw-addr: %s MAC address to %s (%s)", + operation, addr, detail); + } else { + retry_down = !was_taken_down + && nm_platform_link_is_up (nm_device_get_platform (self), + nm_device_get_ip_ifindex (self)); + + _NMLOG ( retry_down + ? LOGL_DEBUG + : LOGL_WARN, + LOGD_DEVICE, + "set-hw-addr: new MAC address %s not successfully %s (%s)%s", + addr, + operation, + detail, + retry_down ? " (retry with taking down)" : ""); } - } else { - _NMLOG (plerr == NM_PLATFORM_ERROR_NOT_FOUND ? LOGL_DEBUG : LOGL_WARN, - LOGD_DEVICE, "set-hw-addr: failed to %s MAC address to %s (%s) (%s)", - operation, addr, detail, - nm_platform_error_to_string_a (plerr)); } - if (was_up) { + if (retry_down) { + /* changing the MAC address failed, but also the device was up (and we did not yet try to take + * it down). Optimally, we change the MAC address without taking the device down, but some + * devices don't like that. So, retry with taking the device down. */ + retry_down = FALSE; + was_taken_down = TRUE; + nm_device_take_down (self, FALSE); + goto again; + } + + if (was_taken_down) { if (!nm_device_bring_up (self, TRUE, NULL)) return FALSE; } |