Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/netinet Add IPv4/TCP hooks for TCP Segment Offload on tr...
details: https://anonhg.NetBSD.org/src/rev/1d082611fe2a
branches: trunk
changeset: 574604:1d082611fe2a
user: matt <matt%NetBSD.org@localhost>
date: Sun Mar 06 00:35:07 2005 +0000
description:
Add IPv4/TCP hooks for TCP Segment Offload on transmit.
diffstat:
sys/netinet/ip_output.c | 22 ++++++++++++--
sys/netinet/tcp_output.c | 70 ++++++++++++++++++++++++++++++++++-------------
2 files changed, 69 insertions(+), 23 deletions(-)
diffs (186 lines):
diff -r fd9f631fd7cd -r 1d082611fe2a sys/netinet/ip_output.c
--- a/sys/netinet/ip_output.c Sun Mar 06 00:13:36 2005 +0000
+++ b/sys/netinet/ip_output.c Sun Mar 06 00:35:07 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ip_output.c,v 1.145 2005/03/05 02:46:38 briggs Exp $ */
+/* $NetBSD: ip_output.c,v 1.146 2005/03/06 00:35:07 matt Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -98,7 +98,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.145 2005/03/05 02:46:38 briggs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.146 2005/03/06 00:35:07 matt Exp $");
#include "opt_pfil_hooks.h"
#include "opt_inet.h"
@@ -758,6 +758,8 @@
hlen = ip->ip_hl << 2;
#endif /* PFIL_HOOKS */
+ m->m_pkthdr.csum_data |= hlen << 16;
+
#if IFA_STATS
/*
* search for the source address structure to
@@ -766,6 +768,19 @@
INADDR_TO_IA(ip->ip_src, ia);
#endif
+ if (m->m_pkthdr.csum_flags & M_CSUM_TSOv4) {
+#if IFA_STATS
+ if (ia)
+ ia->ia_ifa.ifa_data.ifad_outbytes += ip_len;
+#endif
+#ifdef IPSEC
+ /* clean ipsec history once it goes out of the node */
+ ipsec_delaux(m);
+#endif
+ error = (*ifp->if_output)(ifp, m, sintosa(dst), ro->ro_rt);
+ goto done;
+ }
+
/* Maybe skip checksums on loopback interfaces. */
if (__predict_true(!(ifp->if_flags & IFF_LOOPBACK) ||
ip_do_loopback_cksum))
@@ -799,8 +814,7 @@
if (sw_csum & (M_CSUM_TCPv4|M_CSUM_UDPv4)) {
in_delayed_cksum(m);
m->m_pkthdr.csum_flags &= ~(M_CSUM_TCPv4|M_CSUM_UDPv4);
- } else
- m->m_pkthdr.csum_data |= hlen << 16;
+ }
#ifdef IPSEC
/* clean ipsec history once it goes out of the node */
diff -r fd9f631fd7cd -r 1d082611fe2a sys/netinet/tcp_output.c
--- a/sys/netinet/tcp_output.c Sun Mar 06 00:13:36 2005 +0000
+++ b/sys/netinet/tcp_output.c Sun Mar 06 00:35:07 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tcp_output.c,v 1.119 2005/03/02 10:20:18 mycroft Exp $ */
+/* $NetBSD: tcp_output.c,v 1.120 2005/03/06 00:35:07 matt Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -140,7 +140,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tcp_output.c,v 1.119 2005/03/02 10:20:18 mycroft Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tcp_output.c,v 1.120 2005/03/06 00:35:07 matt Exp $");
#include "opt_inet.h"
#include "opt_ipsec.h"
@@ -556,6 +556,7 @@
int maxburst = TCP_MAXBURST;
int af; /* address family on the wire */
int iphdrlen;
+ int use_tso;
int sack_rxmit;
int sack_bytes_rxmt;
struct sackhole *p;
@@ -608,6 +609,21 @@
idle = (tp->snd_max == tp->snd_una);
/*
+ * Determine if we can use TCP segmentation offload:
+ * - If we're using IPv4
+ * - If there is not an IPsec policy that prevents it
+ * - If the interface can do it
+ */
+ use_tso = tp->t_inpcb != NULL &&
+#if defined(IPSEC) || defined(FAST_IPSEC)
+ IPSEC_PCB_SKIP_IPSEC(tp->t_inpcb->inp_sp,
+ IPSEC_DIR_OUTBOUND) &&
+#endif
+ tp->t_inpcb->inp_route.ro_rt != NULL &&
+ (tp->t_inpcb->inp_route.ro_rt->rt_ifp->if_capenable &
+ IFCAP_TSOv4) != 0;
+
+ /*
* Restart Window computation. From draft-floyd-incr-init-win-03:
*
* Optionally, a TCP MAY set the restart window to the
@@ -828,10 +844,19 @@
}
}
if (len > txsegsize) {
- len = txsegsize;
+ if (use_tso) {
+ /*
+ * Truncate TSO transfers to IP_MAXPACKET, and make
+ * sure that we send equal size transfers down the
+ * stack (rather than big-small-big-small-...).
+ */
+ len = (min(len, IP_MAXPACKET) / txsegsize) * txsegsize;
+ } else
+ len = txsegsize;
flags &= ~TH_FIN;
sendalot = 1;
- }
+ } else
+ use_tso = 0;
if (sack_rxmit) {
if (SEQ_LT(p->rxmit + len, tp->snd_una + so->so_snd.sb_cc))
flags &= ~TH_FIN;
@@ -850,7 +875,7 @@
* to send into a small window), then must resend.
*/
if (len) {
- if (len == txsegsize)
+ if (len >= txsegsize)
goto send;
if ((so->so_state & SS_MORETOCOME) == 0 &&
((idle || tp->t_flags & TF_NODELAY) &&
@@ -1083,8 +1108,10 @@
hdrlen += optlen;
#ifdef DIAGNOSTIC
- if (len > txsegsize)
+ if (!use_tso && len > txsegsize)
panic("tcp data to be sent is larger than segment");
+ else if (use_tso && len > IP_MAXPACKET)
+ panic("tcp data to be sent is larger than max TSO size");
if (max_linkhdr + hdrlen > MCLBYTES)
panic("tcphdr too big");
#endif
@@ -1255,19 +1282,24 @@
switch (af) {
#ifdef INET
case AF_INET:
- if (__predict_true(ro->ro_rt == NULL ||
- !(ro->ro_rt->rt_ifp->if_flags &
- IFF_LOOPBACK) ||
- tcp_do_loopback_cksum))
- m->m_pkthdr.csum_flags = M_CSUM_TCPv4;
- else
- m->m_pkthdr.csum_flags = 0;
- m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum);
- if (len + optlen) {
- /* Fixup the pseudo-header checksum. */
- /* XXXJRT Not IP Jumbogram safe. */
- th->th_sum = in_cksum_addword(th->th_sum,
- htons((u_int16_t) (len + optlen)));
+ if (use_tso) {
+ m->m_pkthdr.segsz = txsegsize;
+ m->m_pkthdr.csum_flags |= M_CSUM_TSOv4;
+ } else {
+ if (__predict_true(ro->ro_rt == NULL ||
+ !(ro->ro_rt->rt_ifp->if_flags &
+ IFF_LOOPBACK) ||
+ tcp_do_loopback_cksum))
+ m->m_pkthdr.csum_flags = M_CSUM_TCPv4;
+ else
+ m->m_pkthdr.csum_flags = 0;
+ m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum);
+ if (len + optlen) {
+ /* Fixup the pseudo-header checksum. */
+ /* XXXJRT Not IP Jumbogram safe. */
+ th->th_sum = in_cksum_addword(th->th_sum,
+ htons((u_int16_t) (len + optlen)));
+ }
}
break;
#endif
Home |
Main Index |
Thread Index |
Old Index