summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2015-03-25 10:55:08 +0000
committerhselasky <hselasky@FreeBSD.org>2015-03-25 10:55:08 +0000
commitda7dc9ab83ffd1753176346999a994818a7583ac (patch)
treec8dd27361cf99c5404769c99224743a7b93a52a7
parentb302acbcb96bb5d637092bb2d8ae477da410aa94 (diff)
downloadFreeBSD-src-da7dc9ab83ffd1753176346999a994818a7583ac.zip
FreeBSD-src-da7dc9ab83ffd1753176346999a994818a7583ac.tar.gz
MFC r279281:
Fix a special case in ip_fragment() to produce a more sensible chain of packets. When the data payload length excluding any headers, of an outgoing IPv4 packet exceeds PAGE_SIZE bytes, a special case in ip_fragment() can kick in to optimise the outgoing payload(s). The code which was added in r98849 as part of zero copy socket support assumes that the beginning of any MTU sized payload is aligned to where a MBUF's "m_data" pointer points. This is not always the case and can sometimes cause large IPv4 packets, as part of ping replies, to be split more than needed. Instead of iterating the MBUFs to figure out how much data is in the current chain, use the value already in the "m_pkthdr.len" field of the first MBUF in the chain. Reviewed by: ken @ Differential Revision: https://reviews.freebsd.org/D1893 Sponsored by: Mellanox Technologies
-rw-r--r--sys/netinet/ip_output.c4
1 files changed, 1 insertions, 3 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 4a535ae..5655bfe 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -752,10 +752,8 @@ ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu,
* be less than the receiver's page size ?
*/
int newlen;
- struct mbuf *m;
- for (m = m0, off = 0; m && (off+m->m_len) <= mtu; m = m->m_next)
- off += m->m_len;
+ off = MIN(mtu, m0->m_pkthdr.len);
/*
* firstlen (off - hlen) must be aligned on an
OpenPOWER on IntegriCloud