diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2018-05-29 11:19:22 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2018-05-29 11:21:53 +0200 |
commit | 33e87bd6ecea177723b0655c8188fc684e1b8012 (patch) | |
tree | 102d9ec9c6a84e52a795d08279f177bd6da5fe41 | |
parent | d97eab6c5a809a114cdd1cc54e447503ad253835 (diff) | |
parent | 39b56918471761930588bb63fcd54cbb8385c40d (diff) | |
download | NetworkManager-33e87bd6ecea177723b0655c8188fc684e1b8012.tar.gz |
n-acd: merge branch 'bg/n-acd-fixes-rh1578675'
https://bugzilla.redhat.com/show_bug.cgi?id=1578675
-rw-r--r-- | shared/n-acd/src/n-acd.c | 41 | ||||
-rw-r--r-- | shared/n-acd/src/n-acd.h | 2 | ||||
-rw-r--r-- | src/devices/nm-acd-manager.c | 6 | ||||
-rw-r--r-- | src/devices/nm-device-private.h | 2 | ||||
-rw-r--r-- | src/devices/nm-device-vlan.c | 11 | ||||
-rw-r--r-- | src/devices/nm-device.c | 7 |
6 files changed, 47 insertions, 22 deletions
diff --git a/shared/n-acd/src/n-acd.c b/shared/n-acd/src/n-acd.c index ae149abbf0..9164f95895 100644 --- a/shared/n-acd/src/n-acd.c +++ b/shared/n-acd/src/n-acd.c @@ -534,7 +534,11 @@ static int n_acd_handle_timeout(NAcd *acd) { */ r = n_acd_send(acd, NULL); - if (r < 0) + /* + * During probe we must respect the total timeout and so + * we ignore errors caused by a down interface. + */ + if (r < 0 && r != -N_ACD_E_DOWN) return r; if (++acd->n_iteration >= N_ACD_RFC_PROBE_NUM) @@ -559,11 +563,26 @@ static int n_acd_handle_timeout(NAcd *acd) { */ r = n_acd_send(acd, &acd->config.ip); - if (r < 0) - return r; + if (r < 0) { + if (r != -N_ACD_E_DOWN) + return r; + /* + * We want to send all the 3 announcements even if the + * interface goes temporarily down. Therefore, if send() + * fails, don't increment the iteration and try again. + */ + } else + acd->n_iteration++; - if (++acd->n_iteration < N_ACD_RFC_ANNOUNCE_NUM) { - r = n_acd_schedule(acd, acd->timeout_multiplier * N_ACD_RFC_ANNOUNCE_INTERVAL_USEC, 0); + if (acd->n_iteration < N_ACD_RFC_ANNOUNCE_NUM) { + /* + * Announcements are always scheduled according to the + * time-intervals specified in the spec. We always use + * the RFC5227-mandated multiplier. + * If you reconsider this, note that timeout_multiplier + * might be 0 here. + */ + r = n_acd_schedule(acd, N_ACD_TIMEOUT_RFC5227 * N_ACD_RFC_ANNOUNCE_INTERVAL_USEC, 0); if (r < 0) return r; } @@ -803,14 +822,12 @@ static int n_acd_dispatch_socket(NAcd *acd, struct epoll_event *event) { return -EIO; } else if (errno == ENETDOWN || errno == ENXIO) { /* - * We get ENETDOWN if the network-device goes down or is - * removed. ENXIO might happen on async send-operations if the - * network-device was unplugged and thus the kernel is no - * longer aware of it. - * In any case, we do not allow proceeding with this socket. We - * stop the engine and notify the user gracefully. + * The network device went down or was removed. Ignore + * such errors and let the pending probe time out. + * Subsequent reads will simply return EAGAIN until the + * device is up again and has data queued. */ - return -N_ACD_E_DOWN; + return 0; } else if (errno == EAGAIN) { /* * We cannot read data from the socket (we got EAGAIN). As a safety net diff --git a/shared/n-acd/src/n-acd.h b/shared/n-acd/src/n-acd.h index 46394dcaa3..75646243d8 100644 --- a/shared/n-acd/src/n-acd.h +++ b/shared/n-acd/src/n-acd.h @@ -15,6 +15,8 @@ extern "C" { #include <netinet/in.h> #include <stdbool.h> +#define N_ACD_TIMEOUT_RFC5227 (UINT64_C(9000)) + enum { _N_ACD_E_SUCCESS, diff --git a/src/devices/nm-acd-manager.c b/src/devices/nm-acd-manager.c index 1bade4ff3a..035487a330 100644 --- a/src/devices/nm-acd-manager.c +++ b/src/devices/nm-acd-manager.c @@ -274,7 +274,11 @@ acd_probe_start (NMAcdManager *self, return FALSE; } - _LOGD ("start probe for %s", nm_utils_inet4_ntop (info->address, NULL)); + if (timeout) { + _LOGD ("started probe for %s with timeout %llu", + nm_utils_inet4_ntop (info->address, NULL), + (unsigned long long) timeout); + } return TRUE; } diff --git a/src/devices/nm-device-private.h b/src/devices/nm-device-private.h index b0d3ffa4f6..0b8444112a 100644 --- a/src/devices/nm-device-private.h +++ b/src/devices/nm-device-private.h @@ -43,6 +43,8 @@ enum NMActStageReturn { #define NM_DEVICE_CAP_INTERNAL_MASK 0xc0000000 +void nm_device_arp_announce (NMDevice *self); + NMSettings *nm_device_get_settings (NMDevice *self); gboolean nm_device_set_ip_ifindex (NMDevice *self, int ifindex); diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index ae6a0f3690..a7f4c4bce4 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -110,15 +110,15 @@ parent_hwaddr_maybe_changed (NMDevice *parent, if (nm_device_sys_iface_state_is_external_or_assume (device)) return; - connection = nm_device_get_applied_connection ((NMDevice *) self); + connection = nm_device_get_applied_connection (device); if (!connection) return; /* Update the VLAN MAC only if configuration does not specify one */ - if (nm_device_hw_addr_is_explict ((NMDevice *) self)) + if (nm_device_hw_addr_is_explict (device)) return; - old_mac = nm_device_get_hw_address ((NMDevice *) self); + old_mac = nm_device_get_hw_address (device); new_mac = nm_device_get_hw_address (parent); if (nm_streq0 (old_mac, new_mac)) return; @@ -126,13 +126,14 @@ parent_hwaddr_maybe_changed (NMDevice *parent, _LOGD (LOGD_VLAN, "parent hardware address changed to %s%s%s", NM_PRINT_FMT_QUOTE_STRING (new_mac)); if (new_mac) { - nm_device_hw_addr_set ((NMDevice *) self, new_mac, "vlan-parent", TRUE); + nm_device_hw_addr_set (device, new_mac, "vlan-parent", TRUE); + nm_device_arp_announce (device); /* When changing the hw address the interface is taken down, * removing the IPv6 configuration; reapply it. */ s_ip6 = nm_connection_get_setting_ip6_config (connection); if (s_ip6) - nm_device_reactivate_ip6_config (NM_DEVICE (self), s_ip6, s_ip6); + nm_device_reactivate_ip6_config (device, s_ip6, s_ip6); } } diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index d133452b87..9a40a0dd5e 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -9367,8 +9367,8 @@ arp_cleanup (NMDevice *self) } } -static void -arp_announce (NMDevice *self) +void +nm_device_arp_announce (NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *connection; @@ -9467,8 +9467,7 @@ activate_stage5_ip4_config_result (NMDevice *self) NULL, NULL, NULL); } - arp_announce (self); - + 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 */ |