svn commit: r279046 - head/sys/dev/sfxge
Andrew Rybchenko
arybchik at FreeBSD.org
Fri Feb 20 07:53:47 UTC 2015
Author: arybchik
Date: Fri Feb 20 07:53:46 2015
New Revision: 279046
URL: https://svnweb.freebsd.org/changeset/base/279046
Log:
sfxge: handle fragmented TCP header in mbuf
TCP header is fragmented in the case of VLAN tagged IPv6 traffic without
HW VLAN tagging.
Sponsored by: Solarflare Communications, Inc.
Approved by: gnn (mentor)
Modified:
head/sys/dev/sfxge/sfxge_tx.c
Modified: head/sys/dev/sfxge/sfxge_tx.c
==============================================================================
--- head/sys/dev/sfxge/sfxge_tx.c Fri Feb 20 06:19:23 2015 (r279045)
+++ head/sys/dev/sfxge/sfxge_tx.c Fri Feb 20 07:53:46 2015 (r279046)
@@ -865,6 +865,8 @@ static void tso_fini(struct sfxge_txq *t
static void tso_start(struct sfxge_tso_state *tso, struct mbuf *mbuf)
{
struct ether_header *eh = mtod(mbuf, struct ether_header *);
+ const struct tcphdr *th;
+ struct tcphdr th_copy;
tso->mbuf = mbuf;
@@ -892,13 +894,24 @@ static void tso_start(struct sfxge_tso_s
tso->tcph_off = tso->nh_off + sizeof(struct ip6_hdr);
}
- tso->header_len = tso->tcph_off + 4 * tso_tcph(tso)->th_off;
+ KASSERT(mbuf->m_len >= tso->tcph_off,
+ ("network header is fragmented in mbuf"));
+ /* We need TCP header including flags (window is the next) */
+ if (mbuf->m_len < tso->tcph_off + offsetof(struct tcphdr, th_win)) {
+ m_copydata(tso->mbuf, tso->tcph_off, sizeof(th_copy),
+ (caddr_t)&th_copy);
+ th = &th_copy;
+ } else {
+ th = tso_tcph(tso);
+ }
+
+ tso->header_len = tso->tcph_off + 4 * th->th_off;
tso->seg_size = mbuf->m_pkthdr.tso_segsz;
- tso->seqnum = ntohl(tso_tcph(tso)->th_seq);
+ tso->seqnum = ntohl(th->th_seq);
/* These flags must not be duplicated */
- KASSERT(!(tso_tcph(tso)->th_flags & (TH_URG | TH_SYN | TH_RST)),
+ KASSERT(!(th->th_flags & (TH_URG | TH_SYN | TH_RST)),
("incompatible TCP flag on TSO packet"));
tso->out_len = mbuf->m_pkthdr.len - tso->header_len;
More information about the svn-src-all
mailing list