1 /*	$OpenBSD: uipc_mbuf.c,v 1.70 2004/05/27 04:55:28 tedu Exp $	*/
2 /*	$NetBSD: uipc_mbuf.c,v 1.15.4.1 1996/06/13 17:11:44 cgd Exp $	*/
3 
4 /*
5  * Copyright (c) 1982, 1986, 1988, 1991, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  *	@(#)uipc_mbuf.c	8.2 (Berkeley) 1/4/94
33  */
34 
35 /*
36  *	@(#)COPYRIGHT	1.1 (NRL) 17 January 1995
37  *
38  * NRL grants permission for redistribution and use in source and binary
39  * forms, with or without modification, of the software and documentation
40  * created at NRL provided that the following conditions are met:
41  *
42  * 1. Redistributions of source code must retain the above copyright
43  *    notice, this list of conditions and the following disclaimer.
44  * 2. Redistributions in binary form must reproduce the above copyright
45  *    notice, this list of conditions and the following disclaimer in the
46  *    documentation and/or other materials provided with the distribution.
47  * 3. All advertising materials mentioning features or use of this software
48  *    must display the following acknowledgements:
49  * 	This product includes software developed by the University of
50  * 	California, Berkeley and its contributors.
51  * 	This product includes software developed at the Information
52  * 	Technology Division, US Naval Research Laboratory.
53  * 4. Neither the name of the NRL nor the names of its contributors
54  *    may be used to endorse or promote products derived from this software
55  *    without specific prior written permission.
56  *
57  * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS
58  * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
59  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
60  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL NRL OR
61  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
62  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
63  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
64  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
65  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
66  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
67  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
68  *
69  * The views and conclusions contained in the software and documentation
70  * are those of the authors and should not be interpreted as representing
71  * official policies, either expressed or implied, of the US Naval
72  * Research Laboratory (NRL).
73  */
74 
75 #include <sys/param.h>
76 #include <sys/systm.h>
77 #include <sys/proc.h>
78 #include <sys/malloc.h>
79 #define MBTYPES
80 #include <sys/mbuf.h>
81 #include <sys/kernel.h>
82 #include <sys/syslog.h>
83 #include <sys/domain.h>
84 #include <sys/protosw.h>
85 #include <sys/pool.h>
86 
87 #include <machine/cpu.h>
88 
89 #include <uvm/uvm_extern.h>
90 
91 struct	mbstat mbstat;		/* mbuf stats */
92 struct	pool mbpool;		/* mbuf pool */
93 struct	pool mclpool;		/* mbuf cluster pool */
94 
95 struct vm_map *mb_map;
96 
97 int max_linkhdr;		/* largest link-level header */
98 int max_protohdr;		/* largest protocol header */
99 int max_hdr;			/* largest link+protocol header */
100 int max_datalen;		/* MHLEN - max_hdr */
101 
102 struct mbuf *m_copym0(struct mbuf *, int, int, int, int);
103 void	nmbclust_update(void);
104 
105 
106 const char *mclpool_warnmsg =
107     "WARNING: mclpool limit reached; increase kern.maxclusters";
108 
109 /*
110  * Initialize the mbuf allcator.
111  */
112 void
mbinit()113 mbinit()
114 {
115 	pool_init(&mbpool, MSIZE, 0, 0, 0, "mbpl", NULL);
116 	pool_init(&mclpool, MCLBYTES, 0, 0, 0, "mclpl", NULL);
117 
118 	pool_set_drain_hook(&mbpool, m_reclaim, NULL);
119 	pool_set_drain_hook(&mclpool, m_reclaim, NULL);
120 
121 	nmbclust_update();
122 
123 	/*
124 	 * Set a low water mark for both mbufs and clusters.  This should
125 	 * help ensure that they can be allocated in a memory starvation
126 	 * situation.  This is important for e.g. diskless systems which
127 	 * must allocate mbufs in order for the pagedaemon to clean pages.
128 	 */
129 	pool_setlowat(&mbpool, mblowat);
130 	pool_setlowat(&mclpool, mcllowat);
131 }
132 
133 void
nmbclust_update(void)134 nmbclust_update(void)
135 {
136 	/*
137 	 * Set the hard limit on the mclpool to the number of
138 	 * mbuf clusters the kernel is to support.  Log the limit
139 	 * reached message max once a minute.
140 	 */
141 	(void)pool_sethardlimit(&mclpool, nmbclust, mclpool_warnmsg, 60);
142 }
143 
144 void
m_reclaim(void * arg,int flags)145 m_reclaim(void *arg, int flags)
146 {
147 	register struct domain *dp;
148 	register struct protosw *pr;
149 	int s = splimp();
150 
151 	for (dp = domains; dp; dp = dp->dom_next)
152 		for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
153 			if (pr->pr_drain)
154 				(*pr->pr_drain)();
155 	splx(s);
156 	mbstat.m_drain++;
157 }
158 
159 /*
160  * Space allocation routines.
161  * These are also available as macros
162  * for critical paths.
163  */
164 struct mbuf *
m_get(nowait,type)165 m_get(nowait, type)
166 	int nowait, type;
167 {
168 	register struct mbuf *m;
169 
170 	MGET(m, nowait, type);
171 	return (m);
172 }
173 
174 struct mbuf *
m_gethdr(nowait,type)175 m_gethdr(nowait, type)
176 	int nowait, type;
177 {
178 	register struct mbuf *m;
179 
180 	MGETHDR(m, nowait, type);
181 	return (m);
182 }
183 
184 struct mbuf *
m_getclr(nowait,type)185 m_getclr(nowait, type)
186 	int nowait, type;
187 {
188 	register struct mbuf *m;
189 
190 	MGET(m, nowait, type);
191 	if (m == NULL)
192 		return (NULL);
193 	memset(mtod(m, caddr_t), 0, MLEN);
194 	return (m);
195 }
196 
197 struct mbuf *
m_free(m)198 m_free(m)
199 	struct mbuf *m;
200 {
201 	register struct mbuf *n;
202 
203 	MFREE(m, n);
204 	return (n);
205 }
206 
207 void
m_freem(m)208 m_freem(m)
209 	register struct mbuf *m;
210 {
211 	register struct mbuf *n;
212 
213 	if (m == NULL)
214 		return;
215 	do {
216 		MFREE(m, n);
217 	} while ((m = n) != NULL);
218 }
219 
220 /*
221  * Mbuffer utility routines.
222  */
223 
224 /*
225  * Lesser-used path for M_PREPEND:
226  * allocate new mbuf to prepend to chain,
227  * copy junk along.
228  */
229 struct mbuf *
m_prepend(m,len,how)230 m_prepend(m, len, how)
231 	register struct mbuf *m;
232 	int len, how;
233 {
234 	struct mbuf *mn;
235 
236 	MGET(mn, how, m->m_type);
237 	if (mn == NULL) {
238 		m_freem(m);
239 		return (NULL);
240 	}
241 	if (m->m_flags & M_PKTHDR)
242 		M_MOVE_PKTHDR(mn, m);
243 	mn->m_next = m;
244 	m = mn;
245 	if (len < MHLEN)
246 		MH_ALIGN(m, len);
247 	m->m_len = len;
248 	return (m);
249 }
250 
251 /*
252  * Make a copy of an mbuf chain starting "off0" bytes from the beginning,
253  * continuing for "len" bytes.  If len is M_COPYALL, copy to end of mbuf.
254  * The wait parameter is a choice of M_WAIT/M_DONTWAIT from caller.
255  */
256 int MCFail;
257 
258 struct mbuf *
m_copym(m,off0,len,wait)259 m_copym(m, off0, len, wait)
260 	struct mbuf *m;
261 	int off0, wait;
262 	int len;
263 {
264 	return m_copym0(m, off0, len, wait, 0);	/* shallow copy on M_EXT */
265 }
266 
267 /*
268  * m_copym2() is like m_copym(), except it COPIES cluster mbufs, instead
269  * of merely bumping the reference count.
270  */
271 struct mbuf *
m_copym2(m,off0,len,wait)272 m_copym2(m, off0, len, wait)
273 	struct mbuf *m;
274 	int off0, wait;
275 	int len;
276 {
277 	return m_copym0(m, off0, len, wait, 1);	/* deep copy */
278 }
279 
280 struct mbuf *
m_copym0(m,off0,len,wait,deep)281 m_copym0(m, off0, len, wait, deep)
282 	struct mbuf *m;
283 	int off0, wait;
284 	int len;
285 	int deep;	/* deep copy */
286 {
287 	struct mbuf *n, **np;
288 	int off = off0;
289 	struct mbuf *top;
290 	int copyhdr = 0;
291 
292 	if (off < 0 || len < 0)
293 		panic("m_copym0: off %d, len %d", off, len);
294 	if (off == 0 && m->m_flags & M_PKTHDR)
295 		copyhdr = 1;
296 	while (off > 0) {
297 		if (m == NULL)
298 			panic("m_copym0: null mbuf");
299 		if (off < m->m_len)
300 			break;
301 		off -= m->m_len;
302 		m = m->m_next;
303 	}
304 	np = &top;
305 	top = NULL;
306 	while (len > 0) {
307 		if (m == NULL) {
308 			if (len != M_COPYALL)
309 				panic("m_copym0: m == NULL and not COPYALL");
310 			break;
311 		}
312 		MGET(n, wait, m->m_type);
313 		*np = n;
314 		if (n == NULL)
315 			goto nospace;
316 		if (copyhdr) {
317 			M_DUP_PKTHDR(n, m);
318 			if (len == M_COPYALL)
319 				n->m_pkthdr.len -= off0;
320 			else
321 				n->m_pkthdr.len = len;
322 			copyhdr = 0;
323 		}
324 		n->m_len = min(len, m->m_len - off);
325 		if (m->m_flags & M_EXT) {
326 			if (!deep) {
327 				n->m_data = m->m_data + off;
328 				n->m_ext = m->m_ext;
329 				MCLADDREFERENCE(m, n);
330 			} else {
331 				/*
332 				 * we are unsure about the way m was allocated.
333 				 * copy into multiple MCLBYTES cluster mbufs.
334 				 */
335 				MCLGET(n, wait);
336 				n->m_len = 0;
337 				n->m_len = M_TRAILINGSPACE(n);
338 				n->m_len = min(n->m_len, len);
339 				n->m_len = min(n->m_len, m->m_len - off);
340 				memcpy(mtod(n, caddr_t), mtod(m, caddr_t) + off,
341 				    (unsigned)n->m_len);
342 			}
343 		} else
344 			memcpy(mtod(n, caddr_t), mtod(m, caddr_t)+off,
345 			    (unsigned)n->m_len);
346 		if (len != M_COPYALL)
347 			len -= n->m_len;
348 		off += n->m_len;
349 #ifdef DIAGNOSTIC
350 		if (off > m->m_len)
351 			panic("m_copym0 overrun");
352 #endif
353 		if (off == m->m_len) {
354 			m = m->m_next;
355 			off = 0;
356 		}
357 		np = &n->m_next;
358 	}
359 	if (top == NULL)
360 		MCFail++;
361 	return (top);
362 nospace:
363 	m_freem(top);
364 	MCFail++;
365 	return (NULL);
366 }
367 
368 /*
369  * Copy data from an mbuf chain starting "off" bytes from the beginning,
370  * continuing for "len" bytes, into the indicated buffer.
371  */
372 void
m_copydata(m,off,len,cp)373 m_copydata(m, off, len, cp)
374 	register struct mbuf *m;
375 	register int off;
376 	register int len;
377 	caddr_t cp;
378 {
379 	register unsigned count;
380 
381 	if (off < 0)
382 		panic("m_copydata: off %d < 0", off);
383 	if (len < 0)
384 		panic("m_copydata: len %d < 0", len);
385 	while (off > 0) {
386 		if (m == NULL)
387 			panic("m_copydata: null mbuf in skip");
388 		if (off < m->m_len)
389 			break;
390 		off -= m->m_len;
391 		m = m->m_next;
392 	}
393 	while (len > 0) {
394 		if (m == NULL)
395 			panic("m_copydata: null mbuf");
396 		count = min(m->m_len - off, len);
397 		bcopy(mtod(m, caddr_t) + off, cp, count);
398 		len -= count;
399 		cp += count;
400 		off = 0;
401 		m = m->m_next;
402 	}
403 }
404 
405 /*
406  * Copy data from a buffer back into the indicated mbuf chain,
407  * starting "off" bytes from the beginning, extending the mbuf
408  * chain if necessary. The mbuf needs to be properly initialized
409  * including the setting of m_len.
410  */
411 void
m_copyback(m0,off,len,cp)412 m_copyback(m0, off, len, cp)
413 	struct	mbuf *m0;
414 	register int off;
415 	register int len;
416 	const void *cp;
417 {
418 	register int mlen;
419 	register struct mbuf *m = m0, *n;
420 	int totlen = 0;
421 
422 	if (m0 == NULL)
423 		return;
424 	while (off > (mlen = m->m_len)) {
425 		off -= mlen;
426 		totlen += mlen;
427 		if (m->m_next == NULL) {
428 			n = m_getclr(M_DONTWAIT, m->m_type);
429 			if (n == NULL)
430 				goto out;
431 			n->m_len = min(MLEN, len + off);
432 			m->m_next = n;
433 		}
434 		m = m->m_next;
435 	}
436 	while (len > 0) {
437 		mlen = min (m->m_len - off, len);
438 		bcopy(cp, off + mtod(m, caddr_t), (unsigned)mlen);
439 		cp += mlen;
440 		len -= mlen;
441 		mlen += off;
442 		off = 0;
443 		totlen += mlen;
444 		if (len == 0)
445 			break;
446 		if (m->m_next == NULL) {
447 			n = m_get(M_DONTWAIT, m->m_type);
448 			if (n == NULL)
449 				break;
450 			n->m_len = min(MLEN, len);
451 			m->m_next = n;
452 		}
453 		m = m->m_next;
454 	}
455 out:	if (((m = m0)->m_flags & M_PKTHDR) && (m->m_pkthdr.len < totlen))
456 		m->m_pkthdr.len = totlen;
457 }
458 
459 /*
460  * Concatenate mbuf chain n to m.
461  * Both chains must be of the same type (e.g. MT_DATA).
462  * Any m_pkthdr is not updated.
463  */
464 void
m_cat(m,n)465 m_cat(m, n)
466 	register struct mbuf *m, *n;
467 {
468 	while (m->m_next)
469 		m = m->m_next;
470 	while (n) {
471 		if (m->m_flags & M_EXT ||
472 		    m->m_data + m->m_len + n->m_len >= &m->m_dat[MLEN]) {
473 			/* just join the two chains */
474 			m->m_next = n;
475 			return;
476 		}
477 		/* splat the data from one into the other */
478 		bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
479 		    (u_int)n->m_len);
480 		m->m_len += n->m_len;
481 		n = m_free(n);
482 	}
483 }
484 
485 void
m_adj(mp,req_len)486 m_adj(mp, req_len)
487 	struct mbuf *mp;
488 	int req_len;
489 {
490 	register int len = req_len;
491 	register struct mbuf *m;
492 	register int count;
493 
494 	if ((m = mp) == NULL)
495 		return;
496 	if (len >= 0) {
497 		/*
498 		 * Trim from head.
499 		 */
500 		while (m != NULL && len > 0) {
501 			if (m->m_len <= len) {
502 				len -= m->m_len;
503 				m->m_len = 0;
504 				m = m->m_next;
505 			} else {
506 				m->m_len -= len;
507 				m->m_data += len;
508 				len = 0;
509 			}
510 		}
511 		m = mp;
512 		if (mp->m_flags & M_PKTHDR)
513 			m->m_pkthdr.len -= (req_len - len);
514 	} else {
515 		/*
516 		 * Trim from tail.  Scan the mbuf chain,
517 		 * calculating its length and finding the last mbuf.
518 		 * If the adjustment only affects this mbuf, then just
519 		 * adjust and return.  Otherwise, rescan and truncate
520 		 * after the remaining size.
521 		 */
522 		len = -len;
523 		count = 0;
524 		for (;;) {
525 			count += m->m_len;
526 			if (m->m_next == NULL)
527 				break;
528 			m = m->m_next;
529 		}
530 		if (m->m_len >= len) {
531 			m->m_len -= len;
532 			if (mp->m_flags & M_PKTHDR)
533 				mp->m_pkthdr.len -= len;
534 			return;
535 		}
536 		count -= len;
537 		if (count < 0)
538 			count = 0;
539 		/*
540 		 * Correct length for chain is "count".
541 		 * Find the mbuf with last data, adjust its length,
542 		 * and toss data from remaining mbufs on chain.
543 		 */
544 		m = mp;
545 		if (m->m_flags & M_PKTHDR)
546 			m->m_pkthdr.len = count;
547 		for (; m; m = m->m_next) {
548 			if (m->m_len >= count) {
549 				m->m_len = count;
550 				break;
551 			}
552 			count -= m->m_len;
553 		}
554 		while ((m = m->m_next) != NULL)
555 			m->m_len = 0;
556 	}
557 }
558 
559 /*
560  * Rearange an mbuf chain so that len bytes are contiguous
561  * and in the data area of an mbuf (so that mtod and dtom
562  * will work for a structure of size len).  Returns the resulting
563  * mbuf chain on success, frees it and returns null on failure.
564  * If there is room, it will add up to max_protohdr-len extra bytes to the
565  * contiguous region in an attempt to avoid being called next time.
566  */
567 int MPFail;
568 
569 struct mbuf *
m_pullup(n,len)570 m_pullup(n, len)
571 	register struct mbuf *n;
572 	int len;
573 {
574 	register struct mbuf *m;
575 	register int count;
576 	int space;
577 
578 	/*
579 	 * If first mbuf has no cluster, and has room for len bytes
580 	 * without shifting current data, pullup into it,
581 	 * otherwise allocate a new mbuf to prepend to the chain.
582 	 */
583 	if ((n->m_flags & M_EXT) == 0 &&
584 	    n->m_data + len < &n->m_dat[MLEN] && n->m_next) {
585 		if (n->m_len >= len)
586 			return (n);
587 		m = n;
588 		n = n->m_next;
589 		len -= m->m_len;
590 	} else {
591 		if (len > MHLEN)
592 			goto bad;
593 		MGET(m, M_DONTWAIT, n->m_type);
594 		if (m == NULL)
595 			goto bad;
596 		m->m_len = 0;
597 		if (n->m_flags & M_PKTHDR)
598 			M_MOVE_PKTHDR(m, n);
599 	}
600 	space = &m->m_dat[MLEN] - (m->m_data + m->m_len);
601 	do {
602 		count = min(min(max(len, max_protohdr), space), n->m_len);
603 		bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
604 		    (unsigned)count);
605 		len -= count;
606 		m->m_len += count;
607 		n->m_len -= count;
608 		space -= count;
609 		if (n->m_len)
610 			n->m_data += count;
611 		else
612 			n = m_free(n);
613 	} while (len > 0 && n);
614 	if (len > 0) {
615 		(void)m_free(m);
616 		goto bad;
617 	}
618 	m->m_next = n;
619 	return (m);
620 bad:
621 	m_freem(n);
622 	MPFail++;
623 	return (NULL);
624 }
625 
626 /*
627  * m_pullup2() works like m_pullup, save that len can be <= MCLBYTES.
628  * m_pullup2() only works on values of len such that MHLEN < len <= MCLBYTES,
629  * it calls m_pullup() for values <= MHLEN.  It also only coagulates the
630  * reqested number of bytes.  (For those of us who expect unwieldly option
631  * headers.
632  *
633  * KEBE SAYS:  Remember that dtom() calls with data in clusters does not work!
634  */
635 struct mbuf *
m_pullup2(n,len)636 m_pullup2(n, len)
637 	register struct mbuf *n;
638 	int len;
639 {
640 	register struct mbuf *m;
641 	register int count;
642 	int space;
643 
644 	if (len <= MHLEN)
645 		return m_pullup(n, len);
646 	if ((n->m_flags & M_EXT) != 0 &&
647 	    n->m_data + len < &n->m_data[MCLBYTES] && n->m_next) {
648 		if (n->m_len >= len)
649 			return (n);
650 		m = n;
651 		n = n->m_next;
652 		len -= m->m_len;
653 	} else {
654 		if (len > MCLBYTES)
655 			goto bad;
656 		MGET(m, M_DONTWAIT, n->m_type);
657 		if (m == NULL)
658 			goto bad;
659 		MCLGET(m, M_DONTWAIT);
660 		if ((m->m_flags & M_EXT) == 0)
661 			goto bad;
662 		m->m_len = 0;
663 		if (n->m_flags & M_PKTHDR) {
664 			/* Too many adverse side effects. */
665 			/* M_MOVE_PKTHDR(m, n); */
666 			m->m_flags = (n->m_flags & M_COPYFLAGS) |
667 			    M_EXT | M_CLUSTER;
668 			M_MOVE_HDR(m, n);
669 			/* n->m_data is cool. */
670 		}
671 	}
672 
673 	do {
674 		count = min(len, n->m_len);
675 		bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
676 		    (unsigned)count);
677 		len -= count;
678 		m->m_len += count;
679 		n->m_len -= count;
680 		space -= count;
681 		if (n->m_len)
682 			n->m_data += count;
683 		else
684 			n = m_free(n);
685 	} while (len > 0 && n);
686 	if (len > 0) {
687 		(void)m_free(m);
688 		goto bad;
689 	}
690 	m->m_next = n;
691 
692 	return (m);
693 bad:
694 	m_freem(n);
695 	MPFail++;
696 	return (NULL);
697 }
698 
699 /*
700  * Return a pointer to mbuf/offset of location in mbuf chain.
701  */
702 struct mbuf *
m_getptr(m,loc,off)703 m_getptr(m, loc, off)
704 	struct mbuf *m;
705 	int loc;
706 	int *off;
707 {
708 	while (loc >= 0) {
709 		/* Normal end of search */
710 		if (m->m_len > loc) {
711 	    		*off = loc;
712 	    		return (m);
713 		}
714 		else {
715 	    		loc -= m->m_len;
716 
717 	    		if (m->m_next == NULL) {
718 				if (loc == 0) {
719  					/* Point at the end of valid data */
720 		    			*off = m->m_len;
721 		    			return (m);
722 				}
723 				else
724 		  			return (NULL);
725 	    		} else
726 	      			m = m->m_next;
727 		}
728     	}
729 
730 	return (NULL);
731 }
732 
733 /*
734  * Inject a new mbuf chain of length siz in mbuf chain m0 at
735  * position len0. Returns a pointer to the first injected mbuf, or
736  * NULL on failure (m0 is left undisturbed). Note that if there is
737  * enough space for an object of size siz in the appropriate position,
738  * no memory will be allocated. Also, there will be no data movement in
739  * the first len0 bytes (pointers to that will remain valid).
740  *
741  * XXX It is assumed that siz is less than the size of an mbuf at the moment.
742  */
743 struct mbuf *
m_inject(m0,len0,siz,wait)744 m_inject(m0, len0, siz, wait)
745 	register struct mbuf *m0;
746 	int len0, siz, wait;
747 {
748 	register struct mbuf *m, *n, *n2 = NULL, *n3;
749 	unsigned len = len0, remain;
750 
751 	if ((siz >= MHLEN) || (len0 <= 0))
752 	        return (NULL);
753 	for (m = m0; m && len > m->m_len; m = m->m_next)
754 		len -= m->m_len;
755 	if (m == NULL)
756 		return (NULL);
757 	remain = m->m_len - len;
758 	if (remain == 0) {
759 	        if ((m->m_next) && (M_LEADINGSPACE(m->m_next) >= siz)) {
760 		        m->m_next->m_len += siz;
761 			if (m0->m_flags & M_PKTHDR)
762 				m0->m_pkthdr.len += siz;
763 			m->m_next->m_data -= siz;
764 			return m->m_next;
765 		}
766 	} else {
767 	        n2 = m_copym2(m, len, remain, wait);
768 		if (n2 == NULL)
769 		        return (NULL);
770 	}
771 
772 	MGET(n, wait, MT_DATA);
773 	if (n == NULL) {
774 	        if (n2)
775 		        m_freem(n2);
776 		return (NULL);
777 	}
778 
779 	n->m_len = siz;
780 	if (m0->m_flags & M_PKTHDR)
781 		m0->m_pkthdr.len += siz;
782 	m->m_len -= remain; /* Trim */
783 	if (n2)	{
784 	        for (n3 = n; n3->m_next != NULL; n3 = n3->m_next)
785 		        ;
786 		n3->m_next = n2;
787 	} else
788 	        n3 = n;
789 	for (; n3->m_next != NULL; n3 = n3->m_next)
790 	        ;
791 	n3->m_next = m->m_next;
792 	m->m_next = n;
793 	return n;
794 }
795 
796 /*
797  * Partition an mbuf chain in two pieces, returning the tail --
798  * all but the first len0 bytes.  In case of failure, it returns NULL and
799  * attempts to restore the chain to its original state.
800  */
801 struct mbuf *
m_split(m0,len0,wait)802 m_split(m0, len0, wait)
803 	register struct mbuf *m0;
804 	int len0, wait;
805 {
806 	register struct mbuf *m, *n;
807 	unsigned len = len0, remain, olen;
808 
809 	for (m = m0; m && len > m->m_len; m = m->m_next)
810 		len -= m->m_len;
811 	if (m == NULL)
812 		return (NULL);
813 	remain = m->m_len - len;
814 	if (m0->m_flags & M_PKTHDR) {
815 		MGETHDR(n, wait, m0->m_type);
816 		if (n == NULL)
817 			return (NULL);
818 		M_DUP_PKTHDR(n, m0);
819 		n->m_pkthdr.len -= len0;
820 		olen = m0->m_pkthdr.len;
821 		m0->m_pkthdr.len = len0;
822 		if (m->m_flags & M_EXT)
823 			goto extpacket;
824 		if (remain > MHLEN) {
825 			/* m can't be the lead packet */
826 			MH_ALIGN(n, 0);
827 			n->m_next = m_split(m, len, wait);
828 			if (n->m_next == NULL) {
829 				(void) m_free(n);
830 				m0->m_pkthdr.len = olen;
831 				return (NULL);
832 			} else
833 				return (n);
834 		} else
835 			MH_ALIGN(n, remain);
836 	} else if (remain == 0) {
837 		n = m->m_next;
838 		m->m_next = NULL;
839 		return (n);
840 	} else {
841 		MGET(n, wait, m->m_type);
842 		if (n == NULL)
843 			return (NULL);
844 		M_ALIGN(n, remain);
845 	}
846 extpacket:
847 	if (m->m_flags & M_EXT) {
848 		n->m_ext = m->m_ext;
849 		MCLADDREFERENCE(m, n);
850 		n->m_data = m->m_data + len;
851 	} else {
852 		bcopy(mtod(m, caddr_t) + len, mtod(n, caddr_t), remain);
853 	}
854 	n->m_len = remain;
855 	m->m_len = len;
856 	n->m_next = m->m_next;
857 	m->m_next = NULL;
858 	return (n);
859 }
860 
861 /*
862  * Routine to copy from device local memory into mbufs.
863  */
864 struct mbuf *
m_devget(buf,totlen,off0,ifp,copy)865 m_devget(buf, totlen, off0, ifp, copy)
866 	char *buf;
867 	int totlen, off0;
868 	struct ifnet *ifp;
869 	void (*copy)(const void *, void *, size_t);
870 {
871 	register struct mbuf *m;
872 	struct mbuf *top = NULL, **mp = &top;
873 	register int off = off0, len;
874 	register char *cp;
875 	char *epkt;
876 
877 	cp = buf;
878 	epkt = cp + totlen;
879 	if (off) {
880 		/*
881 		 * If 'off' is non-zero, packet is trailer-encapsulated,
882 		 * so we have to skip the type and length fields.
883 		 */
884 		cp += off + 2 * sizeof(u_int16_t);
885 		totlen -= 2 * sizeof(u_int16_t);
886 	}
887 	MGETHDR(m, M_DONTWAIT, MT_DATA);
888 	if (m == NULL)
889 		return (NULL);
890 	m->m_pkthdr.rcvif = ifp;
891 	m->m_pkthdr.len = totlen;
892 	m->m_len = MHLEN;
893 
894 	while (totlen > 0) {
895 		if (top != NULL) {
896 			MGET(m, M_DONTWAIT, MT_DATA);
897 			if (m == NULL) {
898 				m_freem(top);
899 				return (NULL);
900 			}
901 			m->m_len = MLEN;
902 		}
903 		len = min(totlen, epkt - cp);
904 		if (len >= MINCLSIZE) {
905 			MCLGET(m, M_DONTWAIT);
906 			if (m->m_flags & M_EXT)
907 				m->m_len = len = min(len, MCLBYTES);
908 			else
909 				len = m->m_len;
910 		} else {
911 			/*
912 			 * Place initial small packet/header at end of mbuf.
913 			 */
914 			if (len < m->m_len) {
915 				if (top == NULL &&
916 				    len + max_linkhdr <= m->m_len)
917 					m->m_data += max_linkhdr;
918 				m->m_len = len;
919 			} else
920 				len = m->m_len;
921 		}
922 		if (copy)
923 			copy(cp, mtod(m, caddr_t), (size_t)len);
924 		else
925 			bcopy(cp, mtod(m, caddr_t), (size_t)len);
926 		cp += len;
927 		*mp = m;
928 		mp = &m->m_next;
929 		totlen -= len;
930 		if (cp == epkt)
931 			cp = buf;
932 	}
933 	return (top);
934 }
935 
936 void
m_zero(m)937 m_zero(m)
938 	struct mbuf *m;
939 {
940 	while (m) {
941 #ifdef DIAGNOSTIC
942 		if (M_READONLY(m))
943 			panic("m_zero: M_READONLY");
944 #endif /* DIAGNOSTIC */
945 		if (m->m_flags & M_EXT)
946 			memset(m->m_ext.ext_buf, 0, m->m_ext.ext_size);
947 		else {
948 			if (m->m_flags & M_PKTHDR)
949 				memset(m->m_pktdat, 0, MHLEN);
950 			else
951 				memset(m->m_dat, 0, MLEN);
952 		}
953 		m = m->m_next;
954 	}
955 }
956 
957 /*
958  * Apply function f to the data in an mbuf chain starting "off" bytes from the
959  * beginning, continuing for "len" bytes.
960  */
961 int
m_apply(m,off,len,f,fstate)962 m_apply(m, off, len, f, fstate)
963 	struct mbuf *m;
964 	int off;
965 	int len;
966 	/* fstate, data, len */
967 	int (*f)(caddr_t, caddr_t, unsigned int);
968 	caddr_t fstate;
969 {
970 	int rval;
971 	unsigned int count;
972 
973 	if (len < 0)
974 		panic("m_apply: len %d < 0", len);
975 	if (off < 0)
976 		panic("m_apply: off %d < 0", off);
977 	while (off > 0) {
978 		if (m == NULL)
979 			panic("m_apply: null mbuf in skip");
980 		if (off < m->m_len)
981 			break;
982 		off -= m->m_len;
983 		m = m->m_next;
984 	}
985 	while (len > 0) {
986 		if (m == NULL)
987 			panic("m_apply: null mbuf");
988 		count = min(m->m_len - off, len);
989 
990 		rval = f(fstate, mtod(m, caddr_t) + off, count);
991 		if (rval)
992 			return (rval);
993 
994 		len -= count;
995 		off = 0;
996 		m = m->m_next;
997 	}
998 
999 	return (0);
1000 }
1001 
1002 #ifdef SMALL_KERNEL
1003 /*
1004  * The idea of adding code in a small kernel might look absurd, but this is
1005  * instead of macros.
1006  */
1007 struct mbuf *
_sk_mget(int how,int type)1008 _sk_mget(int how, int type)
1009 {
1010 	struct mbuf *m;
1011 	_MGET(m, how, type);
1012 	return m;
1013 }
1014 
1015 struct mbuf *
_sk_mgethdr(int how,int type)1016 _sk_mgethdr(int how, int type)
1017 {
1018 	struct mbuf *m;
1019 	_MGETHDR(m, how, type);
1020 	return m;
1021 }
1022 
1023 void
_sk_mclget(struct mbuf * m,int how)1024 _sk_mclget(struct mbuf *m, int how)
1025 {
1026 	_MCLGET(m, how);
1027 }
1028 #endif /* SMALL_KERNEL */
1029