aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/ip_output.c
diff options
context:
space:
mode:
authorBill Fenner <fenner@FreeBSD.org>1997-05-06 21:22:04 +0000
committerBill Fenner <fenner@FreeBSD.org>1997-05-06 21:22:04 +0000
commit86b1d6d24da0987c573d63be38ea23ab3afd0989 (patch)
treeff6e87f1f548c1ba3769bec70a37564abcdeff7a /sys/netinet/ip_output.c
parentee359f4838f7e8922824fe563d2ac024cf7b0b9c (diff)
downloadsrc-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.c14
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: