diff options
-rw-r--r-- | sys/net/if_var.h | 11 | ||||
-rw-r--r-- | sys/netinet/tcp_output.c | 12 |
2 files changed, 17 insertions, 6 deletions
diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 58391a1..1ff7a4b 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -236,11 +236,12 @@ struct ifnet { * count limit does not apply. If all three fields are zero, * there is no TSO limit. * - * NOTE: The TSO limits only apply to the data payload part of - * a TCP/IP packet. That means there is no need to subtract - * space for ethernet-, vlan-, IP- or TCP- headers from the - * TSO limits unless the hardware driver in question requires - * so. + * NOTE: The TSO limits should reflect the values used in the + * BUSDMA tag a network adapter is using to load a mbuf chain + * for transmission. The TCP/IP network stack will subtract + * space for all linklevel and protocol level headers and + * ensure that the full mbuf chain passed to the network + * adapter fits within the given limits. */ u_int if_hw_tsomax; diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c index ba0ec40..f1196e1 100644 --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -807,7 +807,8 @@ send: */ if (if_hw_tsomax != 0) { /* compute maximum TSO length */ - max_len = (if_hw_tsomax - hdrlen); + max_len = (if_hw_tsomax - hdrlen - + max_linkhdr); if (max_len <= 0) { len = 0; } else if (len > max_len) { @@ -822,6 +823,15 @@ send: */ if (if_hw_tsomaxsegcount != 0 && if_hw_tsomaxsegsize != 0) { + /* + * Subtract one segment for the LINK + * and TCP/IP headers mbuf that will + * be prepended to this mbuf chain + * after the code in this section + * limits the number of mbufs in the + * chain to if_hw_tsomaxsegcount. + */ + if_hw_tsomaxsegcount -= 1; max_len = 0; mb = sbsndmbuf(&so->so_snd, off, &moff); |