VirtualBox

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

最後變更 在這個檔案從26495是 26495,由 vboxsync 提交於 15 年 前

Devices: whitespace cleanup

  • 屬性 svn:eol-style 設為 native
檔案大小: 8.6 KB
 
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#include <slirp.h>
18
19#define MBUF_ZONE_SIZE 100
20static int mbuf_zone_init(PNATState pData)
21{
22 struct mbuf_zone *mzone;
23 int i;
24 struct mbuf *m;
25 uint8_t *zone = RTMemAlloc(msize * MBUF_ZONE_SIZE);
26 if (zone == NULL)
27 {
28 LogRel(("NAT: can't allocate new zone\n"));
29 return -1;
30 }
31 mzone = RTMemAllocZ(sizeof (struct mbuf_zone));
32 if (mzone == NULL)
33 {
34 RTMemFree(zone);
35 LogRel(("NAT: can't allocate zone descriptor\n"));
36 return -1;
37 }
38
39 for (i = 0; i < MBUF_ZONE_SIZE; ++i)
40 {
41 m = (struct mbuf *)((char *)zone + i*msize);
42 memset(m, 0, sizeof(struct mbuf));
43#ifdef M_BUF_DEBUG
44 m->m_hdr.mh_id = pData->mbuf_zone_count * MBUF_ZONE_SIZE + i;
45#endif
46 insque(pData, m, &m_freelist);
47 }
48 mzone->mbuf_zone_base_addr = zone;
49 LIST_INSERT_HEAD(&pData->mbuf_zone_head, mzone, list);
50 pData->mbuf_zone_count++;
51 pData->mbuf_water_line_limit = pData->mbuf_zone_count * MBUF_ZONE_SIZE;
52 return 0;
53}
54
55void m_fini(PNATState pData)
56{
57 struct mbuf_zone *mz;
58 struct mbuf *m;
59 int i;
60 void *zone;
61 while(!LIST_EMPTY(&pData->mbuf_zone_head))
62 {
63 mz = LIST_FIRST(&pData->mbuf_zone_head);
64 zone = mz->mbuf_zone_base_addr;
65 for (i = 0; i < MBUF_ZONE_SIZE; ++i)
66 {
67 m = (struct mbuf *)((char *)zone + i*msize);
68 if ( (m->m_flags & M_EXT)
69 && m->m_ext != NULL)
70 RTMemFree(m->m_ext);
71 }
72 RTMemFree(zone);
73 LIST_REMOVE(mz, list);
74 RTMemFree(mz);
75 }
76}
77
78void
79m_init(PNATState pData)
80{
81 int rc = 0;
82 m_freelist.m_next = m_freelist.m_prev = &m_freelist;
83 m_usedlist.m_next = m_usedlist.m_prev = &m_usedlist;
84 mbuf_alloced = 0;
85 msize_init(pData);
86#if 1
87 rc = RTCritSectInit(&pData->cs_mbuf_zone);
88 AssertRC(rc);
89 rc = mbuf_zone_init(pData);
90 Assert((rc == 0));
91#endif
92}
93
94void
95msize_init(PNATState pData)
96{
97 /*
98 * Find a nice value for msize
99 */
100 msize = (if_mtu>if_mru ? if_mtu : if_mru)
101 + sizeof(struct m_hdr) + sizeof(void *) /*pointer to the backstore*/
102 + if_maxlinkhdr ;
103}
104#ifdef m_get
105# undef m_get
106#endif
107
108#ifdef m_free
109# undef m_free
110#endif
111/*
112 * Get an mbuf from the free list, if there are none
113 * malloc one
114 *
115 * Because fragmentation can occur if we alloc new mbufs and
116 * free old mbufs, we mark all mbufs above mbuf_thresh as M_DOFREE,
117 * which tells m_free to actually free() it
118 */
119struct mbuf *
120m_get(PNATState pData)
121{
122 register struct mbuf *m;
123 int flags = 0;
124 int rc = 0;
125
126 DEBUG_CALL("m_get");
127
128 rc = RTCritSectEnter(&pData->cs_mbuf_zone);
129 AssertRC(rc);
130
131recheck_zone:
132 if (m_freelist.m_next == &m_freelist)
133 {
134#if 1
135 rc = mbuf_zone_init(pData);
136 if (rc == 0)
137 goto recheck_zone;
138 AssertMsgFailed(("No mbufs on free list\n"));
139 return NULL;
140#else
141 m = (struct mbuf *)RTMemAlloc(msize);
142 if (m == NULL)
143 goto end_error;
144 mbuf_alloced++;
145 if (mbuf_alloced > mbuf_thresh)
146 flags = M_DOFREE;
147 if (mbuf_alloced > mbuf_max)
148 mbuf_max = mbuf_alloced;
149#endif
150 }
151 else
152 {
153 m = m_freelist.m_next;
154 remque(pData, m);
155 }
156
157 STAM_COUNTER_INC(&pData->StatMBufAllocation);
158 /* Insert it in the used list */
159 mbuf_alloced++;
160#if 0
161 if (mbuf_alloced >= MBUF_ZONE_SIZE/2)
162 {
163 pData->fmbuf_water_line = 1;
164 }
165#endif
166 insque(pData, m, &m_usedlist);
167 m->m_flags = (flags | M_USEDLIST);
168
169 /* Initialise it */
170 m->m_size = msize - sizeof(struct m_hdr);
171 m->m_data = m->m_dat;
172 m->m_len = 0;
173 m->m_nextpkt = 0;
174 m->m_prevpkt = 0;
175 m->m_la = NULL;
176 memset(m->m_data, 0, if_maxlinkhdr); /*initialization of ether area */
177
178end_error:
179 DEBUG_ARG("m = %lx", (long )m);
180 rc = RTCritSectLeave(&pData->cs_mbuf_zone);
181 AssertRC(rc);
182 return m;
183}
184
185void
186m_free(PNATState pData, struct mbuf *m)
187{
188 int rc;
189 DEBUG_CALL("m_free");
190 DEBUG_ARG("m = %lx", (long )m);
191
192 rc = RTCritSectEnter(&pData->cs_mbuf_zone);
193 AssertRC(rc);
194 mbuf_alloced--;
195 if(m)
196 {
197 /* Remove from m_usedlist */
198 if (m->m_flags & M_USEDLIST)
199 remque(pData, m);
200
201 /* If it's M_EXT, free() it */
202 if (m->m_flags & M_EXT)
203 RTMemFree(m->m_ext);
204
205 /*
206 * Either free() it or put it on the free list
207 */
208 if (m->m_flags & M_DOFREE)
209 {
210#if 1
211 if ((m->m_flags & M_EXT) == 0)
212 memset(m->m_dat, 0, if_mtu);
213 insque(pData, m, &m_freelist);
214 m->m_flags = M_FREELIST; /* Clobber other flags */
215#else
216 RTMemFree(m);
217#endif
218 mbuf_alloced--;
219 }
220 else if ((m->m_flags & M_FREELIST) == 0)
221 {
222 insque(pData, m,&m_freelist);
223 m->m_flags = M_FREELIST; /* Clobber other flags */
224 }
225 STAM_COUNTER_INC(&pData->StatMBufAllocation);
226 } /* if(m) */
227 rc = RTCritSectLeave(&pData->cs_mbuf_zone);
228 AssertRC(rc);
229}
230
231/* update macros for m_get/m_free*/
232#undef m_get
233#undef m_free
234#include "mbuf.h"
235
236/*
237 * Copy data from one mbuf to the end of
238 * the other.. if result is too big for one mbuf, malloc()
239 * an M_EXT data segment
240 */
241void
242m_cat(PNATState pData, register struct mbuf *m, register struct mbuf *n)
243{
244 /*
245 * If there's no room, realloc
246 */
247 if (M_FREEROOM(m) < n->m_len)
248 m_inc(m,m->m_size+MINCSIZE);
249
250 memcpy(m->m_data+m->m_len, n->m_data, n->m_len);
251 m->m_len += n->m_len;
252
253 m_free(pData, n);
254}
255
256
257/* make m size bytes large */
258void
259m_inc(struct mbuf *m, int size)
260{
261 int datasize;
262
263 /* some compiles throw up on gotos. This one we can fake. */
264 if (m->m_size > size)
265 return;
266
267 if (m->m_flags & M_EXT)
268 {
269 datasize = m->m_data - m->m_ext;
270 m->m_ext = (char *)RTMemRealloc(m->m_ext, size);
271#if 0
272 if (m->m_ext == NULL)
273 return (struct mbuf *)NULL;
274#endif
275 m->m_data = m->m_ext + datasize;
276 }
277 else
278 {
279 char *dat;
280 datasize = m->m_data - m->m_dat;
281 dat = (char *)RTMemAlloc(size);
282#if 0
283 if (dat == NULL)
284 return (struct mbuf *)NULL;
285#endif
286 memcpy(dat, m->m_dat, m->m_size);
287
288 m->m_ext = dat;
289 m->m_data = m->m_ext + datasize;
290 m->m_flags |= M_EXT;
291 }
292
293 m->m_size = size;
294}
295
296
297void
298m_adj(struct mbuf *m, int len)
299{
300 if (m == NULL)
301 return;
302 if (len >= 0)
303 {
304 /* Trim from head */
305 m->m_data += len;
306 m->m_len -= len;
307 }
308 else
309 {
310 /* Trim from tail */
311 len = -len;
312 m->m_len -= len;
313 }
314 Assert(m->m_len >= 0);
315}
316
317
318/*
319 * Copy len bytes from m, starting off bytes into n
320 */
321int
322m_copy(struct mbuf *n, struct mbuf *m, int off, int len)
323{
324 if (len > M_FREEROOM(n))
325 return -1;
326
327 memcpy((n->m_data + n->m_len), (m->m_data + off), len);
328 n->m_len += len;
329 return 0;
330}
331
332
333/*
334 * Given a pointer into an mbuf, return the mbuf
335 * XXX This is a kludge, I should eliminate the need for it
336 * Fortunately, it's not used often
337 */
338struct mbuf *
339dtom(PNATState pData, void *dat)
340{
341 struct mbuf *m;
342
343 DEBUG_CALL("dtom");
344 DEBUG_ARG("dat = %lx", (long )dat);
345
346 /* bug corrected for M_EXT buffers */
347 for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next)
348 {
349 if (m->m_flags & M_EXT)
350 {
351 if ( (char *)dat >= m->m_ext
352 && (char *)dat < (m->m_ext + m->m_size))
353 return m;
354 }
355 else
356 {
357 if ( (char *)dat >= m->m_dat
358 && (char *)dat < (m->m_dat + m->m_size))
359 return m;
360 }
361 }
362
363 DEBUG_ERROR((dfd, "dtom failed"));
364
365 return (struct mbuf *)0;
366}
367#ifndef VBOX_WITH_SLIRP_BSD_MBUF
368void *slirp_ext_m_get(PNATState pData)
369{
370 return (void *)m_get(pData);
371}
372
373void slirp_ext_m_free(PNATState pData, void *arg)
374{
375 struct mbuf *m = (struct mbuf *)arg;
376 m_free(pData, m);
377}
378void slirp_ext_m_append(PNATState pData, void *arg, uint8_t *pu8Buf, size_t cbBuf)
379{
380 char *c;
381 struct mbuf *m = (struct mbuf *)arg;
382 if (cbBuf > M_FREEROOM(m))
383 {
384 m_inc(m, cbBuf);
385 }
386 c = mtod(m, char *);
387 memcpy(c, pu8Buf, cbBuf);
388 m->m_len = cbBuf;
389}
390#endif
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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