Check out the new USENIX Web site. next up previous
Next: Using mbuf_tags Up: The OpenBSD mbuf_tags Previous: Design Rationale

Tags API

The mbuf_tag API is shown in Figure 1. The code implementing the API is contained in the file sys/kern/uipc_mbuf2.c of the OpenBSD distribution.

m_tag_get() allocates a new tag of type type with len bytes of space following the tag header itself. The flag argument is passed directly to the kernel malloc(9). If successful, m_tag_get() returns a memory buffer of (len + sizeof (struct m_tag)) bytes. The first sizeof (struct m_tag) bytes will contain a tag header, the definition of which is also given in Figure 1. The first field contains a pointer to other tags on the same mbuf. The length field contains the size, in bytes, of the array following the tag header itself. There are several types defined, and we describe their use in Section 3. m_tag_free() de-allocates a tag.

m_tag_find() finds an instance of a tag of the given type. The caller can specify that the search start from an arbitrary point in the tag list (as indicated by the third argument). This allows the caller to examine all tags of a given type that are attached to a packet, by repeatedly calling m_tag_find(), as shown in Figure 2.


  
Figure 2: Using m_tag_find().
\begin{figure}
{\small
\begin{verbatim}
/*
 * This code can be written
 * better...
 ...ining the tag ...
 tag = m_tag_find(m, type, tag);
 }\end{verbatim}}\end{figure}

For clarity, the m_tag_first() and m_tag_next() pair of calls can be used to the same effect.

m_tag_prepend() links a new tag to the head of the list. Tags are typically attached in a manner that reflects the order in which the operations they represent were applied to the packet. For example, a packet that is processed (e.g., decrypted) by IPsec twice will have two attached tags, the first of which (as returned by m_tag_find()) will represent the second decryption. m_tag_unlink() detaches a tag from the packet, without deallocating the memory. m_tag_delete() combines m_tag_unlink() and m_tag_free(). m_tag_delete_chain() unlinks and frees all tags attached to a packet, starting from a caller-specified tag. If the last argument is left NULL, all attached flags will be deleted.

m_tag_copy() creates an identical copy of a tag. m_tag_copy_chain() creates a copy of the tag list attached to a packet and attaches it to another packet.

Finally, m_tag_init() is called by kernel components that manually initialize mbufs. There are only a handful of such locations, practically all of them in device drivers that perform their own buffer management (e.g., maintaining a cache of mbufs).


next up previous
Next: Using mbuf_tags Up: The OpenBSD mbuf_tags Previous: Design Rationale
Angelos D. Keromytis
7/7/2003