Deleted Added
full compact
uipc_mbuf2.c (97177) uipc_mbuf2.c (105194)
1/* $FreeBSD: head/sys/kern/uipc_mbuf2.c 97177 2002-05-23 15:59:48Z ume $ */
1/* $FreeBSD: head/sys/kern/uipc_mbuf2.c 105194 2002-10-16 01:54:46Z sam $ */
2/* $KAME: uipc_mbuf2.c,v 1.31 2001/11/28 11:08:53 itojun Exp $ */
3/* $NetBSD: uipc_mbuf.c,v 1.40 1999/04/01 00:23:25 thorpej Exp $ */
4
5/*
6 * Copyright (C) 1999 WIDE Project.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without

--- 55 unchanged lines hidden (view full) ---

65 *
66 * @(#)uipc_mbuf.c 8.4 (Berkeley) 2/14/95
67 */
68
69/*#define PULLDOWN_DEBUG*/
70
71#include <sys/param.h>
72#include <sys/systm.h>
2/* $KAME: uipc_mbuf2.c,v 1.31 2001/11/28 11:08:53 itojun Exp $ */
3/* $NetBSD: uipc_mbuf.c,v 1.40 1999/04/01 00:23:25 thorpej Exp $ */
4
5/*
6 * Copyright (C) 1999 WIDE Project.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without

--- 55 unchanged lines hidden (view full) ---

65 *
66 * @(#)uipc_mbuf.c 8.4 (Berkeley) 2/14/95
67 */
68
69/*#define PULLDOWN_DEBUG*/
70
71#include <sys/param.h>
72#include <sys/systm.h>
73#include <sys/kernel.h>
73#include <sys/lock.h>
74#include <sys/malloc.h>
75#include <sys/mbuf.h>
76#include <sys/mutex.h>
77
74#include <sys/lock.h>
75#include <sys/malloc.h>
76#include <sys/mbuf.h>
77#include <sys/mutex.h>
78
79MALLOC_DEFINE(M_PACKET_TAGS, "tag", "packet-attached information");
80
78/* can't call it m_dup(), as freebsd[34] uses m_dup() with different arg */
79static struct mbuf *m_dup1(struct mbuf *, int, int, int);
80
81/*
82 * ensure that [off, off + len) is contiguous on the mbuf chain "m".
83 * packet chain before "off" is kept untouched.
84 * if offp == NULL, the target will start at <retval, 0> on resulting chain.
85 * if offp != NULL, the target will start at <retval, *offp> on resulting chain.

--- 210 unchanged lines hidden (view full) ---

296 return NULL;
297
298 if (copyhdr)
299 M_COPY_PKTHDR(n, m);
300 m_copydata(m, off, len, mtod(n, caddr_t));
301 return n;
302}
303
81/* can't call it m_dup(), as freebsd[34] uses m_dup() with different arg */
82static struct mbuf *m_dup1(struct mbuf *, int, int, int);
83
84/*
85 * ensure that [off, off + len) is contiguous on the mbuf chain "m".
86 * packet chain before "off" is kept untouched.
87 * if offp == NULL, the target will start at <retval, 0> on resulting chain.
88 * if offp != NULL, the target will start at <retval, *offp> on resulting chain.

--- 210 unchanged lines hidden (view full) ---

299 return NULL;
300
301 if (copyhdr)
302 M_COPY_PKTHDR(n, m);
303 m_copydata(m, off, len, mtod(n, caddr_t));
304 return n;
305}
306
304/*
305 * pkthdr.aux chain manipulation.
306 * we don't allow clusters at this moment.
307 */
308struct mbuf *
309m_aux_add2(struct mbuf *m, int af, int type, void *p)
307/* Get a packet tag structure along with specified data following. */
308struct m_tag *
309m_tag_alloc(u_int32_t cookie, int type, int len, int wait)
310{
310{
311 struct mbuf *n;
312 struct mauxtag *t;
311 struct m_tag *t;
313
312
314 if ((m->m_flags & M_PKTHDR) == 0)
313 if (len < 0)
315 return NULL;
314 return NULL;
315 t = malloc(len + sizeof(struct m_tag), M_PACKET_TAGS, wait);
316 if (t == NULL)
317 return NULL;
318 t->m_tag_id = type;
319 t->m_tag_len = len;
320 t->m_tag_cookie = cookie;
321 return t;
322}
316
323
317 n = m_aux_find(m, af, type);
318 if (n)
319 return n;
324/* Free a packet tag. */
325void
326m_tag_free(struct m_tag *t)
327{
328 free(t, M_PACKET_TAGS);
329}
320
330
321 MGET(n, M_DONTWAIT, m->m_type);
322 if (n == NULL)
323 return NULL;
331/* Prepend a packet tag. */
332void
333m_tag_prepend(struct mbuf *m, struct m_tag *t)
334{
335 KASSERT(m && t, ("m_tag_prepend: null argument, m %p t %p", m, t));
336 SLIST_INSERT_HEAD(&m->m_pkthdr.tags, t, m_tag_link);
337}
324
338
325 t = mtod(n, struct mauxtag *);
326 bzero(t, sizeof(*t));
327 t->af = af;
328 t->type = type;
329 t->p = p;
330 n->m_data += sizeof(struct mauxtag);
331 n->m_len = 0;
332 n->m_next = m->m_pkthdr.aux;
333 m->m_pkthdr.aux = n;
334 return n;
339/* Unlink a packet tag. */
340void
341m_tag_unlink(struct mbuf *m, struct m_tag *t)
342{
343 KASSERT(m && t, ("m_tag_unlink: null argument, m %p t %p", m, t));
344 SLIST_REMOVE(&m->m_pkthdr.tags, t, m_tag, m_tag_link);
335}
336
345}
346
337struct mbuf *
338m_aux_find2(struct mbuf *m, int af, int type, void *p)
347/* Unlink and free a packet tag. */
348void
349m_tag_delete(struct mbuf *m, struct m_tag *t)
339{
350{
340 struct mbuf *n;
341 struct mauxtag *t;
351 KASSERT(m && t, ("m_tag_delete: null argument, m %p t %p", m, t));
352 m_tag_unlink(m, t);
353 m_tag_free(t);
354}
342
355
343 if ((m->m_flags & M_PKTHDR) == 0)
344 return NULL;
356/* Unlink and free a packet tag chain, starting from given tag. */
357void
358m_tag_delete_chain(struct mbuf *m, struct m_tag *t)
359{
360 struct m_tag *p, *q;
345
361
346 for (n = m->m_pkthdr.aux; n; n = n->m_next) {
347 t = (struct mauxtag *)n->m_dat;
348 if (n->m_data != ((caddr_t)t) + sizeof(struct mauxtag)) {
349 printf("m_aux_find: invalid m_data for mbuf=%p (%p %p)\n", n, t, n->m_data);
350 continue;
351 }
352 if (t->af == af && t->type == type && t->p == p)
353 return n;
362 KASSERT(m, ("m_tag_delete_chain: null mbuf"));
363 if (t != NULL)
364 p = t;
365 else
366 p = SLIST_FIRST(&m->m_pkthdr.tags);
367 if (p == NULL)
368 return;
369 while ((q = SLIST_NEXT(p, m_tag_link)) != NULL)
370 m_tag_delete(m, q);
371 m_tag_delete(m, p);
372}
373
374/* Find a tag, starting from a given position. */
375struct m_tag *
376m_tag_locate(struct mbuf *m, u_int32_t cookie, int type, struct m_tag *t)
377{
378 struct m_tag *p;
379
380 KASSERT(m, ("m_tag_find: null mbuf"));
381 if (t == NULL)
382 p = SLIST_FIRST(&m->m_pkthdr.tags);
383 else
384 p = SLIST_NEXT(t, m_tag_link);
385 while (p != NULL) {
386 if (p->m_tag_cookie == cookie && p->m_tag_id == type)
387 return p;
388 p = SLIST_NEXT(p, m_tag_link);
354 }
355 return NULL;
356}
357
389 }
390 return NULL;
391}
392
358struct mbuf *
359m_aux_find(struct mbuf *m, int af, int type)
393/* Copy a single tag. */
394struct m_tag *
395m_tag_copy(struct m_tag *t)
360{
396{
397 struct m_tag *p;
361
398
362 return m_aux_find2(m, af, type, NULL);
399 KASSERT(t, ("m_tag_copy: null tag"));
400 p = m_tag_alloc(t->m_tag_cookie, t->m_tag_id, t->m_tag_len, M_NOWAIT);
401 if (p == NULL)
402 return (NULL);
403 bcopy(t + 1, p + 1, t->m_tag_len); /* Copy the data */
404 return p;
363}
364
405}
406
365struct mbuf *
366m_aux_add(struct mbuf *m, int af, int type)
407/*
408 * Copy two tag chains. The destination mbuf (to) loses any attached
409 * tags even if the operation fails. This should not be a problem, as
410 * m_tag_copy_chain() is typically called with a newly-allocated
411 * destination mbuf.
412 */
413int
414m_tag_copy_chain(struct mbuf *to, struct mbuf *from)
367{
415{
416 struct m_tag *p, *t, *tprev = NULL;
368
417
369 return m_aux_add2(m, af, type, NULL);
418 KASSERT(to && from,
419 ("m_tag_copy: null argument, to %p from %p", to, from));
420 m_tag_delete_chain(to, NULL);
421 SLIST_FOREACH(p, &from->m_pkthdr.tags, m_tag_link) {
422 t = m_tag_copy(p);
423 if (t == NULL) {
424 m_tag_delete_chain(to, NULL);
425 return 0;
426 }
427 if (tprev == NULL)
428 SLIST_INSERT_HEAD(&to->m_pkthdr.tags, t, m_tag_link);
429 else {
430 SLIST_INSERT_AFTER(tprev, t, m_tag_link);
431 tprev = t;
432 }
433 }
434 return 1;
370}
371
435}
436
437/* Initialize tags on an mbuf. */
372void
438void
373m_aux_delete(struct mbuf *m, struct mbuf *victim)
439m_tag_init(struct mbuf *m)
374{
440{
375 struct mbuf *n, *prev, *next;
376 struct mauxtag *t;
441 SLIST_INIT(&m->m_pkthdr.tags);
442}
377
443
378 if ((m->m_flags & M_PKTHDR) == 0)
379 return;
444/* Get first tag in chain. */
445struct m_tag *
446m_tag_first(struct mbuf *m)
447{
448 return SLIST_FIRST(&m->m_pkthdr.tags);
449}
380
450
381 prev = NULL;
382 n = m->m_pkthdr.aux;
383 while (n) {
384 t = (struct mauxtag *)n->m_dat;
385 next = n->m_next;
386 if (n->m_data != ((caddr_t)t) + sizeof(struct mauxtag)) {
387 printf("m_aux_delete: invalid m_data for mbuf=%p (%p %p)\n", n, t, n->m_data);
388 prev = n;
389 n = next;
390 continue;
391 }
392 if (n == victim) {
393 if (prev)
394 prev->m_next = n->m_next;
395 else
396 m->m_pkthdr.aux = n->m_next;
397 n->m_next = NULL;
398 m_free(n);
399 return;
400 } else
401 prev = n;
402 n = next;
403 }
451/* Get next tag in chain. */
452struct m_tag *
453m_tag_next(struct mbuf *m, struct m_tag *t)
454{
455 return SLIST_NEXT(t, m_tag_link);
404}
456}