96
96
ifs_insque(ifm, ifq->ifs_prev);
100
100
ifq = slirp->if_batchq.ifq_prev;
101
/* Set next_m if the queue was empty so far */
102
if (slirp->next_m == &slirp->if_batchq) {
102
107
/* Create a new doubly linked list for this session */
103
108
ifm->ifq_so = so;
152
155
void if_start(Slirp *slirp)
154
157
uint64_t now = qemu_get_clock_ns(rt_clock);
156
bool from_batchq = false;
157
struct mbuf *ifm, *ifqt;
158
bool from_batchq, next_from_batchq;
159
struct mbuf *ifm, *ifm_next, *ifqt;
159
161
DEBUG_CALL("if_start");
161
while (slirp->if_queued) {
162
/* check if we can really output */
163
if (!slirp_can_output(slirp->opaque))
167
* See which queue to get next packet from
168
* If there's something in the fastq, select it immediately
170
if (slirp->if_fastq.ifq_next != &slirp->if_fastq) {
171
ifm = slirp->if_fastq.ifq_next;
173
/* Nothing on fastq, see if next_m is valid */
174
if (slirp->next_m != &slirp->if_batchq) {
177
ifm = slirp->if_batchq.ifq_next;
163
if (slirp->if_start_busy) {
166
slirp->if_start_busy = true;
168
if (slirp->if_fastq.ifq_next != &slirp->if_fastq) {
169
ifm_next = slirp->if_fastq.ifq_next;
170
next_from_batchq = false;
171
} else if (slirp->next_m != &slirp->if_batchq) {
172
/* Nothing on fastq, pick up from batchq via next_m */
173
ifm_next = slirp->next_m;
174
next_from_batchq = true;
181
from_batchq = next_from_batchq;
183
ifm_next = ifm->ifq_next;
184
if (ifm_next == &slirp->if_fastq) {
185
/* No more packets in fastq, switch to batchq */
186
ifm_next = slirp->next_m;
187
next_from_batchq = true;
189
if (ifm_next == &slirp->if_batchq) {
185
194
/* Try to send packet unless it already expired */
186
195
if (ifm->expiration_date >= now && !if_encap(slirp, ifm)) {
187
196
/* Packet is delayed due to pending ARP resolution */
200
if (ifm == slirp->next_m) {
193
201
/* Set which packet to send on next iteration */
194
202
slirp->next_m = ifm->ifq_next;
201
209
/* If there are more packets for this session, re-queue them */
202
210
if (ifm->ifs_next != ifm) {
203
insque(ifm->ifs_next, ifqt);
211
struct mbuf *next = ifm->ifs_next;
217
/* Next packet in fastq is from the same session */
219
next_from_batchq = false;
220
} else if (slirp->next_m == &slirp->if_batchq) {
221
/* Set next_m and ifm_next if the session packet is now the
222
* only one on batchq */
223
slirp->next_m = ifm_next = next;
207
227
/* Update so_queued */