diff options
author | Bill Fenner <fenner@FreeBSD.org> | 1997-05-06 21:22:04 +0000 |
---|---|---|
committer | Bill Fenner <fenner@FreeBSD.org> | 1997-05-06 21:22:04 +0000 |
commit | 86b1d6d24da0987c573d63be38ea23ab3afd0989 (patch) | |
tree | ff6e87f1f548c1ba3769bec70a37564abcdeff7a /sys/netinet/ip_output.c | |
parent | ee359f4838f7e8922824fe563d2ac024cf7b0b9c (diff) | |
download | src-86b1d6d24da0987c573d63be38ea23ab3afd0989.tar.gz src-86b1d6d24da0987c573d63be38ea23ab3afd0989.zip |
Pull up the IP header in ip_mloopback(). This makes sure that the
operations on the header inside ip_mloopback() are performed on
a private copy instead of a shared cluster.
PR: kern/3410
Notes
Notes:
svn path=/head/; revision=25516
Diffstat (limited to 'sys/netinet/ip_output.c')
-rw-r--r-- | sys/netinet/ip_output.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 4b989fc9e7e2..defc06a4d430 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)ip_output.c 8.3 (Berkeley) 1/21/94 - * $Id: ip_output.c,v 1.54 1997/04/03 10:47:12 darrenr Exp $ + * $Id: ip_output.c,v 1.55 1997/04/27 20:01:07 wollman Exp $ */ #define _IP_VHL @@ -72,7 +72,7 @@ u_short ip_id; static struct mbuf *ip_insertoptions __P((struct mbuf *, struct mbuf *, int *)); static void ip_mloopback - __P((struct ifnet *, struct mbuf *, struct sockaddr_in *)); + __P((struct ifnet *, struct mbuf *, struct sockaddr_in *, int)); static int ip_getmoptions __P((int, struct ip_moptions *, struct mbuf **)); static int ip_pcbopts __P((struct mbuf **, struct mbuf *)); @@ -251,7 +251,7 @@ ip_output(m0, opt, ro, flags, imo) * on the outgoing interface, and the caller did not * forbid loopback, loop back a copy. */ - ip_mloopback(ifp, m, dst); + ip_mloopback(ifp, m, dst, hlen); } else { /* @@ -1290,15 +1290,18 @@ ip_freemoptions(imo) * replicating that code here. */ static void -ip_mloopback(ifp, m, dst) +ip_mloopback(ifp, m, dst, hlen) struct ifnet *ifp; register struct mbuf *m; register struct sockaddr_in *dst; + int hlen; { register struct ip *ip; struct mbuf *copym; copym = m_copy(m, 0, M_COPYALL); + if (copym != NULL && (copym->m_flags & M_EXT || copym->m_len < hlen)) + copym = m_pullup(copym, hlen); if (copym != NULL) { /* * We don't bother to fragment if the IP length is greater @@ -1311,8 +1314,7 @@ ip_mloopback(ifp, m, dst) if (ip->ip_vhl == IP_VHL_BORING) { ip->ip_sum = in_cksum_hdr(ip); } else { - ip->ip_sum = in_cksum(copym, - IP_VHL_HL(ip->ip_vhl) << 2); + ip->ip_sum = in_cksum(copym, hlen); } /* * NB: |