63 #include <sys/cdefs.h>
68 #include <sys/param.h>
69 #include <sys/systm.h>
70 #include <sys/kernel.h>
72 #include <sys/malloc.h>
74 #include <sys/mutex.h>
76 #include <security/mac/mac_framework.h>
79 "packet-attached information");
82 static struct mbuf *
m_dup1(
struct mbuf *,
int,
int,
int);
103 panic(
"m == NULL in m_pulldown()");
104 if (len > MCLBYTES) {
109 #ifdef PULLDOWN_DEBUG
113 for (t = m; t; t = t->m_next)
119 while (n != NULL && off > 0) {
126 while (n != NULL && n->m_len == 0)
156 if ((n->m_flags & M_EXT) == 0 ||
157 (n->m_ext.ext_type == EXT_CLUSTER && M_WRITABLE(n)))
164 if ((off == 0 || offp) && len <= n->m_len - off && writable)
173 if (len <= n->m_len - off) {
174 o =
m_dup1(n, off, n->m_len - off, M_DONTWAIT);
180 o->m_next = n->m_next;
192 hlen = n->m_len - off;
200 for (o = n->m_next; o != NULL; o = o->m_next)
202 if (hlen + olen < len) {
211 if ((off == 0 || offp) && M_TRAILINGSPACE(n) >= tlen
213 m_copydata(n->m_next, 0, tlen, mtod(n, caddr_t) + n->m_len);
215 m_adj(n->m_next, tlen);
218 if ((off == 0 || offp) && M_LEADINGSPACE(n->m_next) >= hlen
220 n->m_next->m_data -= hlen;
221 n->m_next->m_len += hlen;
222 bcopy(mtod(n, caddr_t) + off, mtod(n->m_next, caddr_t), hlen);
234 o = m_getcl(M_DONTWAIT, m->m_type, 0);
236 o = m_get(M_DONTWAIT, m->m_type);
243 bcopy(mtod(n, caddr_t) + off, mtod(o, caddr_t), hlen);
246 m_copydata(n->m_next, 0, tlen, mtod(o, caddr_t) + o->m_len);
248 m_adj(n->m_next, tlen);
249 o->m_next = n->m_next;
255 #ifdef PULLDOWN_DEBUG
259 for (t = m; t; t = t->m_next)
260 printf(
"%c%d", t == n ?
'*' :
' ', t->m_len);
261 printf(
" (off=%d)\n", off);
270 m_dup1(
struct mbuf *m,
int off,
int len,
int wait)
277 if (off == 0 && (m->m_flags & M_PKTHDR) != 0)
281 if (len >= MINCLSIZE) {
283 n = m_getcl(wait, m->m_type, M_PKTHDR);
285 n = m_getcl(wait, m->m_type, 0);
288 n = m_gethdr(wait, m->m_type);
290 n = m_get(wait, m->m_type);
309 if (t->m_tag_id == PACKET_TAG_MACLABEL)
310 mac_mbuf_tag_destroy(t);
312 free(t, M_PACKET_TAGS);
321 MBUF_CHECKSLEEP(wait);
324 t =
malloc(len +
sizeof(
struct m_tag), M_PACKET_TAGS, wait);
327 m_tag_setup(t, cookie, type, len);
337 KASSERT(m && t, (
"m_tag_delete: null argument, m %p t %p", m, t));
348 KASSERT(m, (
"m_tag_delete_chain: null mbuf"));
352 p = SLIST_FIRST(&m->m_pkthdr.tags);
355 while ((q = SLIST_NEXT(p, m_tag_link)) != NULL)
372 SLIST_FOREACH_SAFE(p, &m->m_pkthdr.tags, m_tag_link, q)
373 if ((p->m_tag_id & MTAG_PERSISTENT) == 0)
383 KASSERT(m, (
"m_tag_locate: null mbuf"));
385 p = SLIST_FIRST(&m->m_pkthdr.tags);
387 p = SLIST_NEXT(t, m_tag_link);
389 if (p->m_tag_cookie == cookie && p->m_tag_id == type)
391 p = SLIST_NEXT(p, m_tag_link);
402 MBUF_CHECKSLEEP(how);
403 KASSERT(t, (
"m_tag_copy: null tag"));
404 p =
m_tag_alloc(t->m_tag_cookie, t->m_tag_id, t->m_tag_len, how);
413 if (t->m_tag_id == PACKET_TAG_MACLABEL) {
414 if (mac_mbuf_tag_init(p, how) != 0) {
418 mac_mbuf_tag_copy(t, p);
421 bcopy(t + 1, p + 1, t->m_tag_len);
434 struct m_tag *p, *t, *tprev = NULL;
436 MBUF_CHECKSLEEP(how);
438 (
"m_tag_copy_chain: null argument, to %p from %p", to, from));
440 SLIST_FOREACH(p, &from->m_pkthdr.tags, m_tag_link) {
447 SLIST_INSERT_HEAD(&to->m_pkthdr.tags, t, m_tag_link);
449 SLIST_INSERT_AFTER(tprev, t, m_tag_link);
int m_dup_pkthdr(struct mbuf *to, struct mbuf *from, int how)
struct mbuf * m_pulldown(struct mbuf *m, int off, int len, int *offp)
static MALLOC_DEFINE(M_PACKET_TAGS, MBUF_TAG_MEM_NAME,"packet-attached information")
void * malloc(unsigned long size, struct malloc_type *mtp, int flags)
void panic(const char *fmt,...)
struct m_tag * m_tag_locate(struct mbuf *m, uint32_t cookie, int type, struct m_tag *t)
void m_freem(struct mbuf *mb)
void m_tag_delete(struct mbuf *m, struct m_tag *t)
struct m_tag * m_tag_copy(struct m_tag *t, int how)
static struct mbuf * m_dup1(struct mbuf *, int, int, int)
void m_copydata(const struct mbuf *m, int off, int len, caddr_t cp)
int m_tag_copy_chain(struct mbuf *to, struct mbuf *from, int how)
void m_tag_delete_nonpersistent(struct mbuf *m)
void m_adj(struct mbuf *mp, int req_len)
void free(void *addr, struct malloc_type *mtp)
int printf(const char *fmt,...)
void m_tag_free_default(struct m_tag *t)
struct m_tag * m_tag_alloc(uint32_t cookie, int type, int len, int wait)
void m_tag_delete_chain(struct mbuf *m, struct m_tag *t)