Commit e94667b91ccfdb70164ae320b1c4ded6b5b8a3ec

Authored by Mark McLoughlin
1 parent 3e021d40

net: split out packet queueing and flushing into separate functions

We'll be doing more packet queueing in later commits.

Signed-off-by: Mark McLoughlin <markmc@redhat.com>
Showing 1 changed file with 98 additions and 57 deletions
... ... @@ -415,6 +415,8 @@ qemu_deliver_packet(VLANClientState *sender, const uint8_t *buf, int size)
415 415 VLANClientState *vc;
416 416 int ret = -1;
417 417  
  418 + sender->vlan->delivering = 1;
  419 +
418 420 for (vc = sender->vlan->first_client; vc != NULL; vc = vc->next) {
419 421 ssize_t len;
420 422  
... ... @@ -432,13 +434,38 @@ qemu_deliver_packet(VLANClientState *sender, const uint8_t *buf, int size)
432 434 ret = (ret >= 0) ? ret : len;
433 435 }
434 436  
  437 + sender->vlan->delivering = 0;
  438 +
435 439 return ret;
436 440 }
437 441  
  442 +static void qemu_flush_queued_packets(VLANClientState *vc)
  443 +{
  444 + VLANPacket *packet;
  445 +
  446 + while ((packet = vc->vlan->send_queue) != NULL) {
  447 + vc->vlan->send_queue = packet->next;
  448 + qemu_deliver_packet(packet->sender, packet->data, packet->size);
  449 + qemu_free(packet);
  450 + }
  451 +}
  452 +
  453 +static void
  454 +qemu_enqueue_packet(VLANClientState *sender, const uint8_t *buf, int size)
  455 +{
  456 + VLANPacket *packet;
  457 +
  458 + packet = qemu_malloc(sizeof(VLANPacket) + size);
  459 + packet->next = sender->vlan->send_queue;
  460 + packet->sender = sender;
  461 + packet->size = size;
  462 + memcpy(packet->data, buf, size);
  463 + sender->vlan->send_queue = packet;
  464 +}
  465 +
438 466 void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size)
439 467 {
440 468 VLANState *vlan = vc->vlan;
441   - VLANPacket *packet;
442 469  
443 470 if (vc->link_down)
444 471 return;
... ... @@ -448,22 +475,12 @@ void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size)
448 475 hex_dump(stdout, buf, size);
449 476 #endif
450 477 if (vlan->delivering) {
451   - packet = qemu_malloc(sizeof(VLANPacket) + size);
452   - packet->next = vlan->send_queue;
453   - packet->sender = vc;
454   - packet->size = size;
455   - memcpy(packet->data, buf, size);
456   - vlan->send_queue = packet;
457   - } else {
458   - vlan->delivering = 1;
459   - qemu_deliver_packet(vc, buf, size);
460   - while ((packet = vlan->send_queue) != NULL) {
461   - vlan->send_queue = packet->next;
462   - qemu_deliver_packet(packet->sender, packet->data, packet->size);
463   - qemu_free(packet);
464   - }
465   - vlan->delivering = 0;
  478 + qemu_enqueue_packet(vc, buf, size);
  479 + return;
466 480 }
  481 +
  482 + qemu_deliver_packet(vc, buf, size);
  483 + qemu_flush_queued_packets(vc);
467 484 }
468 485  
469 486 static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov,
... ... @@ -496,60 +513,84 @@ static ssize_t calc_iov_length(const struct iovec *iov, int iovcnt)
496 513 return offset;
497 514 }
498 515  
499   -ssize_t qemu_sendv_packet(VLANClientState *sender, const struct iovec *iov,
500   - int iovcnt)
  516 +static int qemu_deliver_packet_iov(VLANClientState *sender,
  517 + const struct iovec *iov, int iovcnt)
