Commit 33e87bd6 authored by Beniamino Galvani's avatar Beniamino Galvani

n-acd: merge branch 'bg/n-acd-fixes-rh1578675'

https://bugzilla.redhat.com/show_bug.cgi?id=1578675
parents d97eab6c 39b56918
......@@ -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
......
......@@ -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,
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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);
}
}
......
......@@ -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 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment