@@ -1160,13 +1160,23 @@ static void gem_set_link(NetClientState *nc)
phy_update_link(DO_UPCAST(NICState, nc, nc)->opaque);
}
-static NetClientInfo net_gem_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = gem_can_receive,
- .receive = gem_receive,
- .cleanup = gem_cleanup,
- .link_status_changed = gem_set_link,
+#define TYPE_GEM_NET_CLIENT "gem-net-client"
+
+static void gem_net_client_class_init(ObjectClass *klass, void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->can_receive = gem_can_receive;
+ ncc->receive = gem_receive;
+ ncc->cleanup = gem_cleanup;
+ ncc->link_status_changed = gem_set_link;
+}
+
+static TypeInfo gem_net_client_info = {
+ .name = TYPE_GEM_NET_CLIENT,
+ .parent = TYPE_NIC_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = gem_net_client_class_init,
};
static int gem_init(SysBusDevice *dev)
@@ -1182,7 +1192,7 @@ static int gem_init(SysBusDevice *dev)
sysbus_init_irq(dev, &s->irq);
qemu_macaddr_default_if_unset(&s->conf.macaddr);
- s->nic = qemu_new_nic(&net_gem_info, &s->conf,
+ s->nic = qemu_new_nic(TYPE_GEM_NET_CLIENT, &s->conf,
object_get_typename(OBJECT(dev)), dev->qdev.id, s);
return 0;
@@ -1228,6 +1238,7 @@ static TypeInfo gem_info = {
static void gem_register_types(void)
{
type_register_static(&gem_info);
+ type_register_static(&gem_net_client_info);
}
type_init(gem_register_types)
@@ -172,6 +172,10 @@ typedef struct dp8393xState {
void* mem_opaque;
} dp8393xState;
+static int nic_can_receive(NetClientState *nc);
+static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf,
+ size_t size);
+
static void dp8393x_update_irq(dp8393xState *s)
{
int level = (s->regs[SONIC_IMR] & s->regs[SONIC_ISR]) ? 1 : 0;
@@ -408,9 +412,9 @@ static void do_transmit_packets(dp8393xState *s)
if (s->regs[SONIC_RCR] & (SONIC_RCR_LB1 | SONIC_RCR_LB0)) {
/* Loopback */
s->regs[SONIC_TCR] |= SONIC_TCR_CRSL;
- if (s->nic->nc.info->can_receive(&s->nic->nc)) {
+ if (nic_can_receive(&s->nic->nc)) {
s->loopback_packet = 1;
- s->nic->nc.info->receive(&s->nic->nc, s->tx_buffer, tx_len);
+ nic_receive(&s->nic->nc, s->tx_buffer, tx_len);
}
} else {
/* Transmit packet */
@@ -871,12 +875,23 @@ static void nic_cleanup(NetClientState *nc)
g_free(s);
}
-static NetClientInfo net_dp83932_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = nic_can_receive,
- .receive = nic_receive,
- .cleanup = nic_cleanup,
+#define TYPE_DP83932_NET_CLIENT "dp83932-net-client"
+
+static void dp83932_net_client_class_init(ObjectClass *klass,
+ void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->can_receive = nic_can_receive;
+ ncc->receive = nic_receive;
+ ncc->cleanup = nic_cleanup;
+}
+
+static TypeInfo dp83932_net_client_info = {
+ .name = TYPE_DP83932_NET_CLIENT,
+ .parent = TYPE_NIC_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = dp83932_net_client_class_init,
};
void dp83932_init(NICInfo *nd, target_phys_addr_t base, int it_shift,
@@ -901,7 +916,8 @@ void dp83932_init(NICInfo *nd, target_phys_addr_t base, int it_shift,
s->conf.macaddr = nd->macaddr;
s->conf.peer = nd->netdev;
- s->nic = qemu_new_nic(&net_dp83932_info, &s->conf, nd->model, nd->name, s);
+ s->nic = qemu_new_nic(TYPE_DP83932_NET_CLIENT, &s->conf, nd->model,
+ nd->name, s);
qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
qemu_register_reset(nic_reset, s);
@@ -911,3 +927,10 @@ void dp83932_init(NICInfo *nd, target_phys_addr_t base, int it_shift,
"dp8393x", 0x40 << it_shift);
memory_region_add_subregion(address_space, base, &s->mmio);
}
+
+static void dp83932_register_types(void)
+{
+ type_register_static(&dp83932_net_client_info);
+}
+
+type_init(dp83932_register_types)
@@ -144,6 +144,9 @@ enum {
defreg(VET),
};
+static ssize_t e1000_receive(NetClientState *nc, const uint8_t *buf,
+ size_t size);
+
static void
e1000_link_down(E1000State *s)
{
@@ -446,7 +449,7 @@ static void
e1000_send_packet(E1000State *s, const uint8_t *buf, int size)
{
if (s->phy_reg[PHY_CTRL] & MII_CR_LOOPBACK) {
- s->nic->nc.info->receive(&s->nic->nc, buf, size);
+ e1000_receive(&s->nic->nc, buf, size);
} else {
qemu_send_packet(&s->nic->nc, buf, size);
}
@@ -1205,13 +1208,23 @@ pci_e1000_uninit(PCIDevice *dev)
return 0;
}
-static NetClientInfo net_e1000_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = e1000_can_receive,
- .receive = e1000_receive,
- .cleanup = e1000_cleanup,
- .link_status_changed = e1000_set_link_status,
+#define TYPE_E1000_NET_CLIENT "e1000-net-client"
+
+static void e1000_net_client_class_init(ObjectClass *klass, void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->can_receive = e1000_can_receive;
+ ncc->receive = e1000_receive;
+ ncc->cleanup = e1000_cleanup;
+ ncc->link_status_changed = e1000_set_link_status;
+}
+
+static TypeInfo e1000_net_client_info = {
+ .name = TYPE_E1000_NET_CLIENT,
+ .parent = TYPE_NIC_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = e1000_net_client_class_init,
};
static int pci_e1000_init(PCIDevice *pci_dev)
@@ -1246,7 +1259,7 @@ static int pci_e1000_init(PCIDevice *pci_dev)
checksum = (uint16_t) EEPROM_SUM - checksum;
d->eeprom_data[EEPROM_CHECKSUM_REG] = checksum;
- d->nic = qemu_new_nic(&net_e1000_info, &d->conf,
+ d->nic = qemu_new_nic(TYPE_E1000_NET_CLIENT, &d->conf,
object_get_typename(OBJECT(d)), d->dev.qdev.id, d);
qemu_format_nic_info_str(&d->nic->nc, macaddr);
@@ -1297,6 +1310,7 @@ static TypeInfo e1000_info = {
static void e1000_register_types(void)
{
type_register_static(&e1000_info);
+ type_register_static(&e1000_net_client_info);
}
type_init(e1000_register_types)
@@ -1844,12 +1844,23 @@ static int pci_nic_uninit(PCIDevice *pci_dev)
return 0;
}
-static NetClientInfo net_eepro100_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = nic_can_receive,
- .receive = nic_receive,
- .cleanup = nic_cleanup,
+#define TYPE_EEPRO100_NET_CLIENT "eepro100-net-client"
+
+static void eepro100_net_client_class_init(ObjectClass *klass,
+ void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->can_receive = nic_can_receive;
+ ncc->receive = nic_receive;
+ ncc->cleanup = nic_cleanup;
+}
+
+static TypeInfo eepro100_net_client_info = {
+ .name = TYPE_EEPRO100_NET_CLIENT,
+ .parent = TYPE_NIC_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = eepro100_net_client_class_init,
};
static int e100_nic_init(PCIDevice *pci_dev)
@@ -1884,7 +1895,7 @@ static int e100_nic_init(PCIDevice *pci_dev)
nic_reset(s);
- s->nic = qemu_new_nic(&net_eepro100_info, &s->conf,
+ s->nic = qemu_new_nic(TYPE_EEPRO100_NET_CLIENT, &s->conf,
object_get_typename(OBJECT(pci_dev)), pci_dev->qdev.id, s);
qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
@@ -2102,6 +2113,8 @@ static void eepro100_register_types(void)
type_register(&type_info);
}
+
+ type_register_static(&eepro100_net_client_info);
}
type_init(eepro100_register_types)
@@ -578,13 +578,23 @@ static void eth_cleanup(NetClientState *nc)
g_free(eth);
}
-static NetClientInfo net_etraxfs_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = eth_can_receive,
- .receive = eth_receive,
- .cleanup = eth_cleanup,
- .link_status_changed = eth_set_link,
+#define TYPE_ETRAXFS_NET_CLIENT "etraxfs-net-client"
+
+static void etraxfs_net_client_class_init(ObjectClass *klass, void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->can_receive = eth_can_receive;
+ ncc->receive = eth_receive;
+ ncc->cleanup = eth_cleanup;
+ ncc->link_status_changed = eth_set_link;
+}
+
+static TypeInfo etraxfs_net_client_info = {
+ .name = TYPE_ETRAXFS_NET_CLIENT,
+ .parent = TYPE_NIC_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = etraxfs_net_client_class_init,
};
static int fs_eth_init(SysBusDevice *dev)
@@ -604,7 +614,7 @@ static int fs_eth_init(SysBusDevice *dev)
sysbus_init_mmio(dev, &s->mmio);
qemu_macaddr_default_if_unset(&s->conf.macaddr);
- s->nic = qemu_new_nic(&net_etraxfs_info, &s->conf,
+ s->nic = qemu_new_nic(TYPE_ETRAXFS_NET_CLIENT, &s->conf,
object_get_typename(OBJECT(s)), dev->qdev.id, s);
qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
@@ -640,6 +650,7 @@ static TypeInfo etraxfs_eth_info = {
static void etraxfs_eth_register_types(void)
{
type_register_static(&etraxfs_eth_info);
+ type_register_static(&etraxfs_net_client_info);
}
type_init(etraxfs_eth_register_types)
@@ -1309,13 +1309,23 @@ static void lan9118_cleanup(NetClientState *nc)
s->nic = NULL;
}
-static NetClientInfo net_lan9118_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = lan9118_can_receive,
- .receive = lan9118_receive,
- .cleanup = lan9118_cleanup,
- .link_status_changed = lan9118_set_link,
+#define TYPE_LAN9118_NET_CLIENT "lan9118-net-client"
+
+static void lan9118_net_client_class_init(ObjectClass *klass, void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->can_receive = lan9118_can_receive;
+ ncc->receive = lan9118_receive;
+ ncc->cleanup = lan9118_cleanup;
+ ncc->link_status_changed = lan9118_set_link;
+}
+
+static TypeInfo lan9118_net_client_info = {
+ .name = TYPE_LAN9118_NET_CLIENT,
+ .parent = TYPE_NIC_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = lan9118_net_client_class_init,
};
static int lan9118_init1(SysBusDevice *dev)
@@ -1331,7 +1341,7 @@ static int lan9118_init1(SysBusDevice *dev)
sysbus_init_irq(dev, &s->irq);
qemu_macaddr_default_if_unset(&s->conf.macaddr);
- s->nic = qemu_new_nic(&net_lan9118_info, &s->conf,
+ s->nic = qemu_new_nic(TYPE_LAN9118_NET_CLIENT, &s->conf,
object_get_typename(OBJECT(dev)), dev->qdev.id, s);
qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
s->eeprom[0] = 0xa5;
@@ -1376,6 +1386,7 @@ static TypeInfo lan9118_info = {
static void lan9118_register_types(void)
{
type_register_static(&lan9118_info);
+ type_register_static(&lan9118_net_client_info);
}
/* Legacy helper function. Should go away when machine config files are
@@ -85,22 +85,6 @@ static const MemoryRegionOps lance_mem_ops = {
},
};
-static void lance_cleanup(NetClientState *nc)
-{
- PCNetState *d = DO_UPCAST(NICState, nc, nc)->opaque;
-
- pcnet_common_cleanup(d);
-}
-
-static NetClientInfo net_lance_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = pcnet_can_receive,
- .receive = pcnet_receive,
- .link_status_changed = pcnet_set_link_status,
- .cleanup = lance_cleanup,
-};
-
static const VMStateDescription vmstate_lance = {
.name = "pcnet",
.version_id = 3,
@@ -127,7 +111,7 @@ static int lance_init(SysBusDevice *dev)
s->phys_mem_read = ledma_memory_read;
s->phys_mem_write = ledma_memory_write;
- return pcnet_common_init(&dev->qdev, s, &net_lance_info);
+ return pcnet_common_init(&dev->qdev, s);
}
static void lance_reset(DeviceState *dev)
@@ -449,12 +449,22 @@ static void mcf_fec_cleanup(NetClientState *nc)
g_free(s);
}
-static NetClientInfo net_mcf_fec_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = mcf_fec_can_receive,
- .receive = mcf_fec_receive,
- .cleanup = mcf_fec_cleanup,
+#define TYPE_MCF_FEC_NET_CLIENT "mcf-fec-net-client"
+
+static void mcf_fec_net_client_class_init(ObjectClass *klass, void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->can_receive = mcf_fec_can_receive;
+ ncc->receive = mcf_fec_receive;
+ ncc->cleanup = mcf_fec_cleanup;
+}
+
+static TypeInfo mcf_fec_net_client_info = {
+ .name = TYPE_MCF_FEC_NET_CLIENT,
+ .parent = TYPE_NIC_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = mcf_fec_net_client_class_init,
};
void mcf_fec_init(MemoryRegion *sysmem, NICInfo *nd,
@@ -474,7 +484,15 @@ void mcf_fec_init(MemoryRegion *sysmem, NICInfo *nd,
s->conf.macaddr = nd->macaddr;
s->conf.peer = nd->netdev;
- s->nic = qemu_new_nic(&net_mcf_fec_info, &s->conf, nd->model, nd->name, s);
+ s->nic = qemu_new_nic(TYPE_MCF_FEC_NET_CLIENT, &s->conf, nd->model,
+ nd->name, s);
qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
}
+
+static void mcf_fec_register_types(void)
+{
+ type_register_static(&mcf_fec_net_client_info);
+}
+
+type_init(mcf_fec_register_types)
@@ -447,12 +447,23 @@ static void milkymist_minimac2_reset(DeviceState *d)
s->phy_regs[R_PHY_ID2] = 0x161a;
}
-static NetClientInfo net_milkymist_minimac2_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = minimac2_can_rx,
- .receive = minimac2_rx,
- .cleanup = minimac2_cleanup,
+#define TYPE_MILKYMIST_MINIMAC2_NET_CLIENT "milkymist-minimac2-net-client"
+
+static void milkymist_minimac2_net_client_class_init(ObjectClass *klass,
+ void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->can_receive = minimac2_can_rx;
+ ncc->receive = minimac2_rx;
+ ncc->cleanup = minimac2_cleanup;
+}
+
+static TypeInfo milkymist_minimac2_net_client_info = {
+ .name = TYPE_MILKYMIST_MINIMAC2_NET_CLIENT,
+ .parent = TYPE_NIC_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = milkymist_minimac2_net_client_class_init,
};
static int milkymist_minimac2_init(SysBusDevice *dev)
@@ -478,7 +489,7 @@ static int milkymist_minimac2_init(SysBusDevice *dev)
sysbus_add_memory(dev, s->buffers_base, &s->buffers);
qemu_macaddr_default_if_unset(&s->conf.macaddr);
- s->nic = qemu_new_nic(&net_milkymist_minimac2_info, &s->conf,
+ s->nic = qemu_new_nic(TYPE_MILKYMIST_MINIMAC2_NET_CLIENT, &s->conf,
object_get_typename(OBJECT(dev)), dev->qdev.id, s);
qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
@@ -545,6 +556,7 @@ static TypeInfo milkymist_minimac2_info = {
static void milkymist_minimac2_register_types(void)
{
type_register_static(&milkymist_minimac2_info);
+ type_register_static(&milkymist_minimac2_net_client_info);
}
type_init(milkymist_minimac2_register_types)
@@ -216,12 +216,22 @@ static void mipsnet_cleanup(NetClientState *nc)
s->nic = NULL;
}
-static NetClientInfo net_mipsnet_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = mipsnet_can_receive,
- .receive = mipsnet_receive,
- .cleanup = mipsnet_cleanup,
+#define TYPE_MIPSNET_NET_CLIENT "mipsnet-net-client"
+
+static void mipsnet_net_client_class_init(ObjectClass *klass, void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->can_receive = mipsnet_can_receive;
+ ncc->receive = mipsnet_receive;
+ ncc->cleanup = mipsnet_cleanup;
+}
+
+static TypeInfo mipsnet_net_client_info = {
+ .name = TYPE_MIPSNET_NET_CLIENT,
+ .parent = TYPE_NIC_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = mipsnet_net_client_class_init,
};
static const MemoryRegionOps mipsnet_ioport_ops = {
@@ -239,7 +249,7 @@ static int mipsnet_sysbus_init(SysBusDevice *dev)
sysbus_init_mmio(dev, &s->io);
sysbus_init_irq(dev, &s->irq);
- s->nic = qemu_new_nic(&net_mipsnet_info, &s->conf,
+ s->nic = qemu_new_nic(TYPE_MIPSNET_NET_CLIENT, &s->conf,
object_get_typename(OBJECT(dev)), dev->qdev.id, s);
qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
@@ -279,6 +289,7 @@ static TypeInfo mipsnet_info = {
static void mipsnet_register_types(void)
{
type_register_static(&mipsnet_info);
+ type_register_static(&mipsnet_net_client_info);
}
type_init(mipsnet_register_types)
@@ -373,12 +373,23 @@ static void eth_cleanup(NetClientState *nc)
s->nic = NULL;
}
-static NetClientInfo net_mv88w8618_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = eth_can_receive,
- .receive = eth_receive,
- .cleanup = eth_cleanup,
+#define TYPE_MV88W8618_NET_CLIENT "mv88w8618-net-client"
+
+static void mv88w8618_net_client_class_init(ObjectClass *klass,
+ void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->can_receive = eth_can_receive;
+ ncc->receive = eth_receive;
+ ncc->cleanup = eth_cleanup;
+}
+
+static TypeInfo mv88w8618_net_client_info = {
+ .name = TYPE_MV88W8618_NET_CLIENT,
+ .parent = TYPE_NIC_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = mv88w8618_net_client_class_init,
};
static int mv88w8618_eth_init(SysBusDevice *dev)
@@ -386,7 +397,7 @@ static int mv88w8618_eth_init(SysBusDevice *dev)
mv88w8618_eth_state *s = FROM_SYSBUS(mv88w8618_eth_state, dev);
sysbus_init_irq(dev, &s->irq);
- s->nic = qemu_new_nic(&net_mv88w8618_info, &s->conf,
+ s->nic = qemu_new_nic(TYPE_MV88W8618_NET_CLIENT, &s->conf,
object_get_typename(OBJECT(dev)), dev->qdev.id, s);
memory_region_init_io(&s->iomem, &mv88w8618_eth_ops, s, "mv88w8618-eth",
MP_ETH_SIZE);
@@ -1691,6 +1702,7 @@ static void musicpal_register_types(void)
type_register_static(&musicpal_lcd_info);
type_register_static(&musicpal_gpio_info);
type_register_static(&musicpal_key_info);
+ type_register_static(&mv88w8618_net_client_info);
}
type_init(musicpal_register_types)
@@ -36,21 +36,6 @@ typedef struct ISANE2000State {
NE2000State ne2000;
} ISANE2000State;
-static void isa_ne2000_cleanup(NetClientState *nc)
-{
- NE2000State *s = DO_UPCAST(NICState, nc, nc)->opaque;
-
- s->nic = NULL;
-}
-
-static NetClientInfo net_ne2000_isa_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = ne2000_can_receive,
- .receive = ne2000_receive,
- .cleanup = isa_ne2000_cleanup,
-};
-
static const VMStateDescription vmstate_isa_ne2000 = {
.name = "ne2000",
.version_id = 2,
@@ -75,7 +60,7 @@ static int isa_ne2000_initfn(ISADevice *dev)
qemu_macaddr_default_if_unset(&s->c.macaddr);
ne2000_reset(s);
- s->nic = qemu_new_nic(&net_ne2000_isa_info, &s->c,
+ s->nic = qemu_new_nic(TYPE_NE2000_NET_CLIENT, &s->c,
object_get_typename(OBJECT(dev)), dev->qdev.id, s);
qemu_format_nic_info_str(&s->nic->nc, s->c.macaddr.a);
@@ -710,12 +710,20 @@ static void ne2000_cleanup(NetClientState *nc)
s->nic = NULL;
}
-static NetClientInfo net_ne2000_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = ne2000_can_receive,
- .receive = ne2000_receive,
- .cleanup = ne2000_cleanup,
+static void ne2000_net_client_class_init(ObjectClass *klass, void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->can_receive = ne2000_can_receive;
+ ncc->receive = ne2000_receive;
+ ncc->cleanup = ne2000_cleanup;
+}
+
+static TypeInfo ne2000_net_client_info = {
+ .name = TYPE_NE2000_NET_CLIENT,
+ .parent = TYPE_NIC_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = ne2000_net_client_class_init,
};
static int pci_ne2000_init(PCIDevice *pci_dev)
@@ -735,7 +743,7 @@ static int pci_ne2000_init(PCIDevice *pci_dev)
qemu_macaddr_default_if_unset(&s->c.macaddr);
ne2000_reset(s);
- s->nic = qemu_new_nic(&net_ne2000_info, &s->c,
+ s->nic = qemu_new_nic(TYPE_NE2000_NET_CLIENT, &s->c,
object_get_typename(OBJECT(pci_dev)), pci_dev->qdev.id, s);
qemu_format_nic_info_str(&s->nic->nc, s->c.macaddr.a);
@@ -784,6 +792,7 @@ static TypeInfo ne2000_info = {
static void ne2000_register_types(void)
{
type_register_static(&ne2000_info);
+ type_register_static(&ne2000_net_client_info);
}
type_init(ne2000_register_types)
@@ -28,6 +28,8 @@ typedef struct NE2000State {
uint8_t mem[NE2000_MEM_SIZE];
} NE2000State;
+#define TYPE_NE2000_NET_CLIENT "ne2000-net-client"
+
void ne2000_setup_io(NE2000State *s, unsigned size);
extern const VMStateDescription vmstate_ne2000;
void ne2000_reset(NE2000State *s);
@@ -466,13 +466,24 @@ static void open_eth_cleanup(NetClientState *nc)
{
}
-static NetClientInfo net_open_eth_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = open_eth_can_receive,
- .receive = open_eth_receive,
- .cleanup = open_eth_cleanup,
- .link_status_changed = open_eth_set_link_status,
+#define TYPE_OPEN_ETH_NET_CLIENT "open-eth-net-client"
+
+static void open_eth_net_client_class_init(ObjectClass *klass,
+ void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->can_receive = open_eth_can_receive;
+ ncc->receive = open_eth_receive;
+ ncc->cleanup = open_eth_cleanup;
+ ncc->link_status_changed = open_eth_set_link_status;
+}
+
+static TypeInfo open_eth_net_client_info = {
+ .name = TYPE_OPEN_ETH_NET_CLIENT,
+ .parent = TYPE_NIC_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = open_eth_net_client_class_init,
};
static void open_eth_start_xmit(OpenEthState *s, desc *tx)
@@ -691,7 +702,7 @@ static int sysbus_open_eth_init(SysBusDevice *dev)
sysbus_init_irq(dev, &s->irq);
- s->nic = qemu_new_nic(&net_open_eth_info, &s->conf,
+ s->nic = qemu_new_nic(TYPE_OPEN_ETH_NET_CLIENT, &s->conf,
object_get_typename(OBJECT(s)), s->dev.qdev.id, s);
return 0;
}
@@ -728,6 +739,7 @@ static TypeInfo open_eth_info = {
static void open_eth_register_types(void)
{
type_register_static(&open_eth_info);
+ type_register_static(&open_eth_net_client_info);
}
type_init(open_eth_register_types)
@@ -264,13 +264,6 @@ static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr,
pci_dma_read(dma_opaque, addr, buf, len);
}
-static void pci_pcnet_cleanup(NetClientState *nc)
-{
- PCNetState *d = DO_UPCAST(NICState, nc, nc)->opaque;
-
- pcnet_common_cleanup(d);
-}
-
static int pci_pcnet_uninit(PCIDevice *dev)
{
PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, dev);
@@ -283,15 +276,6 @@ static int pci_pcnet_uninit(PCIDevice *dev)
return 0;
}
-static NetClientInfo net_pci_pcnet_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = pcnet_can_receive,
- .receive = pcnet_receive,
- .link_status_changed = pcnet_set_link_status,
- .cleanup = pci_pcnet_cleanup,
-};
-
static int pci_pcnet_init(PCIDevice *pci_dev)
{
PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, pci_dev);
@@ -330,7 +314,7 @@ static int pci_pcnet_init(PCIDevice *pci_dev)
s->phys_mem_write = pci_physical_memory_write;
s->dma_opaque = pci_dev;
- return pcnet_common_init(&pci_dev->qdev, s, &net_pci_pcnet_info);
+ return pcnet_common_init(&pci_dev->qdev, s);
}
static void pci_reset(DeviceState *dev)
@@ -1716,12 +1716,34 @@ const VMStateDescription vmstate_pcnet = {
}
};
-void pcnet_common_cleanup(PCNetState *d)
+static void pcnet_common_cleanup(NetClientState *nc)
{
+ NICState *nic = DO_UPCAST(NICState, nc, nc);
+ PCNetState *d = nic->opaque;
+
d->nic = NULL;
}
-int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info)
+#define TYPE_PCNET_NET_CLIENT "pcnet-net-client"
+
+static void pcnet_net_client_class_init(ObjectClass *klass, void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->can_receive = pcnet_can_receive;
+ ncc->receive = pcnet_receive;
+ ncc->link_status_changed = pcnet_set_link_status;
+ ncc->cleanup = pcnet_common_cleanup;
+}
+
+static TypeInfo pcnet_net_client_info = {
+ .name = TYPE_PCNET_NET_CLIENT,
+ .parent = TYPE_NIC_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = pcnet_net_client_class_init,
+};
+
+int pcnet_common_init(DeviceState *dev, PCNetState *s)
{
int i;
uint16_t checksum;
@@ -1729,7 +1751,8 @@ int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info)
s->poll_timer = qemu_new_timer_ns(vm_clock, pcnet_poll_timer, s);
qemu_macaddr_default_if_unset(&s->conf.macaddr);
- s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)), dev->id, s);
+ s->nic = qemu_new_nic(TYPE_PCNET_NET_CLIENT, &s->conf,
+ object_get_typename(OBJECT(dev)), dev->id, s);
qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
add_boot_device_path(s->conf.bootindex, dev, "/ethernet-phy@0");
@@ -1765,3 +1788,10 @@ int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info)
return 0;
}
+
+static void pcnet_register_types(void)
+{
+ type_register_static(&pcnet_net_client_info);
+}
+
+type_init(pcnet_register_types)
@@ -60,6 +60,5 @@ uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap);
int pcnet_can_receive(NetClientState *nc);
ssize_t pcnet_receive(NetClientState *nc, const uint8_t *buf, size_t size_);
void pcnet_set_link_status(NetClientState *nc);
-void pcnet_common_cleanup(PCNetState *d);
-int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info);
+int pcnet_common_init(DeviceState *dev, PCNetState *s);
extern const VMStateDescription vmstate_pcnet;
@@ -3452,12 +3452,23 @@ static int pci_rtl8139_uninit(PCIDevice *dev)
return 0;
}
-static NetClientInfo net_rtl8139_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = rtl8139_can_receive,
- .receive = rtl8139_receive,
- .cleanup = rtl8139_cleanup,
+#define TYPE_RTL8139_NET_CLIENT "rtl8139-net-client"
+
+static void rtl8139_net_client_class_init(ObjectClass *klass,
+ void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->can_receive = rtl8139_can_receive;
+ ncc->receive = rtl8139_receive;
+ ncc->cleanup = rtl8139_cleanup;
+}
+
+static TypeInfo rtl8139_net_client_info = {
+ .name = TYPE_RTL8139_NET_CLIENT,
+ .parent = TYPE_NIC_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = rtl8139_net_client_class_init,
};
static int pci_rtl8139_init(PCIDevice *dev)
@@ -3489,7 +3500,7 @@ static int pci_rtl8139_init(PCIDevice *dev)
s->eeprom.contents[8] = s->conf.macaddr.a[2] | s->conf.macaddr.a[3] << 8;
s->eeprom.contents[9] = s->conf.macaddr.a[4] | s->conf.macaddr.a[5] << 8;
- s->nic = qemu_new_nic(&net_rtl8139_info, &s->conf,
+ s->nic = qemu_new_nic(TYPE_RTL8139_NET_CLIENT, &s->conf,
object_get_typename(OBJECT(dev)), dev->qdev.id, s);
qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
@@ -3538,6 +3549,7 @@ static TypeInfo rtl8139_info = {
static void rtl8139_register_types(void)
{
type_register_static(&rtl8139_info);
+ type_register_static(&rtl8139_net_client_info);
}
type_init(rtl8139_register_types)
@@ -735,12 +735,23 @@ static void smc91c111_cleanup(NetClientState *nc)
s->nic = NULL;
}
-static NetClientInfo net_smc91c111_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = smc91c111_can_receive,
- .receive = smc91c111_receive,
- .cleanup = smc91c111_cleanup,
+#define TYPE_SMC91C111_NET_CLIENT "smc91c111-net-client"
+
+static void smc91c111_net_client_class_init(ObjectClass *klass,
+ void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->can_receive = smc91c111_can_receive;
+ ncc->receive = smc91c111_receive;
+ ncc->cleanup = smc91c111_cleanup;
+}
+
+static TypeInfo smc91c111_net_client_info = {
+ .name = TYPE_SMC91C111_NET_CLIENT,
+ .parent = TYPE_NIC_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = smc91c111_net_client_class_init,
};
static int smc91c111_init1(SysBusDevice *dev)
@@ -751,7 +762,7 @@ static int smc91c111_init1(SysBusDevice *dev)
sysbus_init_mmio(dev, &s->mmio);
sysbus_init_irq(dev, &s->irq);
qemu_macaddr_default_if_unset(&s->conf.macaddr);
- s->nic = qemu_new_nic(&net_smc91c111_info, &s->conf,
+ s->nic = qemu_new_nic(TYPE_SMC91C111_NET_CLIENT, &s->conf,
object_get_typename(OBJECT(dev)), dev->qdev.id, s);
qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
/* ??? Save/restore. */
@@ -784,6 +795,7 @@ static TypeInfo smc91c111_info = {
static void smc91c111_register_types(void)
{
type_register_static(&smc91c111_info);
+ type_register_static(&smc91c111_net_client_info);
}
/* Legacy helper function. Should go away when machine config files are
@@ -175,11 +175,22 @@ static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf,
return size;
}
-static NetClientInfo net_spapr_vlan_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = spapr_vlan_can_receive,
- .receive = spapr_vlan_receive,
+#define TYPE_SPAPR_VLAN_NET_CLIENT "spapr-vlan-net-client"
+
+static void spapr_vlan_net_client_class_init(ObjectClass *klass,
+ void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->can_receive = spapr_vlan_can_receive;
+ ncc->receive = spapr_vlan_receive;
+}
+
+static TypeInfo spapr_vlan_net_client_info = {
+ .name = TYPE_SPAPR_VLAN_NET_CLIENT,
+ .parent = TYPE_NIC_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = spapr_vlan_net_client_class_init,
};
static void spapr_vlan_reset(VIOsPAPRDevice *sdev)
@@ -197,7 +208,7 @@ static int spapr_vlan_init(VIOsPAPRDevice *sdev)
qemu_macaddr_default_if_unset(&dev->nicconf.macaddr);
- dev->nic = qemu_new_nic(&net_spapr_vlan_info, &dev->nicconf,
+ dev->nic = qemu_new_nic(TYPE_SPAPR_VLAN_NET_CLIENT, &dev->nicconf,
object_get_typename(OBJECT(sdev)), sdev->qdev.id, dev);
qemu_format_nic_info_str(&dev->nic->nc, dev->nicconf.macaddr.a);
@@ -515,6 +526,7 @@ static void spapr_vlan_register_types(void)
h_add_logical_lan_buffer);
spapr_register_hypercall(H_MULTICAST_CTRL, h_multicast_ctrl);
type_register_static(&spapr_vlan_info);
+ type_register_static(&spapr_vlan_net_client_info);
}
type_init(spapr_vlan_register_types)
@@ -392,12 +392,23 @@ static void stellaris_enet_cleanup(NetClientState *nc)
g_free(s);
}
-static NetClientInfo net_stellaris_enet_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = stellaris_enet_can_receive,
- .receive = stellaris_enet_receive,
- .cleanup = stellaris_enet_cleanup,
+#define TYPE_STELLARIS_ENET_NET_CLIENT "stellaris-enet-net-client"
+
+static void stellaris_enet_net_client_class_init(ObjectClass *klass,
+ void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->can_receive = stellaris_enet_can_receive;
+ ncc->receive = stellaris_enet_receive;
+ ncc->cleanup = stellaris_enet_cleanup;
+}
+
+static TypeInfo stellaris_enet_net_client_info = {
+ .name = TYPE_STELLARIS_ENET_NET_CLIENT,
+ .parent = TYPE_NIC_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = stellaris_enet_net_client_class_init,
};
static int stellaris_enet_init(SysBusDevice *dev)
@@ -410,7 +421,7 @@ static int stellaris_enet_init(SysBusDevice *dev)
sysbus_init_irq(dev, &s->irq);
qemu_macaddr_default_if_unset(&s->conf.macaddr);
- s->nic = qemu_new_nic(&net_stellaris_enet_info, &s->conf,
+ s->nic = qemu_new_nic(TYPE_STELLARIS_ENET_NET_CLIENT, &s->conf,
object_get_typename(OBJECT(dev)), dev->qdev.id, s);
qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
@@ -444,6 +455,7 @@ static TypeInfo stellaris_enet_info = {
static void stellaris_enet_register_types(void)
{
type_register_static(&stellaris_enet_info);
+ type_register_static(&stellaris_enet_net_client_info);
}
type_init(stellaris_enet_register_types)
@@ -1312,12 +1312,22 @@ static void usb_net_handle_destroy(USBDevice *dev)
qemu_del_net_client(&s->nic->nc);
}
-static NetClientInfo net_usbnet_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = usbnet_can_receive,
- .receive = usbnet_receive,
- .cleanup = usbnet_cleanup,
+#define TYPE_USB_NET_CLIENT "usb-net-client"
+
+static void usb_net_client_class_init(ObjectClass *klass, void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->can_receive = usbnet_can_receive;
+ ncc->receive = usbnet_receive;
+ ncc->cleanup = usbnet_cleanup;
+}
+
+static TypeInfo usb_net_client_info = {
+ .name = TYPE_USB_NET_CLIENT,
+ .parent = TYPE_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = usb_net_client_class_init,
};
static int usb_net_initfn(USBDevice *dev)
@@ -1337,7 +1347,7 @@ static int usb_net_initfn(USBDevice *dev)
s->vendorid = 0x1234;
qemu_macaddr_default_if_unset(&s->conf.macaddr);
- s->nic = qemu_new_nic(&net_usbnet_info, &s->conf,
+ s->nic = qemu_new_nic(TYPE_USB_NET_CLIENT, &s->conf,
object_get_typename(OBJECT(s)), s->dev.qdev.id, s);
qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
snprintf(s->usbstring_mac, sizeof(s->usbstring_mac),
@@ -1422,6 +1432,7 @@ static void usb_net_register_types(void)
{
type_register_static(&net_info);
usb_legacy_register("usb-net", "net", usb_net_init);
+ type_register_static(&usb_net_client_info);
}
type_init(usb_net_register_types)
@@ -988,13 +988,23 @@ static void virtio_net_cleanup(NetClientState *nc)
n->nic = NULL;
}
-static NetClientInfo net_virtio_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = virtio_net_can_receive,
- .receive = virtio_net_receive,
- .cleanup = virtio_net_cleanup,
- .link_status_changed = virtio_net_set_link_status,
+#define TYPE_VIRTIO_NET_CLIENT "virtio-net-client"
+
+static void virtio_net_client_class_init(ObjectClass *klass, void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->can_receive = virtio_net_can_receive;
+ ncc->receive = virtio_net_receive;
+ ncc->cleanup = virtio_net_cleanup;
+ ncc->link_status_changed = virtio_net_set_link_status;
+}
+
+static TypeInfo virtio_net_client_info = {
+ .name = TYPE_VIRTIO_NET_CLIENT,
+ .parent = TYPE_NIC_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = virtio_net_client_class_init,
};
VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf,
@@ -1035,7 +1045,8 @@ VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf,
memcpy(&n->mac[0], &conf->macaddr, sizeof(n->mac));
n->status = VIRTIO_NET_S_LINK_UP;
- n->nic = qemu_new_nic(&net_virtio_info, conf, object_get_typename(OBJECT(dev)), dev->id, n);
+ n->nic = qemu_new_nic(TYPE_VIRTIO_NET_CLIENT, conf,
+ object_get_typename(OBJECT(dev)), dev->id, n);
qemu_format_nic_info_str(&n->nic->nc, conf->macaddr.a);
@@ -1081,3 +1092,10 @@ void virtio_net_exit(VirtIODevice *vdev)
qemu_del_net_client(&n->nic->nc);
virtio_cleanup(&n->vdev);
}
+
+static void virtio_net_register_types(void)
+{
+ type_register_static(&virtio_net_client_info);
+}
+
+type_init(virtio_net_register_types)
@@ -303,11 +303,21 @@ static ssize_t net_rx_packet(NetClientState *nc, const uint8_t *buf, size_t size
/* ------------------------------------------------------------- */
-static NetClientInfo net_xen_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = net_rx_ok,
- .receive = net_rx_packet,
+#define TYPE_XEN_NET_CLIENT "xen-net-client"
+
+static void xen_net_client_class_init(ObjectClass *klass, void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->can_receive = net_rx_ok;
+ ncc->receive = net_rx_packet;
+}
+
+static TypeInfo xen_net_client_info = {
+ .name = TYPE_XEN_NET_CLIENT,
+ .parent = TYPE_NIC_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = xen_net_client_class_init,
};
static int net_init(struct XenDevice *xendev)
@@ -330,7 +340,7 @@ static int net_init(struct XenDevice *xendev)
netdev->conf.peer = NULL;
- netdev->nic = qemu_new_nic(&net_xen_info, &netdev->conf,
+ netdev->nic = qemu_new_nic(TYPE_XEN_NET_CLIENT, &netdev->conf,
"xen", NULL, netdev);
snprintf(netdev->nic->nc.info_str, sizeof(netdev->nic->nc.info_str),
@@ -439,3 +449,10 @@ struct XenDevOps xen_netdev_ops = {
.disconnect = net_disconnect,
.free = net_free,
};
+
+static void xen_net_register_types(void)
+{
+ type_register_static(&xen_net_client_info);
+}
+
+type_init(xen_net_register_types)
@@ -370,12 +370,23 @@ static void eth_cleanup(NetClientState *nc)
s->nic = NULL;
}
-static NetClientInfo net_xgmac_enet_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = eth_can_rx,
- .receive = eth_rx,
- .cleanup = eth_cleanup,
+#define TYPE_XGMAC_ENET_NET_CLIENT "xgmac-enet-net-client"
+
+static void xgmac_enet_net_client_class_init(ObjectClass *klass,
+ void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->can_receive = eth_can_rx;
+ ncc->receive = eth_rx;
+ ncc->cleanup = eth_cleanup;
+}
+
+static TypeInfo xgmac_enet_net_client_info = {
+ .name = TYPE_XGMAC_ENET_NET_CLIENT,
+ .parent = TYPE_NIC_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = xgmac_enet_net_client_class_init,
};
static int xgmac_enet_init(SysBusDevice *dev)
@@ -389,7 +400,7 @@ static int xgmac_enet_init(SysBusDevice *dev)
sysbus_init_irq(dev, &s->mci_irq);
qemu_macaddr_default_if_unset(&s->conf.macaddr);
- s->nic = qemu_new_nic(&net_xgmac_enet_info, &s->conf,
+ s->nic = qemu_new_nic(TYPE_XGMAC_ENET_NET_CLIENT, &s->conf,
object_get_typename(OBJECT(dev)), dev->qdev.id, s);
qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
@@ -428,6 +439,7 @@ static TypeInfo xgmac_enet_info = {
static void xgmac_enet_register_types(void)
{
type_register_static(&xgmac_enet_info);
+ type_register_static(&xgmac_enet_net_client_info);
}
type_init(xgmac_enet_register_types)
@@ -831,12 +831,23 @@ axienet_stream_push(void *opaque, uint8_t *buf, size_t size, uint32_t *hdr)
enet_update_irq(s);
}
-static NetClientInfo net_xilinx_enet_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = eth_can_rx,
- .receive = eth_rx,
- .cleanup = eth_cleanup,
+#define TYPE_XILINX_AXI_NET_CLIENT "xilinx-axi-net-client"
+
+static void xilinx_axi_net_client_class_init(ObjectClass *klass,
+ void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->can_receive = eth_can_rx;
+ ncc->receive = eth_rx;
+ ncc->cleanup = eth_cleanup;
+}
+
+static TypeInfo xilinx_axi_net_client_info = {
+ .name = TYPE_XILINX_AXI_NET_CLIENT,
+ .parent = TYPE_NIC_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = xilinx_axi_net_client_class_init,
};
static int xilinx_enet_init(SysBusDevice *dev)
@@ -855,7 +866,7 @@ static int xilinx_enet_init(SysBusDevice *dev)
sysbus_init_mmio(dev, &s->iomem);
qemu_macaddr_default_if_unset(&s->conf.macaddr);
- s->nic = qemu_new_nic(&net_xilinx_enet_info, &s->conf,
+ s->nic = qemu_new_nic(TYPE_XILINX_AXI_NET_CLIENT, &s->conf,
object_get_typename(OBJECT(dev)), dev->qdev.id, s);
qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
@@ -898,6 +909,7 @@ static TypeInfo xilinx_enet_info = {
static void xilinx_enet_register_types(void)
{
type_register_static(&xilinx_enet_info);
+ type_register_static(&xilinx_axi_net_client_info);
}
type_init(xilinx_enet_register_types)
@@ -201,12 +201,23 @@ static void eth_cleanup(NetClientState *nc)
s->nic = NULL;
}
-static NetClientInfo net_xilinx_ethlite_info = {
- .type = NET_CLIENT_TYPE_NIC,
- .size = sizeof(NICState),
- .can_receive = eth_can_rx,
- .receive = eth_rx,
- .cleanup = eth_cleanup,
+#define TYPE_XILINX_ETHLITE_NET_CLIENT "xilinx-ethlite-net-client"
+
+static void xilinx_ethlite_net_client_class_init(ObjectClass *klass,
+ void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->can_receive = eth_can_rx;
+ ncc->receive = eth_rx;
+ ncc->cleanup = eth_cleanup;
+}
+
+static TypeInfo xilinx_ethlite_net_client_info = {
+ .name = TYPE_XILINX_ETHLITE_NET_CLIENT,
+ .parent = TYPE_NIC_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = xilinx_ethlite_net_client_class_init,
};
static int xilinx_ethlite_init(SysBusDevice *dev)
@@ -221,7 +232,7 @@ static int xilinx_ethlite_init(SysBusDevice *dev)
sysbus_init_mmio(dev, &s->mmio);
qemu_macaddr_default_if_unset(&s->conf.macaddr);
- s->nic = qemu_new_nic(&net_xilinx_ethlite_info, &s->conf,
+ s->nic = qemu_new_nic(TYPE_XILINX_ETHLITE_NET_CLIENT, &s->conf,
object_get_typename(OBJECT(dev)), dev->qdev.id, s);
qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
return 0;
@@ -253,6 +264,7 @@ static TypeInfo xilinx_ethlite_info = {
static void xilinx_ethlite_register_types(void)
{
type_register_static(&xilinx_ethlite_info);
+ type_register_static(&xilinx_ethlite_net_client_info);
}
type_init(xilinx_ethlite_register_types)
@@ -155,8 +155,10 @@ void qemu_macaddr_default_if_unset(MACAddr *macaddr)
static void notify_link_status_changed(NetClientState *nc)
{
- if (nc->info->link_status_changed) {
- nc->info->link_status_changed(nc);
+ NetClientClass *klass = NET_CLIENT_GET_CLASS(nc);
+
+ if (klass->link_status_changed) {
+ klass->link_status_changed(nc);
}
}
@@ -188,18 +190,15 @@ static char *assign_name(NetClientState *nc1, const char *model)
return g_strdup(buf);
}
-NetClientState *qemu_new_net_client(NetClientInfo *info,
+NetClientState *qemu_new_net_client(const char *typename,
NetClientState *peer,
const char *model,
const char *name)
{
NetClientState *nc;
- assert(info->size >= sizeof(NetClientState));
-
- nc = g_malloc0(info->size);
+ nc = NET_CLIENT(object_new(typename));
- nc->info = info;
nc->model = g_strdup(model);
if (name) {
nc->name = g_strdup(name);
@@ -219,7 +218,7 @@ NetClientState *qemu_new_net_client(NetClientInfo *info,
return nc;
}
-NICState *qemu_new_nic(NetClientInfo *info,
+NICState *qemu_new_nic(const char *typename,
NICConf *conf,
const char *model,
const char *name,
@@ -228,12 +227,9 @@ NICState *qemu_new_nic(NetClientInfo *info,
NetClientState *nc;
NICState *nic;
- assert(info->type == NET_CLIENT_TYPE_NIC);
- assert(info->size >= sizeof(NICState));
-
- nc = qemu_new_net_client(info, conf->peer, model, name);
+ nc = qemu_new_net_client(typename, conf->peer, model, name);
- nic = DO_UPCAST(NICState, nc, nc);
+ nic = NIC_NET_CLIENT(nc);
nic->conf = conf;
nic->opaque = opaque;
@@ -242,10 +238,12 @@ NICState *qemu_new_nic(NetClientInfo *info,
static void qemu_cleanup_net_client(NetClientState *nc)
{
+ NetClientClass *klass = NET_CLIENT_GET_CLASS(nc);
+
QTAILQ_REMOVE(&net_clients, nc, next);
- if (nc->info->cleanup) {
- nc->info->cleanup(nc);
+ if (klass->cleanup) {
+ klass->cleanup(nc);
}
}
@@ -259,14 +257,15 @@ static void qemu_free_net_client(NetClientState *nc)
}
g_free(nc->name);
g_free(nc->model);
- g_free(nc);
+ object_delete(OBJECT(nc));
}
void qemu_del_net_client(NetClientState *nc)
{
/* If there is a peer NIC, delete and cleanup client, but do not free. */
- if (nc->peer && nc->peer->info->type == NET_CLIENT_TYPE_NIC) {
- NICState *nic = DO_UPCAST(NICState, nc, nc->peer);
+ if (nc->peer && object_dynamic_cast(OBJECT(nc->peer),
+ TYPE_NIC_NET_CLIENT)) {
+ NICState *nic = NIC_NET_CLIENT(nc->peer);
if (nic->peer_deleted) {
return;
}
@@ -279,8 +278,8 @@ void qemu_del_net_client(NetClientState *nc)
}
/* If this is a peer NIC and peer has already been deleted, free it now. */
- if (nc->peer && nc->info->type == NET_CLIENT_TYPE_NIC) {
- NICState *nic = DO_UPCAST(NICState, nc, nc);
+ if (nc->peer && object_dynamic_cast(OBJECT(nc), TYPE_NIC_NET_CLIENT)) {
+ NICState *nic = NIC_NET_CLIENT(nc);
if (nic->peer_deleted) {
qemu_free_net_client(nc->peer);
}
@@ -295,22 +294,26 @@ void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)
NetClientState *nc;
QTAILQ_FOREACH(nc, &net_clients, next) {
- if (nc->info->type == NET_CLIENT_TYPE_NIC) {
- func(DO_UPCAST(NICState, nc, nc), opaque);
+ if (object_dynamic_cast(OBJECT(nc), TYPE_NIC_NET_CLIENT)) {
+ func(NIC_NET_CLIENT(nc), opaque);
}
}
}
int qemu_can_send_packet(NetClientState *sender)
{
+ NetClientClass *klass;
+
if (!sender->peer) {
return 1;
}
if (sender->peer->receive_disabled) {
return 0;
- } else if (sender->peer->info->can_receive &&
- !sender->peer->info->can_receive(sender->peer)) {
+ }
+
+ klass = NET_CLIENT_GET_CLASS(sender->peer);
+ if (klass->can_receive && !klass->can_receive(sender->peer)) {
return 0;
}
return 1;
@@ -323,6 +326,7 @@ ssize_t qemu_deliver_packet(NetClientState *sender,
void *opaque)
{
NetClientState *nc = opaque;
+ NetClientClass *klass;
ssize_t ret;
if (nc->link_down) {
@@ -333,10 +337,11 @@ ssize_t qemu_deliver_packet(NetClientState *sender,
return 0;
}
- if (flags & QEMU_NET_PACKET_FLAG_RAW && nc->info->receive_raw) {
- ret = nc->info->receive_raw(nc, data, size);
+ klass = NET_CLIENT_GET_CLASS(nc);
+ if (flags & QEMU_NET_PACKET_FLAG_RAW && klass->receive_raw) {
+ ret = klass->receive_raw(nc, data, size);
} else {
- ret = nc->info->receive(nc, data, size);
+ ret = klass->receive(nc, data, size);
}
if (ret == 0) {
@@ -405,12 +410,13 @@ ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size)
static ssize_t nc_sendv_compat(NetClientState *nc, const struct iovec *iov,
int iovcnt)
{
+ NetClientClass *klass = NET_CLIENT_GET_CLASS(nc);
uint8_t buffer[4096];
size_t offset;
offset = iov_to_buf(iov, iovcnt, buffer, 0, sizeof(buffer));
- return nc->info->receive(nc, buffer, offset);
+ return klass->receive(nc, buffer, offset);
}
ssize_t qemu_deliver_packet_iov(NetClientState *sender,
@@ -420,13 +426,14 @@ ssize_t qemu_deliver_packet_iov(NetClientState *sender,
void *opaque)
{
NetClientState *nc = opaque;
+ NetClientClass *klass = NET_CLIENT_GET_CLASS(nc);
if (nc->link_down) {
return iov_size(iov, iovcnt);
}
- if (nc->info->receive_iov) {
- return nc->info->receive_iov(nc, iov, iovcnt);
+ if (klass->receive_iov) {
+ return klass->receive_iov(nc, iov, iovcnt);
} else {
return nc_sendv_compat(nc, iov, iovcnt);
}
@@ -457,8 +464,10 @@ qemu_sendv_packet(NetClientState *nc, const struct iovec *iov, int iovcnt)
void qemu_net_poll(NetClientState *nc, bool enable)
{
- if (nc->info->poll) {
- nc->info->poll(nc, enable);
+ NetClientClass *klass = NET_CLIENT_CLASS(nc);
+
+ if (klass->poll) {
+ klass->poll(nc, enable);
}
}
@@ -467,8 +476,9 @@ NetClientState *qemu_find_netdev(const char *id)
NetClientState *nc;
QTAILQ_FOREACH(nc, &net_clients, next) {
- if (nc->info->type == NET_CLIENT_TYPE_NIC)
+ if (object_dynamic_cast(OBJECT(nc), TYPE_NIC_NET_CLIENT)) {
continue;
+ }
if (!strcmp(nc->name, id)) {
return nc;
}
@@ -1088,29 +1098,29 @@ void qmp_netdev_del(const char *id, Error **errp)
void print_net_client(Monitor *mon, NetClientState *vc)
{
+ NetClientClass *klass = NET_CLIENT_GET_CLASS(vc);
+
monitor_printf(mon, "%s: type=%s,%s\n", vc->name,
- net_client_types[vc->info->type].type, vc->info_str);
+ klass->type_str, vc->info_str);
}
void do_info_network(Monitor *mon)
{
NetClientState *nc, *peer;
- net_client_type type;
net_hub_info(mon);
QTAILQ_FOREACH(nc, &net_clients, next) {
peer = nc->peer;
- type = nc->info->type;
if (net_hub_port_peer_nc(nc)) {
continue;
}
- if (!peer || type == NET_CLIENT_TYPE_NIC) {
+ if (!peer || object_dynamic_cast(OBJECT(nc), TYPE_NIC_NET_CLIENT)) {
print_net_client(mon, nc);
} /* else it's a netdev connected to a NIC, printed with the NIC */
- if (peer && type == NET_CLIENT_TYPE_NIC) {
+ if (peer && object_dynamic_cast(OBJECT(nc), TYPE_NIC_NET_CLIENT)) {
monitor_printf(mon, " \\ ");
print_net_client(mon, peer);
}
@@ -1179,7 +1189,8 @@ void net_check_clients(void)
QTAILQ_FOREACH(nc, &net_clients, next) {
if (!nc->peer) {
fprintf(stderr, "Warning: %s %s has no peer\n",
- nc->info->type == NET_CLIENT_TYPE_NIC ? "nic" : "netdev",
+ object_dynamic_cast(OBJECT(nc),
+ TYPE_NIC_NET_CLIENT) ? "nic" : "netdev",
nc->name);
}
}
@@ -1291,3 +1302,34 @@ unsigned compute_mcast_idx(const uint8_t *ep)
}
return crc >> 26;
}
+
+static TypeInfo net_client_info = {
+ .name = TYPE_NET_CLIENT,
+ .parent = TYPE_OBJECT,
+ .instance_size = sizeof(NetClientState),
+ .class_size = sizeof(NetClientClass),
+ .abstract = true,
+};
+
+static void nic_net_client_class_init(ObjectClass *klass, void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->type_str = "nic";
+}
+
+static TypeInfo nic_net_client_info = {
+ .name = TYPE_NIC_NET_CLIENT,
+ .parent = TYPE_NET_CLIENT,
+ .instance_size = sizeof(NICState),
+ .class_init = nic_net_client_class_init,
+ .abstract = true,
+};
+
+static void net_client_register_types(void)
+{
+ type_register_static(&net_client_info);
+ type_register_static(&nic_net_client_info);
+}
+
+type_init(net_client_register_types)
@@ -1,6 +1,7 @@
#ifndef QEMU_NET_H
#define QEMU_NET_H
+#include "qemu/object.h"
#include "qemu-queue.h"
#include "qemu-common.h"
#include "qdict.h"
@@ -42,6 +43,14 @@ typedef enum {
NET_CLIENT_TYPE_MAX
} net_client_type;
+#define TYPE_NET_CLIENT "net-client"
+#define NET_CLIENT_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(NetClientClass, obj, TYPE_NET_CLIENT)
+#define NET_CLIENT_CLASS(klass) \
+ OBJECT_CLASS_CHECK(NetClientClass, klass, TYPE_NET_CLIENT)
+#define NET_CLIENT(obj) \
+ OBJECT_CHECK(NetClientState, obj, TYPE_NET_CLIENT)
+
typedef void (NetPoll)(NetClientState *, bool enable);
typedef int (NetCanReceive)(NetClientState *);
typedef ssize_t (NetReceive)(NetClientState *, const uint8_t *, size_t);
@@ -49,9 +58,10 @@ typedef ssize_t (NetReceiveIOV)(NetClientState *, const struct iovec *, int);
typedef void (NetCleanup) (NetClientState *);
typedef void (LinkStatusChanged)(NetClientState *);
-typedef struct NetClientInfo {
- net_client_type type;
- size_t size;
+typedef struct NetClientClass {
+ ObjectClass parent;
+
+ const char *type_str; /* human-readable name for "info network" */
NetReceive *receive;
NetReceive *receive_raw;
NetReceiveIOV *receive_iov;
@@ -59,10 +69,11 @@ typedef struct NetClientInfo {
NetCleanup *cleanup;
LinkStatusChanged *link_status_changed;
NetPoll *poll;
-} NetClientInfo;
+} NetClientClass;
+
+typedef struct NetClientState {
+ Object parent;
-struct NetClientState {
- NetClientInfo *info;
int link_down;
QTAILQ_ENTRY(NetClientState) next;
NetClientState *peer;
@@ -71,7 +82,11 @@ struct NetClientState {
char *name;
char info_str[256];
unsigned receive_disabled : 1;
-};
+} NetClientState;
+
+#define TYPE_NIC_NET_CLIENT "nic-net-client"
+#define NIC_NET_CLIENT(obj) \
+ OBJECT_CHECK(NICState, obj, TYPE_NIC_NET_CLIENT)
typedef struct NICState {
NetClientState nc;
@@ -81,11 +96,11 @@ typedef struct NICState {
} NICState;
NetClientState *qemu_find_netdev(const char *id);
-NetClientState *qemu_new_net_client(NetClientInfo *info,
+NetClientState *qemu_new_net_client(const char *typename,
NetClientState *peer,
const char *model,
const char *name);
-NICState *qemu_new_nic(NetClientInfo *info,
+NICState *qemu_new_nic(const char *typename,
NICConf *conf,
const char *model,
const char *name,
@@ -93,11 +93,22 @@ static void dump_cleanup(NetClientState *nc)
close(s->fd);
}
-static NetClientInfo net_dump_info = {
- .type = NET_CLIENT_TYPE_DUMP,
- .size = sizeof(DumpState),
- .receive = dump_receive,
- .cleanup = dump_cleanup,
+#define TYPE_DUMP_NET_CLIENT "dump-net-client"
+
+static void net_dump_class_init(ObjectClass *klass, void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->type_str = "dump",
+ ncc->receive = dump_receive;
+ ncc->cleanup = dump_cleanup;
+}
+
+static TypeInfo net_dump_info = {
+ .name = TYPE_DUMP_NET_CLIENT,
+ .parent = TYPE_NET_CLIENT,
+ .instance_size = sizeof(DumpState),
+ .class_init = net_dump_class_init,
};
static int net_dump_init(NetClientState *peer, const char *device,
@@ -129,7 +140,7 @@ static int net_dump_init(NetClientState *peer, const char *device,
return -1;
}
- nc = qemu_new_net_client(&net_dump_info, peer, device, name);
+ nc = qemu_new_net_client(TYPE_DUMP_NET_CLIENT, peer, device, name);
snprintf(nc->info_str, sizeof(nc->info_str),
"dump to %s (len=%d)", filename, len);
@@ -169,3 +180,10 @@ int net_init_dump(QemuOpts *opts, const char *name, NetClientState *peer)
return net_dump_init(peer, "dump", name, file, len);
}
+
+static void net_dump_register_types(void)
+{
+ type_register_static(&net_dump_info);
+}
+
+type_init(net_dump_register_types)
@@ -128,13 +128,27 @@ static void net_hub_port_cleanup(NetClientState *nc)
QLIST_REMOVE(port, next);
}
-static NetClientInfo net_hub_port_info = {
- .type = NET_CLIENT_TYPE_HUB,
- .size = sizeof(NetHubPort),
- .can_receive = net_hub_port_can_receive,
- .receive = net_hub_port_receive,
- .receive_iov = net_hub_port_receive_iov,
- .cleanup = net_hub_port_cleanup,
+#define TYPE_HUB_PORT_NET_CLIENT "hub-port-net-client"
+#define HUB_PORT(obj) \
+ OBJECT_CHECK(NetHubPort, obj, TYPE_HUB_PORT_NET_CLIENT)
+
+static void net_hub_port_net_client_class_init(ObjectClass *klass,
+ void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->type_str = "hubport",
+ ncc->can_receive = net_hub_port_can_receive;
+ ncc->receive = net_hub_port_receive;
+ ncc->receive_iov = net_hub_port_receive_iov;
+ ncc->cleanup = net_hub_port_cleanup;
+}
+
+static TypeInfo hub_port_net_client_info = {
+ .name = TYPE_HUB_PORT_NET_CLIENT,
+ .parent = TYPE_NET_CLIENT,
+ .instance_size = sizeof(NetHubPort),
+ .class_init = net_hub_port_net_client_class_init,
};
static NetHubPort *net_hub_port_new(NetHub *hub)
@@ -146,8 +160,8 @@ static NetHubPort *net_hub_port_new(NetHub *hub)
snprintf(name, sizeof name, "hub%uport%u", hub->id, id);
- nc = qemu_new_net_client(&net_hub_port_info, NULL, "hub", name);
- port = DO_UPCAST(NetHubPort, nc, nc);
+ nc = qemu_new_net_client(TYPE_HUB_PORT_NET_CLIENT, NULL, "hub", name);
+ port = HUB_PORT(nc);
port->id = id;
port->hub = hub;
@@ -309,18 +323,10 @@ void net_hub_check_clients(void)
continue;
}
- switch (peer->info->type) {
- case NET_CLIENT_TYPE_NIC:
+ if (object_dynamic_cast(OBJECT(peer), TYPE_NIC_NET_CLIENT)) {
has_nic = 1;
- break;
- case NET_CLIENT_TYPE_USER:
- case NET_CLIENT_TYPE_TAP:
- case NET_CLIENT_TYPE_SOCKET:
- case NET_CLIENT_TYPE_VDE:
+ } else {
has_host_dev = 1;
- break;
- default:
- break;
}
}
if (has_host_dev && !has_nic) {
@@ -333,3 +339,10 @@ void net_hub_check_clients(void)
}
}
}
+
+static void net_hub_register_types(void)
+{
+ type_register_static(&hub_port_net_client_info);
+}
+
+type_init(net_hub_register_types)
@@ -121,11 +121,22 @@ static void net_slirp_cleanup(NetClientState *nc)
QTAILQ_REMOVE(&slirp_stacks, s, entry);
}
-static NetClientInfo net_slirp_info = {
- .type = NET_CLIENT_TYPE_USER,
- .size = sizeof(SlirpState),
- .receive = net_slirp_receive,
- .cleanup = net_slirp_cleanup,
+#define TYPE_SLIRP_NET_CLIENT "slirp-net-client"
+
+static void net_slirp_class_init(ObjectClass *klass, void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->type_str = "user";
+ ncc->receive = net_slirp_receive;
+ ncc->cleanup = net_slirp_cleanup;
+}
+
+static TypeInfo net_slirp_info = {
+ .name = TYPE_SLIRP_NET_CLIENT,
+ .parent = TYPE_NET_CLIENT,
+ .instance_size = sizeof(SlirpState),
+ .class_init = net_slirp_class_init,
};
static int net_slirp_init(NetClientState *peer, const char *model,
@@ -231,7 +242,7 @@ static int net_slirp_init(NetClientState *peer, const char *model,
}
#endif
- nc = qemu_new_net_client(&net_slirp_info, peer, model, name);
+ nc = qemu_new_net_client(TYPE_SLIRP_NET_CLIENT, peer, model, name);
snprintf(nc->info_str, sizeof(nc->info_str),
"net=%s,restrict=%s", inet_ntoa(net),
@@ -768,3 +779,9 @@ int net_slirp_parse_legacy(QemuOptsList *opts_list, const char *optarg, int *ret
return 1;
}
+static void net_slirp_register_types(void)
+{
+ type_register_static(&net_slirp_info);
+}
+
+type_init(net_slirp_register_types)
@@ -33,6 +33,10 @@
#include "qemu-option.h"
#include "qemu_socket.h"
+#define TYPE_SOCKET_NET_CLIENT "socket-net-client"
+#define SOCKET_NET_CLIENT(obj) \
+ OBJECT_CHECK(NetSocketState, obj, TYPE_SOCKET_NET_CLIENT)
+
typedef struct NetSocketState {
NetClientState nc;
int listen_fd;
@@ -42,6 +46,7 @@ typedef struct NetSocketState {
unsigned int packet_len;
uint8_t buf[4096];
struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
+ bool is_dgram;
} NetSocketState;
static void net_socket_accept(void *opaque);
@@ -49,20 +54,17 @@ static void net_socket_accept(void *opaque);
/* XXX: we consider we can send the whole packet without blocking */
static ssize_t net_socket_receive(NetClientState *nc, const uint8_t *buf, size_t size)
{
- NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
- uint32_t len;
- len = htonl(size);
-
- send_all(s->fd, (const uint8_t *)&len, sizeof(len));
- return send_all(s->fd, buf, size);
-}
+ NetSocketState *s = SOCKET_NET_CLIENT(nc);
-static ssize_t net_socket_receive_dgram(NetClientState *nc, const uint8_t *buf, size_t size)
-{
- NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
+ if (s->is_dgram) {
+ return sendto(s->fd, (const void *)buf, size, 0,
+ (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
+ } else {
+ uint32_t len = htonl(size);
- return sendto(s->fd, (const void *)buf, size, 0,
- (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
+ send_all(s->fd, (const uint8_t *)&len, sizeof(len));
+ return send_all(s->fd, buf, size);
+ }
}
static void net_socket_send(void *opaque)
@@ -241,7 +243,7 @@ fail:
static void net_socket_cleanup(NetClientState *nc)
{
- NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
+ NetSocketState *s = SOCKET_NET_CLIENT(nc);
if (s->fd != -1) {
qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
close(s->fd);
@@ -254,13 +256,6 @@ static void net_socket_cleanup(NetClientState *nc)
}
}
-static NetClientInfo net_dgram_socket_info = {
- .type = NET_CLIENT_TYPE_SOCKET,
- .size = sizeof(NetSocketState),
- .receive = net_socket_receive_dgram,
- .cleanup = net_socket_cleanup,
-};
-
static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
const char *model,
const char *name,
@@ -303,17 +298,18 @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
}
}
- nc = qemu_new_net_client(&net_dgram_socket_info, peer, model, name);
+ nc = qemu_new_net_client(TYPE_SOCKET_NET_CLIENT, peer, model, name);
snprintf(nc->info_str, sizeof(nc->info_str),
"socket: fd=%d (%s mcast=%s:%d)",
fd, is_connected ? "cloned" : "",
inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
- s = DO_UPCAST(NetSocketState, nc, nc);
+ s = SOCKET_NET_CLIENT(nc);
s->fd = fd;
s->listen_fd = -1;
+ s->is_dgram = true;
qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
@@ -335,13 +331,6 @@ static void net_socket_connect(void *opaque)
qemu_set_fd_handler(s->fd, net_socket_send, NULL, s);
}
-static NetClientInfo net_socket_info = {
- .type = NET_CLIENT_TYPE_SOCKET,
- .size = sizeof(NetSocketState),
- .receive = net_socket_receive,
- .cleanup = net_socket_cleanup,
-};
-
static NetSocketState *net_socket_fd_init_stream(NetClientState *peer,
const char *model,
const char *name,
@@ -350,11 +339,11 @@ static NetSocketState *net_socket_fd_init_stream(NetClientState *peer,
NetClientState *nc;
NetSocketState *s;
- nc = qemu_new_net_client(&net_socket_info, peer, model, name);
+ nc = qemu_new_net_client(TYPE_SOCKET_NET_CLIENT, peer, model, name);
snprintf(nc->info_str, sizeof(nc->info_str), "socket: fd=%d", fd);
- s = DO_UPCAST(NetSocketState, nc, nc);
+ s = SOCKET_NET_CLIENT(nc);
s->fd = fd;
s->listen_fd = -1;
@@ -456,8 +445,8 @@ static int net_socket_listen_init(NetClientState *peer,
return -1;
}
- nc = qemu_new_net_client(&net_socket_info, peer, model, name);
- s = DO_UPCAST(NetSocketState, nc, nc);
+ nc = qemu_new_net_client(TYPE_SOCKET_NET_CLIENT, peer, model, name);
+ s = SOCKET_NET_CLIENT(nc);
s->fd = -1;
s->listen_fd = fd;
s->nc.link_down = true;
@@ -546,6 +535,7 @@ static int net_socket_mcast_init(NetClientState *peer,
if (!s)
return -1;
+ s->is_dgram = true;
s->dgram_dst = saddr;
snprintf(s->nc.info_str, sizeof(s->nc.info_str),
@@ -598,6 +588,7 @@ static int net_socket_udp_init(NetClientState *peer,
return -1;
}
+ s->is_dgram = true;
s->dgram_dst = raddr;
snprintf(s->nc.info_str, sizeof(s->nc.info_str),
@@ -706,3 +697,26 @@ int net_init_socket(QemuOpts *opts, const char *name, NetClientState *peer)
}
return 0;
}
+
+static void net_socket_class_init(ObjectClass *klass, void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->type_str = "socket";
+ ncc->receive = net_socket_receive;
+ ncc->cleanup = net_socket_cleanup;
+}
+
+static TypeInfo net_socket_info = {
+ .name = TYPE_SOCKET_NET_CLIENT,
+ .parent = TYPE_NET_CLIENT,
+ .instance_size = sizeof(NetSocketState),
+ .class_init = net_socket_class_init,
+};
+
+static void net_socket_register_types(void)
+{
+ type_register_static(&net_socket_info);
+}
+
+type_init(net_socket_register_types)
@@ -666,11 +666,23 @@ static void tap_win32_send(void *opaque)
}
}
-static NetClientInfo net_tap_win32_info = {
- .type = NET_CLIENT_TYPE_TAP,
- .size = sizeof(TAPState),
- .receive = tap_receive,
- .cleanup = tap_cleanup,
+#define TYPE_TAP_WIN32_NET_CLIENT "tap-win32-net-client"
+
+static void tap_win32_net_client_class_init(ObjectClass *klass,
+ void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->type_str = "tap";
+ ncc->receive = tap_receive;
+ ncc->cleanup = tap_cleanup;
+}
+
+static TypeInfo tap_win32_net_client_info = {
+ .name = TYPE_TAP_WIN32_NET_CLIENT,
+ .parent = TYPE_NET_CLIENT,
+ .instance_size = sizeof(TAPState),
+ .class_init = tap_win32_net_client_class_init,
};
static int tap_win32_init(NetClientState *peer, const char *model,
@@ -749,3 +761,10 @@ struct vhost_net *tap_get_vhost_net(NetClientState *nc)
{
return NULL;
}
+
+static void tap_win32_register_types(void)
+{
+ type_register_static(&tap_win32_net_client_info);
+}
+
+type_init(tap_win32_register_types)
@@ -49,6 +49,10 @@
*/
#define TAP_BUFSIZE (4096 + 65536)
+#define TYPE_TAP_NET_CLIENT "tap-net-client"
+#define TAP_NET_CLIENT(obj) \
+ OBJECT_CHECK(TAPState, obj, TYPE_TAP_NET_CLIENT)
+
typedef struct TAPState {
NetClientState nc;
int fd;
@@ -118,7 +122,7 @@ static ssize_t tap_write_packet(TAPState *s, const struct iovec *iov, int iovcnt
static ssize_t tap_receive_iov(NetClientState *nc, const struct iovec *iov,
int iovcnt)
{
- TAPState *s = DO_UPCAST(TAPState, nc, nc);
+ TAPState *s = TAP_NET_CLIENT(nc);
const struct iovec *iovp = iov;
struct iovec iov_copy[iovcnt + 1];
struct virtio_net_hdr_mrg_rxbuf hdr = { };
@@ -136,7 +140,7 @@ static ssize_t tap_receive_iov(NetClientState *nc, const struct iovec *iov,
static ssize_t tap_receive_raw(NetClientState *nc, const uint8_t *buf, size_t size)
{
- TAPState *s = DO_UPCAST(TAPState, nc, nc);
+ TAPState *s = TAP_NET_CLIENT(nc);
struct iovec iov[2];
int iovcnt = 0;
struct virtio_net_hdr_mrg_rxbuf hdr = { };
@@ -156,7 +160,7 @@ static ssize_t tap_receive_raw(NetClientState *nc, const uint8_t *buf, size_t si
static ssize_t tap_receive(NetClientState *nc, const uint8_t *buf, size_t size)
{
- TAPState *s = DO_UPCAST(TAPState, nc, nc);
+ TAPState *s = TAP_NET_CLIENT(nc);
struct iovec iov[1];
if (s->host_vnet_hdr_len && !s->using_vnet_hdr) {
@@ -185,7 +189,7 @@ ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen)
static void tap_send_completed(NetClientState *nc, ssize_t len)
{
- TAPState *s = DO_UPCAST(TAPState, nc, nc);
+ TAPState *s = TAP_NET_CLIENT(nc);
tap_read_poll(s, 1);
}
@@ -216,36 +220,29 @@ static void tap_send(void *opaque)
int tap_has_ufo(NetClientState *nc)
{
- TAPState *s = DO_UPCAST(TAPState, nc, nc);
-
- assert(nc->info->type == NET_CLIENT_TYPE_TAP);
+ TAPState *s = TAP_NET_CLIENT(nc);
return s->has_ufo;
}
int tap_has_vnet_hdr(NetClientState *nc)
{
- TAPState *s = DO_UPCAST(TAPState, nc, nc);
-
- assert(nc->info->type == NET_CLIENT_TYPE_TAP);
+ TAPState *s = TAP_NET_CLIENT(nc);
return !!s->host_vnet_hdr_len;
}
int tap_has_vnet_hdr_len(NetClientState *nc, int len)
{
- TAPState *s = DO_UPCAST(TAPState, nc, nc);
-
- assert(nc->info->type == NET_CLIENT_TYPE_TAP);
+ TAPState *s = TAP_NET_CLIENT(nc);
return tap_probe_vnet_hdr_len(s->fd, len);
}
void tap_set_vnet_hdr_len(NetClientState *nc, int len)
{
- TAPState *s = DO_UPCAST(TAPState, nc, nc);
+ TAPState *s = TAP_NET_CLIENT(nc);
- assert(nc->info->type == NET_CLIENT_TYPE_TAP);
assert(len == sizeof(struct virtio_net_hdr_mrg_rxbuf) ||
len == sizeof(struct virtio_net_hdr));
@@ -255,11 +252,10 @@ void tap_set_vnet_hdr_len(NetClientState *nc, int len)
void tap_using_vnet_hdr(NetClientState *nc, int using_vnet_hdr)
{
- TAPState *s = DO_UPCAST(TAPState, nc, nc);
+ TAPState *s = TAP_NET_CLIENT(nc);
using_vnet_hdr = using_vnet_hdr != 0;
- assert(nc->info->type == NET_CLIENT_TYPE_TAP);
assert(!!s->host_vnet_hdr_len == using_vnet_hdr);
s->using_vnet_hdr = using_vnet_hdr;
@@ -268,7 +264,7 @@ void tap_using_vnet_hdr(NetClientState *nc, int using_vnet_hdr)
void tap_set_offload(NetClientState *nc, int csum, int tso4,
int tso6, int ecn, int ufo)
{
- TAPState *s = DO_UPCAST(TAPState, nc, nc);
+ TAPState *s = TAP_NET_CLIENT(nc);
if (s->fd < 0) {
return;
}
@@ -278,7 +274,7 @@ void tap_set_offload(NetClientState *nc, int csum, int tso4,
static void tap_cleanup(NetClientState *nc)
{
- TAPState *s = DO_UPCAST(TAPState, nc, nc);
+ TAPState *s = TAP_NET_CLIENT(nc);
if (s->vhost_net) {
vhost_net_cleanup(s->vhost_net);
@@ -298,33 +294,41 @@ static void tap_cleanup(NetClientState *nc)
static void tap_poll(NetClientState *nc, bool enable)
{
- TAPState *s = DO_UPCAST(TAPState, nc, nc);
+ TAPState *s = TAP_NET_CLIENT(nc);
tap_read_poll(s, enable);
tap_write_poll(s, enable);
}
bool net_is_tap_client(NetClientState *nc)
{
- return nc->info->type == NET_CLIENT_TYPE_TAP;
+ return object_dynamic_cast(OBJECT(nc), TYPE_TAP_NET_CLIENT);
}
int tap_get_fd(NetClientState *nc)
{
- TAPState *s = DO_UPCAST(TAPState, nc, nc);
- assert(nc->info->type == NET_CLIENT_TYPE_TAP);
+ TAPState *s = TAP_NET_CLIENT(nc);
return s->fd;
}
/* fd support */
-static NetClientInfo net_tap_info = {
- .type = NET_CLIENT_TYPE_TAP,
- .size = sizeof(TAPState),
- .receive = tap_receive,
- .receive_raw = tap_receive_raw,
- .receive_iov = tap_receive_iov,
- .poll = tap_poll,
- .cleanup = tap_cleanup,
+static void tap_net_client_class_init(ObjectClass *klass, void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->type_str = "tap";
+ ncc->receive = tap_receive;
+ ncc->receive_raw = tap_receive_raw;
+ ncc->receive_iov = tap_receive_iov;
+ ncc->poll = tap_poll;
+ ncc->cleanup = tap_cleanup;
+}
+
+static TypeInfo tap_net_client_info = {
+ .name = TYPE_TAP_NET_CLIENT,
+ .parent = TYPE_NET_CLIENT,
+ .instance_size = sizeof(TAPState),
+ .class_init = tap_net_client_class_init,
};
static TAPState *net_tap_fd_init(NetClientState *peer,
@@ -336,9 +340,9 @@ static TAPState *net_tap_fd_init(NetClientState *peer,
NetClientState *nc;
TAPState *s;
- nc = qemu_new_net_client(&net_tap_info, peer, model, name);
+ nc = qemu_new_net_client(TYPE_TAP_NET_CLIENT, peer, model, name);
- s = DO_UPCAST(TAPState, nc, nc);
+ s = TAP_NET_CLIENT(nc);
s->fd = fd;
s->host_vnet_hdr_len = vnet_hdr ? sizeof(struct virtio_net_hdr) : 0;
@@ -715,7 +719,13 @@ int net_init_tap(QemuOpts *opts, const char *name, NetClientState *peer)
VHostNetState *tap_get_vhost_net(NetClientState *nc)
{
- TAPState *s = DO_UPCAST(TAPState, nc, nc);
- assert(nc->info->type == NET_CLIENT_TYPE_TAP);
+ TAPState *s = TAP_NET_CLIENT(nc);
return s->vhost_net;
}
+
+static void tap_register_types(void)
+{
+ type_register_static(&tap_net_client_info);
+}
+
+type_init(tap_register_types)
@@ -68,11 +68,22 @@ static void vde_cleanup(NetClientState *nc)
vde_close(s->vde);
}
-static NetClientInfo net_vde_info = {
- .type = NET_CLIENT_TYPE_VDE,
- .size = sizeof(VDEState),
- .receive = vde_receive,
- .cleanup = vde_cleanup,
+#define TYPE_VDE_NET_CLIENT "vde-net-client"
+
+static void vde_net_client_class_init(ObjectClass *klass, void *class_data)
+{
+ NetClientClass *ncc = NET_CLIENT_CLASS(klass);
+
+ ncc->type_str = "vde";
+ ncc->receive = vde_receive;
+ ncc->cleanup = vde_cleanup;
+}
+
+static TypeInfo vde_net_client_info = {
+ .name = TYPE_VDE_NET_CLIENT,
+ .parent = TYPE_NET_CLIENT,
+ .instance_size = sizeof(VDEState),
+ .class_init = vde_net_client_class_init,
};
static int net_vde_init(NetClientState *peer, const char *model,
@@ -128,3 +139,10 @@ int net_init_vde(QemuOpts *opts, const char *name, NetClientState *peer)
return 0;
}
+
+static void vde_register_types(void)
+{
+ type_register_static(&vde_net_client_info);
+}
+
+type_init(vde_register_types)