From 19ce2e4680489f1498a527132e709de4a17c69b3 Mon Sep 17 00:00:00 2001 From: dyoung Date: Fri, 1 Sep 2006 02:44:46 +0000 Subject: [PATCH] Vastly simplify the code that copies an ICMP6 packet to two data paths: ICMP6 reply path, and socket path. --- sys/netinet6/icmp6.c | 52 +++++++++++++------------------------------- 1 file changed, 15 insertions(+), 37 deletions(-) diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index 006941bb49b0..e838d950fbb7 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -1,4 +1,4 @@ -/* $NetBSD: icmp6.c,v 1.119 2006/08/30 15:25:08 christos Exp $ */ +/* $NetBSD: icmp6.c,v 1.120 2006/09/01 02:44:46 dyoung Exp $ */ /* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */ /* @@ -62,7 +62,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: icmp6.c,v 1.119 2006/08/30 15:25:08 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: icmp6.c,v 1.120 2006/09/01 02:44:46 dyoung Exp $"); #include "opt_inet.h" #include "opt_ipsec.h" @@ -593,19 +593,16 @@ icmp6_input(mp, offp, proto) * Copy mbuf to send to two data paths: userland socket(s), * and to the querier (echo reply). * m: a copy for socket, n: a copy for querier + * + * If the first mbuf is shared, or the first mbuf is too short, + * copy the first part of the data into a fresh mbuf. + * Otherwise, we will wrongly overwrite both copies. */ if ((n = m_copym(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) { /* Give up local */ n = m; m = NULL; - goto deliverecho; - } - /* - * If the first mbuf is shared, or the first mbuf is too short, - * copy the first part of the data into a fresh mbuf. - * Otherwise, we will wrongly overwrite both copies. - */ - if ((n->m_flags & M_EXT) != 0 || + } else if (M_READONLY(n) || n->m_len < off + sizeof(struct icmp6_hdr)) { struct mbuf *n0 = n; @@ -623,42 +620,23 @@ icmp6_input(mp, offp, proto) } if (n == NULL) { /* Give up local */ - m_freem(n0); n = m; m = NULL; - goto deliverecho; + } else { + M_MOVE_PKTHDR(n, n0); + m_copydata(n0, 0, M_COPYALL, mtod(n, caddr_t)); + n->m_len = n->m_pkthdr.len = n0->m_pkthdr.len; } - M_MOVE_PKTHDR(n, n0); - /* - * Copy IPv6 and ICMPv6 only. - */ - nip6 = mtod(n, struct ip6_hdr *); - bcopy(ip6, nip6, sizeof(struct ip6_hdr)); - nicmp6 = (struct icmp6_hdr *)(nip6 + 1); - bcopy(icmp6, nicmp6, sizeof(struct icmp6_hdr)); - noff = sizeof(struct ip6_hdr); - n->m_len = noff + sizeof(struct icmp6_hdr); - /* - * Adjust mbuf. ip6_plen will be adjusted in - * ip6_output(). - * n->m_pkthdr.len == n0->m_pkthdr.len at this point. - */ - n->m_pkthdr.len += noff + sizeof(struct icmp6_hdr); - n->m_pkthdr.len -= (off + sizeof(struct icmp6_hdr)); - m_adj(n0, off + sizeof(struct icmp6_hdr)); - n->m_next = n0; - } else { - deliverecho: - nip6 = mtod(n, struct ip6_hdr *); - nicmp6 = (struct icmp6_hdr *)((caddr_t)nip6 + off); - noff = off; + m_freem(n0); } + nip6 = mtod(n, struct ip6_hdr *); + nicmp6 = (struct icmp6_hdr *)((caddr_t)nip6 + off); nicmp6->icmp6_type = ICMP6_ECHO_REPLY; nicmp6->icmp6_code = 0; if (n) { icmp6stat.icp6s_reflect++; icmp6stat.icp6s_outhist[ICMP6_ECHO_REPLY]++; - icmp6_reflect(n, noff); + icmp6_reflect(n, off); } if (!m) goto freeit;