mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-09-06 18:05:37 +00:00
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: Shannon Zhao <zhaoshenglong@huawei.com> Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
a308817743
commit
2bc22a58e1
57
net/net.c
57
net/net.c
|
@ -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++) {
|
||||
|
|
Loading…
Reference in a new issue