Introduce the notion of "persistent mbuf tags"; these are tags that stay

with an mbuf until it is reclaimed.  This is in contrast to tags that
vanish when an mbuf chain passes through an interface.  Persistent tags
are used, for example, by MAC labels.

Add an m_tag_delete_nonpersistent function to strip non-persistent tags
from mbufs and use it to strip such tags from packets as they pass through
the loopback interface and when turned around by icmp.  This fixes problems
with "tag leakage".

Pointed out by:	Jonathan Stone
Reviewed by:	Robert Watson
This commit is contained in:
Sam Leffler 2003-10-29 05:40:07 +00:00
parent 4765b7e51a
commit 9c855a36c1
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=121645
4 changed files with 36 additions and 1 deletions

View File

@ -381,6 +381,23 @@ m_tag_delete_chain(struct mbuf *m, struct m_tag *t)
m_tag_delete(m, p);
}
/*
* Strip off all tags that would normally vanish when
* passing through a network interface. Only persistent
* tags will exist after this; these are expected to remain
* so long as the mbuf chain exists, regardless of the
* path the mbufs take.
*/
void
m_tag_delete_nonpersistent(struct mbuf *m)
{
struct m_tag *p, *q;
SLIST_FOREACH_SAFE(p, &m->m_pkthdr.tags, m_tag_link, q)
if ((p->m_tag_id & MTAG_PERSISTENT) == 0)
m_tag_delete(m, p);
}
/* Find a tag, starting from a given position. */
struct m_tag *
m_tag_locate(struct mbuf *m, u_int32_t cookie, int type, struct m_tag *t)

View File

@ -266,6 +266,7 @@ if_simloop(ifp, m, af, hlen)
int isr;
M_ASSERTPKTHDR(m);
m_tag_delete_nonpersistent(m);
m->m_pkthdr.rcvif = ifp;
/* BPF write needs to be handled specially */

View File

@ -728,6 +728,7 @@ icmp_reflect(m)
bcopy((caddr_t)ip + optlen, (caddr_t)(ip + 1),
(unsigned)(m->m_len - sizeof(struct ip)));
}
m_tag_delete_nonpersistent(m);
m->m_flags &= ~(M_BCAST|M_MCAST);
icmp_send(m, opts, ro);
done:

View File

@ -505,6 +505,21 @@ struct mbuf *m_split(struct mbuf *, int, int);
* struct m_tag *mtag = &p->tag;
*/
/*
* Persistent tags stay with an mbuf until the mbuf is reclaimed.
* Otherwise tags are expected to ``vanish'' when they pass through
* a network interface. For most interfaces this happens normally
* as the tags are reclaimed when the mbuf is free'd. However in
* some special cases reclaiming must be done manually. An example
* is packets that pass through the loopback interface. Also, one
* must be careful to do this when ``turning around'' packets (e.g.
* icmp_reflect).
*
* To mark a tag persistent bit-or this flag in when defining the
* tag id. The tag will then be treated as described above.
*/
#define MTAG_PERSISTENT 0x800
#define PACKET_TAG_NONE 0 /* Nadda */
/* Packet tag for use with PACKET_ABI_COMPAT */
@ -542,7 +557,7 @@ struct mbuf *m_split(struct mbuf *, int, int);
#define PACKET_TAG_IPFW 16 /* ipfw classification */
#define PACKET_TAG_DIVERT 17 /* divert info */
#define PACKET_TAG_IPFORWARD 18 /* ipforward info */
#define PACKET_TAG_MACLABEL 19 /* MAC label */
#define PACKET_TAG_MACLABEL (19 | MTAG_PERSISTENT) /* MAC label */
/* Packet tag routines */
struct m_tag *m_tag_alloc(u_int32_t, int, int, int);
@ -557,6 +572,7 @@ 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 *);
/* these are for openbsd compatibility */
#define MTAG_ABI_COMPAT 0 /* compatibility ABI */