mirror of https://github.com/xemu-project/xemu.git
Merge remote-tracking branch 'stefanha/net' into staging
* stefanha/net: net: add the support for -netdev socket, listen net: fix the coding style hub: add the support for hub own flow control net: determine if packets can be sent before net queue deliver packets net: cleanup deliver/deliver_iov func pointers net: Make "info network" output more readable info net: Rename qemu_del_vlan_client() to qemu_del_net_client() net: Rename vc local variables to nc net: Rename VLANClientState to NetClientState net: Rename non_vlan_clients to net_clients net: Remove VLANState net: Remove vlan code from net.c net: Convert qdev_prop_vlan to peer with hub net: Drop vlan argument to qemu_new_net_client() hub: Check that hubs are configured correctly net: Look up 'vlan' net clients using hubs net: Use hubs for the vlan feature net: Add a hub net client net: Add interface to bridge when SIOCBRADDIF isn't available
This commit is contained in:
commit
f57fb88436
|
@ -405,7 +405,7 @@ static void phy_update_link(GemState *s)
|
|||
}
|
||||
}
|
||||
|
||||
static int gem_can_receive(VLANClientState *nc)
|
||||
static int gem_can_receive(NetClientState *nc)
|
||||
{
|
||||
GemState *s;
|
||||
|
||||
|
@ -602,7 +602,7 @@ static int gem_mac_address_filter(GemState *s, const uint8_t *packet)
|
|||
* gem_receive:
|
||||
* Fit a packet handed to us by QEMU into the receive descriptor ring.
|
||||
*/
|
||||
static ssize_t gem_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
unsigned desc[2];
|
||||
target_phys_addr_t packet_desc_addr, last_desc_addr;
|
||||
|
@ -1146,7 +1146,7 @@ static const MemoryRegionOps gem_ops = {
|
|||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
static void gem_cleanup(VLANClientState *nc)
|
||||
static void gem_cleanup(NetClientState *nc)
|
||||
{
|
||||
GemState *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -1154,7 +1154,7 @@ static void gem_cleanup(VLANClientState *nc)
|
|||
s->nic = NULL;
|
||||
}
|
||||
|
||||
static void gem_set_link(VLANClientState *nc)
|
||||
static void gem_set_link(NetClientState *nc)
|
||||
{
|
||||
DB_PRINT("\n");
|
||||
phy_update_link(DO_UPCAST(NICState, nc, nc)->opaque);
|
||||
|
|
|
@ -673,7 +673,7 @@ static const MemoryRegionOps dp8393x_ops = {
|
|||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
static int nic_can_receive(VLANClientState *nc)
|
||||
static int nic_can_receive(NetClientState *nc)
|
||||
{
|
||||
dp8393xState *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -722,7 +722,7 @@ static int receive_filter(dp8393xState *s, const uint8_t * buf, int size)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static ssize_t nic_receive(VLANClientState *nc, const uint8_t * buf, size_t size)
|
||||
static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size)
|
||||
{
|
||||
dp8393xState *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
uint16_t data[10];
|
||||
|
@ -858,7 +858,7 @@ static void nic_reset(void *opaque)
|
|||
dp8393x_update_irq(s);
|
||||
}
|
||||
|
||||
static void nic_cleanup(VLANClientState *nc)
|
||||
static void nic_cleanup(NetClientState *nc)
|
||||
{
|
||||
dp8393xState *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -899,7 +899,6 @@ void dp83932_init(NICInfo *nd, target_phys_addr_t base, int it_shift,
|
|||
s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */
|
||||
|
||||
s->conf.macaddr = nd->macaddr;
|
||||
s->conf.vlan = nd->vlan;
|
||||
s->conf.peer = nd->netdev;
|
||||
|
||||
s->nic = qemu_new_nic(&net_dp83932_info, &s->conf, nd->model, nd->name, s);
|
||||
|
|
10
hw/e1000.c
10
hw/e1000.c
|
@ -720,7 +720,7 @@ receive_filter(E1000State *s, const uint8_t *buf, int size)
|
|||
}
|
||||
|
||||
static void
|
||||
e1000_set_link_status(VLANClientState *nc)
|
||||
e1000_set_link_status(NetClientState *nc)
|
||||
{
|
||||
E1000State *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
uint32_t old_status = s->mac_reg[STATUS];
|
||||
|
@ -754,7 +754,7 @@ static bool e1000_has_rxbufs(E1000State *s, size_t total_size)
|
|||
}
|
||||
|
||||
static int
|
||||
e1000_can_receive(VLANClientState *nc)
|
||||
e1000_can_receive(NetClientState *nc)
|
||||
{
|
||||
E1000State *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -770,7 +770,7 @@ static uint64_t rx_desc_base(E1000State *s)
|
|||
}
|
||||
|
||||
static ssize_t
|
||||
e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
e1000_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
E1000State *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
struct e1000_rx_desc desc;
|
||||
|
@ -1185,7 +1185,7 @@ e1000_mmio_setup(E1000State *d)
|
|||
}
|
||||
|
||||
static void
|
||||
e1000_cleanup(VLANClientState *nc)
|
||||
e1000_cleanup(NetClientState *nc)
|
||||
{
|
||||
E1000State *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -1201,7 +1201,7 @@ pci_e1000_uninit(PCIDevice *dev)
|
|||
qemu_free_timer(d->autoneg_timer);
|
||||
memory_region_destroy(&d->mmio);
|
||||
memory_region_destroy(&d->io);
|
||||
qemu_del_vlan_client(&d->nic->nc);
|
||||
qemu_del_net_client(&d->nic->nc);
|
||||
}
|
||||
|
||||
static NetClientInfo net_e1000_info = {
|
||||
|
|
|
@ -1616,7 +1616,7 @@ static const MemoryRegionOps eepro100_ops = {
|
|||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
static int nic_can_receive(VLANClientState *nc)
|
||||
static int nic_can_receive(NetClientState *nc)
|
||||
{
|
||||
EEPRO100State *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
TRACE(RXTX, logout("%p\n", s));
|
||||
|
@ -1626,7 +1626,7 @@ static int nic_can_receive(VLANClientState *nc)
|
|||
#endif
|
||||
}
|
||||
|
||||
static ssize_t nic_receive(VLANClientState *nc, const uint8_t * buf, size_t size)
|
||||
static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size)
|
||||
{
|
||||
/* TODO:
|
||||
* - Magic packets should set bit 30 in power management driver register.
|
||||
|
@ -1831,7 +1831,7 @@ static const VMStateDescription vmstate_eepro100 = {
|
|||
}
|
||||
};
|
||||
|
||||
static void nic_cleanup(VLANClientState *nc)
|
||||
static void nic_cleanup(NetClientState *nc)
|
||||
{
|
||||
EEPRO100State *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -1847,7 +1847,7 @@ static void pci_nic_uninit(PCIDevice *pci_dev)
|
|||
memory_region_destroy(&s->flash_bar);
|
||||
vmstate_unregister(&pci_dev->qdev, s->vmstate, s);
|
||||
eeprom93xx_free(&pci_dev->qdev, s->eeprom);
|
||||
qemu_del_vlan_client(&s->nic->nc);
|
||||
qemu_del_net_client(&s->nic->nc);
|
||||
}
|
||||
|
||||
static NetClientInfo net_eepro100_info = {
|
||||
|
|
|
@ -507,12 +507,12 @@ static int eth_match_groupaddr(struct fs_eth *eth, const unsigned char *sa)
|
|||
return match;
|
||||
}
|
||||
|
||||
static int eth_can_receive(VLANClientState *nc)
|
||||
static int eth_can_receive(NetClientState *nc)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static ssize_t eth_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
static ssize_t eth_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
unsigned char sa_bcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
struct fs_eth *eth = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
@ -549,7 +549,7 @@ static int eth_tx_push(void *opaque, unsigned char *buf, int len, bool eop)
|
|||
return len;
|
||||
}
|
||||
|
||||
static void eth_set_link(VLANClientState *nc)
|
||||
static void eth_set_link(NetClientState *nc)
|
||||
{
|
||||
struct fs_eth *eth = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
D(printf("%s %d\n", __func__, nc->link_down));
|
||||
|
@ -566,7 +566,7 @@ static const MemoryRegionOps eth_ops = {
|
|||
}
|
||||
};
|
||||
|
||||
static void eth_cleanup(VLANClientState *nc)
|
||||
static void eth_cleanup(NetClientState *nc)
|
||||
{
|
||||
struct fs_eth *eth = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ static void lan9215_init(uint32_t base, qemu_irq irq)
|
|||
SysBusDevice *s;
|
||||
|
||||
/* This should be a 9215 but the 9118 is close enough */
|
||||
if (nd_table[0].vlan) {
|
||||
if (nd_table[0].used) {
|
||||
qemu_check_nic_model(&nd_table[0], "lan9118");
|
||||
dev = qdev_create(NULL, "lan9118");
|
||||
qdev_set_nic_properties(dev, &nd_table[0]);
|
||||
|
|
|
@ -284,7 +284,7 @@ static void highbank_init(ram_addr_t ram_size,
|
|||
|
||||
sysbus_create_simple("sysbus-ahci", 0xffe08000, pic[83]);
|
||||
|
||||
if (nd_table[0].vlan) {
|
||||
if (nd_table[0].used) {
|
||||
qemu_check_nic_model(&nd_table[0], "xgmac");
|
||||
dev = qdev_create(NULL, "xgmac");
|
||||
qdev_set_nic_properties(dev, &nd_table[0]);
|
||||
|
|
|
@ -493,7 +493,7 @@ static void integratorcp_init(ram_addr_t ram_size,
|
|||
sysbus_create_simple("pl050_keyboard", 0x18000000, pic[3]);
|
||||
sysbus_create_simple("pl050_mouse", 0x19000000, pic[4]);
|
||||
sysbus_create_varargs("pl181", 0x1c000000, pic[23], pic[24], NULL);
|
||||
if (nd_table[0].vlan)
|
||||
if (nd_table[0].used)
|
||||
smc91c111_init(&nd_table[0], 0xc8000000, pic[27]);
|
||||
|
||||
sysbus_create_simple("pl110", 0xc0000000, pic[22]);
|
||||
|
|
2
hw/kzm.c
2
hw/kzm.c
|
@ -121,7 +121,7 @@ static void kzm_init(ram_addr_t ram_size,
|
|||
imx_timerp_create(0x53f98000, qdev_get_gpio_in(dev, 27), ccm);
|
||||
imx_timerg_create(0x53f90000, qdev_get_gpio_in(dev, 29), ccm);
|
||||
|
||||
if (nd_table[0].vlan) {
|
||||
if (nd_table[0].used) {
|
||||
lan9118_init(&nd_table[0], 0xb6000000, qdev_get_gpio_in(dev, 52));
|
||||
}
|
||||
|
||||
|
|
|
@ -384,7 +384,7 @@ static void phy_update_link(lan9118_state *s)
|
|||
phy_update_irq(s);
|
||||
}
|
||||
|
||||
static void lan9118_set_link(VLANClientState *nc)
|
||||
static void lan9118_set_link(NetClientState *nc)
|
||||
{
|
||||
phy_update_link(DO_UPCAST(NICState, nc, nc)->opaque);
|
||||
}
|
||||
|
@ -456,7 +456,7 @@ static void lan9118_reset(DeviceState *d)
|
|||
lan9118_reload_eeprom(s);
|
||||
}
|
||||
|
||||
static int lan9118_can_receive(VLANClientState *nc)
|
||||
static int lan9118_can_receive(NetClientState *nc)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
@ -509,7 +509,7 @@ static int lan9118_filter(lan9118_state *s, const uint8_t *addr)
|
|||
}
|
||||
}
|
||||
|
||||
static ssize_t lan9118_receive(VLANClientState *nc, const uint8_t *buf,
|
||||
static ssize_t lan9118_receive(NetClientState *nc, const uint8_t *buf,
|
||||
size_t size)
|
||||
{
|
||||
lan9118_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
@ -1304,7 +1304,7 @@ static const MemoryRegionOps lan9118_16bit_mem_ops = {
|
|||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
static void lan9118_cleanup(VLANClientState *nc)
|
||||
static void lan9118_cleanup(NetClientState *nc)
|
||||
{
|
||||
lan9118_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ static const MemoryRegionOps lance_mem_ops = {
|
|||
},
|
||||
};
|
||||
|
||||
static void lance_cleanup(VLANClientState *nc)
|
||||
static void lance_cleanup(NetClientState *nc)
|
||||
{
|
||||
PCNetState *d = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
|
|
@ -236,7 +236,7 @@ static void mcf5208evb_init(ram_addr_t ram_size,
|
|||
fprintf(stderr, "Too many NICs\n");
|
||||
exit(1);
|
||||
}
|
||||
if (nd_table[0].vlan)
|
||||
if (nd_table[0].used)
|
||||
mcf_fec_init(address_space_mem, &nd_table[0],
|
||||
0xfc030000, pic + 36);
|
||||
|
||||
|
|
|
@ -351,13 +351,13 @@ static void mcf_fec_write(void *opaque, target_phys_addr_t addr,
|
|||
mcf_fec_update(s);
|
||||
}
|
||||
|
||||
static int mcf_fec_can_receive(VLANClientState *nc)
|
||||
static int mcf_fec_can_receive(NetClientState *nc)
|
||||
{
|
||||
mcf_fec_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
return s->rx_enabled;
|
||||
}
|
||||
|
||||
static ssize_t mcf_fec_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
static ssize_t mcf_fec_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
mcf_fec_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
mcf_fec_bd bd;
|
||||
|
@ -439,7 +439,7 @@ static const MemoryRegionOps mcf_fec_ops = {
|
|||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
static void mcf_fec_cleanup(VLANClientState *nc)
|
||||
static void mcf_fec_cleanup(NetClientState *nc)
|
||||
{
|
||||
mcf_fec_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -472,7 +472,6 @@ void mcf_fec_init(MemoryRegion *sysmem, NICInfo *nd,
|
|||
memory_region_add_subregion(sysmem, base, &s->iomem);
|
||||
|
||||
s->conf.macaddr = nd->macaddr;
|
||||
s->conf.vlan = nd->vlan;
|
||||
s->conf.peer = nd->netdev;
|
||||
|
||||
s->nic = qemu_new_nic(&net_mcf_fec_info, &s->conf, nd->model, nd->name, s);
|
||||
|
|
|
@ -278,7 +278,7 @@ static void update_rx_interrupt(MilkymistMinimac2State *s)
|
|||
}
|
||||
}
|
||||
|
||||
static ssize_t minimac2_rx(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
static ssize_t minimac2_rx(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
MilkymistMinimac2State *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -408,7 +408,7 @@ static const MemoryRegionOps minimac2_ops = {
|
|||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
static int minimac2_can_rx(VLANClientState *nc)
|
||||
static int minimac2_can_rx(NetClientState *nc)
|
||||
{
|
||||
MilkymistMinimac2State *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -422,7 +422,7 @@ static int minimac2_can_rx(VLANClientState *nc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void minimac2_cleanup(VLANClientState *nc)
|
||||
static void minimac2_cleanup(NetClientState *nc)
|
||||
{
|
||||
MilkymistMinimac2State *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
|
|
@ -217,7 +217,7 @@ mips_mipssim_init (ram_addr_t ram_size,
|
|||
if (serial_hds[0])
|
||||
serial_init(0x3f8, env->irq[4], 115200, serial_hds[0]);
|
||||
|
||||
if (nd_table[0].vlan)
|
||||
if (nd_table[0].used)
|
||||
/* MIPSnet uses the MIPS CPU INT0, which is interrupt 2. */
|
||||
mipsnet_init(0x4200, env->irq[2], &nd_table[0]);
|
||||
}
|
||||
|
|
|
@ -283,7 +283,7 @@ void mips_r4k_init (ram_addr_t ram_size,
|
|||
|
||||
isa_vga_init(isa_bus);
|
||||
|
||||
if (nd_table[0].vlan)
|
||||
if (nd_table[0].used)
|
||||
isa_ne2000_init(isa_bus, 0x300, 9, &nd_table[0]);
|
||||
|
||||
ide_drive_get(hd, MAX_IDE_BUS);
|
||||
|
|
|
@ -62,7 +62,7 @@ static int mipsnet_buffer_full(MIPSnetState *s)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int mipsnet_can_receive(VLANClientState *nc)
|
||||
static int mipsnet_can_receive(NetClientState *nc)
|
||||
{
|
||||
MIPSnetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -71,7 +71,7 @@ static int mipsnet_can_receive(VLANClientState *nc)
|
|||
return !mipsnet_buffer_full(s);
|
||||
}
|
||||
|
||||
static ssize_t mipsnet_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
static ssize_t mipsnet_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
MIPSnetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -209,7 +209,7 @@ static const VMStateDescription vmstate_mipsnet = {
|
|||
}
|
||||
};
|
||||
|
||||
static void mipsnet_cleanup(VLANClientState *nc)
|
||||
static void mipsnet_cleanup(NetClientState *nc)
|
||||
{
|
||||
MIPSnetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
|
|
@ -182,12 +182,12 @@ static void eth_rx_desc_get(uint32_t addr, mv88w8618_rx_desc *desc)
|
|||
le32_to_cpus(&desc->next);
|
||||
}
|
||||
|
||||
static int eth_can_receive(VLANClientState *nc)
|
||||
static int eth_can_receive(NetClientState *nc)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static ssize_t eth_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
static ssize_t eth_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
mv88w8618_eth_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
uint32_t desc_addr;
|
||||
|
@ -366,7 +366,7 @@ static const MemoryRegionOps mv88w8618_eth_ops = {
|
|||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
static void eth_cleanup(VLANClientState *nc)
|
||||
static void eth_cleanup(NetClientState *nc)
|
||||
{
|
||||
mv88w8618_eth_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ typedef struct ISANE2000State {
|
|||
NE2000State ne2000;
|
||||
} ISANE2000State;
|
||||
|
||||
static void isa_ne2000_cleanup(VLANClientState *nc)
|
||||
static void isa_ne2000_cleanup(NetClientState *nc)
|
||||
{
|
||||
NE2000State *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
|
|
@ -165,7 +165,7 @@ static int ne2000_buffer_full(NE2000State *s)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ne2000_can_receive(VLANClientState *nc)
|
||||
int ne2000_can_receive(NetClientState *nc)
|
||||
{
|
||||
NE2000State *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -176,7 +176,7 @@ int ne2000_can_receive(VLANClientState *nc)
|
|||
|
||||
#define MIN_BUF_SIZE 60
|
||||
|
||||
ssize_t ne2000_receive(VLANClientState *nc, const uint8_t *buf, size_t size_)
|
||||
ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
|
||||
{
|
||||
NE2000State *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
int size = size_;
|
||||
|
@ -703,7 +703,7 @@ void ne2000_setup_io(NE2000State *s, unsigned size)
|
|||
memory_region_init_io(&s->io, &ne2000_ops, s, "ne2000", size);
|
||||
}
|
||||
|
||||
static void ne2000_cleanup(VLANClientState *nc)
|
||||
static void ne2000_cleanup(NetClientState *nc)
|
||||
{
|
||||
NE2000State *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -750,7 +750,7 @@ static void pci_ne2000_exit(PCIDevice *pci_dev)
|
|||
NE2000State *s = &d->ne2000;
|
||||
|
||||
memory_region_destroy(&s->io);
|
||||
qemu_del_vlan_client(&s->nic->nc);
|
||||
qemu_del_net_client(&s->nic->nc);
|
||||
}
|
||||
|
||||
static Property ne2000_properties[] = {
|
||||
|
|
|
@ -31,5 +31,5 @@ typedef struct NE2000State {
|
|||
void ne2000_setup_io(NE2000State *s, unsigned size);
|
||||
extern const VMStateDescription vmstate_ne2000;
|
||||
void ne2000_reset(NE2000State *s);
|
||||
int ne2000_can_receive(VLANClientState *vc);
|
||||
ssize_t ne2000_receive(VLANClientState *vc, const uint8_t *buf, size_t size_);
|
||||
int ne2000_can_receive(NetClientState *nc);
|
||||
ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_);
|
||||
|
|
|
@ -311,7 +311,7 @@ static void open_eth_int_source_write(OpenEthState *s,
|
|||
s->regs[INT_SOURCE] & s->regs[INT_MASK]);
|
||||
}
|
||||
|
||||
static void open_eth_set_link_status(VLANClientState *nc)
|
||||
static void open_eth_set_link_status(NetClientState *nc)
|
||||
{
|
||||
OpenEthState *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -342,7 +342,7 @@ static void open_eth_reset(void *opaque)
|
|||
open_eth_set_link_status(&s->nic->nc);
|
||||
}
|
||||
|
||||
static int open_eth_can_receive(VLANClientState *nc)
|
||||
static int open_eth_can_receive(NetClientState *nc)
|
||||
{
|
||||
OpenEthState *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -351,7 +351,7 @@ static int open_eth_can_receive(VLANClientState *nc)
|
|||
(rx_desc(s)->len_flags & RXD_E);
|
||||
}
|
||||
|
||||
static ssize_t open_eth_receive(VLANClientState *nc,
|
||||
static ssize_t open_eth_receive(NetClientState *nc,
|
||||
const uint8_t *buf, size_t size)
|
||||
{
|
||||
OpenEthState *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
@ -462,7 +462,7 @@ static ssize_t open_eth_receive(VLANClientState *nc,
|
|||
return size;
|
||||
}
|
||||
|
||||
static void open_eth_cleanup(VLANClientState *nc)
|
||||
static void open_eth_cleanup(NetClientState *nc)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ static void openrisc_sim_init(ram_addr_t ram_size,
|
|||
serial_mm_init(get_system_memory(), 0x90000000, 0, cpu->env.irq[2],
|
||||
115200, serial_hds[0], DEVICE_NATIVE_ENDIAN);
|
||||
|
||||
if (nd_table[0].vlan) {
|
||||
if (nd_table[0].used) {
|
||||
openrisc_sim_net_init(get_system_memory(), 0x92000000,
|
||||
0x92000400, cpu->env.irq[4], nd_table);
|
||||
}
|
||||
|
|
|
@ -264,7 +264,7 @@ 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(VLANClientState *nc)
|
||||
static void pci_pcnet_cleanup(NetClientState *nc)
|
||||
{
|
||||
PCNetState *d = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -279,7 +279,7 @@ static void pci_pcnet_uninit(PCIDevice *dev)
|
|||
memory_region_destroy(&d->io_bar);
|
||||
qemu_del_timer(d->state.poll_timer);
|
||||
qemu_free_timer(d->state.poll_timer);
|
||||
qemu_del_vlan_client(&d->state.nic->nc);
|
||||
qemu_del_net_client(&d->state.nic->nc);
|
||||
}
|
||||
|
||||
static NetClientInfo net_pci_pcnet_info = {
|
||||
|
|
|
@ -1004,7 +1004,7 @@ static int pcnet_tdte_poll(PCNetState *s)
|
|||
return !!(CSR_CXST(s) & 0x8000);
|
||||
}
|
||||
|
||||
int pcnet_can_receive(VLANClientState *nc)
|
||||
int pcnet_can_receive(NetClientState *nc)
|
||||
{
|
||||
PCNetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
if (CSR_STOP(s) || CSR_SPND(s))
|
||||
|
@ -1015,7 +1015,7 @@ int pcnet_can_receive(VLANClientState *nc)
|
|||
|
||||
#define MIN_BUF_SIZE 60
|
||||
|
||||
ssize_t pcnet_receive(VLANClientState *nc, const uint8_t *buf, size_t size_)
|
||||
ssize_t pcnet_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
|
||||
{
|
||||
PCNetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
int is_padr = 0, is_bcast = 0, is_ladr = 0;
|
||||
|
@ -1197,7 +1197,7 @@ ssize_t pcnet_receive(VLANClientState *nc, const uint8_t *buf, size_t size_)
|
|||
return size_;
|
||||
}
|
||||
|
||||
void pcnet_set_link_status(VLANClientState *nc)
|
||||
void pcnet_set_link_status(NetClientState *nc)
|
||||
{
|
||||
PCNetState *d = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
|
|
@ -57,9 +57,9 @@ uint32_t pcnet_ioport_readw(void *opaque, uint32_t addr);
|
|||
void pcnet_ioport_writel(void *opaque, uint32_t addr, uint32_t val);
|
||||
uint32_t pcnet_ioport_readl(void *opaque, uint32_t addr);
|
||||
uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap);
|
||||
int pcnet_can_receive(VLANClientState *nc);
|
||||
ssize_t pcnet_receive(VLANClientState *nc, const uint8_t *buf, size_t size_);
|
||||
void pcnet_set_link_status(VLANClientState *nc);
|
||||
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);
|
||||
extern const VMStateDescription vmstate_pcnet;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "qerror.h"
|
||||
#include "blockdev.h"
|
||||
#include "hw/block-common.h"
|
||||
#include "net/hub.h"
|
||||
|
||||
void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
|
||||
{
|
||||
|
@ -583,7 +584,7 @@ PropertyInfo qdev_prop_chr = {
|
|||
|
||||
static int parse_netdev(DeviceState *dev, const char *str, void **ptr)
|
||||
{
|
||||
VLANClientState *netdev = qemu_find_netdev(str);
|
||||
NetClientState *netdev = qemu_find_netdev(str);
|
||||
|
||||
if (netdev == NULL) {
|
||||
return -ENOENT;
|
||||
|
@ -597,7 +598,7 @@ static int parse_netdev(DeviceState *dev, const char *str, void **ptr)
|
|||
|
||||
static const char *print_netdev(void *ptr)
|
||||
{
|
||||
VLANClientState *netdev = ptr;
|
||||
NetClientState *netdev = ptr;
|
||||
|
||||
return netdev->name ? netdev->name : "";
|
||||
}
|
||||
|
@ -624,13 +625,16 @@ PropertyInfo qdev_prop_netdev = {
|
|||
|
||||
static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
|
||||
{
|
||||
VLANState **ptr = qdev_get_prop_ptr(dev, prop);
|
||||
NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
|
||||
|
||||
if (*ptr) {
|
||||
return snprintf(dest, len, "%d", (*ptr)->id);
|
||||
} else {
|
||||
return snprintf(dest, len, "<null>");
|
||||
int id;
|
||||
if (!net_hub_id_for_client(*ptr, &id)) {
|
||||
return snprintf(dest, len, "%d", id);
|
||||
}
|
||||
}
|
||||
|
||||
return snprintf(dest, len, "<null>");
|
||||
}
|
||||
|
||||
static void get_vlan(Object *obj, Visitor *v, void *opaque,
|
||||
|
@ -638,11 +642,17 @@ static void get_vlan(Object *obj, Visitor *v, void *opaque,
|
|||
{
|
||||
DeviceState *dev = DEVICE(obj);
|
||||
Property *prop = opaque;
|
||||
VLANState **ptr = qdev_get_prop_ptr(dev, prop);
|
||||
int64_t id;
|
||||
NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
|
||||
int32_t id = -1;
|
||||
|
||||
id = *ptr ? (*ptr)->id : -1;
|
||||
visit_type_int64(v, &id, name, errp);
|
||||
if (*ptr) {
|
||||
int hub_id;
|
||||
if (!net_hub_id_for_client(*ptr, &hub_id)) {
|
||||
id = hub_id;
|
||||
}
|
||||
}
|
||||
|
||||
visit_type_int32(v, &id, name, errp);
|
||||
}
|
||||
|
||||
static void set_vlan(Object *obj, Visitor *v, void *opaque,
|
||||
|
@ -650,17 +660,17 @@ static void set_vlan(Object *obj, Visitor *v, void *opaque,
|
|||
{
|
||||
DeviceState *dev = DEVICE(obj);
|
||||
Property *prop = opaque;
|
||||
VLANState **ptr = qdev_get_prop_ptr(dev, prop);
|
||||
NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
|
||||
Error *local_err = NULL;
|
||||
int64_t id;
|
||||
VLANState *vlan;
|
||||
int32_t id;
|
||||
NetClientState *hubport;
|
||||
|
||||
if (dev->state != DEV_STATE_CREATED) {
|
||||
error_set(errp, QERR_PERMISSION_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
visit_type_int64(v, &id, name, &local_err);
|
||||
visit_type_int32(v, &id, name, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
|
@ -669,13 +679,14 @@ static void set_vlan(Object *obj, Visitor *v, void *opaque,
|
|||
*ptr = NULL;
|
||||
return;
|
||||
}
|
||||
vlan = qemu_find_vlan(id, 1);
|
||||
if (!vlan) {
|
||||
|
||||
hubport = net_hub_port_find(id);
|
||||
if (!hubport) {
|
||||
error_set(errp, QERR_INVALID_PARAMETER_VALUE,
|
||||
name, prop->info->name);
|
||||
return;
|
||||
}
|
||||
*ptr = vlan;
|
||||
*ptr = hubport;
|
||||
}
|
||||
|
||||
PropertyInfo qdev_prop_vlan = {
|
||||
|
@ -1175,7 +1186,7 @@ void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *valu
|
|||
assert_no_error(errp);
|
||||
}
|
||||
|
||||
void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState *value)
|
||||
void qdev_prop_set_netdev(DeviceState *dev, const char *name, NetClientState *value)
|
||||
{
|
||||
Error *errp = NULL;
|
||||
assert(!value || value->name);
|
||||
|
@ -1184,13 +1195,6 @@ void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState *v
|
|||
assert_no_error(errp);
|
||||
}
|
||||
|
||||
void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value)
|
||||
{
|
||||
Error *errp = NULL;
|
||||
object_property_set_int(OBJECT(dev), value ? value->id : -1, name, &errp);
|
||||
assert_no_error(errp);
|
||||
}
|
||||
|
||||
void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
|
||||
{
|
||||
Error *errp = NULL;
|
||||
|
|
|
@ -320,8 +320,6 @@ void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
|
|||
void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
|
||||
{
|
||||
qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
|
||||
if (nd->vlan)
|
||||
qdev_prop_set_vlan(dev, "vlan", nd->vlan);
|
||||
if (nd->netdev)
|
||||
qdev_prop_set_netdev(dev, "netdev", nd->netdev);
|
||||
if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
|
||||
|
|
|
@ -289,9 +289,9 @@ extern PropertyInfo qdev_prop_pci_host_devaddr;
|
|||
#define DEFINE_PROP_STRING(_n, _s, _f) \
|
||||
DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*)
|
||||
#define DEFINE_PROP_NETDEV(_n, _s, _f) \
|
||||
DEFINE_PROP(_n, _s, _f, qdev_prop_netdev, VLANClientState*)
|
||||
DEFINE_PROP(_n, _s, _f, qdev_prop_netdev, NetClientState*)
|
||||
#define DEFINE_PROP_VLAN(_n, _s, _f) \
|
||||
DEFINE_PROP(_n, _s, _f, qdev_prop_vlan, VLANState*)
|
||||
DEFINE_PROP(_n, _s, _f, qdev_prop_vlan, NetClientState*)
|
||||
#define DEFINE_PROP_DRIVE(_n, _s, _f) \
|
||||
DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockDriverState *)
|
||||
#define DEFINE_PROP_MACADDR(_n, _s, _f) \
|
||||
|
@ -320,8 +320,7 @@ void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value);
|
|||
void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value);
|
||||
void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value);
|
||||
void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value);
|
||||
void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState *value);
|
||||
void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value);
|
||||
void qdev_prop_set_netdev(DeviceState *dev, const char *name, NetClientState *value);
|
||||
int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value) QEMU_WARN_UNUSED_RESULT;
|
||||
void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value);
|
||||
void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value);
|
||||
|
|
10
hw/rtl8139.c
10
hw/rtl8139.c
|
@ -788,7 +788,7 @@ static bool rtl8139_cp_rx_valid(RTL8139State *s)
|
|||
return !(s->RxRingAddrLO == 0 && s->RxRingAddrHI == 0);
|
||||
}
|
||||
|
||||
static int rtl8139_can_receive(VLANClientState *nc)
|
||||
static int rtl8139_can_receive(NetClientState *nc)
|
||||
{
|
||||
RTL8139State *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
int avail;
|
||||
|
@ -810,7 +810,7 @@ static int rtl8139_can_receive(VLANClientState *nc)
|
|||
}
|
||||
}
|
||||
|
||||
static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_t size_, int do_interrupt)
|
||||
static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t size_, int do_interrupt)
|
||||
{
|
||||
RTL8139State *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
/* size is the length of the buffer passed to the driver */
|
||||
|
@ -1187,7 +1187,7 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
|
|||
return size_;
|
||||
}
|
||||
|
||||
static ssize_t rtl8139_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
static ssize_t rtl8139_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
return rtl8139_do_receive(nc, buf, size, 1);
|
||||
}
|
||||
|
@ -3431,7 +3431,7 @@ static void rtl8139_timer(void *opaque)
|
|||
rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock));
|
||||
}
|
||||
|
||||
static void rtl8139_cleanup(VLANClientState *nc)
|
||||
static void rtl8139_cleanup(NetClientState *nc)
|
||||
{
|
||||
RTL8139State *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -3450,7 +3450,7 @@ static void pci_rtl8139_uninit(PCIDevice *dev)
|
|||
}
|
||||
qemu_del_timer(s->timer);
|
||||
qemu_free_timer(s->timer);
|
||||
qemu_del_vlan_client(&s->nic->nc);
|
||||
qemu_del_net_client(&s->nic->nc);
|
||||
}
|
||||
|
||||
static NetClientInfo net_rtl8139_info = {
|
||||
|
|
|
@ -628,7 +628,7 @@ static uint32_t smc91c111_readl(void *opaque, target_phys_addr_t offset)
|
|||
return val;
|
||||
}
|
||||
|
||||
static int smc91c111_can_receive(VLANClientState *nc)
|
||||
static int smc91c111_can_receive(NetClientState *nc)
|
||||
{
|
||||
smc91c111_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -639,7 +639,7 @@ static int smc91c111_can_receive(VLANClientState *nc)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static ssize_t smc91c111_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
static ssize_t smc91c111_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
smc91c111_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
int status;
|
||||
|
@ -728,7 +728,7 @@ static const MemoryRegionOps smc91c111_mem_ops = {
|
|||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
static void smc91c111_cleanup(VLANClientState *nc)
|
||||
static void smc91c111_cleanup(NetClientState *nc)
|
||||
{
|
||||
smc91c111_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
|
|
@ -83,14 +83,14 @@ typedef struct VIOsPAPRVLANDevice {
|
|||
target_ulong rxq_ptr;
|
||||
} VIOsPAPRVLANDevice;
|
||||
|
||||
static int spapr_vlan_can_receive(VLANClientState *nc)
|
||||
static int spapr_vlan_can_receive(NetClientState *nc)
|
||||
{
|
||||
VIOsPAPRVLANDevice *dev = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
return (dev->isopen && dev->rx_bufs > 0);
|
||||
}
|
||||
|
||||
static ssize_t spapr_vlan_receive(VLANClientState *nc, const uint8_t *buf,
|
||||
static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf,
|
||||
size_t size)
|
||||
{
|
||||
VIOsPAPRDevice *sdev = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
|
|
@ -78,7 +78,7 @@ static void stellaris_enet_update(stellaris_enet_state *s)
|
|||
}
|
||||
|
||||
/* TODO: Implement MAC address filtering. */
|
||||
static ssize_t stellaris_enet_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
static ssize_t stellaris_enet_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
stellaris_enet_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
int n;
|
||||
|
@ -120,7 +120,7 @@ static ssize_t stellaris_enet_receive(VLANClientState *nc, const uint8_t *buf, s
|
|||
return size;
|
||||
}
|
||||
|
||||
static int stellaris_enet_can_receive(VLANClientState *nc)
|
||||
static int stellaris_enet_can_receive(NetClientState *nc)
|
||||
{
|
||||
stellaris_enet_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -381,7 +381,7 @@ static int stellaris_enet_load(QEMUFile *f, void *opaque, int version_id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void stellaris_enet_cleanup(VLANClientState *nc)
|
||||
static void stellaris_enet_cleanup(NetClientState *nc)
|
||||
{
|
||||
stellaris_enet_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
|
|
@ -1247,7 +1247,7 @@ static int usb_net_handle_data(USBDevice *dev, USBPacket *p)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t usbnet_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
static ssize_t usbnet_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
USBNetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
struct rndis_packet_msg_type *msg;
|
||||
|
@ -1285,7 +1285,7 @@ static ssize_t usbnet_receive(VLANClientState *nc, const uint8_t *buf, size_t si
|
|||
return size;
|
||||
}
|
||||
|
||||
static int usbnet_can_receive(VLANClientState *nc)
|
||||
static int usbnet_can_receive(NetClientState *nc)
|
||||
{
|
||||
USBNetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -1296,7 +1296,7 @@ static int usbnet_can_receive(VLANClientState *nc)
|
|||
return !s->in_len;
|
||||
}
|
||||
|
||||
static void usbnet_cleanup(VLANClientState *nc)
|
||||
static void usbnet_cleanup(NetClientState *nc)
|
||||
{
|
||||
USBNetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -1309,7 +1309,7 @@ static void usb_net_handle_destroy(USBDevice *dev)
|
|||
|
||||
/* TODO: remove the nd_table[] entry */
|
||||
rndis_clear_responsequeue(s);
|
||||
qemu_del_vlan_client(&s->nic->nc);
|
||||
qemu_del_net_client(&s->nic->nc);
|
||||
}
|
||||
|
||||
static NetClientInfo net_usbnet_info = {
|
||||
|
|
|
@ -427,7 +427,7 @@ static void vexpress_common_init(const VEDBoardInfo *daughterboard,
|
|||
memory_region_add_subregion(sysmem, map[VE_VIDEORAM], vram);
|
||||
|
||||
/* 0x4e000000 LAN9118 Ethernet */
|
||||
if (nd_table[0].vlan) {
|
||||
if (nd_table[0].used) {
|
||||
lan9118_init(&nd_table[0], map[VE_ETHERNET], pic[15]);
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ struct vhost_net {
|
|||
struct vhost_dev dev;
|
||||
struct vhost_virtqueue vqs[2];
|
||||
int backend;
|
||||
VLANClientState *vc;
|
||||
NetClientState *nc;
|
||||
};
|
||||
|
||||
unsigned vhost_net_get_features(struct vhost_net *net, unsigned features)
|
||||
|
@ -80,7 +80,7 @@ void vhost_net_ack_features(struct vhost_net *net, unsigned features)
|
|||
}
|
||||
}
|
||||
|
||||
static int vhost_net_get_fd(VLANClientState *backend)
|
||||
static int vhost_net_get_fd(NetClientState *backend)
|
||||
{
|
||||
switch (backend->info->type) {
|
||||
case NET_CLIENT_OPTIONS_KIND_TAP:
|
||||
|
@ -91,7 +91,7 @@ static int vhost_net_get_fd(VLANClientState *backend)
|
|||
}
|
||||
}
|
||||
|
||||
struct vhost_net *vhost_net_init(VLANClientState *backend, int devfd,
|
||||
struct vhost_net *vhost_net_init(NetClientState *backend, int devfd,
|
||||
bool force)
|
||||
{
|
||||
int r;
|
||||
|
@ -104,7 +104,7 @@ struct vhost_net *vhost_net_init(VLANClientState *backend, int devfd,
|
|||
if (r < 0) {
|
||||
goto fail;
|
||||
}
|
||||
net->vc = backend;
|
||||
net->nc = backend;
|
||||
net->dev.backend_features = tap_has_vnet_hdr(backend) ? 0 :
|
||||
(1 << VHOST_NET_F_VIRTIO_NET_HDR);
|
||||
net->backend = r;
|
||||
|
@ -151,7 +151,7 @@ int vhost_net_start(struct vhost_net *net,
|
|||
goto fail_notifiers;
|
||||
}
|
||||
if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
|
||||
tap_set_vnet_hdr_len(net->vc,
|
||||
tap_set_vnet_hdr_len(net->nc,
|
||||
sizeof(struct virtio_net_hdr_mrg_rxbuf));
|
||||
}
|
||||
|
||||
|
@ -160,7 +160,7 @@ int vhost_net_start(struct vhost_net *net,
|
|||
goto fail_start;
|
||||
}
|
||||
|
||||
net->vc->info->poll(net->vc, false);
|
||||
net->nc->info->poll(net->nc, false);
|
||||
qemu_set_fd_handler(net->backend, NULL, NULL, NULL);
|
||||
file.fd = net->backend;
|
||||
for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
|
||||
|
@ -177,10 +177,10 @@ fail:
|
|||
int r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file);
|
||||
assert(r >= 0);
|
||||
}
|
||||
net->vc->info->poll(net->vc, true);
|
||||
net->nc->info->poll(net->nc, true);
|
||||
vhost_dev_stop(&net->dev, dev);
|
||||
if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
|
||||
tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr));
|
||||
tap_set_vnet_hdr_len(net->nc, sizeof(struct virtio_net_hdr));
|
||||
}
|
||||
fail_start:
|
||||
vhost_dev_disable_notifiers(&net->dev, dev);
|
||||
|
@ -197,10 +197,10 @@ void vhost_net_stop(struct vhost_net *net,
|
|||
int r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file);
|
||||
assert(r >= 0);
|
||||
}
|
||||
net->vc->info->poll(net->vc, true);
|
||||
net->nc->info->poll(net->nc, true);
|
||||
vhost_dev_stop(&net->dev, dev);
|
||||
if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
|
||||
tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr));
|
||||
tap_set_vnet_hdr_len(net->nc, sizeof(struct virtio_net_hdr));
|
||||
}
|
||||
vhost_dev_disable_notifiers(&net->dev, dev);
|
||||
}
|
||||
|
@ -209,12 +209,12 @@ void vhost_net_cleanup(struct vhost_net *net)
|
|||
{
|
||||
vhost_dev_cleanup(&net->dev);
|
||||
if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
|
||||
tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr));
|
||||
tap_set_vnet_hdr_len(net->nc, sizeof(struct virtio_net_hdr));
|
||||
}
|
||||
g_free(net);
|
||||
}
|
||||
#else
|
||||
struct vhost_net *vhost_net_init(VLANClientState *backend, int devfd,
|
||||
struct vhost_net *vhost_net_init(NetClientState *backend, int devfd,
|
||||
bool force)
|
||||
{
|
||||
error_report("vhost-net support is not compiled in");
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
struct vhost_net;
|
||||
typedef struct vhost_net VHostNetState;
|
||||
|
||||
VHostNetState *vhost_net_init(VLANClientState *backend, int devfd, bool force);
|
||||
VHostNetState *vhost_net_init(NetClientState *backend, int devfd, bool force);
|
||||
|
||||
bool vhost_net_query(VHostNetState *net, VirtIODevice *dev);
|
||||
int vhost_net_start(VHostNetState *net, VirtIODevice *dev);
|
||||
|
|
|
@ -163,7 +163,7 @@ static void virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status)
|
|||
}
|
||||
}
|
||||
|
||||
static void virtio_net_set_link_status(VLANClientState *nc)
|
||||
static void virtio_net_set_link_status(NetClientState *nc)
|
||||
{
|
||||
VirtIONet *n = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
uint16_t old_status = n->status;
|
||||
|
@ -453,7 +453,7 @@ static void virtio_net_handle_rx(VirtIODevice *vdev, VirtQueue *vq)
|
|||
qemu_notify_event();
|
||||
}
|
||||
|
||||
static int virtio_net_can_receive(VLANClientState *nc)
|
||||
static int virtio_net_can_receive(NetClientState *nc)
|
||||
{
|
||||
VirtIONet *n = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
if (!n->vdev.vm_running) {
|
||||
|
@ -593,7 +593,7 @@ static int receive_filter(VirtIONet *n, const uint8_t *buf, int size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
VirtIONet *n = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
struct virtio_net_hdr_mrg_rxbuf *mhdr = NULL;
|
||||
|
@ -690,7 +690,7 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_
|
|||
|
||||
static int32_t virtio_net_flush_tx(VirtIONet *n, VirtQueue *vq);
|
||||
|
||||
static void virtio_net_tx_complete(VLANClientState *nc, ssize_t len)
|
||||
static void virtio_net_tx_complete(NetClientState *nc, ssize_t len)
|
||||
{
|
||||
VirtIONet *n = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -980,7 +980,7 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void virtio_net_cleanup(VLANClientState *nc)
|
||||
static void virtio_net_cleanup(NetClientState *nc)
|
||||
{
|
||||
VirtIONet *n = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -1077,6 +1077,6 @@ void virtio_net_exit(VirtIODevice *vdev)
|
|||
qemu_bh_delete(n->tx_bh);
|
||||
}
|
||||
|
||||
qemu_del_vlan_client(&n->nic->nc);
|
||||
qemu_del_net_client(&n->nic->nc);
|
||||
virtio_cleanup(&n->vdev);
|
||||
}
|
||||
|
|
|
@ -233,7 +233,7 @@ static void net_rx_response(struct XenNetDev *netdev,
|
|||
|
||||
#define NET_IP_ALIGN 2
|
||||
|
||||
static int net_rx_ok(VLANClientState *nc)
|
||||
static int net_rx_ok(NetClientState *nc)
|
||||
{
|
||||
struct XenNetDev *netdev = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
RING_IDX rc, rp;
|
||||
|
@ -254,7 +254,7 @@ static int net_rx_ok(VLANClientState *nc)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static ssize_t net_rx_packet(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
static ssize_t net_rx_packet(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
struct XenNetDev *netdev = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
netif_rx_request_t rxreq;
|
||||
|
@ -325,7 +325,6 @@ static int net_init(struct XenDevice *xendev)
|
|||
return -1;
|
||||
}
|
||||
|
||||
netdev->conf.vlan = qemu_find_vlan(netdev->xendev.dev, 1);
|
||||
netdev->conf.peer = NULL;
|
||||
|
||||
netdev->nic = qemu_new_nic(&net_xen_info, &netdev->conf,
|
||||
|
@ -407,7 +406,7 @@ static void net_disconnect(struct XenDevice *xendev)
|
|||
netdev->rxs = NULL;
|
||||
}
|
||||
if (netdev->nic) {
|
||||
qemu_del_vlan_client(&netdev->nic->nc);
|
||||
qemu_del_net_client(&netdev->nic->nc);
|
||||
netdev->nic = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -308,7 +308,7 @@ static const MemoryRegionOps enet_mem_ops = {
|
|||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
static int eth_can_rx(VLANClientState *nc)
|
||||
static int eth_can_rx(NetClientState *nc)
|
||||
{
|
||||
struct XgmacState *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -316,7 +316,7 @@ static int eth_can_rx(VLANClientState *nc)
|
|||
return s->regs[DMA_CONTROL] & DMA_CONTROL_SR;
|
||||
}
|
||||
|
||||
static ssize_t eth_rx(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
struct XgmacState *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
static const unsigned char sa_bcast[6] = {0xff, 0xff, 0xff,
|
||||
|
@ -364,7 +364,7 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void eth_cleanup(VLANClientState *nc)
|
||||
static void eth_cleanup(NetClientState *nc)
|
||||
{
|
||||
struct XgmacState *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
s->nic = NULL;
|
||||
|
|
|
@ -612,7 +612,7 @@ static const MemoryRegionOps enet_ops = {
|
|||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
static int eth_can_rx(VLANClientState *nc)
|
||||
static int eth_can_rx(NetClientState *nc)
|
||||
{
|
||||
struct XilinxAXIEnet *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
@ -635,7 +635,7 @@ static int enet_match_addr(const uint8_t *buf, uint32_t f0, uint32_t f1)
|
|||
return match;
|
||||
}
|
||||
|
||||
static ssize_t eth_rx(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
struct XilinxAXIEnet *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
static const unsigned char sa_bcast[6] = {0xff, 0xff, 0xff,
|
||||
|
@ -780,7 +780,7 @@ static ssize_t eth_rx(VLANClientState *nc, const uint8_t *buf, size_t size)
|
|||
return size;
|
||||
}
|
||||
|
||||
static void eth_cleanup(VLANClientState *nc)
|
||||
static void eth_cleanup(NetClientState *nc)
|
||||
{
|
||||
/* FIXME. */
|
||||
struct XilinxAXIEnet *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
|
|
@ -160,7 +160,7 @@ static const MemoryRegionOps eth_ops = {
|
|||
}
|
||||
};
|
||||
|
||||
static int eth_can_rx(VLANClientState *nc)
|
||||
static int eth_can_rx(NetClientState *nc)
|
||||
{
|
||||
struct xlx_ethlite *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
int r;
|
||||
|
@ -168,7 +168,7 @@ static int eth_can_rx(VLANClientState *nc)
|
|||
return r;
|
||||
}
|
||||
|
||||
static ssize_t eth_rx(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
struct xlx_ethlite *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
unsigned int rxbase = s->rxbuf * (0x800 / 4);
|
||||
|
@ -194,7 +194,7 @@ static ssize_t eth_rx(VLANClientState *nc, const uint8_t *buf, size_t size)
|
|||
return size;
|
||||
}
|
||||
|
||||
static void eth_cleanup(VLANClientState *nc)
|
||||
static void eth_cleanup(NetClientState *nc)
|
||||
{
|
||||
struct xlx_ethlite *s = DO_UPCAST(NICState, nc, nc)->opaque;
|
||||
|
||||
|
|
|
@ -201,7 +201,7 @@ static void lx_init(const LxBoardDesc *board,
|
|||
memory_region_init(system_io, "lx60.io", 224 * 1024 * 1024);
|
||||
memory_region_add_subregion(system_memory, 0xf0000000, system_io);
|
||||
lx60_fpga_init(system_io, 0x0d020000);
|
||||
if (nd_table[0].vlan) {
|
||||
if (nd_table[0].used) {
|
||||
lx60_net_init(system_io, 0x0d030000, 0x0d030400, 0x0d800000,
|
||||
xtensa_get_extint(env, 1), nd_table);
|
||||
}
|
||||
|
|
614
net.c
614
net.c
|
@ -30,6 +30,7 @@
|
|||
#include "net/dump.h"
|
||||
#include "net/slirp.h"
|
||||
#include "net/vde.h"
|
||||
#include "net/hub.h"
|
||||
#include "net/util.h"
|
||||
#include "monitor.h"
|
||||
#include "qemu-common.h"
|
||||
|
@ -46,8 +47,7 @@
|
|||
# define CONFIG_NET_BRIDGE
|
||||
#endif
|
||||
|
||||
static QTAILQ_HEAD(, VLANState) vlans;
|
||||
static QTAILQ_HEAD(, VLANClientState) non_vlan_clients;
|
||||
static QTAILQ_HEAD(, NetClientState) net_clients;
|
||||
|
||||
int default_net = 1;
|
||||
|
||||
|
@ -132,11 +132,11 @@ int parse_host_port(struct sockaddr_in *saddr, const char *str)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void qemu_format_nic_info_str(VLANClientState *vc, uint8_t macaddr[6])
|
||||
void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6])
|
||||
{
|
||||
snprintf(vc->info_str, sizeof(vc->info_str),
|
||||
snprintf(nc->info_str, sizeof(nc->info_str),
|
||||
"model=%s,macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
vc->model,
|
||||
nc->model,
|
||||
macaddr[0], macaddr[1], macaddr[2],
|
||||
macaddr[3], macaddr[4], macaddr[5]);
|
||||
}
|
||||
|
@ -156,23 +156,25 @@ void qemu_macaddr_default_if_unset(MACAddr *macaddr)
|
|||
macaddr->a[5] = 0x56 + index++;
|
||||
}
|
||||
|
||||
static char *assign_name(VLANClientState *vc1, const char *model)
|
||||
/**
|
||||
* Generate a name for net client
|
||||
*
|
||||
* Only net clients created with the legacy -net option need this. Naming is
|
||||
* mandatory for net clients created with -netdev.
|
||||
*/
|
||||
static char *assign_name(NetClientState *nc1, const char *model)
|
||||
{
|
||||
VLANState *vlan;
|
||||
VLANClientState *vc;
|
||||
NetClientState *nc;
|
||||
char buf[256];
|
||||
int id = 0;
|
||||
|
||||
QTAILQ_FOREACH(vlan, &vlans, next) {
|
||||
QTAILQ_FOREACH(vc, &vlan->clients, next) {
|
||||
if (vc != vc1 && strcmp(vc->model, model) == 0) {
|
||||
id++;
|
||||
}
|
||||
QTAILQ_FOREACH(nc, &net_clients, next) {
|
||||
if (nc == nc1) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
|
||||
if (vc != vc1 && strcmp(vc->model, model) == 0) {
|
||||
/* For compatibility only bump id for net clients on a vlan */
|
||||
if (strcmp(nc->model, model) == 0 &&
|
||||
net_hub_id_for_client(nc, NULL) == 0) {
|
||||
id++;
|
||||
}
|
||||
}
|
||||
|
@ -182,55 +184,35 @@ static char *assign_name(VLANClientState *vc1, const char *model)
|
|||
return g_strdup(buf);
|
||||
}
|
||||
|
||||
static ssize_t qemu_deliver_packet(VLANClientState *sender,
|
||||
unsigned flags,
|
||||
const uint8_t *data,
|
||||
size_t size,
|
||||
void *opaque);
|
||||
static ssize_t qemu_deliver_packet_iov(VLANClientState *sender,
|
||||
unsigned flags,
|
||||
const struct iovec *iov,
|
||||
int iovcnt,
|
||||
void *opaque);
|
||||
|
||||
VLANClientState *qemu_new_net_client(NetClientInfo *info,
|
||||
VLANState *vlan,
|
||||
VLANClientState *peer,
|
||||
const char *model,
|
||||
const char *name)
|
||||
NetClientState *qemu_new_net_client(NetClientInfo *info,
|
||||
NetClientState *peer,
|
||||
const char *model,
|
||||
const char *name)
|
||||
{
|
||||
VLANClientState *vc;
|
||||
NetClientState *nc;
|
||||
|
||||
assert(info->size >= sizeof(VLANClientState));
|
||||
assert(info->size >= sizeof(NetClientState));
|
||||
|
||||
vc = g_malloc0(info->size);
|
||||
nc = g_malloc0(info->size);
|
||||
|
||||
vc->info = info;
|
||||
vc->model = g_strdup(model);
|
||||
nc->info = info;
|
||||
nc->model = g_strdup(model);
|
||||
if (name) {
|
||||
vc->name = g_strdup(name);
|
||||
nc->name = g_strdup(name);
|
||||
} else {
|
||||
vc->name = assign_name(vc, model);
|
||||
nc->name = assign_name(nc, model);
|
||||
}
|
||||
|
||||
if (vlan) {
|
||||
assert(!peer);
|
||||
vc->vlan = vlan;
|
||||
QTAILQ_INSERT_TAIL(&vc->vlan->clients, vc, next);
|
||||
} else {
|
||||
if (peer) {
|
||||
assert(!peer->peer);
|
||||
vc->peer = peer;
|
||||
peer->peer = vc;
|
||||
}
|
||||
QTAILQ_INSERT_TAIL(&non_vlan_clients, vc, next);
|
||||
|
||||
vc->send_queue = qemu_new_net_queue(qemu_deliver_packet,
|
||||
qemu_deliver_packet_iov,
|
||||
vc);
|
||||
if (peer) {
|
||||
assert(!peer->peer);
|
||||
nc->peer = peer;
|
||||
peer->peer = nc;
|
||||
}
|
||||
QTAILQ_INSERT_TAIL(&net_clients, nc, next);
|
||||
|
||||
return vc;
|
||||
nc->send_queue = qemu_new_net_queue(nc);
|
||||
|
||||
return nc;
|
||||
}
|
||||
|
||||
NICState *qemu_new_nic(NetClientInfo *info,
|
||||
|
@ -239,13 +221,13 @@ NICState *qemu_new_nic(NetClientInfo *info,
|
|||
const char *name,
|
||||
void *opaque)
|
||||
{
|
||||
VLANClientState *nc;
|
||||
NetClientState *nc;
|
||||
NICState *nic;
|
||||
|
||||
assert(info->type == NET_CLIENT_OPTIONS_KIND_NIC);
|
||||
assert(info->size >= sizeof(NICState));
|
||||
|
||||
nc = qemu_new_net_client(info, conf->vlan, conf->peer, model, name);
|
||||
nc = qemu_new_net_client(info, conf->peer, model, name);
|
||||
|
||||
nic = DO_UPCAST(NICState, nc, nc);
|
||||
nic->conf = conf;
|
||||
|
@ -254,250 +236,131 @@ NICState *qemu_new_nic(NetClientInfo *info,
|
|||
return nic;
|
||||
}
|
||||
|
||||
static void qemu_cleanup_vlan_client(VLANClientState *vc)
|
||||
static void qemu_cleanup_net_client(NetClientState *nc)
|
||||
{
|
||||
if (vc->vlan) {
|
||||
QTAILQ_REMOVE(&vc->vlan->clients, vc, next);
|
||||
} else {
|
||||
QTAILQ_REMOVE(&non_vlan_clients, vc, next);
|
||||
}
|
||||
QTAILQ_REMOVE(&net_clients, nc, next);
|
||||
|
||||
if (vc->info->cleanup) {
|
||||
vc->info->cleanup(vc);
|
||||
if (nc->info->cleanup) {
|
||||
nc->info->cleanup(nc);
|
||||
}
|
||||
}
|
||||
|
||||
static void qemu_free_vlan_client(VLANClientState *vc)
|
||||
static void qemu_free_net_client(NetClientState *nc)
|
||||
{
|
||||
if (!vc->vlan) {
|
||||
if (vc->send_queue) {
|
||||
qemu_del_net_queue(vc->send_queue);
|
||||
}
|
||||
if (vc->peer) {
|
||||
vc->peer->peer = NULL;
|
||||
}
|
||||
if (nc->send_queue) {
|
||||
qemu_del_net_queue(nc->send_queue);
|
||||
}
|
||||
g_free(vc->name);
|
||||
g_free(vc->model);
|
||||
g_free(vc);
|
||||
if (nc->peer) {
|
||||
nc->peer->peer = NULL;
|
||||
}
|
||||
g_free(nc->name);
|
||||
g_free(nc->model);
|
||||
g_free(nc);
|
||||
}
|
||||
|
||||
void qemu_del_vlan_client(VLANClientState *vc)
|
||||
void qemu_del_net_client(NetClientState *nc)
|
||||
{
|
||||
/* If there is a peer NIC, delete and cleanup client, but do not free. */
|
||||
if (!vc->vlan && vc->peer && vc->peer->info->type == NET_CLIENT_OPTIONS_KIND_NIC) {
|
||||
NICState *nic = DO_UPCAST(NICState, nc, vc->peer);
|
||||
if (nc->peer && nc->peer->info->type == NET_CLIENT_OPTIONS_KIND_NIC) {
|
||||
NICState *nic = DO_UPCAST(NICState, nc, nc->peer);
|
||||
if (nic->peer_deleted) {
|
||||
return;
|
||||
}
|
||||
nic->peer_deleted = true;
|
||||
/* Let NIC know peer is gone. */
|
||||
vc->peer->link_down = true;
|
||||
if (vc->peer->info->link_status_changed) {
|
||||
vc->peer->info->link_status_changed(vc->peer);
|
||||
nc->peer->link_down = true;
|
||||
if (nc->peer->info->link_status_changed) {
|
||||
nc->peer->info->link_status_changed(nc->peer);
|
||||
}
|
||||
qemu_cleanup_vlan_client(vc);
|
||||
qemu_cleanup_net_client(nc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If this is a peer NIC and peer has already been deleted, free it now. */
|
||||
if (!vc->vlan && vc->peer && vc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) {
|
||||
NICState *nic = DO_UPCAST(NICState, nc, vc);
|
||||
if (nc->peer && nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) {
|
||||
NICState *nic = DO_UPCAST(NICState, nc, nc);
|
||||
if (nic->peer_deleted) {
|
||||
qemu_free_vlan_client(vc->peer);
|
||||
qemu_free_net_client(nc->peer);
|
||||
}
|
||||
}
|
||||
|
||||
qemu_cleanup_vlan_client(vc);
|
||||
qemu_free_vlan_client(vc);
|
||||
}
|
||||
|
||||
VLANClientState *
|
||||
qemu_find_vlan_client_by_name(Monitor *mon, int vlan_id,
|
||||
const char *client_str)
|
||||
{
|
||||
VLANState *vlan;
|
||||
VLANClientState *vc;
|
||||
|
||||
vlan = qemu_find_vlan(vlan_id, 0);
|
||||
if (!vlan) {
|
||||
monitor_printf(mon, "unknown VLAN %d\n", vlan_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
QTAILQ_FOREACH(vc, &vlan->clients, next) {
|
||||
if (!strcmp(vc->name, client_str)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!vc) {
|
||||
monitor_printf(mon, "can't find device %s on VLAN %d\n",
|
||||
client_str, vlan_id);
|
||||
}
|
||||
|
||||
return vc;
|
||||
qemu_cleanup_net_client(nc);
|
||||
qemu_free_net_client(nc);
|
||||
}
|
||||
|
||||
void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)
|
||||
{
|
||||
VLANClientState *nc;
|
||||
VLANState *vlan;
|
||||
NetClientState *nc;
|
||||
|
||||
QTAILQ_FOREACH(nc, &non_vlan_clients, next) {
|
||||
QTAILQ_FOREACH(nc, &net_clients, next) {
|
||||
if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) {
|
||||
func(DO_UPCAST(NICState, nc, nc), opaque);
|
||||
}
|
||||
}
|
||||
|
||||
QTAILQ_FOREACH(vlan, &vlans, next) {
|
||||
QTAILQ_FOREACH(nc, &vlan->clients, next) {
|
||||
if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) {
|
||||
func(DO_UPCAST(NICState, nc, nc), opaque);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int qemu_can_send_packet(VLANClientState *sender)
|
||||
int qemu_can_send_packet(NetClientState *sender)
|
||||
{
|
||||
VLANState *vlan = sender->vlan;
|
||||
VLANClientState *vc;
|
||||
|
||||
if (sender->peer) {
|
||||
if (sender->peer->receive_disabled) {
|
||||
return 0;
|
||||
} else if (sender->peer->info->can_receive &&
|
||||
!sender->peer->info->can_receive(sender->peer)) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sender->vlan) {
|
||||
if (!sender->peer) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
QTAILQ_FOREACH(vc, &vlan->clients, next) {
|
||||
if (vc == sender) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* no can_receive() handler, they can always receive */
|
||||
if (vc->info->can_receive && !vc->info->can_receive(vc)) {
|
||||
return 0;
|
||||
}
|
||||
if (sender->peer->receive_disabled) {
|
||||
return 0;
|
||||
} else if (sender->peer->info->can_receive &&
|
||||
!sender->peer->info->can_receive(sender->peer)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static ssize_t qemu_deliver_packet(VLANClientState *sender,
|
||||
unsigned flags,
|
||||
const uint8_t *data,
|
||||
size_t size,
|
||||
void *opaque)
|
||||
ssize_t qemu_deliver_packet(NetClientState *sender,
|
||||
unsigned flags,
|
||||
const uint8_t *data,
|
||||
size_t size,
|
||||
void *opaque)
|
||||
{
|
||||
VLANClientState *vc = opaque;
|
||||
NetClientState *nc = opaque;
|
||||
ssize_t ret;
|
||||
|
||||
if (vc->link_down) {
|
||||
if (nc->link_down) {
|
||||
return size;
|
||||
}
|
||||
|
||||
if (vc->receive_disabled) {
|
||||
if (nc->receive_disabled) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->info->receive_raw) {
|
||||
ret = vc->info->receive_raw(vc, data, size);
|
||||
if (flags & QEMU_NET_PACKET_FLAG_RAW && nc->info->receive_raw) {
|
||||
ret = nc->info->receive_raw(nc, data, size);
|
||||
} else {
|
||||
ret = vc->info->receive(vc, data, size);
|
||||
ret = nc->info->receive(nc, data, size);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
vc->receive_disabled = 1;
|
||||
nc->receive_disabled = 1;
|
||||
};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender,
|
||||
unsigned flags,
|
||||
const uint8_t *buf,
|
||||
size_t size,
|
||||
void *opaque)
|
||||
void qemu_purge_queued_packets(NetClientState *nc)
|
||||
{
|
||||
VLANState *vlan = opaque;
|
||||
VLANClientState *vc;
|
||||
ssize_t ret = -1;
|
||||
|
||||
QTAILQ_FOREACH(vc, &vlan->clients, next) {
|
||||
ssize_t len;
|
||||
|
||||
if (vc == sender) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vc->link_down) {
|
||||
ret = size;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vc->receive_disabled) {
|
||||
ret = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->info->receive_raw) {
|
||||
len = vc->info->receive_raw(vc, buf, size);
|
||||
} else {
|
||||
len = vc->info->receive(vc, buf, size);
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
vc->receive_disabled = 1;
|
||||
}
|
||||
|
||||
ret = (ret >= 0) ? ret : len;
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void qemu_purge_queued_packets(VLANClientState *vc)
|
||||
{
|
||||
NetQueue *queue;
|
||||
|
||||
if (!vc->peer && !vc->vlan) {
|
||||
if (!nc->peer) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (vc->peer) {
|
||||
queue = vc->peer->send_queue;
|
||||
} else {
|
||||
queue = vc->vlan->send_queue;
|
||||
}
|
||||
|
||||
qemu_net_queue_purge(queue, vc);
|
||||
qemu_net_queue_purge(nc->peer->send_queue, nc);
|
||||
}
|
||||
|
||||
void qemu_flush_queued_packets(VLANClientState *vc)
|
||||
void qemu_flush_queued_packets(NetClientState *nc)
|
||||
{
|
||||
NetQueue *queue;
|
||||
nc->receive_disabled = 0;
|
||||
|
||||
vc->receive_disabled = 0;
|
||||
|
||||
if (vc->vlan) {
|
||||
queue = vc->vlan->send_queue;
|
||||
} else {
|
||||
queue = vc->send_queue;
|
||||
}
|
||||
|
||||
qemu_net_queue_flush(queue);
|
||||
qemu_net_queue_flush(nc->send_queue);
|
||||
}
|
||||
|
||||
static ssize_t qemu_send_packet_async_with_flags(VLANClientState *sender,
|
||||
static ssize_t qemu_send_packet_async_with_flags(NetClientState *sender,
|
||||
unsigned flags,
|
||||
const uint8_t *buf, int size,
|
||||
NetPacketSent *sent_cb)
|
||||
|
@ -509,20 +372,16 @@ static ssize_t qemu_send_packet_async_with_flags(VLANClientState *sender,
|
|||
hex_dump(stdout, buf, size);
|
||||
#endif
|
||||
|
||||
if (sender->link_down || (!sender->peer && !sender->vlan)) {
|
||||
if (sender->link_down || !sender->peer) {
|
||||
return size;
|
||||
}
|
||||
|
||||
if (sender->peer) {
|
||||
queue = sender->peer->send_queue;
|
||||
} else {
|
||||
queue = sender->vlan->send_queue;
|
||||
}
|
||||
queue = sender->peer->send_queue;
|
||||
|
||||
return qemu_net_queue_send(queue, sender, flags, buf, size, sent_cb);
|
||||
}
|
||||
|
||||
ssize_t qemu_send_packet_async(VLANClientState *sender,
|
||||
ssize_t qemu_send_packet_async(NetClientState *sender,
|
||||
const uint8_t *buf, int size,
|
||||
NetPacketSent *sent_cb)
|
||||
{
|
||||
|
@ -530,18 +389,18 @@ ssize_t qemu_send_packet_async(VLANClientState *sender,
|
|||
buf, size, sent_cb);
|
||||
}
|
||||
|
||||
void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size)
|
||||
void qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size)
|
||||
{
|
||||
qemu_send_packet_async(vc, buf, size, NULL);
|
||||
qemu_send_packet_async(nc, buf, size, NULL);
|
||||
}
|
||||
|
||||
ssize_t qemu_send_packet_raw(VLANClientState *vc, const uint8_t *buf, int size)
|
||||
ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size)
|
||||
{
|
||||
return qemu_send_packet_async_with_flags(vc, QEMU_NET_PACKET_FLAG_RAW,
|
||||
return qemu_send_packet_async_with_flags(nc, QEMU_NET_PACKET_FLAG_RAW,
|
||||
buf, size, NULL);
|
||||
}
|
||||
|
||||
static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov,
|
||||
static ssize_t nc_sendv_compat(NetClientState *nc, const struct iovec *iov,
|
||||
int iovcnt)
|
||||
{
|
||||
uint8_t buffer[4096];
|
||||
|
@ -549,79 +408,39 @@ static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov,
|
|||
|
||||
offset = iov_to_buf(iov, iovcnt, 0, buffer, sizeof(buffer));
|
||||
|
||||
return vc->info->receive(vc, buffer, offset);
|
||||
return nc->info->receive(nc, buffer, offset);
|
||||
}
|
||||
|
||||
static ssize_t qemu_deliver_packet_iov(VLANClientState *sender,
|
||||
unsigned flags,
|
||||
const struct iovec *iov,
|
||||
int iovcnt,
|
||||
void *opaque)
|
||||
ssize_t qemu_deliver_packet_iov(NetClientState *sender,
|
||||
unsigned flags,
|
||||
const struct iovec *iov,
|
||||
int iovcnt,
|
||||
void *opaque)
|
||||
{
|
||||
VLANClientState *vc = opaque;
|
||||
NetClientState *nc = opaque;
|
||||
|
||||
if (vc->link_down) {
|
||||
if (nc->link_down) {
|
||||
return iov_size(iov, iovcnt);
|
||||
}
|
||||
|
||||
if (vc->info->receive_iov) {
|
||||
return vc->info->receive_iov(vc, iov, iovcnt);
|
||||
if (nc->info->receive_iov) {
|
||||
return nc->info->receive_iov(nc, iov, iovcnt);
|
||||
} else {
|
||||
return vc_sendv_compat(vc, iov, iovcnt);
|
||||
return nc_sendv_compat(nc, iov, iovcnt);
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t qemu_vlan_deliver_packet_iov(VLANClientState *sender,
|
||||
unsigned flags,
|
||||
const struct iovec *iov,
|
||||
int iovcnt,
|
||||
void *opaque)
|
||||
{
|
||||
VLANState *vlan = opaque;
|
||||
VLANClientState *vc;
|
||||
ssize_t ret = -1;
|
||||
|
||||
QTAILQ_FOREACH(vc, &vlan->clients, next) {
|
||||
ssize_t len;
|
||||
|
||||
if (vc == sender) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vc->link_down) {
|
||||
ret = iov_size(iov, iovcnt);
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(!(flags & QEMU_NET_PACKET_FLAG_RAW));
|
||||
|
||||
if (vc->info->receive_iov) {
|
||||
len = vc->info->receive_iov(vc, iov, iovcnt);
|
||||
} else {
|
||||
len = vc_sendv_compat(vc, iov, iovcnt);
|
||||
}
|
||||
|
||||
ret = (ret >= 0) ? ret : len;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t qemu_sendv_packet_async(VLANClientState *sender,
|
||||
ssize_t qemu_sendv_packet_async(NetClientState *sender,
|
||||
const struct iovec *iov, int iovcnt,
|
||||
NetPacketSent *sent_cb)
|
||||
{
|
||||
NetQueue *queue;
|
||||
|
||||
if (sender->link_down || (!sender->peer && !sender->vlan)) {
|
||||
if (sender->link_down || !sender->peer) {
|
||||
return iov_size(iov, iovcnt);
|
||||
}
|
||||
|
||||
if (sender->peer) {
|
||||
queue = sender->peer->send_queue;
|
||||
} else {
|
||||
queue = sender->vlan->send_queue;
|
||||
}
|
||||
queue = sender->peer->send_queue;
|
||||
|
||||
return qemu_net_queue_send_iov(queue, sender,
|
||||
QEMU_NET_PACKET_FLAG_NONE,
|
||||
|
@ -629,48 +448,20 @@ ssize_t qemu_sendv_packet_async(VLANClientState *sender,
|
|||
}
|
||||
|
||||
ssize_t
|
||||
qemu_sendv_packet(VLANClientState *vc, const struct iovec *iov, int iovcnt)
|
||||
qemu_sendv_packet(NetClientState *nc, const struct iovec *iov, int iovcnt)
|
||||
{
|
||||
return qemu_sendv_packet_async(vc, iov, iovcnt, NULL);
|
||||
return qemu_sendv_packet_async(nc, iov, iovcnt, NULL);
|
||||
}
|
||||
|
||||
/* find or alloc a new VLAN */
|
||||
VLANState *qemu_find_vlan(int id, int allocate)
|
||||
NetClientState *qemu_find_netdev(const char *id)
|
||||
{
|
||||
VLANState *vlan;
|
||||
NetClientState *nc;
|
||||
|
||||
QTAILQ_FOREACH(vlan, &vlans, next) {
|
||||
if (vlan->id == id) {
|
||||
return vlan;
|
||||
}
|
||||
}
|
||||
|
||||
if (!allocate) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vlan = g_malloc0(sizeof(VLANState));
|
||||
vlan->id = id;
|
||||
QTAILQ_INIT(&vlan->clients);
|
||||
|
||||
vlan->send_queue = qemu_new_net_queue(qemu_vlan_deliver_packet,
|
||||
qemu_vlan_deliver_packet_iov,
|
||||
vlan);
|
||||
|
||||
QTAILQ_INSERT_TAIL(&vlans, vlan, next);
|
||||
|
||||
return vlan;
|
||||
}
|
||||
|
||||
VLANClientState *qemu_find_netdev(const char *id)
|
||||
{
|
||||
VLANClientState *vc;
|
||||
|
||||
QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
|
||||
if (vc->info->type == NET_CLIENT_OPTIONS_KIND_NIC)
|
||||
QTAILQ_FOREACH(nc, &net_clients, next) {
|
||||
if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC)
|
||||
continue;
|
||||
if (!strcmp(vc->name, id)) {
|
||||
return vc;
|
||||
if (!strcmp(nc->name, id)) {
|
||||
return nc;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -750,7 +541,7 @@ int net_handle_fd_param(Monitor *mon, const char *param)
|
|||
}
|
||||
|
||||
static int net_init_nic(const NetClientOptions *opts, const char *name,
|
||||
VLANState *vlan)
|
||||
NetClientState *peer)
|
||||
{
|
||||
int idx;
|
||||
NICInfo *nd;
|
||||
|
@ -776,8 +567,8 @@ static int net_init_nic(const NetClientOptions *opts, const char *name,
|
|||
return -1;
|
||||
}
|
||||
} else {
|
||||
assert(vlan);
|
||||
nd->vlan = vlan;
|
||||
assert(peer);
|
||||
nd->netdev = peer;
|
||||
}
|
||||
if (name) {
|
||||
nd->name = g_strdup(name);
|
||||
|
@ -816,20 +607,21 @@ static int net_init_nic(const NetClientOptions *opts, const char *name,
|
|||
static int (* const net_client_init_fun[NET_CLIENT_OPTIONS_KIND_MAX])(
|
||||
const NetClientOptions *opts,
|
||||
const char *name,
|
||||
VLANState *vlan) = {
|
||||
[NET_CLIENT_OPTIONS_KIND_NIC] = net_init_nic,
|
||||
NetClientState *peer) = {
|
||||
[NET_CLIENT_OPTIONS_KIND_NIC] = net_init_nic,
|
||||
#ifdef CONFIG_SLIRP
|
||||
[NET_CLIENT_OPTIONS_KIND_USER] = net_init_slirp,
|
||||
[NET_CLIENT_OPTIONS_KIND_USER] = net_init_slirp,
|
||||
#endif
|
||||
[NET_CLIENT_OPTIONS_KIND_TAP] = net_init_tap,
|
||||
[NET_CLIENT_OPTIONS_KIND_SOCKET] = net_init_socket,
|
||||
[NET_CLIENT_OPTIONS_KIND_TAP] = net_init_tap,
|
||||
[NET_CLIENT_OPTIONS_KIND_SOCKET] = net_init_socket,
|
||||
#ifdef CONFIG_VDE
|
||||
[NET_CLIENT_OPTIONS_KIND_VDE] = net_init_vde,
|
||||
[NET_CLIENT_OPTIONS_KIND_VDE] = net_init_vde,
|
||||
#endif
|
||||
[NET_CLIENT_OPTIONS_KIND_DUMP] = net_init_dump,
|
||||
[NET_CLIENT_OPTIONS_KIND_DUMP] = net_init_dump,
|
||||
#ifdef CONFIG_NET_BRIDGE
|
||||
[NET_CLIENT_OPTIONS_KIND_BRIDGE] = net_init_bridge,
|
||||
[NET_CLIENT_OPTIONS_KIND_BRIDGE] = net_init_bridge,
|
||||
#endif
|
||||
[NET_CLIENT_OPTIONS_KIND_HUBPORT] = net_init_hubport,
|
||||
};
|
||||
|
||||
|
||||
|
@ -859,6 +651,7 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp)
|
|||
#ifdef CONFIG_NET_BRIDGE
|
||||
case NET_CLIENT_OPTIONS_KIND_BRIDGE:
|
||||
#endif
|
||||
case NET_CLIENT_OPTIONS_KIND_HUBPORT:
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -874,17 +667,17 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp)
|
|||
}
|
||||
|
||||
if (net_client_init_fun[opts->kind]) {
|
||||
VLANState *vlan = NULL;
|
||||
NetClientState *peer = NULL;
|
||||
|
||||
/* Do not add to a vlan if it's a -netdev or a nic with a netdev=
|
||||
* parameter. */
|
||||
if (!is_netdev &&
|
||||
(opts->kind != NET_CLIENT_OPTIONS_KIND_NIC ||
|
||||
!opts->nic->has_netdev)) {
|
||||
vlan = qemu_find_vlan(u.net->has_vlan ? u.net->vlan : 0, true);
|
||||
peer = net_hub_add_port(u.net->has_vlan ? u.net->vlan : 0, NULL);
|
||||
}
|
||||
|
||||
if (net_client_init_fun[opts->kind](opts, name, vlan) < 0) {
|
||||
if (net_client_init_fun[opts->kind](opts, name, peer) < 0) {
|
||||
/* TODO push error reporting into init() methods */
|
||||
error_set(errp, QERR_DEVICE_INIT_FAILED,
|
||||
NetClientOptionsKind_lookup[opts->kind]);
|
||||
|
@ -986,19 +779,19 @@ void net_host_device_add(Monitor *mon, const QDict *qdict)
|
|||
|
||||
void net_host_device_remove(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
VLANClientState *vc;
|
||||
NetClientState *nc;
|
||||
int vlan_id = qdict_get_int(qdict, "vlan_id");
|
||||
const char *device = qdict_get_str(qdict, "device");
|
||||
|
||||
vc = qemu_find_vlan_client_by_name(mon, vlan_id, device);
|
||||
if (!vc) {
|
||||
nc = net_hub_find_client_by_name(vlan_id, device);
|
||||
if (!nc) {
|
||||
return;
|
||||
}
|
||||
if (!net_host_check_device(vc->model)) {
|
||||
if (!net_host_check_device(nc->model)) {
|
||||
monitor_printf(mon, "invalid host network device %s\n", device);
|
||||
return;
|
||||
}
|
||||
qemu_del_vlan_client(vc);
|
||||
qemu_del_net_client(nc);
|
||||
}
|
||||
|
||||
void netdev_add(QemuOpts *opts, Error **errp)
|
||||
|
@ -1038,48 +831,45 @@ exit_err:
|
|||
|
||||
void qmp_netdev_del(const char *id, Error **errp)
|
||||
{
|
||||
VLANClientState *vc;
|
||||
NetClientState *nc;
|
||||
|
||||
vc = qemu_find_netdev(id);
|
||||
if (!vc) {
|
||||
nc = qemu_find_netdev(id);
|
||||
if (!nc) {
|
||||
error_set(errp, QERR_DEVICE_NOT_FOUND, id);
|
||||
return;
|
||||
}
|
||||
|
||||
qemu_del_vlan_client(vc);
|
||||
qemu_del_net_client(nc);
|
||||
qemu_opts_del(qemu_opts_find(qemu_find_opts_err("netdev", errp), id));
|
||||
}
|
||||
|
||||
static void print_net_client(Monitor *mon, VLANClientState *vc)
|
||||
void print_net_client(Monitor *mon, NetClientState *nc)
|
||||
{
|
||||
monitor_printf(mon, "%s: type=%s,%s\n", vc->name,
|
||||
NetClientOptionsKind_lookup[vc->info->type], vc->info_str);
|
||||
monitor_printf(mon, "%s: type=%s,%s\n", nc->name,
|
||||
NetClientOptionsKind_lookup[nc->info->type], nc->info_str);
|
||||
}
|
||||
|
||||
void do_info_network(Monitor *mon)
|
||||
{
|
||||
VLANState *vlan;
|
||||
VLANClientState *vc, *peer;
|
||||
NetClientState *nc, *peer;
|
||||
NetClientOptionsKind type;
|
||||
|
||||
QTAILQ_FOREACH(vlan, &vlans, next) {
|
||||
monitor_printf(mon, "VLAN %d devices:\n", vlan->id);
|
||||
net_hub_info(mon);
|
||||
|
||||
QTAILQ_FOREACH(vc, &vlan->clients, next) {
|
||||
monitor_printf(mon, " ");
|
||||
print_net_client(mon, vc);
|
||||
QTAILQ_FOREACH(nc, &net_clients, next) {
|
||||
peer = nc->peer;
|
||||
type = nc->info->type;
|
||||
|
||||
/* Skip if already printed in hub info */
|
||||
if (net_hub_id_for_client(nc, NULL) == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
monitor_printf(mon, "Devices not on any VLAN:\n");
|
||||
QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
|
||||
peer = vc->peer;
|
||||
type = vc->info->type;
|
||||
|
||||
if (!peer || type == NET_CLIENT_OPTIONS_KIND_NIC) {
|
||||
monitor_printf(mon, " ");
|
||||
print_net_client(mon, vc);
|
||||
print_net_client(mon, nc);
|
||||
} /* else it's a netdev connected to a NIC, printed with the NIC */
|
||||
if (peer && type == NET_CLIENT_OPTIONS_KIND_NIC) {
|
||||
monitor_printf(mon, " \\ ");
|
||||
monitor_printf(mon, " \\ ");
|
||||
print_net_client(mon, peer);
|
||||
}
|
||||
}
|
||||
|
@ -1087,32 +877,23 @@ void do_info_network(Monitor *mon)
|
|||
|
||||
void qmp_set_link(const char *name, bool up, Error **errp)
|
||||
{
|
||||
VLANState *vlan;
|
||||
VLANClientState *vc = NULL;
|
||||
NetClientState *nc = NULL;
|
||||
|
||||
QTAILQ_FOREACH(vlan, &vlans, next) {
|
||||
QTAILQ_FOREACH(vc, &vlan->clients, next) {
|
||||
if (strcmp(vc->name, name) == 0) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
|
||||
if (!strcmp(vc->name, name)) {
|
||||
QTAILQ_FOREACH(nc, &net_clients, next) {
|
||||
if (!strcmp(nc->name, name)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
done:
|
||||
|
||||
if (!vc) {
|
||||
if (!nc) {
|
||||
error_set(errp, QERR_DEVICE_NOT_FOUND, name);
|
||||
return;
|
||||
}
|
||||
|
||||
vc->link_down = !up;
|
||||
nc->link_down = !up;
|
||||
|
||||
if (vc->info->link_status_changed) {
|
||||
vc->info->link_status_changed(vc);
|
||||
if (nc->info->link_status_changed) {
|
||||
nc->info->link_status_changed(nc);
|
||||
}
|
||||
|
||||
/* Notify peer. Don't update peer link status: this makes it possible to
|
||||
|
@ -1122,31 +903,23 @@ done:
|
|||
* Current behaviour is compatible with qemu vlans where there could be
|
||||
* multiple clients that can still communicate with each other in
|
||||
* disconnected mode. For now maintain this compatibility. */
|
||||
if (vc->peer && vc->peer->info->link_status_changed) {
|
||||
vc->peer->info->link_status_changed(vc->peer);
|
||||
if (nc->peer && nc->peer->info->link_status_changed) {
|
||||
nc->peer->info->link_status_changed(nc->peer);
|
||||
}
|
||||
}
|
||||
|
||||
void net_cleanup(void)
|
||||
{
|
||||
VLANState *vlan;
|
||||
VLANClientState *vc, *next_vc;
|
||||
NetClientState *nc, *next_vc;
|
||||
|
||||
QTAILQ_FOREACH(vlan, &vlans, next) {
|
||||
QTAILQ_FOREACH_SAFE(vc, &vlan->clients, next, next_vc) {
|
||||
qemu_del_vlan_client(vc);
|
||||
}
|
||||
}
|
||||
|
||||
QTAILQ_FOREACH_SAFE(vc, &non_vlan_clients, next, next_vc) {
|
||||
qemu_del_vlan_client(vc);
|
||||
QTAILQ_FOREACH_SAFE(nc, &net_clients, next, next_vc) {
|
||||
qemu_del_net_client(nc);
|
||||
}
|
||||
}
|
||||
|
||||
void net_check_clients(void)
|
||||
{
|
||||
VLANState *vlan;
|
||||
VLANClientState *vc;
|
||||
NetClientState *nc;
|
||||
int i;
|
||||
|
||||
/* Don't warn about the default network setup that you get if
|
||||
|
@ -1161,35 +934,13 @@ void net_check_clients(void)
|
|||
return;
|
||||
}
|
||||
|
||||
QTAILQ_FOREACH(vlan, &vlans, next) {
|
||||
int has_nic = 0, has_host_dev = 0;
|
||||
net_hub_check_clients();
|
||||
|
||||
QTAILQ_FOREACH(vc, &vlan->clients, next) {
|
||||
switch (vc->info->type) {
|
||||
case NET_CLIENT_OPTIONS_KIND_NIC:
|
||||
has_nic = 1;
|
||||
break;
|
||||
case NET_CLIENT_OPTIONS_KIND_USER:
|
||||
case NET_CLIENT_OPTIONS_KIND_TAP:
|
||||
case NET_CLIENT_OPTIONS_KIND_SOCKET:
|
||||
case NET_CLIENT_OPTIONS_KIND_VDE:
|
||||
has_host_dev = 1;
|
||||
break;
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
if (has_host_dev && !has_nic)
|
||||
fprintf(stderr, "Warning: vlan %d with no nics\n", vlan->id);
|
||||
if (has_nic && !has_host_dev)
|
||||
fprintf(stderr,
|
||||
"Warning: vlan %d is not connected to host network\n",
|
||||
vlan->id);
|
||||
}
|
||||
QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
|
||||
if (!vc->peer) {
|
||||
QTAILQ_FOREACH(nc, &net_clients, next) {
|
||||
if (!nc->peer) {
|
||||
fprintf(stderr, "Warning: %s %s has no peer\n",
|
||||
vc->info->type == NET_CLIENT_OPTIONS_KIND_NIC ? "nic" : "netdev",
|
||||
vc->name);
|
||||
nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC ?
|
||||
"nic" : "netdev", nc->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1249,8 +1000,7 @@ int net_init_clients(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
QTAILQ_INIT(&vlans);
|
||||
QTAILQ_INIT(&non_vlan_clients);
|
||||
QTAILQ_INIT(&net_clients);
|
||||
|
||||
if (qemu_opts_foreach(qemu_find_opts("netdev"), net_init_netdev, NULL, 1) == -1)
|
||||
return -1;
|
||||
|
|
86
net.h
86
net.h
|
@ -17,25 +17,24 @@ struct MACAddr {
|
|||
|
||||
typedef struct NICConf {
|
||||
MACAddr macaddr;
|
||||
VLANState *vlan;
|
||||
VLANClientState *peer;
|
||||
NetClientState *peer;
|
||||
int32_t bootindex;
|
||||
} NICConf;
|
||||
|
||||
#define DEFINE_NIC_PROPERTIES(_state, _conf) \
|
||||
DEFINE_PROP_MACADDR("mac", _state, _conf.macaddr), \
|
||||
DEFINE_PROP_VLAN("vlan", _state, _conf.vlan), \
|
||||
DEFINE_PROP_VLAN("vlan", _state, _conf.peer), \
|
||||
DEFINE_PROP_NETDEV("netdev", _state, _conf.peer), \
|
||||
DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1)
|
||||
|
||||
/* VLANs support */
|
||||
/* Net clients */
|
||||
|
||||
typedef void (NetPoll)(VLANClientState *, bool enable);
|
||||
typedef int (NetCanReceive)(VLANClientState *);
|
||||
typedef ssize_t (NetReceive)(VLANClientState *, const uint8_t *, size_t);
|
||||
typedef ssize_t (NetReceiveIOV)(VLANClientState *, const struct iovec *, int);
|
||||
typedef void (NetCleanup) (VLANClientState *);
|
||||
typedef void (LinkStatusChanged)(VLANClientState *);
|
||||
typedef void (NetPoll)(NetClientState *, bool enable);
|
||||
typedef int (NetCanReceive)(NetClientState *);
|
||||
typedef ssize_t (NetReceive)(NetClientState *, const uint8_t *, size_t);
|
||||
typedef ssize_t (NetReceiveIOV)(NetClientState *, const struct iovec *, int);
|
||||
typedef void (NetCleanup) (NetClientState *);
|
||||
typedef void (LinkStatusChanged)(NetClientState *);
|
||||
|
||||
typedef struct NetClientInfo {
|
||||
NetClientOptionsKind type;
|
||||
|
@ -49,12 +48,11 @@ typedef struct NetClientInfo {
|
|||
NetPoll *poll;
|
||||
} NetClientInfo;
|
||||
|
||||
struct VLANClientState {
|
||||
struct NetClientState {
|
||||
NetClientInfo *info;
|
||||
int link_down;
|
||||
QTAILQ_ENTRY(VLANClientState) next;
|
||||
struct VLANState *vlan;
|
||||
VLANClientState *peer;
|
||||
QTAILQ_ENTRY(NetClientState) next;
|
||||
NetClientState *peer;
|
||||
NetQueue *send_queue;
|
||||
char *model;
|
||||
char *name;
|
||||
|
@ -63,54 +61,57 @@ struct VLANClientState {
|
|||
};
|
||||
|
||||
typedef struct NICState {
|
||||
VLANClientState nc;
|
||||
NetClientState nc;
|
||||
NICConf *conf;
|
||||
void *opaque;
|
||||
bool peer_deleted;
|
||||
} NICState;
|
||||
|
||||
struct VLANState {
|
||||
int id;
|
||||
QTAILQ_HEAD(, VLANClientState) clients;
|
||||
QTAILQ_ENTRY(VLANState) next;
|
||||
NetQueue *send_queue;
|
||||
};
|
||||
|
||||
VLANState *qemu_find_vlan(int id, int allocate);
|
||||
VLANClientState *qemu_find_netdev(const char *id);
|
||||
VLANClientState *qemu_new_net_client(NetClientInfo *info,
|
||||
VLANState *vlan,
|
||||
VLANClientState *peer,
|
||||
const char *model,
|
||||
const char *name);
|
||||
NetClientState *qemu_find_netdev(const char *id);
|
||||
NetClientState *qemu_new_net_client(NetClientInfo *info,
|
||||
NetClientState *peer,
|
||||
const char *model,
|
||||
const char *name);
|
||||
NICState *qemu_new_nic(NetClientInfo *info,
|
||||
NICConf *conf,
|
||||
const char *model,
|
||||
const char *name,
|
||||
void *opaque);
|
||||
void qemu_del_vlan_client(VLANClientState *vc);
|
||||
VLANClientState *qemu_find_vlan_client_by_name(Monitor *mon, int vlan_id,
|
||||
const char *client_str);
|
||||
void qemu_del_net_client(NetClientState *nc);
|
||||
NetClientState *qemu_find_vlan_client_by_name(Monitor *mon, int vlan_id,
|
||||
const char *client_str);
|
||||
typedef void (*qemu_nic_foreach)(NICState *nic, void *opaque);
|
||||
void qemu_foreach_nic(qemu_nic_foreach func, void *opaque);
|
||||
int qemu_can_send_packet(VLANClientState *vc);
|
||||
ssize_t qemu_sendv_packet(VLANClientState *vc, const struct iovec *iov,
|
||||
int qemu_can_send_packet(NetClientState *nc);
|
||||
ssize_t qemu_sendv_packet(NetClientState *nc, const struct iovec *iov,
|
||||
int iovcnt);
|
||||
ssize_t qemu_sendv_packet_async(VLANClientState *vc, const struct iovec *iov,
|
||||
ssize_t qemu_sendv_packet_async(NetClientState *nc, const struct iovec *iov,
|
||||
int iovcnt, NetPacketSent *sent_cb);
|
||||
void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size);
|
||||
ssize_t qemu_send_packet_raw(VLANClientState *vc, const uint8_t *buf, int size);
|
||||
ssize_t qemu_send_packet_async(VLANClientState *vc, const uint8_t *buf,
|
||||
void qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size);
|
||||
ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size);
|
||||
ssize_t qemu_send_packet_async(NetClientState *nc, const uint8_t *buf,
|
||||
int size, NetPacketSent *sent_cb);
|
||||
void qemu_purge_queued_packets(VLANClientState *vc);
|
||||
void qemu_flush_queued_packets(VLANClientState *vc);
|
||||
void qemu_format_nic_info_str(VLANClientState *vc, uint8_t macaddr[6]);
|
||||
void qemu_purge_queued_packets(NetClientState *nc);
|
||||
void qemu_flush_queued_packets(NetClientState *nc);
|
||||
void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6]);
|
||||
void qemu_macaddr_default_if_unset(MACAddr *macaddr);
|
||||
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);
|
||||
|
||||
ssize_t qemu_deliver_packet(NetClientState *sender,
|
||||
unsigned flags,
|
||||
const uint8_t *data,
|
||||
size_t size,
|
||||
void *opaque);
|
||||
ssize_t qemu_deliver_packet_iov(NetClientState *sender,
|
||||
unsigned flags,
|
||||
const struct iovec *iov,
|
||||
int iovcnt,
|
||||
void *opaque);
|
||||
|
||||
void print_net_client(Monitor *mon, NetClientState *nc);
|
||||
void do_info_network(Monitor *mon);
|
||||
|
||||
/* NIC info */
|
||||
|
@ -122,8 +123,7 @@ struct NICInfo {
|
|||
char *model;
|
||||
char *name;
|
||||
char *devaddr;
|
||||
VLANState *vlan;
|
||||
VLANClientState *netdev;
|
||||
NetClientState *netdev;
|
||||
int used; /* is this slot in nd_table[] being used? */
|
||||
int instantiated; /* does this NICInfo correspond to an instantiated NIC? */
|
||||
int nvectors;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
common-obj-y = queue.o checksum.o util.o
|
||||
common-obj-y = queue.o checksum.o util.o hub.o
|
||||
common-obj-y += socket.o
|
||||
common-obj-y += dump.o
|
||||
common-obj-$(CONFIG_POSIX) += tap.o
|
||||
|
|
27
net/dump.c
27
net/dump.c
|
@ -27,9 +27,10 @@
|
|||
#include "qemu-error.h"
|
||||
#include "qemu-log.h"
|
||||
#include "qemu-timer.h"
|
||||
#include "hub.h"
|
||||
|
||||
typedef struct DumpState {
|
||||
VLANClientState nc;
|
||||
NetClientState nc;
|
||||
int64_t start_ts;
|
||||
int fd;
|
||||
int pcap_caplen;
|
||||
|
@ -56,7 +57,7 @@ struct pcap_sf_pkthdr {
|
|||
uint32_t len;
|
||||
};
|
||||
|
||||
static ssize_t dump_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
static ssize_t dump_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
DumpState *s = DO_UPCAST(DumpState, nc, nc);
|
||||
struct pcap_sf_pkthdr hdr;
|
||||
|
@ -85,7 +86,7 @@ static ssize_t dump_receive(VLANClientState *nc, const uint8_t *buf, size_t size
|
|||
return size;
|
||||
}
|
||||
|
||||
static void dump_cleanup(VLANClientState *nc)
|
||||
static void dump_cleanup(NetClientState *nc)
|
||||
{
|
||||
DumpState *s = DO_UPCAST(DumpState, nc, nc);
|
||||
|
||||
|
@ -99,11 +100,11 @@ static NetClientInfo net_dump_info = {
|
|||
.cleanup = dump_cleanup,
|
||||
};
|
||||
|
||||
static int net_dump_init(VLANState *vlan, const char *device,
|
||||
static int net_dump_init(NetClientState *peer, const char *device,
|
||||
const char *name, const char *filename, int len)
|
||||
{
|
||||
struct pcap_file_hdr hdr;
|
||||
VLANClientState *nc;
|
||||
NetClientState *nc;
|
||||
DumpState *s;
|
||||
struct tm tm;
|
||||
int fd;
|
||||
|
@ -128,7 +129,7 @@ static int net_dump_init(VLANState *vlan, const char *device,
|
|||
return -1;
|
||||
}
|
||||
|
||||
nc = qemu_new_net_client(&net_dump_info, vlan, NULL, device, name);
|
||||
nc = qemu_new_net_client(&net_dump_info, peer, device, name);
|
||||
|
||||
snprintf(nc->info_str, sizeof(nc->info_str),
|
||||
"dump to %s (len=%d)", filename, len);
|
||||
|
@ -145,7 +146,7 @@ static int net_dump_init(VLANState *vlan, const char *device,
|
|||
}
|
||||
|
||||
int net_init_dump(const NetClientOptions *opts, const char *name,
|
||||
VLANState *vlan)
|
||||
NetClientState *peer)
|
||||
{
|
||||
int len;
|
||||
const char *file;
|
||||
|
@ -155,12 +156,18 @@ int net_init_dump(const NetClientOptions *opts, const char *name,
|
|||
assert(opts->kind == NET_CLIENT_OPTIONS_KIND_DUMP);
|
||||
dump = opts->dump;
|
||||
|
||||
assert(vlan);
|
||||
assert(peer);
|
||||
|
||||
if (dump->has_file) {
|
||||
file = dump->file;
|
||||
} else {
|
||||
snprintf(def_file, sizeof(def_file), "qemu-vlan%d.pcap", vlan->id);
|
||||
int id;
|
||||
int ret;
|
||||
|
||||
ret = net_hub_id_for_client(peer, &id);
|
||||
assert(ret == 0); /* peer must be on a hub */
|
||||
|
||||
snprintf(def_file, sizeof(def_file), "qemu-vlan%d.pcap", id);
|
||||
file = def_file;
|
||||
}
|
||||
|
||||
|
@ -174,5 +181,5 @@ int net_init_dump(const NetClientOptions *opts, const char *name,
|
|||
len = 65536;
|
||||
}
|
||||
|
||||
return net_dump_init(vlan, "dump", name, file, len);
|
||||
return net_dump_init(peer, "dump", name, file, len);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,6 @@
|
|||
#include "qapi-types.h"
|
||||
|
||||
int net_init_dump(const NetClientOptions *opts, const char *name,
|
||||
VLANState *vlan);
|
||||
NetClientState *peer);
|
||||
|
||||
#endif /* QEMU_NET_DUMP_H */
|
||||
|
|
|
@ -0,0 +1,339 @@
|
|||
/*
|
||||
* Hub net client
|
||||
*
|
||||
* Copyright IBM, Corp. 2012
|
||||
*
|
||||
* Authors:
|
||||
* Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
||||
* Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU LGPL, version 2 or later.
|
||||
* See the COPYING.LIB file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "monitor.h"
|
||||
#include "net.h"
|
||||
#include "hub.h"
|
||||
#include "iov.h"
|
||||
|
||||
/*
|
||||
* A hub broadcasts incoming packets to all its ports except the source port.
|
||||
* Hubs can be used to provide independent network segments, also confusingly
|
||||
* named the QEMU 'vlan' feature.
|
||||
*/
|
||||
|
||||
typedef struct NetHub NetHub;
|
||||
|
||||
typedef struct NetHubPort {
|
||||
NetClientState nc;
|
||||
QLIST_ENTRY(NetHubPort) next;
|
||||
NetHub *hub;
|
||||
int id;
|
||||
} NetHubPort;
|
||||
|
||||
struct NetHub {
|
||||
int id;
|
||||
QLIST_ENTRY(NetHub) next;
|
||||
int num_ports;
|
||||
QLIST_HEAD(, NetHubPort) ports;
|
||||
};
|
||||
|
||||
static QLIST_HEAD(, NetHub) hubs = QLIST_HEAD_INITIALIZER(&hubs);
|
||||
|
||||
static ssize_t net_hub_receive(NetHub *hub, NetHubPort *source_port,
|
||||
const uint8_t *buf, size_t len)
|
||||
{
|
||||
NetHubPort *port;
|
||||
|
||||
QLIST_FOREACH(port, &hub->ports, next) {
|
||||
if (port == source_port) {
|
||||
continue;
|
||||
}
|
||||
|
||||
qemu_send_packet(&port->nc, buf, len);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t net_hub_receive_iov(NetHub *hub, NetHubPort *source_port,
|
||||
const struct iovec *iov, int iovcnt)
|
||||
{
|
||||
NetHubPort *port;
|
||||
ssize_t len = iov_size(iov, iovcnt);
|
||||
|
||||
QLIST_FOREACH(port, &hub->ports, next) {
|
||||
if (port == source_port) {
|
||||
continue;
|
||||
}
|
||||
|
||||
qemu_sendv_packet(&port->nc, iov, iovcnt);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static NetHub *net_hub_new(int id)
|
||||
{
|
||||
NetHub *hub;
|
||||
|
||||
hub = g_malloc(sizeof(*hub));
|
||||
hub->id = id;
|
||||
hub->num_ports = 0;
|
||||
QLIST_INIT(&hub->ports);
|
||||
|
||||
QLIST_INSERT_HEAD(&hubs, hub, next);
|
||||
|
||||
return hub;
|
||||
}
|
||||
|
||||
static int net_hub_port_can_receive(NetClientState *nc)
|
||||
{
|
||||
NetHubPort *port;
|
||||
NetHubPort *src_port = DO_UPCAST(NetHubPort, nc, nc);
|
||||
NetHub *hub = src_port->hub;
|
||||
|
||||
QLIST_FOREACH(port, &hub->ports, next) {
|
||||
if (port == src_port) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!qemu_can_send_packet(&port->nc)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static ssize_t net_hub_port_receive(NetClientState *nc,
|
||||
const uint8_t *buf, size_t len)
|
||||
{
|
||||
NetHubPort *port = DO_UPCAST(NetHubPort, nc, nc);
|
||||
|
||||
return net_hub_receive(port->hub, port, buf, len);
|
||||
}
|
||||
|
||||
static ssize_t net_hub_port_receive_iov(NetClientState *nc,
|
||||
const struct iovec *iov, int iovcnt)
|
||||
{
|
||||
NetHubPort *port = DO_UPCAST(NetHubPort, nc, nc);
|
||||
|
||||
return net_hub_receive_iov(port->hub, port, iov, iovcnt);
|
||||
}
|
||||
|
||||
static void net_hub_port_cleanup(NetClientState *nc)
|
||||
{
|
||||
NetHubPort *port = DO_UPCAST(NetHubPort, nc, nc);
|
||||
|
||||
QLIST_REMOVE(port, next);
|
||||
}
|
||||
|
||||
static NetClientInfo net_hub_port_info = {
|
||||
.type = NET_CLIENT_OPTIONS_KIND_HUBPORT,
|
||||
.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,
|
||||
};
|
||||
|
||||
static NetHubPort *net_hub_port_new(NetHub *hub, const char *name)
|
||||
{
|
||||
NetClientState *nc;
|
||||
NetHubPort *port;
|
||||
int id = hub->num_ports++;
|
||||
char default_name[128];
|
||||
|
||||
if (!name) {
|
||||
snprintf(default_name, sizeof(default_name),
|
||||
"hub%dport%d", hub->id, id);
|
||||
name = default_name;
|
||||
}
|
||||
|
||||
nc = qemu_new_net_client(&net_hub_port_info, NULL, "hub", name);
|
||||
port = DO_UPCAST(NetHubPort, nc, nc);
|
||||
port->id = id;
|
||||
port->hub = hub;
|
||||
|
||||
QLIST_INSERT_HEAD(&hub->ports, port, next);
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a port on a given hub
|
||||
* @name: Net client name or NULL for default name.
|
||||
*
|
||||
* If there is no existing hub with the given id then a new hub is created.
|
||||
*/
|
||||
NetClientState *net_hub_add_port(int hub_id, const char *name)
|
||||
{
|
||||
NetHub *hub;
|
||||
NetHubPort *port;
|
||||
|
||||
QLIST_FOREACH(hub, &hubs, next) {
|
||||
if (hub->id == hub_id) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hub) {
|
||||
hub = net_hub_new(hub_id);
|
||||
}
|
||||
|
||||
port = net_hub_port_new(hub, name);
|
||||
return &port->nc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a specific client on a hub
|
||||
*/
|
||||
NetClientState *net_hub_find_client_by_name(int hub_id, const char *name)
|
||||
{
|
||||
NetHub *hub;
|
||||
NetHubPort *port;
|
||||
NetClientState *peer;
|
||||
|
||||
QLIST_FOREACH(hub, &hubs, next) {
|
||||
if (hub->id == hub_id) {
|
||||
QLIST_FOREACH(port, &hub->ports, next) {
|
||||
peer = port->nc.peer;
|
||||
|
||||
if (peer && strcmp(peer->name, name) == 0) {
|
||||
return peer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a available port on a hub; otherwise create one new port
|
||||
*/
|
||||
NetClientState *net_hub_port_find(int hub_id)
|
||||
{
|
||||
NetHub *hub;
|
||||
NetHubPort *port;
|
||||
NetClientState *nc;
|
||||
|
||||
QLIST_FOREACH(hub, &hubs, next) {
|
||||
if (hub->id == hub_id) {
|
||||
QLIST_FOREACH(port, &hub->ports, next) {
|
||||
nc = port->nc.peer;
|
||||
if (!nc) {
|
||||
return &(port->nc);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nc = net_hub_add_port(hub_id, NULL);
|
||||
return nc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print hub configuration
|
||||
*/
|
||||
void net_hub_info(Monitor *mon)
|
||||
{
|
||||
NetHub *hub;
|
||||
NetHubPort *port;
|
||||
|
||||
QLIST_FOREACH(hub, &hubs, next) {
|
||||
monitor_printf(mon, "hub %d\n", hub->id);
|
||||
QLIST_FOREACH(port, &hub->ports, next) {
|
||||
if (port->nc.peer) {
|
||||
monitor_printf(mon, " \\ ");
|
||||
print_net_client(mon, port->nc.peer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the hub id that a client is connected to
|
||||
*
|
||||
* @id Pointer for hub id output, may be NULL
|
||||
*/
|
||||
int net_hub_id_for_client(NetClientState *nc, int *id)
|
||||
{
|
||||
NetHubPort *port;
|
||||
|
||||
if (nc->info->type == NET_CLIENT_OPTIONS_KIND_HUBPORT) {
|
||||
port = DO_UPCAST(NetHubPort, nc, nc);
|
||||
} else if (nc->peer != NULL && nc->peer->info->type ==
|
||||
NET_CLIENT_OPTIONS_KIND_HUBPORT) {
|
||||
port = DO_UPCAST(NetHubPort, nc, nc->peer);
|
||||
} else {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (id) {
|
||||
*id = port->hub->id;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int net_init_hubport(const NetClientOptions *opts, const char *name,
|
||||
NetClientState *peer)
|
||||
{
|
||||
const NetdevHubPortOptions *hubport;
|
||||
|
||||
assert(opts->kind == NET_CLIENT_OPTIONS_KIND_HUBPORT);
|
||||
hubport = opts->hubport;
|
||||
|
||||
/* Treat hub port like a backend, NIC must be the one to peer */
|
||||
if (peer) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
net_hub_add_port(hubport->hubid, name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Warn if hub configurations are likely wrong
|
||||
*/
|
||||
void net_hub_check_clients(void)
|
||||
{
|
||||
NetHub *hub;
|
||||
NetHubPort *port;
|
||||
NetClientState *peer;
|
||||
|
||||
QLIST_FOREACH(hub, &hubs, next) {
|
||||
int has_nic = 0, has_host_dev = 0;
|
||||
|
||||
QLIST_FOREACH(port, &hub->ports, next) {
|
||||
peer = port->nc.peer;
|
||||
if (!peer) {
|
||||
fprintf(stderr, "Warning: hub port %s has no peer\n",
|
||||
port->nc.name);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (peer->info->type) {
|
||||
case NET_CLIENT_OPTIONS_KIND_NIC:
|
||||
has_nic = 1;
|
||||
break;
|
||||
case NET_CLIENT_OPTIONS_KIND_USER:
|
||||
case NET_CLIENT_OPTIONS_KIND_TAP:
|
||||
case NET_CLIENT_OPTIONS_KIND_SOCKET:
|
||||
case NET_CLIENT_OPTIONS_KIND_VDE:
|
||||
has_host_dev = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (has_host_dev && !has_nic) {
|
||||
fprintf(stderr, "Warning: vlan %d with no nics\n", hub->id);
|
||||
}
|
||||
if (has_nic && !has_host_dev) {
|
||||
fprintf(stderr,
|
||||
"Warning: vlan %d is not connected to host network\n",
|
||||
hub->id);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Hub net client
|
||||
*
|
||||
* Copyright IBM, Corp. 2012
|
||||
*
|
||||
* Authors:
|
||||
* Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
||||
* Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU LGPL, version 2 or later.
|
||||
* See the COPYING.LIB file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NET_HUB_H
|
||||
#define NET_HUB_H
|
||||
|
||||
#include "qemu-common.h"
|
||||
|
||||
int net_init_hubport(const NetClientOptions *opts, const char *name,
|
||||
NetClientState *peer);
|
||||
NetClientState *net_hub_add_port(int hub_id, const char *name);
|
||||
NetClientState *net_hub_find_client_by_name(int hub_id, const char *name);
|
||||
void net_hub_info(Monitor *mon);
|
||||
int net_hub_id_for_client(NetClientState *nc, int *id);
|
||||
void net_hub_check_clients(void);
|
||||
NetClientState *net_hub_port_find(int hub_id);
|
||||
|
||||
#endif /* NET_HUB_H */
|
38
net/queue.c
38
net/queue.c
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "net/queue.h"
|
||||
#include "qemu-queue.h"
|
||||
#include "net.h"
|
||||
|
||||
/* The delivery handler may only return zero if it will call
|
||||
* qemu_net_queue_flush() when it determines that it is once again able
|
||||
|
@ -40,7 +41,7 @@
|
|||
|
||||
struct NetPacket {
|
||||
QTAILQ_ENTRY(NetPacket) entry;
|
||||
VLANClientState *sender;
|
||||
NetClientState *sender;
|
||||
unsigned flags;
|
||||
int size;
|
||||
NetPacketSent *sent_cb;
|
||||
|
@ -48,8 +49,6 @@ struct NetPacket {
|
|||
};
|
||||
|
||||
struct NetQueue {
|
||||
NetPacketDeliver *deliver;
|
||||
NetPacketDeliverIOV *deliver_iov;
|
||||
void *opaque;
|
||||
|
||||
QTAILQ_HEAD(packets, NetPacket) packets;
|
||||
|
@ -57,16 +56,12 @@ struct NetQueue {
|
|||
unsigned delivering : 1;
|
||||
};
|
||||
|
||||
NetQueue *qemu_new_net_queue(NetPacketDeliver *deliver,
|
||||
NetPacketDeliverIOV *deliver_iov,
|
||||
void *opaque)
|
||||
NetQueue *qemu_new_net_queue(void *opaque)
|
||||
{
|
||||
NetQueue *queue;
|
||||
|
||||
queue = g_malloc0(sizeof(NetQueue));
|
||||
|
||||
queue->deliver = deliver;
|
||||
queue->deliver_iov = deliver_iov;
|
||||
queue->opaque = opaque;
|
||||
|
||||
QTAILQ_INIT(&queue->packets);
|
||||
|
@ -89,7 +84,7 @@ void qemu_del_net_queue(NetQueue *queue)
|
|||
}
|
||||
|
||||
static ssize_t qemu_net_queue_append(NetQueue *queue,
|
||||
VLANClientState *sender,
|
||||
NetClientState *sender,
|
||||
unsigned flags,
|
||||
const uint8_t *buf,
|
||||
size_t size,
|
||||
|
@ -110,7 +105,7 @@ static ssize_t qemu_net_queue_append(NetQueue *queue,
|
|||
}
|
||||
|
||||
static ssize_t qemu_net_queue_append_iov(NetQueue *queue,
|
||||
VLANClientState *sender,
|
||||
NetClientState *sender,
|
||||
unsigned flags,
|
||||
const struct iovec *iov,
|
||||
int iovcnt,
|
||||
|
@ -143,7 +138,7 @@ static ssize_t qemu_net_queue_append_iov(NetQueue *queue,
|
|||
}
|
||||
|
||||
static ssize_t qemu_net_queue_deliver(NetQueue *queue,
|
||||
VLANClientState *sender,
|
||||
NetClientState *sender,
|
||||
unsigned flags,
|
||||
const uint8_t *data,
|
||||
size_t size)
|
||||
|
@ -151,14 +146,14 @@ static ssize_t qemu_net_queue_deliver(NetQueue *queue,
|
|||
ssize_t ret = -1;
|
||||
|
||||
queue->delivering = 1;
|
||||
ret = queue->deliver(sender, flags, data, size, queue->opaque);
|
||||
ret = qemu_deliver_packet(sender, flags, data, size, queue->opaque);
|
||||
queue->delivering = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t qemu_net_queue_deliver_iov(NetQueue *queue,
|
||||
VLANClientState *sender,
|
||||
NetClientState *sender,
|
||||
unsigned flags,
|
||||
const struct iovec *iov,
|
||||
int iovcnt)
|
||||
|
@ -166,14 +161,14 @@ static ssize_t qemu_net_queue_deliver_iov(NetQueue *queue,
|
|||
ssize_t ret = -1;
|
||||
|
||||
queue->delivering = 1;
|
||||
ret = queue->deliver_iov(sender, flags, iov, iovcnt, queue->opaque);
|
||||
ret = qemu_deliver_packet_iov(sender, flags, iov, iovcnt, queue->opaque);
|
||||
queue->delivering = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t qemu_net_queue_send(NetQueue *queue,
|
||||
VLANClientState *sender,
|
||||
NetClientState *sender,
|
||||
unsigned flags,
|
||||
const uint8_t *data,
|
||||
size_t size,
|
||||
|
@ -181,8 +176,8 @@ ssize_t qemu_net_queue_send(NetQueue *queue,
|
|||
{
|
||||
ssize_t ret;
|
||||
|
||||
if (queue->delivering) {
|
||||
return qemu_net_queue_append(queue, sender, flags, data, size, NULL);
|
||||
if (queue->delivering || !qemu_can_send_packet(sender)) {
|
||||
return qemu_net_queue_append(queue, sender, flags, data, size, sent_cb);
|
||||
}
|
||||
|
||||
ret = qemu_net_queue_deliver(queue, sender, flags, data, size);
|
||||
|
@ -197,7 +192,7 @@ ssize_t qemu_net_queue_send(NetQueue *queue,
|
|||
}
|
||||
|
||||
ssize_t qemu_net_queue_send_iov(NetQueue *queue,
|
||||
VLANClientState *sender,
|
||||
NetClientState *sender,
|
||||
unsigned flags,
|
||||
const struct iovec *iov,
|
||||
int iovcnt,
|
||||
|
@ -205,8 +200,9 @@ ssize_t qemu_net_queue_send_iov(NetQueue *queue,
|
|||
{
|
||||
ssize_t ret;
|
||||
|
||||
if (queue->delivering) {
|
||||
return qemu_net_queue_append_iov(queue, sender, flags, iov, iovcnt, NULL);
|
||||
if (queue->delivering || !qemu_can_send_packet(sender)) {
|
||||
return qemu_net_queue_append_iov(queue, sender, flags,
|
||||
iov, iovcnt, sent_cb);
|
||||
}
|
||||
|
||||
ret = qemu_net_queue_deliver_iov(queue, sender, flags, iov, iovcnt);
|
||||
|
@ -220,7 +216,7 @@ ssize_t qemu_net_queue_send_iov(NetQueue *queue,
|
|||
return ret;
|
||||
}
|
||||
|
||||
void qemu_net_queue_purge(NetQueue *queue, VLANClientState *from)
|
||||
void qemu_net_queue_purge(NetQueue *queue, NetClientState *from)
|
||||
{
|
||||
NetPacket *packet, *next;
|
||||
|
||||
|
|
25
net/queue.h
25
net/queue.h
|
@ -29,43 +29,30 @@
|
|||
typedef struct NetPacket NetPacket;
|
||||
typedef struct NetQueue NetQueue;
|
||||
|
||||
typedef void (NetPacketSent) (VLANClientState *sender, ssize_t ret);
|
||||
|
||||
typedef ssize_t (NetPacketDeliver) (VLANClientState *sender,
|
||||
unsigned flags,
|
||||
const uint8_t *buf,
|
||||
size_t size,
|
||||
void *opaque);
|
||||
|
||||
typedef ssize_t (NetPacketDeliverIOV) (VLANClientState *sender,
|
||||
unsigned flags,
|
||||
const struct iovec *iov,
|
||||
int iovcnt,
|
||||
void *opaque);
|
||||
typedef void (NetPacketSent) (NetClientState *sender, ssize_t ret);
|
||||
|
||||
#define QEMU_NET_PACKET_FLAG_NONE 0
|
||||
#define QEMU_NET_PACKET_FLAG_RAW (1<<0)
|
||||
|
||||
NetQueue *qemu_new_net_queue(NetPacketDeliver *deliver,
|
||||
NetPacketDeliverIOV *deliver_iov,
|
||||
void *opaque);
|
||||
NetQueue *qemu_new_net_queue(void *opaque);
|
||||
|
||||
void qemu_del_net_queue(NetQueue *queue);
|
||||
|
||||
ssize_t qemu_net_queue_send(NetQueue *queue,
|
||||
VLANClientState *sender,
|
||||
NetClientState *sender,
|
||||
unsigned flags,
|
||||
const uint8_t *data,
|
||||
size_t size,
|
||||
NetPacketSent *sent_cb);
|
||||
|
||||
ssize_t qemu_net_queue_send_iov(NetQueue *queue,
|
||||
VLANClientState *sender,
|
||||
NetClientState *sender,
|
||||
unsigned flags,
|
||||
const struct iovec *iov,
|
||||
int iovcnt,
|
||||
NetPacketSent *sent_cb);
|
||||
|
||||
void qemu_net_queue_purge(NetQueue *queue, VLANClientState *from);
|
||||
void qemu_net_queue_purge(NetQueue *queue, NetClientState *from);
|
||||
void qemu_net_queue_flush(NetQueue *queue);
|
||||
|
||||
#endif /* QEMU_NET_QUEUE_H */
|
||||
|
|
34
net/slirp.c
34
net/slirp.c
|
@ -30,6 +30,7 @@
|
|||
#include <sys/wait.h>
|
||||
#endif
|
||||
#include "net.h"
|
||||
#include "net/hub.h"
|
||||
#include "monitor.h"
|
||||
#include "qemu_socket.h"
|
||||
#include "slirp/libslirp.h"
|
||||
|
@ -67,7 +68,7 @@ struct slirp_config_str {
|
|||
};
|
||||
|
||||
typedef struct SlirpState {
|
||||
VLANClientState nc;
|
||||
NetClientState nc;
|
||||
QTAILQ_ENTRY(SlirpState) entry;
|
||||
Slirp *slirp;
|
||||
#ifndef _WIN32
|
||||
|
@ -96,13 +97,6 @@ static void slirp_smb_cleanup(SlirpState *s);
|
|||
static inline void slirp_smb_cleanup(SlirpState *s) { }
|
||||
#endif
|
||||
|
||||
int slirp_can_output(void *opaque)
|
||||
{
|
||||
SlirpState *s = opaque;
|
||||
|
||||
return qemu_can_send_packet(&s->nc);
|
||||
}
|
||||
|
||||
void slirp_output(void *opaque, const uint8_t *pkt, int pkt_len)
|
||||
{
|
||||
SlirpState *s = opaque;
|
||||
|
@ -110,7 +104,7 @@ void slirp_output(void *opaque, const uint8_t *pkt, int pkt_len)
|
|||
qemu_send_packet(&s->nc, pkt, pkt_len);
|
||||
}
|
||||
|
||||
static ssize_t net_slirp_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
static ssize_t net_slirp_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
SlirpState *s = DO_UPCAST(SlirpState, nc, nc);
|
||||
|
||||
|
@ -119,7 +113,7 @@ static ssize_t net_slirp_receive(VLANClientState *nc, const uint8_t *buf, size_t
|
|||
return size;
|
||||
}
|
||||
|
||||
static void net_slirp_cleanup(VLANClientState *nc)
|
||||
static void net_slirp_cleanup(NetClientState *nc)
|
||||
{
|
||||
SlirpState *s = DO_UPCAST(SlirpState, nc, nc);
|
||||
|
||||
|
@ -135,7 +129,7 @@ static NetClientInfo net_slirp_info = {
|
|||
.cleanup = net_slirp_cleanup,
|
||||
};
|
||||
|
||||
static int net_slirp_init(VLANState *vlan, const char *model,
|
||||
static int net_slirp_init(NetClientState *peer, const char *model,
|
||||
const char *name, int restricted,
|
||||
const char *vnetwork, const char *vhost,
|
||||
const char *vhostname, const char *tftp_export,
|
||||
|
@ -152,7 +146,7 @@ static int net_slirp_init(VLANState *vlan, const char *model,
|
|||
#ifndef _WIN32
|
||||
struct in_addr smbsrv = { .s_addr = 0 };
|
||||
#endif
|
||||
VLANClientState *nc;
|
||||
NetClientState *nc;
|
||||
SlirpState *s;
|
||||
char buf[20];
|
||||
uint32_t addr;
|
||||
|
@ -238,7 +232,7 @@ static int net_slirp_init(VLANState *vlan, const char *model,
|
|||
}
|
||||
#endif
|
||||
|
||||
nc = qemu_new_net_client(&net_slirp_info, vlan, NULL, model, name);
|
||||
nc = qemu_new_net_client(&net_slirp_info, peer, model, name);
|
||||
|
||||
snprintf(nc->info_str, sizeof(nc->info_str),
|
||||
"net=%s,restrict=%s", inet_ntoa(net),
|
||||
|
@ -274,7 +268,7 @@ static int net_slirp_init(VLANState *vlan, const char *model,
|
|||
return 0;
|
||||
|
||||
error:
|
||||
qemu_del_vlan_client(nc);
|
||||
qemu_del_net_client(nc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -283,8 +277,8 @@ static SlirpState *slirp_lookup(Monitor *mon, const char *vlan,
|
|||
{
|
||||
|
||||
if (vlan) {
|
||||
VLANClientState *nc;
|
||||
nc = qemu_find_vlan_client_by_name(mon, strtol(vlan, NULL, 0), stack);
|
||||
NetClientState *nc;
|
||||
nc = net_hub_find_client_by_name(strtol(vlan, NULL, 0), stack);
|
||||
if (!nc) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -679,8 +673,10 @@ void do_info_usernet(Monitor *mon)
|
|||
SlirpState *s;
|
||||
|
||||
QTAILQ_FOREACH(s, &slirp_stacks, entry) {
|
||||
int id;
|
||||
bool got_vlan_id = net_hub_id_for_client(&s->nc, &id) == 0;
|
||||
monitor_printf(mon, "VLAN %d (%s):\n",
|
||||
s->nc.vlan ? s->nc.vlan->id : -1,
|
||||
got_vlan_id ? id : -1,
|
||||
s->nc.name);
|
||||
slirp_connection_info(s->slirp, mon);
|
||||
}
|
||||
|
@ -703,7 +699,7 @@ net_init_slirp_configs(const StringList *fwd, int flags)
|
|||
}
|
||||
|
||||
int net_init_slirp(const NetClientOptions *opts, const char *name,
|
||||
VLANState *vlan)
|
||||
NetClientState *peer)
|
||||
{
|
||||
struct slirp_config_str *config;
|
||||
char *vnet;
|
||||
|
@ -722,7 +718,7 @@ int net_init_slirp(const NetClientOptions *opts, const char *name,
|
|||
net_init_slirp_configs(user->hostfwd, SLIRP_CFG_HOSTFWD);
|
||||
net_init_slirp_configs(user->guestfwd, 0);
|
||||
|
||||
ret = net_slirp_init(vlan, "user", name, user->restrict, vnet, user->host,
|
||||
ret = net_slirp_init(peer, "user", name, user->restrict, vnet, user->host,
|
||||
user->hostname, user->tftp, user->bootfile,
|
||||
user->dhcpstart, user->dns, user->smb,
|
||||
user->smbserver);
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#ifdef CONFIG_SLIRP
|
||||
|
||||
int net_init_slirp(const NetClientOptions *opts, const char *name,
|
||||
VLANState *vlan);
|
||||
NetClientState *peer);
|
||||
|
||||
void net_slirp_hostfwd_add(Monitor *mon, const QDict *qdict);
|
||||
void net_slirp_hostfwd_remove(Monitor *mon, const QDict *qdict);
|
||||
|
|
134
net/socket.c
134
net/socket.c
|
@ -34,7 +34,8 @@
|
|||
#include "qemu_socket.h"
|
||||
|
||||
typedef struct NetSocketState {
|
||||
VLANClientState nc;
|
||||
NetClientState nc;
|
||||
int listen_fd;
|
||||
int fd;
|
||||
int state; /* 0 = getting length, 1 = getting data */
|
||||
unsigned int index;
|
||||
|
@ -43,15 +44,10 @@ typedef struct NetSocketState {
|
|||
struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
|
||||
} NetSocketState;
|
||||
|
||||
typedef struct NetSocketListenState {
|
||||
VLANState *vlan;
|
||||
char *model;
|
||||
char *name;
|
||||
int fd;
|
||||
} NetSocketListenState;
|
||||
static void net_socket_accept(void *opaque);
|
||||
|
||||
/* XXX: we consider we can send the whole packet without blocking */
|
||||
static ssize_t net_socket_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
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;
|
||||
|
@ -61,7 +57,7 @@ static ssize_t net_socket_receive(VLANClientState *nc, const uint8_t *buf, size_
|
|||
return send_all(s->fd, buf, size);
|
||||
}
|
||||
|
||||
static ssize_t net_socket_receive_dgram(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
static ssize_t net_socket_receive_dgram(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
|
||||
|
||||
|
@ -86,7 +82,19 @@ static void net_socket_send(void *opaque)
|
|||
/* end of connection */
|
||||
eoc:
|
||||
qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
|
||||
if (s->listen_fd != -1) {
|
||||
qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
|
||||
}
|
||||
closesocket(s->fd);
|
||||
|
||||
s->fd = -1;
|
||||
s->state = 0;
|
||||
s->index = 0;
|
||||
s->packet_len = 0;
|
||||
s->nc.link_down = true;
|
||||
memset(s->buf, 0, sizeof(s->buf));
|
||||
memset(s->nc.info_str, 0, sizeof(s->nc.info_str));
|
||||
|
||||
return;
|
||||
}
|
||||
buf = buf1;
|
||||
|
@ -231,11 +239,19 @@ fail:
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void net_socket_cleanup(VLANClientState *nc)
|
||||
static void net_socket_cleanup(NetClientState *nc)
|
||||
{
|
||||
NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
|
||||
qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
|
||||
close(s->fd);
|
||||
if (s->fd != -1) {
|
||||
qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
|
||||
close(s->fd);
|
||||
s->fd = -1;
|
||||
}
|
||||
if (s->listen_fd != -1) {
|
||||
qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
|
||||
closesocket(s->listen_fd);
|
||||
s->listen_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static NetClientInfo net_dgram_socket_info = {
|
||||
|
@ -245,7 +261,7 @@ static NetClientInfo net_dgram_socket_info = {
|
|||
.cleanup = net_socket_cleanup,
|
||||
};
|
||||
|
||||
static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan,
|
||||
static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
|
||||
const char *model,
|
||||
const char *name,
|
||||
int fd, int is_connected)
|
||||
|
@ -253,7 +269,7 @@ static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan,
|
|||
struct sockaddr_in saddr;
|
||||
int newfd;
|
||||
socklen_t saddr_len;
|
||||
VLANClientState *nc;
|
||||
NetClientState *nc;
|
||||
NetSocketState *s;
|
||||
|
||||
/* fd passed: multicast: "learn" dgram_dst address from bound address and save it
|
||||
|
@ -287,7 +303,7 @@ static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan,
|
|||
}
|
||||
}
|
||||
|
||||
nc = qemu_new_net_client(&net_dgram_socket_info, vlan, NULL, model, name);
|
||||
nc = qemu_new_net_client(&net_dgram_socket_info, peer, model, name);
|
||||
|
||||
snprintf(nc->info_str, sizeof(nc->info_str),
|
||||
"socket: fd=%d (%s mcast=%s:%d)",
|
||||
|
@ -297,11 +313,14 @@ static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan,
|
|||
s = DO_UPCAST(NetSocketState, nc, nc);
|
||||
|
||||
s->fd = fd;
|
||||
s->listen_fd = -1;
|
||||
|
||||
qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
|
||||
|
||||
/* mcast: save bound address as dst */
|
||||
if (is_connected) s->dgram_dst=saddr;
|
||||
if (is_connected) {
|
||||
s->dgram_dst = saddr;
|
||||
}
|
||||
|
||||
return s;
|
||||
|
||||
|
@ -323,21 +342,22 @@ static NetClientInfo net_socket_info = {
|
|||
.cleanup = net_socket_cleanup,
|
||||
};
|
||||
|
||||
static NetSocketState *net_socket_fd_init_stream(VLANState *vlan,
|
||||
static NetSocketState *net_socket_fd_init_stream(NetClientState *peer,
|
||||
const char *model,
|
||||
const char *name,
|
||||
int fd, int is_connected)
|
||||
{
|
||||
VLANClientState *nc;
|
||||
NetClientState *nc;
|
||||
NetSocketState *s;
|
||||
|
||||
nc = qemu_new_net_client(&net_socket_info, vlan, NULL, model, name);
|
||||
nc = qemu_new_net_client(&net_socket_info, peer, model, name);
|
||||
|
||||
snprintf(nc->info_str, sizeof(nc->info_str), "socket: fd=%d", fd);
|
||||
|
||||
s = DO_UPCAST(NetSocketState, nc, nc);
|
||||
|
||||
s->fd = fd;
|
||||
s->listen_fd = -1;
|
||||
|
||||
if (is_connected) {
|
||||
net_socket_connect(s);
|
||||
|
@ -347,7 +367,7 @@ static NetSocketState *net_socket_fd_init_stream(VLANState *vlan,
|
|||
return s;
|
||||
}
|
||||
|
||||
static NetSocketState *net_socket_fd_init(VLANState *vlan,
|
||||
static NetSocketState *net_socket_fd_init(NetClientState *peer,
|
||||
const char *model, const char *name,
|
||||
int fd, int is_connected)
|
||||
{
|
||||
|
@ -362,60 +382,59 @@ static NetSocketState *net_socket_fd_init(VLANState *vlan,
|
|||
}
|
||||
switch(so_type) {
|
||||
case SOCK_DGRAM:
|
||||
return net_socket_fd_init_dgram(vlan, model, name, fd, is_connected);
|
||||
return net_socket_fd_init_dgram(peer, model, name, fd, is_connected);
|
||||
case SOCK_STREAM:
|
||||
return net_socket_fd_init_stream(vlan, model, name, fd, is_connected);
|
||||
return net_socket_fd_init_stream(peer, model, name, fd, is_connected);
|
||||
default:
|
||||
/* who knows ... this could be a eg. a pty, do warn and continue as stream */
|
||||
fprintf(stderr, "qemu: warning: socket type=%d for fd=%d is not SOCK_DGRAM or SOCK_STREAM\n", so_type, fd);
|
||||
return net_socket_fd_init_stream(vlan, model, name, fd, is_connected);
|
||||
return net_socket_fd_init_stream(peer, model, name, fd, is_connected);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void net_socket_accept(void *opaque)
|
||||
{
|
||||
NetSocketListenState *s = opaque;
|
||||
NetSocketState *s1;
|
||||
NetSocketState *s = opaque;
|
||||
struct sockaddr_in saddr;
|
||||
socklen_t len;
|
||||
int fd;
|
||||
|
||||
for(;;) {
|
||||
len = sizeof(saddr);
|
||||
fd = qemu_accept(s->fd, (struct sockaddr *)&saddr, &len);
|
||||
fd = qemu_accept(s->listen_fd, (struct sockaddr *)&saddr, &len);
|
||||
if (fd < 0 && errno != EINTR) {
|
||||
return;
|
||||
} else if (fd >= 0) {
|
||||
qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
s1 = net_socket_fd_init(s->vlan, s->model, s->name, fd, 1);
|
||||
if (s1) {
|
||||
snprintf(s1->nc.info_str, sizeof(s1->nc.info_str),
|
||||
"socket: connection from %s:%d",
|
||||
inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
|
||||
}
|
||||
|
||||
s->fd = fd;
|
||||
s->nc.link_down = false;
|
||||
net_socket_connect(s);
|
||||
snprintf(s->nc.info_str, sizeof(s->nc.info_str),
|
||||
"socket: connection from %s:%d",
|
||||
inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
|
||||
}
|
||||
|
||||
static int net_socket_listen_init(VLANState *vlan,
|
||||
static int net_socket_listen_init(NetClientState *peer,
|
||||
const char *model,
|
||||
const char *name,
|
||||
const char *host_str)
|
||||
{
|
||||
NetSocketListenState *s;
|
||||
int fd, val, ret;
|
||||
NetClientState *nc;
|
||||
NetSocketState *s;
|
||||
struct sockaddr_in saddr;
|
||||
int fd, val, ret;
|
||||
|
||||
if (parse_host_port(&saddr, host_str) < 0)
|
||||
return -1;
|
||||
|
||||
s = g_malloc0(sizeof(NetSocketListenState));
|
||||
|
||||
fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (fd < 0) {
|
||||
perror("socket");
|
||||
g_free(s);
|
||||
return -1;
|
||||
}
|
||||
socket_set_nonblock(fd);
|
||||
|
@ -427,26 +446,27 @@ static int net_socket_listen_init(VLANState *vlan,
|
|||
ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
|
||||
if (ret < 0) {
|
||||
perror("bind");
|
||||
g_free(s);
|
||||
closesocket(fd);
|
||||
return -1;
|
||||
}
|
||||
ret = listen(fd, 0);
|
||||
if (ret < 0) {
|
||||
perror("listen");
|
||||
g_free(s);
|
||||
closesocket(fd);
|
||||
return -1;
|
||||
}
|
||||
s->vlan = vlan;
|
||||
s->model = g_strdup(model);
|
||||
s->name = name ? g_strdup(name) : NULL;
|
||||
s->fd = fd;
|
||||
qemu_set_fd_handler(fd, net_socket_accept, NULL, s);
|
||||
|
||||
nc = qemu_new_net_client(&net_socket_info, peer, model, name);
|
||||
s = DO_UPCAST(NetSocketState, nc, nc);
|
||||
s->fd = -1;
|
||||
s->listen_fd = fd;
|
||||
s->nc.link_down = true;
|
||||
|
||||
qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int net_socket_connect_init(VLANState *vlan,
|
||||
static int net_socket_connect_init(NetClientState *peer,
|
||||
const char *model,
|
||||
const char *name,
|
||||
const char *host_str)
|
||||
|
@ -487,7 +507,7 @@ static int net_socket_connect_init(VLANState *vlan,
|
|||
break;
|
||||
}
|
||||
}
|
||||
s = net_socket_fd_init(vlan, model, name, fd, connected);
|
||||
s = net_socket_fd_init(peer, model, name, fd, connected);
|
||||
if (!s)
|
||||
return -1;
|
||||
snprintf(s->nc.info_str, sizeof(s->nc.info_str),
|
||||
|
@ -496,7 +516,7 @@ static int net_socket_connect_init(VLANState *vlan,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int net_socket_mcast_init(VLANState *vlan,
|
||||
static int net_socket_mcast_init(NetClientState *peer,
|
||||
const char *model,
|
||||
const char *name,
|
||||
const char *host_str,
|
||||
|
@ -522,7 +542,7 @@ static int net_socket_mcast_init(VLANState *vlan,
|
|||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
s = net_socket_fd_init(vlan, model, name, fd, 0);
|
||||
s = net_socket_fd_init(peer, model, name, fd, 0);
|
||||
if (!s)
|
||||
return -1;
|
||||
|
||||
|
@ -535,7 +555,7 @@ static int net_socket_mcast_init(VLANState *vlan,
|
|||
|
||||
}
|
||||
|
||||
static int net_socket_udp_init(VLANState *vlan,
|
||||
static int net_socket_udp_init(NetClientState *peer,
|
||||
const char *model,
|
||||
const char *name,
|
||||
const char *rhost,
|
||||
|
@ -573,7 +593,7 @@ static int net_socket_udp_init(VLANState *vlan,
|
|||
return -1;
|
||||
}
|
||||
|
||||
s = net_socket_fd_init(vlan, model, name, fd, 0);
|
||||
s = net_socket_fd_init(peer, model, name, fd, 0);
|
||||
if (!s) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -587,7 +607,7 @@ static int net_socket_udp_init(VLANState *vlan,
|
|||
}
|
||||
|
||||
int net_init_socket(const NetClientOptions *opts, const char *name,
|
||||
VLANState *vlan)
|
||||
NetClientState *peer)
|
||||
{
|
||||
const NetdevSocketOptions *sock;
|
||||
|
||||
|
@ -610,21 +630,21 @@ int net_init_socket(const NetClientOptions *opts, const char *name,
|
|||
int fd;
|
||||
|
||||
fd = net_handle_fd_param(cur_mon, sock->fd);
|
||||
if (fd == -1 || !net_socket_fd_init(vlan, "socket", name, fd, 1)) {
|
||||
if (fd == -1 || !net_socket_fd_init(peer, "socket", name, fd, 1)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sock->has_listen) {
|
||||
if (net_socket_listen_init(vlan, "socket", name, sock->listen) == -1) {
|
||||
if (net_socket_listen_init(peer, "socket", name, sock->listen) == -1) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sock->has_connect) {
|
||||
if (net_socket_connect_init(vlan, "socket", name, sock->connect) ==
|
||||
if (net_socket_connect_init(peer, "socket", name, sock->connect) ==
|
||||
-1) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -634,7 +654,7 @@ int net_init_socket(const NetClientOptions *opts, const char *name,
|
|||
if (sock->has_mcast) {
|
||||
/* if sock->localaddr is missing, it has been initialized to "all bits
|
||||
* zero" */
|
||||
if (net_socket_mcast_init(vlan, "socket", name, sock->mcast,
|
||||
if (net_socket_mcast_init(peer, "socket", name, sock->mcast,
|
||||
sock->localaddr) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -646,7 +666,7 @@ int net_init_socket(const NetClientOptions *opts, const char *name,
|
|||
error_report("localaddr= is mandatory with udp=");
|
||||
return -1;
|
||||
}
|
||||
if (net_socket_udp_init(vlan, "udp", name, sock->udp, sock->localaddr) ==
|
||||
if (net_socket_udp_init(peer, "udp", name, sock->udp, sock->localaddr) ==
|
||||
-1) {
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,6 @@
|
|||
#include "qapi-types.h"
|
||||
|
||||
int net_init_socket(const NetClientOptions *opts, const char *name,
|
||||
VLANState *vlan);
|
||||
NetClientState *peer);
|
||||
|
||||
#endif /* QEMU_NET_SOCKET_H */
|
||||
|
|
|
@ -630,11 +630,11 @@ static int tap_win32_open(tap_win32_overlapped_t **phandle,
|
|||
/********************************************/
|
||||
|
||||
typedef struct TAPState {
|
||||
VLANClientState nc;
|
||||
NetClientState nc;
|
||||
tap_win32_overlapped_t *handle;
|
||||
} TAPState;
|
||||
|
||||
static void tap_cleanup(VLANClientState *nc)
|
||||
static void tap_cleanup(NetClientState *nc)
|
||||
{
|
||||
TAPState *s = DO_UPCAST(TAPState, nc, nc);
|
||||
|
||||
|
@ -645,7 +645,7 @@ static void tap_cleanup(VLANClientState *nc)
|
|||
*/
|
||||
}
|
||||
|
||||
static ssize_t tap_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
static ssize_t tap_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
TAPState *s = DO_UPCAST(TAPState, nc, nc);
|
||||
|
||||
|
@ -673,10 +673,10 @@ static NetClientInfo net_tap_win32_info = {
|
|||
.cleanup = tap_cleanup,
|
||||
};
|
||||
|
||||
static int tap_win32_init(VLANState *vlan, const char *model,
|
||||
static int tap_win32_init(NetClientState *peer, const char *model,
|
||||
const char *name, const char *ifname)
|
||||
{
|
||||
VLANClientState *nc;
|
||||
NetClientState *nc;
|
||||
TAPState *s;
|
||||
tap_win32_overlapped_t *handle;
|
||||
|
||||
|
@ -685,7 +685,7 @@ static int tap_win32_init(VLANState *vlan, const char *model,
|
|||
return -1;
|
||||
}
|
||||
|
||||
nc = qemu_new_net_client(&net_tap_win32_info, vlan, NULL, model, name);
|
||||
nc = qemu_new_net_client(&net_tap_win32_info, peer, model, name);
|
||||
|
||||
s = DO_UPCAST(TAPState, nc, nc);
|
||||
|
||||
|
@ -700,7 +700,7 @@ static int tap_win32_init(VLANState *vlan, const char *model,
|
|||
}
|
||||
|
||||
int net_init_tap(const NetClientOptions *opts, const char *name,
|
||||
VLANState *vlan)
|
||||
NetClientState *peer)
|
||||
{
|
||||
const NetdevTapOptions *tap;
|
||||
|
||||
|
@ -712,19 +712,19 @@ int net_init_tap(const NetClientOptions *opts, const char *name,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (tap_win32_init(vlan, "tap", name, tap->ifname) == -1) {
|
||||
if (tap_win32_init(peer, "tap", name, tap->ifname) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tap_has_ufo(VLANClientState *vc)
|
||||
int tap_has_ufo(NetClientState *nc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tap_has_vnet_hdr(VLANClientState *vc)
|
||||
int tap_has_vnet_hdr(NetClientState *nc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -738,16 +738,16 @@ void tap_fd_set_vnet_hdr_len(int fd, int len)
|
|||
{
|
||||
}
|
||||
|
||||
void tap_using_vnet_hdr(VLANClientState *vc, int using_vnet_hdr)
|
||||
void tap_using_vnet_hdr(NetClientState *nc, int using_vnet_hdr)
|
||||
{
|
||||
}
|
||||
|
||||
void tap_set_offload(VLANClientState *vc, int csum, int tso4,
|
||||
void tap_set_offload(NetClientState *nc, int csum, int tso4,
|
||||
int tso6, int ecn, int ufo)
|
||||
{
|
||||
}
|
||||
|
||||
struct vhost_net *tap_get_vhost_net(VLANClientState *nc)
|
||||
struct vhost_net *tap_get_vhost_net(NetClientState *nc)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
|
44
net/tap.c
44
net/tap.c
|
@ -50,7 +50,7 @@
|
|||
#define TAP_BUFSIZE (4096 + 65536)
|
||||
|
||||
typedef struct TAPState {
|
||||
VLANClientState nc;
|
||||
NetClientState nc;
|
||||
int fd;
|
||||
char down_script[1024];
|
||||
char down_script_arg[128];
|
||||
|
@ -115,7 +115,7 @@ static ssize_t tap_write_packet(TAPState *s, const struct iovec *iov, int iovcnt
|
|||
return len;
|
||||
}
|
||||
|
||||
static ssize_t tap_receive_iov(VLANClientState *nc, const struct iovec *iov,
|
||||
static ssize_t tap_receive_iov(NetClientState *nc, const struct iovec *iov,
|
||||
int iovcnt)
|
||||
{
|
||||
TAPState *s = DO_UPCAST(TAPState, nc, nc);
|
||||
|
@ -134,7 +134,7 @@ static ssize_t tap_receive_iov(VLANClientState *nc, const struct iovec *iov,
|
|||
return tap_write_packet(s, iovp, iovcnt);
|
||||
}
|
||||
|
||||
static ssize_t tap_receive_raw(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
static ssize_t tap_receive_raw(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
TAPState *s = DO_UPCAST(TAPState, nc, nc);
|
||||
struct iovec iov[2];
|
||||
|
@ -154,7 +154,7 @@ static ssize_t tap_receive_raw(VLANClientState *nc, const uint8_t *buf, size_t s
|
|||
return tap_write_packet(s, iov, iovcnt);
|
||||
}
|
||||
|
||||
static ssize_t tap_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
static ssize_t tap_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
TAPState *s = DO_UPCAST(TAPState, nc, nc);
|
||||
struct iovec iov[1];
|
||||
|
@ -183,7 +183,7 @@ ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void tap_send_completed(VLANClientState *nc, ssize_t len)
|
||||
static void tap_send_completed(NetClientState *nc, ssize_t len)
|
||||
{
|
||||
TAPState *s = DO_UPCAST(TAPState, nc, nc);
|
||||
tap_read_poll(s, 1);
|
||||
|
@ -214,7 +214,7 @@ static void tap_send(void *opaque)
|
|||
} while (size > 0 && qemu_can_send_packet(&s->nc));
|
||||
}
|
||||
|
||||
int tap_has_ufo(VLANClientState *nc)
|
||||
int tap_has_ufo(NetClientState *nc)
|
||||
{
|
||||
TAPState *s = DO_UPCAST(TAPState, nc, nc);
|
||||
|
||||
|
@ -223,7 +223,7 @@ int tap_has_ufo(VLANClientState *nc)
|
|||
return s->has_ufo;
|
||||
}
|
||||
|
||||
int tap_has_vnet_hdr(VLANClientState *nc)
|
||||
int tap_has_vnet_hdr(NetClientState *nc)
|
||||
{
|
||||
TAPState *s = DO_UPCAST(TAPState, nc, nc);
|
||||
|
||||
|
@ -232,7 +232,7 @@ int tap_has_vnet_hdr(VLANClientState *nc)
|
|||
return !!s->host_vnet_hdr_len;
|
||||
}
|
||||
|
||||
int tap_has_vnet_hdr_len(VLANClientState *nc, int len)
|
||||
int tap_has_vnet_hdr_len(NetClientState *nc, int len)
|
||||
{
|
||||
TAPState *s = DO_UPCAST(TAPState, nc, nc);
|
||||
|
||||
|
@ -241,7 +241,7 @@ int tap_has_vnet_hdr_len(VLANClientState *nc, int len)
|
|||
return tap_probe_vnet_hdr_len(s->fd, len);
|
||||
}
|
||||
|
||||
void tap_set_vnet_hdr_len(VLANClientState *nc, int len)
|
||||
void tap_set_vnet_hdr_len(NetClientState *nc, int len)
|
||||
{
|
||||
TAPState *s = DO_UPCAST(TAPState, nc, nc);
|
||||
|
||||
|
@ -253,7 +253,7 @@ void tap_set_vnet_hdr_len(VLANClientState *nc, int len)
|
|||
s->host_vnet_hdr_len = len;
|
||||
}
|
||||
|
||||
void tap_using_vnet_hdr(VLANClientState *nc, int using_vnet_hdr)
|
||||
void tap_using_vnet_hdr(NetClientState *nc, int using_vnet_hdr)
|
||||
{
|
||||
TAPState *s = DO_UPCAST(TAPState, nc, nc);
|
||||
|
||||
|
@ -265,7 +265,7 @@ void tap_using_vnet_hdr(VLANClientState *nc, int using_vnet_hdr)
|
|||
s->using_vnet_hdr = using_vnet_hdr;
|
||||
}
|
||||
|
||||
void tap_set_offload(VLANClientState *nc, int csum, int tso4,
|
||||
void tap_set_offload(NetClientState *nc, int csum, int tso4,
|
||||
int tso6, int ecn, int ufo)
|
||||
{
|
||||
TAPState *s = DO_UPCAST(TAPState, nc, nc);
|
||||
|
@ -276,7 +276,7 @@ void tap_set_offload(VLANClientState *nc, int csum, int tso4,
|
|||
tap_fd_set_offload(s->fd, csum, tso4, tso6, ecn, ufo);
|
||||
}
|
||||
|
||||
static void tap_cleanup(VLANClientState *nc)
|
||||
static void tap_cleanup(NetClientState *nc)
|
||||
{
|
||||
TAPState *s = DO_UPCAST(TAPState, nc, nc);
|
||||
|
||||
|
@ -296,14 +296,14 @@ static void tap_cleanup(VLANClientState *nc)
|
|||
s->fd = -1;
|
||||
}
|
||||
|
||||
static void tap_poll(VLANClientState *nc, bool enable)
|
||||
static void tap_poll(NetClientState *nc, bool enable)
|
||||
{
|
||||
TAPState *s = DO_UPCAST(TAPState, nc, nc);
|
||||
tap_read_poll(s, enable);
|
||||
tap_write_poll(s, enable);
|
||||
}
|
||||
|
||||
int tap_get_fd(VLANClientState *nc)
|
||||
int tap_get_fd(NetClientState *nc)
|
||||
{
|
||||
TAPState *s = DO_UPCAST(TAPState, nc, nc);
|
||||
assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP);
|
||||
|
@ -322,16 +322,16 @@ static NetClientInfo net_tap_info = {
|
|||
.cleanup = tap_cleanup,
|
||||
};
|
||||
|
||||
static TAPState *net_tap_fd_init(VLANState *vlan,
|
||||
static TAPState *net_tap_fd_init(NetClientState *peer,
|
||||
const char *model,
|
||||
const char *name,
|
||||
int fd,
|
||||
int vnet_hdr)
|
||||
{
|
||||
VLANClientState *nc;
|
||||
NetClientState *nc;
|
||||
TAPState *s;
|
||||
|
||||
nc = qemu_new_net_client(&net_tap_info, vlan, NULL, model, name);
|
||||
nc = qemu_new_net_client(&net_tap_info, peer, model, name);
|
||||
|
||||
s = DO_UPCAST(TAPState, nc, nc);
|
||||
|
||||
|
@ -514,7 +514,7 @@ static int net_bridge_run_helper(const char *helper, const char *bridge)
|
|||
}
|
||||
|
||||
int net_init_bridge(const NetClientOptions *opts, const char *name,
|
||||
VLANState *vlan)
|
||||
NetClientState *peer)
|
||||
{
|
||||
const NetdevBridgeOptions *bridge;
|
||||
const char *helper, *br;
|
||||
|
@ -537,7 +537,7 @@ int net_init_bridge(const NetClientOptions *opts, const char *name,
|
|||
|
||||
vnet_hdr = tap_probe_vnet_hdr(fd);
|
||||
|
||||
s = net_tap_fd_init(vlan, "bridge", name, fd, vnet_hdr);
|
||||
s = net_tap_fd_init(peer, "bridge", name, fd, vnet_hdr);
|
||||
if (!s) {
|
||||
close(fd);
|
||||
return -1;
|
||||
|
@ -587,7 +587,7 @@ static int net_tap_init(const NetdevTapOptions *tap, int *vnet_hdr,
|
|||
}
|
||||
|
||||
int net_init_tap(const NetClientOptions *opts, const char *name,
|
||||
VLANState *vlan)
|
||||
NetClientState *peer)
|
||||
{
|
||||
const NetdevTapOptions *tap;
|
||||
|
||||
|
@ -650,7 +650,7 @@ int net_init_tap(const NetClientOptions *opts, const char *name,
|
|||
model = "tap";
|
||||
}
|
||||
|
||||
s = net_tap_fd_init(vlan, model, name, fd, vnet_hdr);
|
||||
s = net_tap_fd_init(peer, model, name, fd, vnet_hdr);
|
||||
if (!s) {
|
||||
close(fd);
|
||||
return -1;
|
||||
|
@ -708,7 +708,7 @@ int net_init_tap(const NetClientOptions *opts, const char *name,
|
|||
return 0;
|
||||
}
|
||||
|
||||
VHostNetState *tap_get_vhost_net(VLANClientState *nc)
|
||||
VHostNetState *tap_get_vhost_net(NetClientState *nc)
|
||||
{
|
||||
TAPState *s = DO_UPCAST(TAPState, nc, nc);
|
||||
assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP);
|
||||
|
|
20
net/tap.h
20
net/tap.h
|
@ -33,18 +33,18 @@
|
|||
#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
|
||||
|
||||
int net_init_tap(const NetClientOptions *opts, const char *name,
|
||||
VLANState *vlan);
|
||||
NetClientState *peer);
|
||||
|
||||
int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required);
|
||||
|
||||
ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen);
|
||||
|
||||
int tap_has_ufo(VLANClientState *vc);
|
||||
int tap_has_vnet_hdr(VLANClientState *vc);
|
||||
int tap_has_vnet_hdr_len(VLANClientState *vc, int len);
|
||||
void tap_using_vnet_hdr(VLANClientState *vc, int using_vnet_hdr);
|
||||
void tap_set_offload(VLANClientState *vc, int csum, int tso4, int tso6, int ecn, int ufo);
|
||||
void tap_set_vnet_hdr_len(VLANClientState *vc, int len);
|
||||
int tap_has_ufo(NetClientState *nc);
|
||||
int tap_has_vnet_hdr(NetClientState *nc);
|
||||
int tap_has_vnet_hdr_len(NetClientState *nc, int len);
|
||||
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);
|
||||
void tap_set_vnet_hdr_len(NetClientState *nc, int len);
|
||||
|
||||
int tap_set_sndbuf(int fd, const NetdevTapOptions *tap);
|
||||
int tap_probe_vnet_hdr(int fd);
|
||||
|
@ -53,12 +53,12 @@ int tap_probe_has_ufo(int fd);
|
|||
void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo);
|
||||
void tap_fd_set_vnet_hdr_len(int fd, int len);
|
||||
|
||||
int tap_get_fd(VLANClientState *vc);
|
||||
int tap_get_fd(NetClientState *nc);
|
||||
|
||||
struct vhost_net;
|
||||
struct vhost_net *tap_get_vhost_net(VLANClientState *vc);
|
||||
struct vhost_net *tap_get_vhost_net(NetClientState *nc);
|
||||
|
||||
int net_init_bridge(const NetClientOptions *opts, const char *name,
|
||||
VLANState *vlan);
|
||||
NetClientState *peer);
|
||||
|
||||
#endif /* QEMU_NET_TAP_H */
|
||||
|
|
16
net/vde.c
16
net/vde.c
|
@ -33,7 +33,7 @@
|
|||
#include "qemu-option.h"
|
||||
|
||||
typedef struct VDEState {
|
||||
VLANClientState nc;
|
||||
NetClientState nc;
|
||||
VDECONN *vde;
|
||||
} VDEState;
|
||||
|
||||
|
@ -49,7 +49,7 @@ static void vde_to_qemu(void *opaque)
|
|||
}
|
||||
}
|
||||
|
||||
static ssize_t vde_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
static ssize_t vde_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
VDEState *s = DO_UPCAST(VDEState, nc, nc);
|
||||
ssize_t ret;
|
||||
|
@ -61,7 +61,7 @@ static ssize_t vde_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void vde_cleanup(VLANClientState *nc)
|
||||
static void vde_cleanup(NetClientState *nc)
|
||||
{
|
||||
VDEState *s = DO_UPCAST(VDEState, nc, nc);
|
||||
qemu_set_fd_handler(vde_datafd(s->vde), NULL, NULL, NULL);
|
||||
|
@ -75,11 +75,11 @@ static NetClientInfo net_vde_info = {
|
|||
.cleanup = vde_cleanup,
|
||||
};
|
||||
|
||||
static int net_vde_init(VLANState *vlan, const char *model,
|
||||
static int net_vde_init(NetClientState *peer, const char *model,
|
||||
const char *name, const char *sock,
|
||||
int port, const char *group, int mode)
|
||||
{
|
||||
VLANClientState *nc;
|
||||
NetClientState *nc;
|
||||
VDEState *s;
|
||||
VDECONN *vde;
|
||||
char *init_group = (char *)group;
|
||||
|
@ -96,7 +96,7 @@ static int net_vde_init(VLANState *vlan, const char *model,
|
|||
return -1;
|
||||
}
|
||||
|
||||
nc = qemu_new_net_client(&net_vde_info, vlan, NULL, model, name);
|
||||
nc = qemu_new_net_client(&net_vde_info, peer, model, name);
|
||||
|
||||
snprintf(nc->info_str, sizeof(nc->info_str), "sock=%s,fd=%d",
|
||||
sock, vde_datafd(vde));
|
||||
|
@ -111,7 +111,7 @@ static int net_vde_init(VLANState *vlan, const char *model,
|
|||
}
|
||||
|
||||
int net_init_vde(const NetClientOptions *opts, const char *name,
|
||||
VLANState *vlan)
|
||||
NetClientState *peer)
|
||||
{
|
||||
const NetdevVdeOptions *vde;
|
||||
|
||||
|
@ -119,7 +119,7 @@ int net_init_vde(const NetClientOptions *opts, const char *name,
|
|||
vde = opts->vde;
|
||||
|
||||
/* missing optional values have been initialized to "all bits zero" */
|
||||
if (net_vde_init(vlan, "vde", name, vde->sock, vde->port, vde->group,
|
||||
if (net_vde_init(peer, "vde", name, vde->sock, vde->port, vde->group,
|
||||
vde->has_mode ? vde->mode : 0700) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#ifdef CONFIG_VDE
|
||||
|
||||
int net_init_vde(const NetClientOptions *opts, const char *name,
|
||||
VLANState *vlan);
|
||||
NetClientState *peer);
|
||||
|
||||
#endif /* CONFIG_VDE */
|
||||
|
||||
|
|
|
@ -2093,6 +2093,19 @@
|
|||
'*br': 'str',
|
||||
'*helper': 'str' } }
|
||||
|
||||
##
|
||||
# @NetdevHubPortOptions
|
||||
#
|
||||
# Connect two or more net clients through a software hub.
|
||||
#
|
||||
# @hubid: hub identifier number
|
||||
#
|
||||
# Since 1.2
|
||||
##
|
||||
{ 'type': 'NetdevHubPortOptions',
|
||||
'data': {
|
||||
'hubid': 'int32' } }
|
||||
|
||||
##
|
||||
# @NetClientOptions
|
||||
#
|
||||
|
@ -2102,14 +2115,15 @@
|
|||
##
|
||||
{ 'union': 'NetClientOptions',
|
||||
'data': {
|
||||
'none': 'NetdevNoneOptions',
|
||||
'nic': 'NetLegacyNicOptions',
|
||||
'user': 'NetdevUserOptions',
|
||||
'tap': 'NetdevTapOptions',
|
||||
'socket': 'NetdevSocketOptions',
|
||||
'vde': 'NetdevVdeOptions',
|
||||
'dump': 'NetdevDumpOptions',
|
||||
'bridge': 'NetdevBridgeOptions' } }
|
||||
'none': 'NetdevNoneOptions',
|
||||
'nic': 'NetLegacyNicOptions',
|
||||
'user': 'NetdevUserOptions',
|
||||
'tap': 'NetdevTapOptions',
|
||||
'socket': 'NetdevSocketOptions',
|
||||
'vde': 'NetdevVdeOptions',
|
||||
'dump': 'NetdevDumpOptions',
|
||||
'bridge': 'NetdevBridgeOptions',
|
||||
'hubport': 'NetdevHubPortOptions' } }
|
||||
|
||||
##
|
||||
# @NetLegacy
|
||||
|
|
|
@ -35,6 +35,10 @@
|
|||
|
||||
#include <linux/sockios.h>
|
||||
|
||||
#ifndef SIOCBRADDIF
|
||||
#include <linux/if_bridge.h>
|
||||
#endif
|
||||
|
||||
#include "qemu-queue.h"
|
||||
|
||||
#include "net/tap-linux.h"
|
||||
|
@ -221,6 +225,10 @@ static int drop_privileges(void)
|
|||
int main(int argc, char **argv)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
#ifndef SIOCBRADDIF
|
||||
unsigned long ifargs[4];
|
||||
#endif
|
||||
int ifindex;
|
||||
int fd, ctlfd, unixfd = -1;
|
||||
int use_vnet = 0;
|
||||
int mtu;
|
||||
|
@ -361,9 +369,19 @@ int main(int argc, char **argv)
|
|||
|
||||
/* add the interface to the bridge */
|
||||
prep_ifreq(&ifr, bridge);
|
||||
ifr.ifr_ifindex = if_nametoindex(iface);
|
||||
|
||||
if (ioctl(ctlfd, SIOCBRADDIF, &ifr) == -1) {
|
||||
ifindex = if_nametoindex(iface);
|
||||
#ifndef SIOCBRADDIF
|
||||
ifargs[0] = BRCTL_ADD_IF;
|
||||
ifargs[1] = ifindex;
|
||||
ifargs[2] = 0;
|
||||
ifargs[3] = 0;
|
||||
ifr.ifr_data = (void *)ifargs;
|
||||
ret = ioctl(ctlfd, SIOCDEVPRIVATE, &ifr);
|
||||
#else
|
||||
ifr.ifr_ifindex = ifindex;
|
||||
ret = ioctl(ctlfd, SIOCBRADDIF, &ifr);
|
||||
#endif
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "failed to add interface `%s' to bridge `%s': %s\n",
|
||||
iface, bridge, strerror(errno));
|
||||
ret = EXIT_FAILURE;
|
||||
|
|
|
@ -252,8 +252,7 @@ typedef struct TextConsole TextConsole;
|
|||
typedef TextConsole QEMUConsole;
|
||||
typedef struct CharDriverState CharDriverState;
|
||||
typedef struct MACAddr MACAddr;
|
||||
typedef struct VLANState VLANState;
|
||||
typedef struct VLANClientState VLANClientState;
|
||||
typedef struct NetClientState NetClientState;
|
||||
typedef struct i2c_bus i2c_bus;
|
||||
typedef struct ISABus ISABus;
|
||||
typedef struct ISADevice ISADevice;
|
||||
|
|
|
@ -177,11 +177,6 @@ void if_start(Slirp *slirp)
|
|||
}
|
||||
|
||||
while (ifm_next) {
|
||||
/* check if we can really output */
|
||||
if (!slirp_can_output(slirp->opaque)) {
|
||||
break;
|
||||
}
|
||||
|
||||
ifm = ifm_next;
|
||||
from_batchq = next_from_batchq;
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
|
|||
void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
|
||||
|
||||
/* you must provide the following functions: */
|
||||
int slirp_can_output(void *opaque);
|
||||
void slirp_output(void *opaque, const uint8_t *pkt, int pkt_len);
|
||||
|
||||
int slirp_add_hostfwd(Slirp *slirp, int is_udp,
|
||||
|
|
Loading…
Reference in New Issue