Revision c27ff608
b/net.c | ||
---|---|---|
438 | 438 |
vlan->delivering = 1; |
439 | 439 |
qemu_deliver_packet(vc, buf, size); |
440 | 440 |
while ((packet = vlan->send_queue) != NULL) { |
441 |
qemu_deliver_packet(packet->sender, packet->data, packet->size); |
|
442 | 441 |
vlan->send_queue = packet->next; |
442 |
qemu_deliver_packet(packet->sender, packet->data, packet->size); |
|
443 | 443 |
qemu_free(packet); |
444 | 444 |
} |
445 | 445 |
vlan->delivering = 0; |
... | ... | |
476 | 476 |
return offset; |
477 | 477 |
} |
478 | 478 |
|
479 |
ssize_t qemu_sendv_packet(VLANClientState *vc1, const struct iovec *iov,
|
|
479 |
ssize_t qemu_sendv_packet(VLANClientState *sender, const struct iovec *iov,
|
|
480 | 480 |
int iovcnt) |
481 | 481 |
{ |
482 |
VLANState *vlan = vc1->vlan;
|
|
482 |
VLANState *vlan = sender->vlan;
|
|
483 | 483 |
VLANClientState *vc; |
484 |
VLANPacket *packet; |
|
484 | 485 |
ssize_t max_len = 0; |
486 |
int i; |
|
485 | 487 |
|
486 |
if (vc1->link_down)
|
|
488 |
if (sender->link_down)
|
|
487 | 489 |
return calc_iov_length(iov, iovcnt); |
488 | 490 |
|
489 |
for (vc = vlan->first_client; vc != NULL; vc = vc->next) {
|
|
490 |
ssize_t len = 0;
|
|
491 |
if (vlan->delivering) {
|
|
492 |
max_len = calc_iov_length(iov, iovcnt);
|
|
491 | 493 |
|
492 |
if (vc == vc1) |
|
493 |
continue; |
|
494 |
packet = qemu_malloc(sizeof(VLANPacket) + max_len); |
|
495 |
packet->next = vlan->send_queue; |
|
496 |
packet->sender = sender; |
|
497 |
packet->size = 0; |
|
498 |
for (i = 0; i < iovcnt; i++) { |
|
499 |
size_t len = iov[i].iov_len; |
|
500 |
|
|
501 |
memcpy(packet->data + packet->size, iov[i].iov_base, len); |
|
502 |
packet->size += len; |
|
503 |
} |
|
504 |
vlan->send_queue = packet; |
|
505 |
} else { |
|
506 |
vlan->delivering = 1; |
|
507 |
|
|
508 |
for (vc = vlan->first_client; vc != NULL; vc = vc->next) { |
|
509 |
ssize_t len = 0; |
|
494 | 510 |
|
495 |
if (vc->link_down) |
|
496 |
len = calc_iov_length(iov, iovcnt); |
|
497 |
else if (vc->fd_readv) |
|
498 |
len = vc->fd_readv(vc->opaque, iov, iovcnt); |
|
499 |
else if (vc->fd_read) |
|
500 |
len = vc_sendv_compat(vc, iov, iovcnt); |
|
511 |
if (vc == sender) { |
|
512 |
continue; |
|
513 |
} |
|
514 |
if (vc->link_down) { |
|
515 |
len = calc_iov_length(iov, iovcnt); |
|
516 |
} else if (vc->fd_readv) { |
|
517 |
len = vc->fd_readv(vc->opaque, iov, iovcnt); |
|
518 |
} else if (vc->fd_read) { |
|
519 |
len = vc_sendv_compat(vc, iov, iovcnt); |
|
520 |
} |
|
521 |
max_len = MAX(max_len, len); |
|
522 |
} |
|
501 | 523 |
|
502 |
max_len = MAX(max_len, len); |
|
524 |
while ((packet = vlan->send_queue) != NULL) { |
|
525 |
vlan->send_queue = packet->next; |
|
526 |
qemu_deliver_packet(packet->sender, packet->data, packet->size); |
|
527 |
qemu_free(packet); |
|
528 |
} |
|
529 |
vlan->delivering = 0; |
|
503 | 530 |
} |
504 | 531 |
|
505 | 532 |
return max_len; |
Also available in: Unified diff