Index: sys/netinet/ip_fastfwd.c =================================================================== --- sys/netinet/ip_fastfwd.c +++ sys/netinet/ip_fastfwd.c @@ -429,7 +429,25 @@ else mtu = ifp->if_mtu; - if (ip_len <= mtu) { + /* + * Allow forwarding TSO packets directly if the outbound + * interface also supports TSO. + * + * This is very important when using VMs to perform intra-host + * packet routing. Since the packet never hits the wire the + * TCP segments are not actually generated until it reaches a + * physical interface, and thus we get to see TSO packets on + * input. + * + * Not doing this means that the backend domain (usually Dom0) + * would have to perform software TCP segmentation for us, which + * will introduce a huge performance penalty. + */ + if ((ip_len <= mtu) || (ip->ip_p == IPPROTO_TCP && + (m->m_pkthdr.csum_flags & CSUM_TSO) != 0 && + (ifp->if_hwassist & CSUM_TSO) != 0 && + (ifp->if_capenable & IFCAP_TSO4) != 0 && + (m->m_pkthdr.tso_segsz <= ifp->if_hw_tsomaxsegsize))) { /* * Avoid confusing lower layers. */