* Send packets out our output hook. */
| 770 | * Send packets out our output hook. |
| 771 | */ |
| 772 | static int |
| 773 | ng_source_send(sc_p sc, int tosend, int *sent_p) |
| 774 | { |
| 775 | struct mbuf *m, *m2; |
| 776 | int sent; |
| 777 | int error = 0; |
| 778 | |
| 779 | KASSERT(tosend >= 0, ("%s: negative tosend param", __func__)); |
| 780 | KASSERT(sc->node->nd_flags & NG_SOURCE_ACTIVE, |
| 781 | ("%s: inactive node", __func__)); |
| 782 | |
| 783 | if ((uint64_t)tosend > sc->packets) |
| 784 | tosend = sc->packets; |
| 785 | |
| 786 | /* Go through the queue sending packets one by one. */ |
| 787 | for (sent = 0; error == 0 && sent < tosend; ++sent) { |
| 788 | _IF_DEQUEUE(&sc->snd_queue, m); |
| 789 | if (m == NULL) |
| 790 | break; |
| 791 | |
| 792 | /* Duplicate and modify the packet. */ |
| 793 | error = ng_source_dup_mod(sc, m, &m2); |
| 794 | if (error) { |
| 795 | if (error == ENOBUFS) |
| 796 | _IF_PREPEND(&sc->snd_queue, m); |
| 797 | else |
| 798 | _IF_ENQUEUE(&sc->snd_queue, m); |
| 799 | break; |
| 800 | } |
| 801 | |
| 802 | /* Re-enqueue the original packet for us. */ |
| 803 | _IF_ENQUEUE(&sc->snd_queue, m); |
| 804 | |
| 805 | sc->stats.outFrames++; |
| 806 | sc->stats.outOctets += m2->m_pkthdr.len; |
| 807 | NG_SEND_DATA_ONLY(error, sc->output, m2); |
| 808 | if (error) |
| 809 | break; |
| 810 | } |
| 811 | |
| 812 | sc->packets -= sent; |
| 813 | if (sent_p != NULL) |
| 814 | *sent_p = sent; |
| 815 | return (error); |
| 816 | } |
| 817 | |
| 818 | /* |
| 819 | * Modify packet in 'm' by changing 'len' bytes starting at 'offset' |
no test coverage detected