summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2003-10-29 05:40:07 +0000
committersam <sam@FreeBSD.org>2003-10-29 05:40:07 +0000
commit409cf5f514ad9056b7dac76a11c4844021c2be2b (patch)
treed88c488f67b1157ed3b937a89a30e71bdcc2bd2b
parent0e35eb160176704d52210e5e548a61a6aaa6cd84 (diff)
downloadFreeBSD-src-409cf5f514ad9056b7dac76a11c4844021c2be2b.zip
FreeBSD-src-409cf5f514ad9056b7dac76a11c4844021c2be2b.tar.gz
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
-rw-r--r--sys/kern/uipc_mbuf2.c17
-rw-r--r--sys/net/if_loop.c1
-rw-r--r--sys/netinet/ip_icmp.c1
-rw-r--r--sys/sys/mbuf.h18
4 files changed, 36 insertions, 1 deletions
diff --git a/sys/kern/uipc_mbuf2.c b/sys/kern/uipc_mbuf2.c
index 215fc68..1b579e3 100644
--- a/sys/kern/uipc_mbuf2.c
+++ b/sys/kern/uipc_mbuf2.c
@@ -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)
diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c
index 265c830..21b87e5 100644
--- a/sys/net/if_loop.c
+++ b/sys/net/if_loop.c
@@ -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 */
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index 1e485e3..8f71b05 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -728,6 +728,7 @@ match:
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:
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index 6fa1ef7..1efd248 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -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 */
OpenPOWER on IntegriCloud