501 518 {
502   - VLANState *vlan = sender->vlan;
503 519 VLANClientState *vc;
  520 + int ret = -1;
  521 +
  522 + sender->vlan->delivering = 1;
  523 +
  524 + for (vc = sender->vlan->first_client; vc != NULL; vc = vc->next) {
  525 + ssize_t len;
  526 +
  527 + if (vc == sender) {
  528 + continue;
  529 + }
  530 +
  531 + if (vc->link_down) {
  532 + ret = calc_iov_length(iov, iovcnt);
  533 + continue;
  534 + }
  535 +
  536 + if (vc->receive_iov) {
  537 + len = vc->receive_iov(vc, iov, iovcnt);
  538 + } else {
  539 + len = vc_sendv_compat(vc, iov, iovcnt);
  540 + }
  541 +
  542 + ret = (ret >= 0) ? ret : len;
  543 + }
  544 +
  545 + sender->vlan->delivering = 0;
  546 +
  547 + return ret;
  548 +}
  549 +
  550 +static ssize_t qemu_enqueue_packet_iov(VLANClientState *sender,
  551 + const struct iovec *iov, int iovcnt)
  552 +{
504 553 VLANPacket *packet;
505   - ssize_t max_len = 0;
  554 + size_t max_len = 0;
506 555 int i;
507 556  
508   - if (sender->link_down)
509   - return calc_iov_length(iov, iovcnt);
  557 + max_len = calc_iov_length(iov, iovcnt);
510 558  
511   - if (vlan->delivering) {
512   - max_len = calc_iov_length(iov, iovcnt);
  559 + packet = qemu_malloc(sizeof(VLANPacket) + max_len);
  560 + packet->next = sender->vlan->send_queue;
  561 + packet->sender = sender;
  562 + packet->size = 0;
513 563  
514   - packet = qemu_malloc(sizeof(VLANPacket) + max_len);
515   - packet->next = vlan->send_queue;
516   - packet->sender = sender;
517   - packet->size = 0;
518   - for (i = 0; i < iovcnt; i++) {
519   - size_t len = iov[i].iov_len;
  564 + for (i = 0; i < iovcnt; i++) {
  565 + size_t len = iov[i].iov_len;
520 566  
521   - memcpy(packet->data + packet->size, iov[i].iov_base, len);
522   - packet->size += len;
523   - }
524   - vlan->send_queue = packet;
525   - } else {
526   - vlan->delivering = 1;
  567 + memcpy(packet->data + packet->size, iov[i].iov_base, len);
  568 + packet->size += len;
  569 + }
527 570  
528   - for (vc = vlan->first_client; vc != NULL; vc = vc->next) {
529   - ssize_t len = 0;
  571 + sender->vlan->send_queue = packet;
530 572  
531   - if (vc == sender) {
532   - continue;
533   - }
534   - if (vc->link_down) {
535   - len = calc_iov_length(iov, iovcnt);
536   - } else if (vc->receive_iov) {
537   - len = vc->receive_iov(vc, iov, iovcnt);
538   - } else if (vc->receive) {
539   - len = vc_sendv_compat(vc, iov, iovcnt);
540   - }
541   - max_len = MAX(max_len, len);
542   - }
  573 + return packet->size;
  574 +}
543 575  
544   - while ((packet = vlan->send_queue) != NULL) {
545   - vlan->send_queue = packet->next;
546   - qemu_deliver_packet(packet->sender, packet->data, packet->size);
547   - qemu_free(packet);
548   - }
549   - vlan->delivering = 0;
  576 +ssize_t qemu_sendv_packet(VLANClientState *sender, const struct iovec *iov,
  577 + int iovcnt)
  578 +{
  579 + int ret;
  580 +
  581 + if (sender->link_down) {
  582 + return calc_iov_length(iov, iovcnt);
  583 + }
  584 +
  585 + if (sender->vlan->delivering) {
  586 + return qemu_enqueue_packet_iov(sender, iov, iovcnt);
550 587 }
551 588  
552   - return max_len;
  589 + ret = qemu_deliver_packet_iov(sender, iov, iovcnt);
  590 +
  591 + qemu_flush_queued_packets(sender);
  592 +
  593 + return ret;
553 594 }
554 595  
555 596 static void config_error(Monitor *mon, const char *fmt, ...)
... ...