summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2018-05-29 11:19:22 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2018-05-29 11:21:53 +0200
commit33e87bd6ecea177723b0655c8188fc684e1b8012 (patch)
tree102d9ec9c6a84e52a795d08279f177bd6da5fe41
parentd97eab6c5a809a114cdd1cc54e447503ad253835 (diff)
parent39b56918471761930588bb63fcd54cbb8385c40d (diff)
downloadNetworkManager-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.c41
-rw-r--r--shared/n-acd/src/n-acd.h2
-rw-r--r--src/devices/nm-acd-manager.c6
-rw-r--r--src/devices/nm-device-private.h2
-rw-r--r--src/devices/nm-device-vlan.c11
-rw-r--r--src/devices/nm-device.c7
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 */