Page MenuHomeFreeBSD

D6612.id17140.diff
No OneTemporary

D6612.id17140.diff

Index: sys/netinet/ip_fastfwd.c
===================================================================
--- sys/netinet/ip_fastfwd.c
+++ sys/netinet/ip_fastfwd.c
@@ -105,6 +105,7 @@
#include <netinet/ip_var.h>
#include <netinet/ip_icmp.h>
#include <netinet/ip_options.h>
+#include <netinet/tcp.h>
#include <machine/in_cksum.h>
@@ -160,7 +161,7 @@
struct sockaddr_in *dst = NULL;
struct ifnet *ifp;
struct in_addr odest, dest;
- uint16_t ip_len, ip_off;
+ uint16_t ip_len, ip_off, tcp_len;
int error = 0;
int mtu;
struct m_tag *fwd_tag = NULL;
@@ -429,7 +430,36 @@
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 ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0 &&
+ ip->ip_p == IPPROTO_TCP) {
+ struct tcphdr *th;
+
+ th = mtodo(m, sizeof(struct ip));
+ tcp_len = ip_len - (sizeof(struct ip) + (th->th_off << 2));
+ }
+
+ 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) &&
+ howmany(tcp_len, m->m_pkthdr.tso_segsz) <=
+ ifp->if_hw_tsomaxsegcount &&
+ tcp_len <= ifp->if_hw_tsomax)) {
/*
* Avoid confusing lower layers.
*/

File Metadata

Mime Type
text/plain
Expires
Fri, Jan 30, 12:27 AM (11 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28091945
Default Alt Text
D6612.id17140.diff (1 KB)

Event Timeline