M_TAG_GET(9) | Kernel Developer's Manual | M_TAG_GET(9)

# NAME

`m_tag_get`, `m_tag_find`, `m_tag_prepend`, `m_tag_delete`, `m_tag_copy`, `m_tag_delete_chain`, `m_tag_init`, `m_tag_copy_chain`, `m_tag_first`, `m_tag_next` — a framework for generic packet attributes

# SYNOPSIS

`#include <sys/mbuf.h>`

struct m_tag *
`m_tag_get`(int type, int len, int flags);

struct m_tag *
`m_tag_find`(struct mbuf *mbuf, int type, struct m_tag *tag);

void
`m_tag_prepend`(struct mbuf *mbuf, struct m_tag *tag);

void
`m_tag_delete`(struct mbuf *mbuf, struct m_tag *tag);

struct m_tag *
`m_tag_copy`(struct m_tag *tag);

void
`m_tag_delete_chain`(struct mbuf *mbuf);

void
`m_tag_init`(struct mbuf *mbuf);

int
`m_tag_copy_chain`(struct mbuf *mbuf, struct mbuf *mbuf2);

struct m_tag *
`m_tag_first`(struct mbuf *mbuf);

struct m_tag *
`m_tag_next`(struct mbuf *mbuf, struct m_tag *tag);

# DESCRIPTION

These functions allow the manipulation of generic packet attributes. They are used by the kernel to keep track of operations done or scheduled to happen to packets. These attributes are attached to mbuf(9) packet headers.

Mbuf tags get allocated using pool(9).

`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 pool_get(9). If successful, `m_tag_get`() returns a memory buffer of (len + sizeof (struct m_tag)) bytes. The first sizeof(struct m_tag) bytes contain a struct m_tag:

    struct m_tag {
    	SLIST_ENTRY(m_tag)	m_tag_link;	/* List of packet tags */
    	u_int16_t		m_tag_id;	/* Tag ID */
    	u_int16_t		m_tag_len;	/* Length of data */
    };

The m_tag_link field is used to link tags together (see queue(3) for more details). The m_tag_id and m_tag_len fields are set to type and len respectively. Following this structure are len bytes of space that can be used to store tag-specific information.

The currently defined tag types are:

PACKET_TAG_IPSEC_IN_DONE
  Used by ipsec(4) to indicate successful processing performed on an input packet. The tag contains a struct tdb_ident, as defined in sys/netinet/ip_ipsp.h, identifying the security association under which the packet arrived.
PACKET_TAG_IPSEC_OUT_DONE
  Used by IPsec to indicate that an output packet has been IPsec-processed. The tag contains a struct tdb_ident identifying the security association applied to the packet. This tag is primarily used to detect and avoid loops in IPsec processing on output.
PACKET_TAG_IPSEC_FLOWINFO
  Used by the IPv4 stack to specify the IPsec flow of an output IP packet. The tag contains a u_int32_t identifying the IPsec flow.
PACKET_TAG_WIREGUARD
  Used by the wg(4) interface to detect loops in processing. The tag contains a pointer to the wg peer that already processed the packet.
PACKET_TAG_GRE
  Used by the gre(4) interface to detect loops in processing. The tag contains a pointer to the gre interface that already processed the packet.
PACKET_TAG_DLT
  Used by bpf(4) to indicate that the packet was injected. The tag contains a u_int identifying the data link layer type.
PACKET_TAG_PF_DIVERT
  Indicates that the packet was diverted by pf(4) using the divert-to or divert-reply directives. The tag contains a struct pf_divert identifying the port, address and routing domain the packet should be diverted to.
PACKET_TAG_PF_REASSEMBLED
  Used by pf(4) to reassemble IPv6 fragments. The tag contains a struct pf_fragment_tag.
PACKET_TAG_SRCROUTE
  Used by the IPv4 stack to keep track of the source route of an incoming IP packet, in case a protocol wants to respond over the same route. The tag contains a struct ip_srcrt.
PACKET_TAG_CARP_BAL_IP
  Used by carp(4) to mark packets received in mode balancing ip. These packets need some special treatment since they contain layer 3 unicast inside layer 2 multicast. The tag contains no data.

`m_tag_find`() finds an instance of a tag of type type attached to packet mbuf. If tag is `NULL`, the first such tag is returned. Otherwise, the first tag of type type after tag is returned. If no such tag is found, `NULL` is returned.

`m_tag_prepend`() adds the new tag tag at the head of the tag list for packet mbuf.

`m_tag_delete`() removes and then de-allocates tag tag from the list of tags of packet mbuf.

`m_tag_copy`() creates an unlinked copy of tag tag.

`m_tag_delete_chain`() deletes all tags attached to packet mbuf.

`m_tag_init`() initializes the tag storage for packet mbuf.

`m_tag_copy_chain`() copies all tags from packet mbuf to packet mbuf2. On success, it returns 0. Otherwise, it returns `ENOBUFS`.

`m_tag_first`() returns the first tag attached to packet mbuf.

`m_tag_next`() returns the tag following tag in packet mbuf.

The `M_MOVE_PKTHDR`() and `M_MOVE_HDR`() macros defined in sys/sys/mbuf.h move the tags from the old to the new mbuf.

# CODE REFERENCES

The tag-manipulating code is contained in the file sys/kern/uipc_mbuf2.c.

# SEE ALSO

bpf(4), bridge(4), gif(4), gre(4), ipsec(4), pf(4), mbuf(9)

# HISTORY

The packet tags first appeared in OpenBSD 2.9 and were written by Angelos D. Keromytis <angelos@openbsd.org>.

June 13, 2025 | Debian