m_tag fixups in preparation for heavier use:

o promote several m_tag_* routines to inline
o add an m_tag_setup inline to set the fixed fields in a packet tag
o add an m_tag_free method pointer to each mtag to support, for example,
  allocating tags from zones
o have m_tag_find check if the tag list is not empty before calling
  m_tag_locate to search

Reviewed by:	brooks, silence from others
This commit is contained in:
Sam Leffler 2004-01-02 17:27:39 +00:00
parent a06598ec58
commit 4f9f9cf3a4
2 changed files with 85 additions and 58 deletions

View File

@ -310,6 +310,17 @@ m_dup1(struct mbuf *m, int off, int len, int wait)
return n;
}
/* Free a packet tag. */
static void
_m_tag_free(struct m_tag *t)
{
#ifdef MAC
if (t->m_tag_id == PACKET_TAG_MACLABEL)
mac_destroy_mbuf_tag(t);
#endif
free(t, M_PACKET_TAGS);
}
/* Get a packet tag structure along with specified data following. */
struct m_tag *
m_tag_alloc(u_int32_t cookie, int type, int len, int wait)
@ -321,39 +332,11 @@ m_tag_alloc(u_int32_t cookie, int type, int len, int wait)
t = malloc(len + sizeof(struct m_tag), M_PACKET_TAGS, wait);
if (t == NULL)
return NULL;
t->m_tag_id = type;
t->m_tag_len = len;
t->m_tag_cookie = cookie;
m_tag_setup(t, cookie, type, len);
t->m_tag_free = _m_tag_free;
return t;
}
/* Free a packet tag. */
void
m_tag_free(struct m_tag *t)
{
#ifdef MAC
if (t->m_tag_id == PACKET_TAG_MACLABEL)
mac_destroy_mbuf_tag(t);
#endif
free(t, M_PACKET_TAGS);
}
/* Prepend a packet tag. */
void
m_tag_prepend(struct mbuf *m, struct m_tag *t)
{
KASSERT(m && t, ("m_tag_prepend: null argument, m %p t %p", m, t));
SLIST_INSERT_HEAD(&m->m_pkthdr.tags, t, m_tag_link);
}
/* Unlink a packet tag. */
void
m_tag_unlink(struct mbuf *m, struct m_tag *t)
{
KASSERT(m && t, ("m_tag_unlink: null argument, m %p t %p", m, t));
SLIST_REMOVE(&m->m_pkthdr.tags, t, m_tag, m_tag_link);
}
/* Unlink and free a packet tag. */
void
m_tag_delete(struct mbuf *m, struct m_tag *t)
@ -473,24 +456,3 @@ m_tag_copy_chain(struct mbuf *to, struct mbuf *from, int how)
}
return 1;
}
/* Initialize tags on an mbuf. */
void
m_tag_init(struct mbuf *m)
{
SLIST_INIT(&m->m_pkthdr.tags);
}
/* Get first tag in chain. */
struct m_tag *
m_tag_first(struct mbuf *m)
{
return SLIST_FIRST(&m->m_pkthdr.tags);
}
/* Get next tag in chain. */
struct m_tag *
m_tag_next(struct mbuf *m, struct m_tag *t)
{
return SLIST_NEXT(t, m_tag_link);
}

View File

@ -83,6 +83,7 @@ struct m_tag {
u_int16_t m_tag_id; /* Tag ID */
u_int16_t m_tag_len; /* Length of data */
u_int32_t m_tag_cookie; /* ABI/Module ID */
void (*m_tag_free)(struct m_tag *);
};
/*
@ -569,19 +570,82 @@ struct mbuf *m_split(struct mbuf *, int, int);
/* Packet tag routines. */
struct m_tag *m_tag_alloc(u_int32_t, int, int, int);
void m_tag_free(struct m_tag *);
void m_tag_prepend(struct mbuf *, struct m_tag *);
void m_tag_unlink(struct mbuf *, struct m_tag *);
void m_tag_delete(struct mbuf *, struct m_tag *);
void m_tag_delete_chain(struct mbuf *, struct m_tag *);
struct m_tag *m_tag_locate(struct mbuf *, u_int32_t, int, struct m_tag *);
struct m_tag *m_tag_copy(struct m_tag *, int);
int m_tag_copy_chain(struct mbuf *, struct mbuf *, int);
void m_tag_init(struct mbuf *);
struct m_tag *m_tag_first(struct mbuf *);
struct m_tag *m_tag_next(struct mbuf *, struct m_tag *);
void m_tag_delete_nonpersistent(struct mbuf *);
/*
* Initialize the list of tags associated with an mbuf.
*/
static __inline void
m_tag_init(struct mbuf *m)
{
SLIST_INIT(&m->m_pkthdr.tags);
}
/*
* Setup the contents of a tag. Note that this does not
* fillin the free method; the caller is expected to do that.
*
* XXX probably should be called m_tag_init; but that was
* already taken.
*/
static __inline void
m_tag_setup(struct m_tag *t, u_int32_t cookie, int type, int len)
{
t->m_tag_id = type;
t->m_tag_len = len;
t->m_tag_cookie = cookie;
}
/*
* Reclaim resources associated with a tag.
*/
static __inline void
m_tag_free(struct m_tag *t)
{
(*t->m_tag_free)(t);
}
/*
* Return the first tag associated with an mbuf.
*/
static __inline struct m_tag *
m_tag_first(struct mbuf *m)
{
return SLIST_FIRST(&m->m_pkthdr.tags);
}
/*
* Return the next tag in the list of tags associated with an mbuf.
*/
static __inline struct m_tag *
m_tag_next(struct mbuf *m, struct m_tag *t)
{
return SLIST_NEXT(t, m_tag_link);
}
/*
* Prepend a tag to the list of tags associated with an mbuf.
*/
static __inline void
m_tag_prepend(struct mbuf *m, struct m_tag *t)
{
SLIST_INSERT_HEAD(&m->m_pkthdr.tags, t, m_tag_link);
}
/*
* Unlink a tag from the list of tags associated with an mbuf.
*/
static __inline void
m_tag_unlink(struct mbuf *m, struct m_tag *t)
{
SLIST_REMOVE(&m->m_pkthdr.tags, t, m_tag, m_tag_link);
}
/* These are for OpenBSD compatibility. */
#define MTAG_ABI_COMPAT 0 /* compatibility ABI */
@ -594,7 +658,8 @@ m_tag_get(int type, int length, int wait)
static __inline struct m_tag *
m_tag_find(struct mbuf *m, int type, struct m_tag *start)
{
return m_tag_locate(m, MTAG_ABI_COMPAT, type, start);
return SLIST_EMPTY(&m->m_pkthdr.tags) ?
NULL : m_tag_locate(m, MTAG_ABI_COMPAT, type, start);
}
#endif /* _KERNEL */