summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2019-02-21 16:18:48 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2019-02-22 09:52:07 +0100
commitad45119dc267bbbeaab2d6c631735201001123f6 (patch)
tree7f1a80864f0cccb83777c0c533a6865f5078fa47
parentfefb965cfe0b83885e8e4b0c6b0fd27e5c86100d (diff)
downloadNetworkManager-bg/arp-master-rh1678796.tar.gz
device: do ARP announcements only after masters have a slavebg/arp-master-rh1678796
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
-rw-r--r--src/devices/nm-device.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 6aa6da8e5c..8b71812d18 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -3200,6 +3200,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;
@@ -3208,6 +3209,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;
@@ -3230,15 +3232,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);
}
@@ -10377,6 +10384,7 @@ activate_stage5_ip4_config_result (NMDevice *self)
NMActRequest *req;
const char *method;
int ip_ifindex;
+ gboolean do_announce = FALSE;
req = nm_device_get_act_request (self);
g_assert (req);
@@ -10419,7 +10427,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 */