1
2
3
4
5
6
7
8#include <slirp.h>
9
10#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm))
11
12static void
13ifs_insque(struct mbuf *ifm, struct mbuf *ifmhead)
14{
15 ifm->ifs_next = ifmhead->ifs_next;
16 ifmhead->ifs_next = ifm;
17 ifm->ifs_prev = ifmhead;
18 ifm->ifs_next->ifs_prev = ifm;
19}
20
21static void
22ifs_remque(struct mbuf *ifm)
23{
24 ifm->ifs_prev->ifs_next = ifm->ifs_next;
25 ifm->ifs_next->ifs_prev = ifm->ifs_prev;
26}
27
28void
29if_init(Slirp *slirp)
30{
31 slirp->if_fastq.ifq_next = slirp->if_fastq.ifq_prev = &slirp->if_fastq;
32 slirp->if_batchq.ifq_next = slirp->if_batchq.ifq_prev = &slirp->if_batchq;
33 slirp->next_m = &slirp->if_batchq;
34}
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49void
50if_output(struct socket *so, struct mbuf *ifm)
51{
52 Slirp *slirp = ifm->slirp;
53 struct mbuf *ifq;
54 int on_fastq = 1;
55
56 DEBUG_CALL("if_output");
57 DEBUG_ARG("so = %lx", (long)so);
58 DEBUG_ARG("ifm = %lx", (long)ifm);
59
60
61
62
63
64
65 if (ifm->m_flags & M_USEDLIST) {
66 remque(ifm);
67 ifm->m_flags &= ~M_USEDLIST;
68 }
69
70
71
72
73
74
75
76
77 for (ifq = slirp->if_batchq.ifq_prev; ifq != &slirp->if_batchq;
78 ifq = ifq->ifq_prev) {
79 if (so == ifq->ifq_so) {
80
81 ifm->ifq_so = so;
82 ifs_insque(ifm, ifq->ifs_prev);
83 goto diddit;
84 }
85 }
86
87
88 if (so && (so->so_iptos & IPTOS_LOWDELAY)) {
89 ifq = slirp->if_fastq.ifq_prev;
90 on_fastq = 1;
91
92
93
94
95 if (ifq->ifq_so == so) {
96 ifm->ifq_so = so;
97 ifs_insque(ifm, ifq->ifs_prev);
98 goto diddit;
99 }
100 } else
101 ifq = slirp->if_batchq.ifq_prev;
102
103
104 ifm->ifq_so = so;
105 ifs_init(ifm);
106 insque(ifm, ifq);
107
108diddit:
109 slirp->if_queued++;
110
111 if (so) {
112
113 so->so_queued++;
114 so->so_nqueued++;
115
116
117
118
119
120
121
122 if (on_fastq && ((so->so_nqueued >= 6) &&
123 (so->so_nqueued - so->so_queued) >= 3)) {
124
125
126 remque(ifm->ifs_next);
127
128
129 insque(ifm->ifs_next, &slirp->if_batchq);
130 }
131 }
132
133#ifndef FULL_BOLT
134
135
136
137 if_start(ifm->slirp);
138#endif
139}
140
141
142
143
144
145
146
147
148
149
150
151
152
153void
154if_start(Slirp *slirp)
155{
156 struct mbuf *ifm, *ifqt;
157
158 DEBUG_CALL("if_start");
159
160 if (slirp->if_queued == 0)
161 return;
162
163 again:
164
165 if (!slirp_can_output(slirp->opaque))
166 return;
167
168
169
170
171
172 if (slirp->if_fastq.ifq_next != &slirp->if_fastq) {
173 ifm = slirp->if_fastq.ifq_next;
174 } else {
175
176 if (slirp->next_m != &slirp->if_batchq)
177 ifm = slirp->next_m;
178 else
179 ifm = slirp->if_batchq.ifq_next;
180
181
182 slirp->next_m = ifm->ifq_next;
183 }
184
185 ifqt = ifm->ifq_prev;
186 remque(ifm);
187 slirp->if_queued--;
188
189
190 if (ifm->ifs_next != ifm) {
191 insque(ifm->ifs_next, ifqt);
192 ifs_remque(ifm);
193 }
194
195
196 if (ifm->ifq_so) {
197 if (--ifm->ifq_so->so_queued == 0)
198
199 ifm->ifq_so->so_nqueued = 0;
200 }
201
202
203 if_encap(slirp, (uint8_t *)ifm->m_data, ifm->m_len);
204
205 m_free(ifm);
206
207 if (slirp->if_queued)
208 goto again;
209}
210