discover/network: Ignore interfaces with pre-existing MAC address
diff mbox

Message ID 20170115235629.4923-1-sam@mendozajonas.com
State Accepted
Headers show

Commit Message

Samuel Mendoza-Jonas Jan. 15, 2017, 11:56 p.m. UTC
Petitboot uses the MAC address of network interfaces as a unique
identifier. This can cause a crash in pb-discover on a machine that has
multiple interfaces with the same MAC address.
While duplicate MAC addresses are rare and imply an issue with the
larger system configuration Petitboot should handle this gracefully, so
log a warning and ignore any interfaces other than the first to appear
that share a MAC address.

Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
---
 discover/network.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

Patch
diff mbox

diff --git a/discover/network.c b/discover/network.c
index 69223b1..8a1e465 100644
--- a/discover/network.c
+++ b/discover/network.c
@@ -214,18 +214,27 @@  static int network_send_link_query(struct network *network)
 	return 0;
 }
 
-static void add_interface(struct network *network,
+static int add_interface(struct network *network,
 		struct interface *interface)
 {
 	char *uuid = mac_bytes_to_string(interface, interface->hwaddr,
 						sizeof(interface->hwaddr));
 
+	if (find_interface_by_uuid(network, uuid)) {
+		pb_log("%s: %s has duplicate MAC address, ignoring (%s)\n",
+		       __func__, interface->name, uuid);
+		talloc_free(uuid);
+		return -1;
+	}
+
 	list_add(&network->interfaces, &interface->list);
 	interface->dev = discover_device_create(network->handler, uuid,
 						interface->name);
 	interface->dev->device->type = DEVICE_TYPE_NETWORK;
 	device_handler_add_device(network->handler, interface->dev);
 	talloc_free(uuid);
+
+	return 0;
 }
 
 static void remove_interface(struct network *network,
@@ -560,7 +569,10 @@  static int network_handle_nlmsg(struct network *network, struct nlmsghdr *nlmsg)
 		interface->state = IFSTATE_NEW;
 		memcpy(interface->hwaddr, ifaddr, sizeof(interface->hwaddr));
 		strncpy(interface->name, ifname, sizeof(interface->name) - 1);
-		add_interface(network, interface);
+		if (add_interface(network, interface)) {
+			talloc_free(interface);
+			return -1;
+		}
 	}
 
 	/* A repeated RTM_NEWLINK can represent an interface name change */