Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/netinet/ip_input.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/netinet/ip_input.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.150.2.1 retrieving revision 1.154 diff -u -p -r1.150.2.1 -r1.154 --- src/sys/netinet/ip_input.c 2002/06/20 15:52:21 1.150.2.1 +++ src/sys/netinet/ip_input.c 2002/06/30 22:40:34 1.154 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_input.c,v 1.150.2.1 2002/06/20 15:52:21 gehenna Exp $ */ +/* $NetBSD: ip_input.c,v 1.154 2002/06/30 22:40:34 thorpej Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -102,7 +102,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.150.2.1 2002/06/20 15:52:21 gehenna Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.154 2002/06/30 22:40:34 thorpej Exp $"); #include "opt_gateway.h" #include "opt_pfil_hooks.h" @@ -420,10 +420,24 @@ ip_input(struct mbuf *m) if (TAILQ_FIRST(&in_ifaddr) == 0) goto bad; ipstat.ips_total++; - if (m->m_len < sizeof (struct ip) && - (m = m_pullup(m, sizeof (struct ip))) == 0) { - ipstat.ips_toosmall++; - return; + /* + * If the IP header is not aligned, slurp it up into a new + * mbuf with space for link headers, in the event we forward + * it. Otherwise, if it is aligned, make sure the entire + * base IP header is in the first mbuf of the chain. + */ + if (IP_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) { + if ((m = m_copyup(m, sizeof(struct ip), + (max_linkhdr + 3) & ~3)) == NULL) { + /* XXXJRT new stat, please */ + ipstat.ips_toosmall++; + return; + } + } else if (__predict_false(m->m_len < sizeof (struct ip))) { + if ((m = m_pullup(m, sizeof (struct ip))) == NULL) { + ipstat.ips_toosmall++; + return; + } } ip = mtod(m, struct ip *); if (ip->ip_v != IPVERSION) {