* Enqueue packet. */
| 707 | * Enqueue packet. |
| 708 | */ |
| 709 | static void |
| 710 | ng_car_enqueue(struct hookinfo *hinfo, item_p item) |
| 711 | { |
| 712 | struct mbuf *m; |
| 713 | int len; |
| 714 | |
| 715 | NGI_GET_M(item, m); |
| 716 | NG_FREE_ITEM(item); |
| 717 | |
| 718 | /* Lock queue mutex. */ |
| 719 | mtx_lock(&hinfo->q_mtx); |
| 720 | |
| 721 | /* Calculate used queue length. */ |
| 722 | len = hinfo->q_last - hinfo->q_first; |
| 723 | if (len < 0) |
| 724 | len += NG_CAR_QUEUE_SIZE; |
| 725 | |
| 726 | /* If queue is overflowed or we have no RED tokens. */ |
| 727 | if ((len >= (NG_CAR_QUEUE_SIZE - 1)) || |
| 728 | (hinfo->te + len >= NG_CAR_QUEUE_SIZE)) { |
| 729 | /* Drop packet. */ |
| 730 | ++hinfo->stats.red_pkts; |
| 731 | ++hinfo->stats.dropped_pkts; |
| 732 | NG_FREE_M(m); |
| 733 | |
| 734 | hinfo->te = 0; |
| 735 | } else { |
| 736 | /* This packet is yellow. */ |
| 737 | ++hinfo->stats.yellow_pkts; |
| 738 | |
| 739 | /* Enqueue packet. */ |
| 740 | hinfo->q[hinfo->q_last] = m; |
| 741 | hinfo->q_last++; |
| 742 | if (hinfo->q_last >= NG_CAR_QUEUE_SIZE) |
| 743 | hinfo->q_last = 0; |
| 744 | |
| 745 | /* Use RED tokens. */ |
| 746 | if (len > NG_CAR_QUEUE_MIN_TH) |
| 747 | hinfo->te += len - NG_CAR_QUEUE_MIN_TH; |
| 748 | |
| 749 | /* If this is a first packet in the queue. */ |
| 750 | if (len == 0) { |
| 751 | if (hinfo->conf.opt & NG_CAR_COUNT_PACKETS) { |
| 752 | hinfo->tc -= 128; |
| 753 | } else { |
| 754 | hinfo->tc -= m->m_pkthdr.len; |
| 755 | } |
| 756 | |
| 757 | /* Schedule queue processing. */ |
| 758 | ng_car_schedule(hinfo); |
| 759 | } |
| 760 | } |
| 761 | |
| 762 | /* Unlock queue mutex. */ |
| 763 | mtx_unlock(&hinfo->q_mtx); |
| 764 | } |
no test coverage detected