From b16cb0a948acd6a3b5f47aa494607a001944c194 Mon Sep 17 00:00:00 2001 From: sam Date: Mon, 30 Dec 2002 20:22:40 +0000 Subject: Correct mbuf packet header propagation. Previously, packet headers were sometimes propagated using M_COPY_PKTHDR which actually did something between a "move" and a "copy" operation. This is replaced by M_MOVE_PKTHDR (which copies the pkthdr contents and "removes" it from the source mbuf) and m_dup_pkthdr which copies the packet header contents including any m_tag chain. This corrects numerous problems whereby mbuf tags could be lost during packet manipulations. These changes also introduce arguments to m_tag_copy and m_tag_copy_chain to specify if the tag copy work should potentially block. This introduces an incompatibility with openbsd which we may want to revisit. Note that move/dup of packet headers does not handle target mbufs that have a cluster bound to them. We may want to support this; for now we watch for it with an assert. Finally, M_COPYFLAGS was updated to include M_FIRSTFRAG|M_LASTFRAG. Supported by: Vernier Networks Reviewed by: Robert Watson --- sys/netinet/ip_input.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'sys/netinet') diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 90f54e0..51332a5 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -1763,8 +1763,17 @@ ip_forward(struct mbuf *m, int srcrt, struct sockaddr_in *next_hop) * data in a cluster may change before we reach icmp_error(). */ MGET(mcopy, M_DONTWAIT, m->m_type); + if (mcopy != NULL && !m_dup_pkthdr(mcopy, m, M_DONTWAIT)) { + /* + * It's probably ok if the pkthdr dup fails (because + * the deep copy of the tag chain failed), but for now + * be conservative and just discard the copy since + * code below may some day want the tags. + */ + m_free(mcopy); + mcopy = NULL; + } if (mcopy != NULL) { - M_COPY_PKTHDR(mcopy, m); mcopy->m_len = imin((ip->ip_hl << 2) + 8, (int)ip->ip_len); m_copydata(m, 0, mcopy->m_len, mtod(mcopy, caddr_t)); -- cgit v1.1