Blame SOURCES/1006-device-announce-arp-after-slaves-rh1678796.patch

d4f493
From 17612d182004af4045b7e55654f231114e311f12 Mon Sep 17 00:00:00 2001
d4f493
From: Beniamino Galvani <bgalvani@redhat.com>
d4f493
Date: Thu, 21 Feb 2019 16:18:48 +0100
d4f493
Subject: [PATCH] device: do ARP announcements only after masters have a slave
d4f493
d4f493
Delay ARP announcements for masters until the first interfaces gets
d4f493
enslaved. There is no point in doing it before as the ARP packets
d4f493
would be dropped in most cases; also, if the first slave is added when
d4f493
we already started announcing, the MAC of the master is going to
d4f493
change and so the remaining ARPs will have a wrong "sender mac
d4f493
address" field.
d4f493
d4f493
https://bugzilla.redhat.com/show_bug.cgi?id=1678796
d4f493
d4f493
https://github.com/NetworkManager/NetworkManager/pull/301
d4f493
(cherry picked from commit de1022285a6c09763d878cf60ef7e200343ae373)
d4f493
---
d4f493
 src/devices/nm-device.c | 38 +++++++++++++++++++++++++++++++++++---
d4f493
 1 file changed, 35 insertions(+), 3 deletions(-)
d4f493
d4f493
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
d4f493
index a81541c87..a150442d3 100644
d4f493
--- a/src/devices/nm-device.c
d4f493
+++ b/src/devices/nm-device.c
d4f493
@@ -2849,6 +2849,7 @@ find_slave_info (NMDevice *self, NMDevice *slave)
d4f493
 static gboolean
d4f493
 nm_device_master_enslave_slave (NMDevice *self, NMDevice *slave, NMConnection *connection)
d4f493
 {
d4f493
+	NMDevicePrivate *priv;
d4f493
 	SlaveInfo *info;
d4f493
 	gboolean success = FALSE;
d4f493
 	gboolean configure;
d4f493
@@ -2857,6 +2858,7 @@ nm_device_master_enslave_slave (NMDevice *self, NMDevice *slave, NMConnection *c
d4f493
 	g_return_val_if_fail (slave != NULL, FALSE);
d4f493
 	g_return_val_if_fail (NM_DEVICE_GET_CLASS (self)->enslave_slave != NULL, FALSE);
d4f493
 
d4f493
+	priv = NM_DEVICE_GET_PRIVATE (self);
d4f493
 	info = find_slave_info (self, slave);
d4f493
 	if (!info)
d4f493
 		return FALSE;
d4f493
@@ -2879,15 +2881,20 @@ nm_device_master_enslave_slave (NMDevice *self, NMDevice *slave, NMConnection *c
d4f493
 	 */
d4f493
 	nm_device_update_hw_address (self);
d4f493
 
d4f493
+	/* Send ARP announcements if did not yet and have addresses. */
d4f493
+	if (   priv->ip4_state == IP_DONE
d4f493
+	    && !priv->acd.announcing)
d4f493
+		nm_device_arp_announce (self);
d4f493
+
d4f493
 	/* Restart IP configuration if we're waiting for slaves.  Do this
d4f493
 	 * after updating the hardware address as IP config may need the
d4f493
 	 * new address.
d4f493
 	 */
d4f493
 	if (success) {
d4f493
-		if (NM_DEVICE_GET_PRIVATE (self)->ip4_state == IP_WAIT)
d4f493
+		if (priv->ip4_state == IP_WAIT)
d4f493
 			nm_device_activate_stage3_ip4_start (self);
d4f493
 
d4f493
-		if (NM_DEVICE_GET_PRIVATE (self)->ip6_state == IP_WAIT)
d4f493
+		if (priv->ip6_state == IP_WAIT)
d4f493
 			nm_device_activate_stage3_ip6_start (self);
d4f493
 	}
d4f493
 
d4f493
@@ -9795,6 +9802,7 @@ activate_stage5_ip4_config_result (NMDevice *self)
d4f493
 	const char *method;
d4f493
 	NMConnection *connection;
d4f493
 	int ip_ifindex;
d4f493
+	gboolean do_announce = FALSE;
d4f493
 
d4f493
 	req = nm_device_get_act_request (self);
d4f493
 	g_assert (req);
d4f493
@@ -9840,7 +9848,31 @@ activate_stage5_ip4_config_result (NMDevice *self)
d4f493
 		                           NULL, NULL, NULL);
d4f493
 	}
d4f493
 
d4f493
-	nm_device_arp_announce (self);
d4f493
+	/* Send ARP announcements */
d4f493
+
d4f493
+	if (nm_device_is_master (self)) {
d4f493
+		CList *iter;
d4f493
+		SlaveInfo *info;
d4f493
+
d4f493
+		/* Skip announcement if there are no device enslaved, for two reasons:
d4f493
+		 * 1) the master has a temporary MAC address until the first slave comes
d4f493
+		 * 2) announcements are going to be dropped anyway without slaves
d4f493
+		 */
d4f493
+		do_announce = FALSE;
d4f493
+
d4f493
+		c_list_for_each (iter, &priv->slaves) {
d4f493
+			info = c_list_entry (iter, SlaveInfo, lst_slave);
d4f493
+			if (info->slave_is_enslaved) {
d4f493
+				do_announce = TRUE;
d4f493
+				break;
d4f493
+			}
d4f493
+		}
d4f493
+	} else
d4f493
+		do_announce = TRUE;
d4f493
+
d4f493
+	if (do_announce)
d4f493
+		nm_device_arp_announce (self);
d4f493
+
d4f493
 	nm_device_remove_pending_action (self, NM_PENDING_ACTION_DHCP4, FALSE);
d4f493
 
d4f493
 	/* Enter the IP_CHECK state if this is the first method to complete */
d4f493
-- 
d4f493
2.20.1
d4f493