Make divert_output() do an m_pullup only if truly needed.
ok?
Index: netinet/ip_divert.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_divert.c,v
retrieving revision 1.31
diff -u -p -r1.31 ip_divert.c
--- netinet/ip_divert.c 5 Dec 2014 15:50:04 -0000 1.31
+++ netinet/ip_divert.c 13 Dec 2014 04:32:23 -0000
@@ -101,7 +101,8 @@ divert_output(struct inpcb *inp, struct
/* Do basic sanity checks. */
if (m->m_pkthdr.len < sizeof(struct ip))
goto fail;
- if ((m = m_pullup(m, sizeof(struct ip))) == NULL) {
+ if (m->m_len < sizeof(struct ip) &&
+ (m = m_pullup(m, sizeof(struct ip))) == NULL) {
/* m_pullup() has freed the mbuf, so just return. */
divstat.divs_errors++;
return (ENOBUFS);
Index: netinet6/ip6_divert.c
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_divert.c,v
retrieving revision 1.31
diff -u -p -r1.31 ip6_divert.c
--- netinet6/ip6_divert.c 5 Dec 2014 15:50:04 -0000 1.31
+++ netinet6/ip6_divert.c 13 Dec 2014 04:32:24 -0000
@@ -104,7 +104,8 @@ divert6_output(struct inpcb *inp, struct
/* Do basic sanity checks. */
if (m->m_pkthdr.len < sizeof(struct ip6_hdr))
goto fail;
- if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
+ if (m->m_len < sizeof(struct ip6_hdr) &&
+ (m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
/* m_pullup() has freed the mbuf, so just return. */
div6stat.divs_errors++;
return (ENOBUFS);