summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAngelos D. Keromytis <angelos@cvs.openbsd.org>2001-06-25 01:59:30 +0000
committerAngelos D. Keromytis <angelos@cvs.openbsd.org>2001-06-25 01:59:30 +0000
commitad8f9ae7dbaa959c90e908ad3c5fa381772bcc5e (patch)
treed88f5ba71ebbb82d215e67ab2faf8b6a0d3904d7
parent175d546a58b674b442ad2b97998b92ecdff00136 (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.c34
-rw-r--r--sys/netinet/tcp_output.c51
-rw-r--r--sys/netinet/tcp_subr.c9
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);
}