From patchwork Mon Nov 12 11:12:46 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lin Ma X-Patchwork-Id: 198364 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id D771E2C0087 for ; Mon, 12 Nov 2012 22:13:18 +1100 (EST) Received: from localhost ([::1]:51712 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TXrx6-0005hm-7Y for incoming@patchwork.ozlabs.org; Mon, 12 Nov 2012 06:13:16 -0500 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) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer; bh=Y+UuGrsj9qJ3EUryz9TJ9z3cYY3JfmUlWMU0kR7H0GM=; b=T2lVCllqfRlBmhlP0Ijztr4jYbUvvRXIF1j0XSdW8BHa24CrwR4z6A2xJRVZpqTOpt 3vZXlkWHpy3UFIBBzyHoxYnZIpsk8yRZmMayWZvTmxEXPJ9CYUQoE86KYV1cwOyE/Cku RoAM0DESG6dj9Jp0DqIEYpAe/ZAmelwhv1x7QT2IAG98tzVgG25+hZPG78pp2h3dQuJN +vOay5dX5ZWXQGb+1oUUzjzkQYypGhbi153HxLhjhzQUPTi75Vtvwt7JXnHnvByBZtNr cGdNGJyxeE/nx9F/k4PDzuy3D+pM6WCtHtsQZ7d0EKVhpARyCFTJgnVNDbvvZ8d8/8e4 KsKw== Received: by 10.50.183.200 with SMTP id eo8mr7655055igc.54.1352718782607; Mon, 12 Nov 2012 03:13:02 -0800 (PST) Received: from a480.apac.novell.com ([222.126.194.154]) by mx.google.com with ESMTPS id 10sm7910930ign.5.2012.11.12.03.12.59 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 12 Nov 2012 03:13:01 -0800 (PST) From: Lin Ma To: qemu-devel@nongnu.org Date: Mon, 12 Nov 2012 19:12:46 +0800 Message-Id: <1352718766-5663-1-git-send-email-lma@suse.com> X-Mailer: git-send-email 1.7.10.4 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 209.85.210.173 Cc: pbonzini@redhat.com, Lin Ma Subject: [Qemu-devel] [PATCH] add mac address collision checking for device_add & pci_add X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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,