tcp_output() does:

        if (... && len > tp->t_maxseg && ...)
                tso = 1;

Then:

        if (len + optlen + ipoptlen > tp->t_maxopd) {
                ...
                if (tso) {
                        ...
                        if (sendalot && off + len < so->so_snd.sb_cc) {
                                len -= len % (tp->t_maxopd - optlen);
                                sendalot = 1;
                        }

Then later:

        if (tso) {
                KASSERT(len > tp->t_maxopd - optlen,
                    ("%s: len <= tso_segsz", __func__));
                m->m_pkthdr.csum_flags |= CSUM_TSO;
                m->m_pkthdr.tso_segsz = tp->t_maxopd - optlen;
        }

So there is an assumption here that
tp->t_maxseg >= tp->t_maxopd - optlen.

But tcp_mss_update() does not ensure that at all, because it rounds down
tp->t_maxseg to a multiple of MCLBYTES and does not change tp->t_maxopd
accordingly:

        tp->t_maxopd = mss;

        if (...)
                mss -= TCPOLEN_TSTAMP_APPA;

#if     (MCLBYTES & (MCLBYTES - 1)) == 0
        if (mss > MCLBYTES)
                mss &= ~(MCLBYTES-1);
#else
        if (mss > MCLBYTES)
                mss = mss / MCLBYTES * MCLBYTES;
#endif
        tp->t_maxseg = mss;

(All the above code is from 9, but I found the assertion failure on 8.2
which has fairly similar code.)

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

_______________________________________________
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"

Reply via email to