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,6 +415,8 @@ qemu_deliver_packet(VLANClientState *sender, const uint8_t *buf, int size)
415 VLANClientState *vc; 415 VLANClientState *vc;
416 int ret = -1; 416 int ret = -1;
417 417
  418 + sender->vlan->delivering = 1;
  419 +
418 for (vc = sender->vlan->first_client; vc != NULL; vc = vc->next) { 420 for (vc = sender->vlan->first_client; vc != NULL; vc = vc->next) {
419 ssize_t len; 421 ssize_t len;
420 422
@@ -432,13 +434,38 @@ qemu_deliver_packet(VLANClientState *sender, const uint8_t *buf, int size) @@ -432,13 +434,38 @@ qemu_deliver_packet(VLANClientState *sender, const uint8_t *buf, int size)
432 ret = (ret >= 0) ? ret : len; 434 ret = (ret >= 0) ? ret : len;
433 } 435 }
434 436
  437 + sender->vlan->delivering = 0;
  438 +
435 return ret; 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 void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size) 466 void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size)
439 { 467 {
440 VLANState *vlan = vc->vlan; 468 VLANState *vlan = vc->vlan;
441 - VLANPacket *packet;  
442 469
443 if (vc->link_down) 470 if (vc->link_down)
444 return; 471 return;
@@ -448,22 +475,12 @@ void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size) @@ -448,22 +475,12 @@ void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size)
448 hex_dump(stdout, buf, size); 475 hex_dump(stdout, buf, size);
449 #endif 476 #endif
450 if (vlan->delivering) { 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 static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov, 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,60 +513,84 @@ static ssize_t calc_iov_length(const struct iovec *iov, int iovcnt)
496 return offset; 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 VLANClientState *vc; 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 VLANPacket *packet; 553 VLANPacket *packet;
505 - ssize_t max_len = 0; 554 + size_t max_len = 0;
506 int i; 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 static void config_error(Monitor *mon, const char *fmt, ...) 596 static void config_error(Monitor *mon, const char *fmt, ...)