* Dequeueing sequence - we basically do the following: * 1) Try to extract the frame from the inbound (bandwidth) queue; * 2) In accordance to BER specified, discard the frame randomly; * 3) If the frame survives BER, prepend it with delay info and move it * to outbound (delay) queue; * 4) Loop to 2) until bandwidth quota for this timeslice is reached, or * inbound queue is flush
| 728 | * is not due to be dequeued yet |
| 729 | */ |
| 730 | static void |
| 731 | pipe_dequeue(struct hookinfo *hinfo, struct timeval *now) { |
| 732 | static uint64_t rand, oldrand; |
| 733 | const node_p node = NG_HOOK_NODE(hinfo->hook); |
| 734 | const priv_p priv = NG_NODE_PRIVATE(node); |
| 735 | struct hookinfo *dest; |
| 736 | struct ngp_fifo *ngp_f, *ngp_f1; |
| 737 | struct ngp_hdr *ngp_h; |
| 738 | struct timeval *when; |
| 739 | struct mbuf *m; |
| 740 | int plen, error = 0; |
| 741 | |
| 742 | /* Which one is the destination hook? */ |
| 743 | if (hinfo == &priv->lower) |
| 744 | dest = &priv->upper; |
| 745 | else |
| 746 | dest = &priv->lower; |
| 747 | |
| 748 | /* Bandwidth queue processing */ |
| 749 | while ((ngp_f = TAILQ_FIRST(&hinfo->fifo_head))) { |
| 750 | when = &hinfo->qin_utime; |
| 751 | if (when->tv_sec > now->tv_sec || (when->tv_sec == now->tv_sec |
| 752 | && when->tv_usec > now->tv_usec)) |
| 753 | break; |
| 754 | |
| 755 | ngp_h = TAILQ_FIRST(&ngp_f->packet_head); |
| 756 | m = ngp_h->m; |
| 757 | |
| 758 | /* Deficit Round Robin (DRR) processing */ |
| 759 | if (hinfo->cfg.drr) { |
| 760 | if (ngp_f->rr_deficit >= m->m_pkthdr.len) { |
| 761 | ngp_f->rr_deficit -= m->m_pkthdr.len; |
| 762 | } else { |
| 763 | ngp_f->rr_deficit += hinfo->cfg.drr; |
| 764 | TAILQ_REMOVE(&hinfo->fifo_head, ngp_f, fifo_le); |
| 765 | TAILQ_INSERT_TAIL(&hinfo->fifo_head, |
| 766 | ngp_f, fifo_le); |
| 767 | continue; |
| 768 | } |
| 769 | } |
| 770 | |
| 771 | /* |
| 772 | * Either create a duplicate and pass it on, or dequeue |
| 773 | * the original packet... |
| 774 | */ |
| 775 | if (hinfo->cfg.duplicate && |
| 776 | random() % 100 <= hinfo->cfg.duplicate) { |
| 777 | ngp_h = uma_zalloc(ngp_zone, M_NOWAIT); |
| 778 | KASSERT(ngp_h != NULL, ("ngp_h zalloc failed (3)")); |
| 779 | m = m_dup(m, M_NOWAIT); |
| 780 | KASSERT(m != NULL, ("m_dup failed")); |
| 781 | ngp_h->m = m; |
| 782 | } else { |
| 783 | TAILQ_REMOVE(&ngp_f->packet_head, ngp_h, ngp_link); |
| 784 | hinfo->run.qin_frames--; |
| 785 | hinfo->run.qin_octets -= m->m_pkthdr.len; |
| 786 | ngp_f->packets--; |
| 787 | } |
no test coverage detected