From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:49858) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TXrww-0005gw-KL for qemu-devel@nongnu.org; Mon, 12 Nov 2012 06:13:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TXrwt-0006tM-I9 for qemu-devel@nongnu.org; Mon, 12 Nov 2012 06:13:06 -0500 Received: from mail-ia0-f173.google.com ([209.85.210.173]:34539) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TXrwt-0006tE-DE for qemu-devel@nongnu.org; Mon, 12 Nov 2012 06:13:03 -0500 Received: by mail-ia0-f173.google.com with SMTP id m10so4245832iam.4 for ; Mon, 12 Nov 2012 03:13:02 -0800 (PST) Sender: Lin Ma From: Lin Ma Date: Mon, 12 Nov 2012 19:12:46 +0800 Message-Id: <1352718766-5663-1-git-send-email-lma@suse.com> Subject: [Qemu-devel] [PATCH] add mac address collision checking for device_add & pci_add List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: pbonzini@redhat.com, Lin Ma QEMU doesn't check if there are mac collisions when adding nics. It causes mac address collisions in guest if adding the nics which include existing physical address. This patch fixes the issue. Signed-off-by: Lin Ma --- hw/qdev-properties.c | 9 +++++++++ net.c | 28 ++++++++++++++++++++++++++++ net.h | 1 + 3 files changed, 38 insertions(+) diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c index 8aca0d4..23318af 100644 --- a/hw/qdev-properties.c +++ b/hw/qdev-properties.c @@ -761,6 +761,15 @@ static void set_mac(Object *obj, Visitor *v, void *opaque, } mac->a[i] = strtol(str+pos, &p, 16); } + + if (qemu_check_macaddr_uniqueness(mac->a) < 0) { + goto collision; + } + g_free(str); + return; + +collision: + error_set_from_qdev_prop_error(errp, -EEXIST, dev, prop, str); g_free(str); return; diff --git a/net.c b/net.c index e8ae13e..3077405 100644 --- a/net.c +++ b/net.c @@ -535,6 +535,29 @@ int qemu_find_nic_model(NICInfo *nd, const char * const *models, return -1; } +int qemu_check_macaddr_uniqueness(uint8_t *macaddr) +{ + NetClientState *nc; + uint8_t existing_mac[6]; + char *mac_str; + int i; + + QTAILQ_FOREACH(nc, &net_clients, next) { + if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) { + mac_str = strstr(nc->info_str, "macaddr=") + strlen("macaddr="); + for (i = 0; i < 6; i++) { + existing_mac[i] = strtol(mac_str, (char **)&mac_str, 16); + mac_str++; + } + if (memcmp(macaddr, &existing_mac, sizeof(existing_mac)) == 0) { + return -1; + } + } + } + + return 0; +} + static int net_init_nic(const NetClientOptions *opts, const char *name, NetClientState *peer) { @@ -582,6 +605,11 @@ static int net_init_nic(const NetClientOptions *opts, const char *name, } qemu_macaddr_default_if_unset(&nd->macaddr); + if (qemu_check_macaddr_uniqueness(nd->macaddr.a) < 0) { + error_report("ethernet address collision"); + return -1; + } + if (nic->has_vectors) { if (nic->vectors > 0x7ffffff) { error_report("invalid # of vectors: %"PRIu32, nic->vectors); diff --git a/net.h b/net.h index 04fda1d..227e47d 100644 --- a/net.h +++ b/net.h @@ -99,6 +99,7 @@ int qemu_show_nic_models(const char *arg, const char *const *models); void qemu_check_nic_model(NICInfo *nd, const char *model); int qemu_find_nic_model(NICInfo *nd, const char * const *models, const char *default_model); +int qemu_check_macaddr_uniqueness(uint8_t *macaddr); ssize_t qemu_deliver_packet(NetClientState *sender, unsigned flags, -- 1.7.10.4