VirtualBox

source: vbox/trunk/src/VBox/Devices/Network/slirp/mbuf.c@ 13949

Last change on this file since 13949 was 13949, checked in by vboxsync, 16 years ago

backed out r38966

  • Property svn:eol-style set to native
File size: 6.0 KB
Line 
1/*
2 * Copyright (c) 1995 Danny Gasparovski
3 *
4 * Please read the file COPYRIGHT for the
5 * terms and conditions of the copyright.
6 */
7
8/*
9 * mbuf's in SLiRP are much simpler than the real mbufs in
10 * FreeBSD. They are fixed size, determined by the MTU,
11 * so that one whole packet can fit. Mbuf's cannot be
12 * chained together. If there's more data than the mbuf
13 * could hold, an external malloced buffer is pointed to
14 * by m_ext (and the data pointers) and M_EXT is set in
15 * the flags
16 */
17
18#include <slirp.h>
19
20
21void
22m_init(PNATState pData)
23{
24 m_freelist.m_next = m_freelist.m_prev = &m_freelist;
25 m_usedlist.m_next = m_usedlist.m_prev = &m_usedlist;
26 mbuf_alloced = 0;
27
28 VBOX_SLIRP_LOCK_CREATE(&pData->m_usedlist_mutex);
29 VBOX_SLIRP_LOCK_CREATE(&pData->m_freelist_mutex);
30 VBOX_SLIRP_LOCK_CREATE(&pData->mbuf_alloced_mutex);
31
32 msize_init(pData);
33}
34
35void
36msize_init(PNATState pData)
37{
38 /*
39 * Find a nice value for msize
40 * XXX if_maxlinkhdr already in mtu
41 */
42 msize = (if_mtu>if_mru?if_mtu:if_mru) +
43 if_maxlinkhdr + sizeof(struct m_hdr ) + 6;
44}
45
46/*
47 * Get an mbuf from the free list, if there are none
48 * malloc one
49 *
50 * Because fragmentation can occur if we alloc new mbufs and
51 * free old mbufs, we mark all mbufs above mbuf_thresh as M_DOFREE,
52 * which tells m_free to actually free() it
53 */
54struct mbuf *
55m_get(PNATState pData)
56{
57 register struct mbuf *m;
58 int flags = 0;
59#ifdef VBOX_WITH_SYNC_SLIRP
60 int on_free_list = 0;
61#endif
62
63 DEBUG_CALL("m_get");
64
65 VBOX_SLIRP_LOCK(pData->m_freelist_mutex);
66
67 if (m_freelist.m_next == &m_freelist) {
68 m = (struct mbuf *)malloc(msize);
69 if (m == NULL) {
70 VBOX_SLIRP_UNLOCK(pData->m_freelist_mutex);
71 goto end_error;
72 }
73
74 VBOX_SLIRP_LOCK(pData->mbuf_alloced_mutex);
75
76 mbuf_alloced++;
77 if (mbuf_alloced > mbuf_thresh)
78 flags = M_DOFREE;
79 if (mbuf_alloced > mbuf_max)
80 mbuf_max = mbuf_alloced;
81 VBOX_SLIRP_UNLOCK(pData->mbuf_alloced_mutex);
82 } else {
83 m = m_freelist.m_next;
84 remque(pData, m);
85 }
86
87 VBOX_SLIRP_UNLOCK(pData->m_freelist_mutex);
88
89 VBOX_SLIRP_LOCK(pData->m_usedlist_mutex);
90 /* Insert it in the used list */
91 insque(pData, m,&m_usedlist);
92 VBOX_SLIRP_UNLOCK(pData->m_usedlist_mutex);
93
94 m->m_flags = (flags | M_USEDLIST);
95
96 /* Initialise it */
97 m->m_size = msize - sizeof(struct m_hdr);
98 m->m_data = m->m_dat;
99 m->m_len = 0;
100 m->m_nextpkt = 0;
101 m->m_prevpkt = 0;
102
103end_error:
104 DEBUG_ARG("m = %lx", (long )m);
105 return m;
106}
107
108void
109m_free(PNATState pData, struct mbuf *m)
110{
111
112 DEBUG_CALL("m_free");
113 DEBUG_ARG("m = %lx", (long )m);
114
115 if(m) {
116 /* Remove from m_usedlist */
117 if (m->m_flags & M_USEDLIST) {
118 VBOX_SLIRP_LOCK(pData->m_usedlist_mutex);
119 remque(pData, m);
120 VBOX_SLIRP_UNLOCK(pData->m_usedlist_mutex);
121 }
122
123 /* If it's M_EXT, free() it */
124 if (m->m_flags & M_EXT)
125 free(m->m_ext);
126
127 /*
128 * Either free() it or put it on the free list
129 */
130 if (m->m_flags & M_DOFREE) {
131 u32ptr_done(pData, ptr_to_u32(pData, m), m);
132 free(m);
133#ifdef VBOX_WITH_SYNC_SLIRP
134 m = NULL;
135#endif
136 VBOX_SLIRP_LOCK(pData->mbuf_alloced_mutex);
137 mbuf_alloced--;
138 VBOX_SLIRP_UNLOCK(pData->mbuf_alloced_mutex);
139 } else if ((m->m_flags & M_FREELIST) == 0) {
140 VBOX_SLIRP_LOCK(pData->m_freelist_mutex);
141 insque(pData, m,&m_freelist);
142 m->m_flags = M_FREELIST; /* Clobber other flags */
143 VBOX_SLIRP_UNLOCK(pData->m_freelist_mutex);
144 }
145 } /* if(m) */
146}
147
148/*
149 * Copy data from one mbuf to the end of
150 * the other.. if result is too big for one mbuf, malloc()
151 * an M_EXT data segment
152 */
153void
154m_cat(PNATState pData, register struct mbuf *m, register struct mbuf *n)
155{
156 /*
157 * If there's no room, realloc
158 */
159
160 if (M_FREEROOM(m) < n->m_len)
161 m_inc(m,m->m_size+MINCSIZE);
162
163 memcpy(m->m_data+m->m_len, n->m_data, n->m_len);
164 m->m_len += n->m_len;
165
166 m_free(pData, n);
167
168}
169
170
171/* make m size bytes large */
172void
173m_inc(m, size)
174 struct mbuf *m;
175 int size;
176{
177 int datasize;
178
179 /* some compiles throw up on gotos. This one we can fake. */
180 if(m->m_size>size) {
181 return;
182 }
183
184 if (m->m_flags & M_EXT) {
185 datasize = m->m_data - m->m_ext;
186 m->m_ext = (char *)realloc(m->m_ext,size);
187/* if (m->m_ext == NULL)
188 * return (struct mbuf *)NULL;
189 */
190 m->m_data = m->m_ext + datasize;
191 } else {
192 char *dat;
193 datasize = m->m_data - m->m_dat;
194 dat = (char *)malloc(size);
195/* if (dat == NULL)
196 * return (struct mbuf *)NULL;
197 */
198 memcpy(dat, m->m_dat, m->m_size);
199
200 m->m_ext = dat;
201 m->m_data = m->m_ext + datasize;
202 m->m_flags |= M_EXT;
203 }
204
205 m->m_size = size;
206}
207
208
209
210void
211m_adj(m, len)
212 struct mbuf *m;
213 int len;
214{
215 if (m == NULL)
216 return;
217 if (len >= 0) {
218 /* Trim from head */
219 m->m_data += len;
220 m->m_len -= len;
221 } else {
222 /* Trim from tail */
223 len = -len;
224 m->m_len -= len;
225 }
226}
227
228
229/*
230 * Copy len bytes from m, starting off bytes into n
231 */
232int
233m_copy(n, m, off, len)
234 struct mbuf *n, *m;
235 int off, len;
236{
237 if (len > M_FREEROOM(n)) {
238 return -1;
239 }
240
241 memcpy((n->m_data + n->m_len), (m->m_data + off), len);
242 n->m_len += len;
243 return 0;
244}
245
246
247/*
248 * Given a pointer into an mbuf, return the mbuf
249 * XXX This is a kludge, I should eliminate the need for it
250 * Fortunately, it's not used often
251 */
252struct mbuf *
253dtom(PNATState pData, void *dat)
254{
255 struct mbuf *m;
256
257 DEBUG_CALL("dtom");
258 DEBUG_ARG("dat = %lx", (long )dat);
259
260 /* bug corrected for M_EXT buffers */
261#ifndef VBOX_WITH_SYNC_SLIRP
262 for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next) {
263#else
264 struct mbuf *mnext;
265 VBOX_SLIRP_LOCK(pData->m_usedlist_mutex);
266 m = m_usedlist.m_next;
267 while(1) {
268 mnext = m->m_next;
269#endif
270 if (m->m_flags & M_EXT) {
271 if( (char *)dat>=m->m_ext && (char *)dat<(m->m_ext + m->m_size) ) {
272 return m;
273 }
274 } else {
275 if( (char *)dat >= m->m_dat && (char *)dat<(m->m_dat + m->m_size) ) {
276 return m;
277 }
278 }
279#ifdef VBOX_WITH_SYNC_SLIRP
280 m = mnext;
281#endif
282 }
283
284 DEBUG_ERROR((dfd, "dtom failed"));
285
286 return (struct mbuf *)0;
287}
288
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette