diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2019-02-21 16:18:48 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2019-02-22 14:30:40 +0100 |
commit | de1022285a6c09763d878cf60ef7e200343ae373 (patch) | |
tree | 3441a07e360a55f1991a3f4f4e574824c1f49c9d | |
parent | e2fe19356665b94a16f2a149a330502750694b58 (diff) | |
download | NetworkManager-de1022285a6c09763d878cf60ef7e200343ae373.tar.gz |
device: do ARP announcements only after masters have a slave
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
https://github.com/NetworkManager/NetworkManager/pull/301
-rw-r--r-- | src/devices/nm-device.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index a241fd573d..8568611ccb 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); } @@ -10376,6 +10383,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); @@ -10418,7 +10426,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 */ |