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} |