diff options
author | andre <andre@FreeBSD.org> | 2006-09-06 21:51:59 +0000 |
---|---|---|
committer | andre <andre@FreeBSD.org> | 2006-09-06 21:51:59 +0000 |
commit | cb05913fd251edc3d35bcbeca73a8b681e2e58e8 (patch) | |
tree | b5d4180eab9fff2a64a310b178d7e69374bbdacf /sys/netinet/ip_output.c | |
parent | 0dddb6a1cc063906ce418aa1a75805e68b4ec971 (diff) | |
download | FreeBSD-src-cb05913fd251edc3d35bcbeca73a8b681e2e58e8.zip FreeBSD-src-cb05913fd251edc3d35bcbeca73a8b681e2e58e8.tar.gz |
First step of TSO (TCP segmentation offload) support in our network stack.
o add IFCAP_TSO[46] for drivers to announce this capability for IPv4 and IPv6
o add CSUM_TSO flag to mbuf pkthdr csum_flags field
o add tso_segsz field to mbuf pkthdr
o enhance ip_output() packet length check to allow for large TSO packets
o extend tcp_maxmtu[46]() with a flag pointer to pass interface capabilities
o adjust all callers of tcp_maxmtu[46]() accordingly
Discussed on: -current, -net
Sponsored by: TCP/IP Optimization Fundraise 2005
Diffstat (limited to 'sys/netinet/ip_output.c')
-rw-r--r-- | sys/netinet/ip_output.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 79d3806..8311732 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -495,19 +495,29 @@ passout: /* * If small enough for interface, or the interface will take - * care of the fragmentation for us, can just send directly. + * care of the fragmentation for us, we can just send directly. */ - if (ip->ip_len <= ifp->if_mtu || (ifp->if_hwassist & CSUM_FRAGMENT && - ((ip->ip_off & IP_DF) == 0))) { + if (ip->ip_len <= ifp->if_mtu || + (m->m_pkthdr.csum_flags & ifp->if_hwassist & CSUM_TSO) != 0 || + ((ip->ip_off & IP_DF) == 0 && (ifp->if_hwassist & CSUM_FRAGMENT))) { ip->ip_len = htons(ip->ip_len); ip->ip_off = htons(ip->ip_off); ip->ip_sum = 0; if (sw_csum & CSUM_DELAY_IP) ip->ip_sum = in_cksum(m, hlen); - /* Record statistics for this interface address. */ + /* + * Record statistics for this interface address. + * With CSUM_TSO the byte/packet count will be slightly + * incorrect because we count the IP+TCP headers only + * once instead of for every generated packet. + */ if (!(flags & IP_FORWARDING) && ia) { - ia->ia_ifa.if_opackets++; + if (m->m_pkthdr.csum_flags & CSUM_TSO) + ia->ia_ifa.if_opackets += + m->m_pkthdr.len / m->m_pkthdr.tso_segsz; + else + ia->ia_ifa.if_opackets++; ia->ia_ifa.if_obytes += m->m_pkthdr.len; } #ifdef IPSEC @@ -529,7 +539,8 @@ passout: goto done; } - if (ip->ip_off & IP_DF) { + /* Balk when DF bit is set or the interface didn't support TSO. */ + if ((ip->ip_off & IP_DF) || (m->m_pkthdr.csum_flags & CSUM_TSO)) { error = EMSGSIZE; /* * This case can happen if the user changed the MTU |