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)
This commit is contained in:
Andrew Rybchenko 2015-02-20 07:53:46 +00:00
parent 7f745b2b49
commit b2c43c38e7

View File

@ -865,6 +865,8 @@ static void tso_fini(struct sfxge_txq *txq)
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_state *tso, struct mbuf *mbuf)
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;