Commit 2bc22a58 authored by Shannon Zhao's avatar Shannon Zhao Committed by Stefan Hajnoczi
Browse files

net/net: Record usage status of mac address



Currently QEMU dynamically generates mac address for the NIC which
doesn't specify the mac address. But when we hotplug a NIC without
specifying mac address, the mac address will increase for the same NIC
along with hotplug and hot-unplug, and at last it will overflow. And if
we codeplug one NIC with mac address e.g. "52:54:00:12:34:56", then
hotplug one NIC without specifying mac address and the mac address of
the hotplugged NIC is duplicate of "52:54:00:12:34:56".

This patch add a mac_table to record the usage status and free the mac
address when the NIC is unrealized.

Signed-off-by: default avatarShannon Zhao <zhaoshenglong@huawei.com>
Signed-off-by: default avatarShannon Zhao <shannon.zhao@linaro.org>
Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
parent a3088177
Loading
Loading
Loading
Loading
+55 −4
Original line number Diff line number Diff line
@@ -167,19 +167,68 @@ void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6])
             macaddr[3], macaddr[4], macaddr[5]);
}

static int mac_table[256] = {0};

static void qemu_macaddr_set_used(MACAddr *macaddr)
{
    int index;

    for (index = 0x56; index < 0xFF; index++) {
        if (macaddr->a[5] == index) {
            mac_table[index]++;
        }
    }
}

static void qemu_macaddr_set_free(MACAddr *macaddr)
{
    int index;
    static const MACAddr base = { .a = { 0x52, 0x54, 0x00, 0x12, 0x34, 0 } };

    if (memcmp(macaddr->a, &base.a, (sizeof(base.a) - 1)) != 0) {
        return;
    }
    for (index = 0x56; index < 0xFF; index++) {
        if (macaddr->a[5] == index) {
            mac_table[index]--;
        }
    }
}

static int qemu_macaddr_get_free(void)
{
    int index;

    for (index = 0x56; index < 0xFF; index++) {
        if (mac_table[index] == 0) {
            return index;
        }
    }

    return -1;
}

void qemu_macaddr_default_if_unset(MACAddr *macaddr)
{
    static int index = 0;
    static const MACAddr zero = { .a = { 0,0,0,0,0,0 } };
    static const MACAddr base = { .a = { 0x52, 0x54, 0x00, 0x12, 0x34, 0 } };

    if (memcmp(macaddr, &zero, sizeof(zero)) != 0)
    if (memcmp(macaddr, &zero, sizeof(zero)) != 0) {
        if (memcmp(macaddr->a, &base.a, (sizeof(base.a) - 1)) != 0) {
            return;
        } else {
            qemu_macaddr_set_used(macaddr);
            return;
        }
    }

    macaddr->a[0] = 0x52;
    macaddr->a[1] = 0x54;
    macaddr->a[2] = 0x00;
    macaddr->a[3] = 0x12;
    macaddr->a[4] = 0x34;
    macaddr->a[5] = 0x56 + index++;
    macaddr->a[5] = qemu_macaddr_get_free();
    qemu_macaddr_set_used(macaddr);
}

/**
@@ -374,6 +423,8 @@ void qemu_del_nic(NICState *nic)
{
    int i, queues = MAX(nic->conf->peers.queues, 1);

    qemu_macaddr_set_free(&nic->conf->macaddr);

    /* If this is a peer NIC and peer has already been deleted, free it now. */
    if (nic->peer_deleted) {
        for (i = 0; i < queues; i++) {