diff options
author | Angelos D. Keromytis <angelos@cvs.openbsd.org> | 2001-06-25 01:59:30 +0000 |
---|---|---|
committer | Angelos D. Keromytis <angelos@cvs.openbsd.org> | 2001-06-25 01:59:30 +0000 |
commit | ad8f9ae7dbaa959c90e908ad3c5fa381772bcc5e (patch) | |
tree | d88f5ba71ebbb82d215e67ab2faf8b6a0d3904d7 | |
parent | 175d546a58b674b442ad2b97998b92ecdff00136 (diff) |
Always defer output TCP checksumming until ip_output() (or hardware,
if it exists). Cuts down on code a bit, and we don't need to look at
the routing entry at TCP. Based on NetBSD. UDP case to follow.
-rw-r--r-- | sys/netinet/ip_output.c | 34 | ||||
-rw-r--r-- | sys/netinet/tcp_output.c | 51 | ||||
-rw-r--r-- | sys/netinet/tcp_subr.c | 9 |
3 files changed, 35 insertions, 59 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index cefbdded6f6..2e548f4552a 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_output.c,v 1.120 2001/06/25 01:21:15 provos Exp $ */ +/* $OpenBSD: ip_output.c,v 1.121 2001/06/25 01:59:29 angelos Exp $ */ /* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */ /* @@ -64,6 +64,9 @@ #include <netinet/ip_icmp.h> #include <netinet/tcp.h> #include <netinet/udp.h> +#include <netinet/tcp_timer.h> +#include <netinet/tcp_var.h> +#include <netinet/udp_var.h> #ifdef vax #include <machine/mtpr.h> @@ -670,16 +673,18 @@ sendit: } #endif /* Catch routing changes wrt. hardware checksumming for TCP or UDP. */ - if (m->m_pkthdr.csum & M_TCPV4_CSUM_OUT && - !(ifp->if_capabilities & IFCAP_CSUM_TCPv4)) { - in_delayed_cksum(m); - m->m_pkthdr.csum &= ~M_TCPV4_CSUM_OUT; /* Clear */ - } - - if (m->m_pkthdr.csum & M_UDPV4_CSUM_OUT && - !(ifp->if_capabilities & IFCAP_CSUM_UDPv4)) { - in_delayed_cksum(m); - m->m_pkthdr.csum &= ~M_UDPV4_CSUM_OUT; /* Clear */ + if (m->m_pkthdr.csum & M_TCPV4_CSUM_OUT) { + if (!(ifp->if_capabilities & IFCAP_CSUM_TCPv4) || + ifp->if_bridge != NULL) { + in_delayed_cksum(m); + m->m_pkthdr.csum &= ~M_TCPV4_CSUM_OUT; /* Clear */ + } + } else if (m->m_pkthdr.csum & M_UDPV4_CSUM_OUT) { + if (!(ifp->if_capabilities & IFCAP_CSUM_UDPv4) || + ifp->if_bridge != NULL) { + in_delayed_cksum(m); + m->m_pkthdr.csum &= ~M_UDPV4_CSUM_OUT; /* Clear */ + } } /* @@ -696,6 +701,11 @@ sendit: ip->ip_sum = 0; ip->ip_sum = in_cksum(m, hlen); } + /* Update relevant hardware checksum stats for TCP/UDP */ + if (m->m_pkthdr.csum & M_TCPV4_CSUM_OUT) + tcpstat.tcps_outhwcsum++; + else if (m->m_pkthdr.csum & M_UDPV4_CSUM_OUT) + udpstat.udps_outhwcsum++; error = (*ifp->if_output)(ifp, m, sintosa(dst), ro->ro_rt); goto done; } @@ -1857,7 +1867,7 @@ in_delayed_cksum(struct mbuf *m) ip = mtod(m, struct ip *); offset = ip->ip_hl << 2; - csum = in4_cksum(m, 0, offset, ntohs(ip->ip_len) - offset); + csum = in4_cksum(m, 0, offset, m->m_pkthdr.len - offset); if (csum == 0 && ip->ip_p == IPPROTO_UDP) csum = 0xffff; diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c index 0fac61efd0a..d7587bc52e6 100644 --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_output.c,v 1.42 2001/06/25 00:11:58 angelos Exp $ */ +/* $OpenBSD: tcp_output.c,v 1.43 2001/06/25 01:59:29 angelos Exp $ */ /* $NetBSD: tcp_output.c,v 1.16 1997/06/03 16:17:09 kml Exp $ */ /* @@ -226,8 +226,6 @@ tcp_output(tp) u_char opt[MAX_TCPOPTLEN]; unsigned int optlen, hdrlen; int idle, sendalot = 0; - struct route *ro; - struct ifnet *ifp; #ifdef TCP_SACK int i, sack_rxmit = 0; struct sackhole *p; @@ -846,22 +844,6 @@ send: */ tp->snd_up = tp->snd_una; /* drag it along */ - /* Put TCP length in pseudo-header */ - switch (tp->pf) { - case 0: /*default to PF_INET*/ -#ifdef INET - case AF_INET: - if (len + optlen) - mtod(m, struct ipovly *)->ih_len = htons((u_int16_t)( - sizeof (struct tcphdr) + optlen + len)); - break; -#endif /* INET */ -#ifdef INET6 - case AF_INET6: - break; -#endif /* INET6 */ - } - #ifdef TCP_SIGNATURE if (tp->t_flags & TF_SIGNATURE) { MD5_CTX ctx; @@ -910,7 +892,8 @@ send: ippseudo.ippseudo_dst = ipovly->ih_dst; ippseudo.ippseudo_pad = 0; ippseudo.ippseudo_p = IPPROTO_TCP; - ippseudo.ippseudo_len = ipovly->ih_len; + ippseudo.ippseudo_len = ipovly->ih_len + len + + optlen; MD5Update(&ctx, (char *)&ippseudo, sizeof(struct ippseudo)); MD5Update(&ctx, mtod(m, caddr_t) + @@ -951,29 +934,11 @@ send: case 0: /*default to PF_INET*/ #ifdef INET case AF_INET: - /* - * If we know our route, and the interface supports TCPv4 - * checksumming, only compute the pseudoheader. - */ - ro = &tp->t_inpcb->inp_route; - if (ro->ro_rt && (ro->ro_rt->rt_flags & RTF_UP)) { - ifp = ro->ro_rt->rt_ifp; - if ((ifp->if_capabilities & IFCAP_CSUM_TCPv4) && - ifp->if_bridge == NULL) { - struct ipovly *ipov; - - ipov = mtod(m, struct ipovly *); - m->m_pkthdr.csum |= M_TCPV4_CSUM_OUT; - tcpstat.tcps_outhwcsum++; - th->th_sum = in_cksum_phdr(ipov->ih_src.s_addr, - ipov->ih_dst.s_addr, - htons(sizeof(struct tcphdr) + len + - optlen + IPPROTO_TCP)); - break; - } - } - - th->th_sum = in_cksum(m, (int)(hdrlen + len)); + /* Defer checksumming until later (ip_output() or hardware) */ + m->m_pkthdr.csum |= M_TCPV4_CSUM_OUT; + if (len + optlen) + th->th_sum = in_cksum_addword(th->th_sum, + htons((u_int16_t)(len + optlen))); break; #endif /* INET */ #ifdef INET6 diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 38f4243d42d..50a1e1aaa1c 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_subr.c,v 1.47 2001/06/23 19:02:53 angelos Exp $ */ +/* $OpenBSD: tcp_subr.c,v 1.48 2001/06/25 01:59:29 angelos Exp $ */ /* $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $ */ /* @@ -235,13 +235,15 @@ tcp_template(tp) bzero(ipovly->ih_x1, sizeof ipovly->ih_x1); ipovly->ih_pr = IPPROTO_TCP; - ipovly->ih_len = htons(sizeof (struct tcpiphdr) - - sizeof (struct ip)); + ipovly->ih_len = htons(sizeof (struct tcphdr)); ipovly->ih_src = inp->inp_laddr; ipovly->ih_dst = inp->inp_faddr; th = (struct tcphdr *)(mtod(m, caddr_t) + sizeof(struct ip)); + th->th_sum = in_cksum_phdr(ipovly->ih_src.s_addr, + ipovly->ih_dst.s_addr, + htons(sizeof (struct tcphdr) + IPPROTO_TCP)); } break; #endif /* INET */ @@ -277,7 +279,6 @@ tcp_template(tp) th->th_off = 5; th->th_flags = 0; th->th_win = 0; - th->th_sum = 0; th->th_urp = 0; return (m); } |