summaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
authorAngelos D. Keromytis <angelos@cvs.openbsd.org>2001-06-23 02:27:12 +0000
committerAngelos D. Keromytis <angelos@cvs.openbsd.org>2001-06-23 02:27:12 +0000
commitc2aa68d2ac00ee99e6cd348159b9357e348772df (patch)
treef76ac23aa90872946925525300f770dcad012bfb /sys/netinet
parentb8794969a7662bd38ddaacd86161705cfdd40e16 (diff)
TCP, UDP, IPv4 input hardware checksumming processing; also IPv4
output hardware checksumming. Not tested yet, but should be done tonight. Remain to be solved: interactions with bridge, TCP/UDP output checksumming, interactions of TCP/UDP checksumming with routing changes.
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_input.c11
-rw-r--r--sys/netinet/ip_output.c39
-rw-r--r--sys/netinet/tcp_input.c11
-rw-r--r--sys/netinet/udp_usrreq.c15
4 files changed, 56 insertions, 20 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 4af835b04b9..18dce3acddc 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_input.c,v 1.76 2001/06/19 00:48:23 deraadt Exp $ */
+/* $OpenBSD: ip_input.c,v 1.77 2001/06/23 02:27:09 angelos Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/*
@@ -332,9 +332,12 @@ ipv4_input(m)
}
}
- if (in_cksum(m, hlen) != 0) {
- ipstat.ips_badsum++;
- goto bad;
+ if ((m->m_pkthdr.csum & M_IPV4_CSUM_IN_OK) == 0) {
+ if (m->m_pkthdr.csum & M_IPV4_CSUM_IN_BAD ||
+ in_cksum(m, hlen) != 0) {
+ ipstat.ips_badsum++;
+ goto bad;
+ }
}
/*
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 9a52a837e2d..c6ca2c6e493 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_output.c,v 1.104 2001/06/19 18:49:53 jasoni Exp $ */
+/* $OpenBSD: ip_output.c,v 1.105 2001/06/23 02:27:10 angelos Exp $ */
/* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */
/*
@@ -592,12 +592,29 @@ sendit:
if ((u_int16_t)ip->ip_len <= ifp->if_mtu) {
ip->ip_len = htons((u_int16_t)ip->ip_len);
ip->ip_off = htons((u_int16_t)ip->ip_off);
- ip->ip_sum = 0;
- ip->ip_sum = in_cksum(m, hlen);
+ if (ifp->if_capabilities & IFCAP_CSUM_IPv4)
+ m->m_pkthdr.csum |= M_IPV4_CSUM_OUT;
+ else {
+ ip->ip_sum = 0;
+ ip->ip_sum = in_cksum(m, hlen);
+ }
error = (*ifp->if_output)(ifp, m, sintosa(dst), ro->ro_rt);
goto done;
}
+ /* Catch routing changes. */
+ if (m->m_pkthdr.csum & M_TCPV4_CSUM_OUT &&
+ !(ifp->if_capabilities & IFCAP_CSUM_TCPv4)) {
+ /* XXX Compute TCP checksum */
+ m->m_pkthdr.csum &= ~M_TCPV4_CSUM_OUT; /* Clear */
+ }
+
+ if (m->m_pkthdr.csum & M_UDPV4_CSUM_OUT &&
+ !(ifp->if_capabilities & IFCAP_CSUM_UDPv4)) {
+ /* XXX Compute UDP checksum */
+ m->m_pkthdr.csum &= ~M_UDPV4_CSUM_OUT; /* Clear */
+ }
+
/*
* Too large for interface; fragment if possible.
* Must be able to put at least 8 bytes per fragment.
@@ -659,8 +676,12 @@ sendit:
m->m_pkthdr.len = mhlen + len;
m->m_pkthdr.rcvif = (struct ifnet *)0;
mhip->ip_off = htons((u_int16_t)mhip->ip_off);
- mhip->ip_sum = 0;
- mhip->ip_sum = in_cksum(m, mhlen);
+ if (ifp->if_capabilities & IFCAP_CSUM_IPv4)
+ m->m_pkthdr.csum |= M_IPV4_CSUM_OUT;
+ else {
+ mhip->ip_sum = 0;
+ mhip->ip_sum = in_cksum(m, mhlen);
+ }
ipstat.ips_ofragments++;
}
/*
@@ -672,8 +693,12 @@ sendit:
m->m_pkthdr.len = hlen + firstlen;
ip->ip_len = htons((u_int16_t)m->m_pkthdr.len);
ip->ip_off = htons((u_int16_t)(ip->ip_off | IP_MF));
- ip->ip_sum = 0;
- ip->ip_sum = in_cksum(m, hlen);
+ if (ifp->if_capabilities & IFCAP_CSUM_IPv4)
+ m->m_pkthdr.csum |= M_IPV4_CSUM_OUT;
+ else {
+ ip->ip_sum = 0;
+ ip->ip_sum = in_cksum(m, hlen);
+ }
sendorfree:
for (m = m0; m; m = m0) {
m0 = m->m_nextpkt;
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 750b3e58b8f..1b92826a59c 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_input.c,v 1.94 2001/06/12 10:59:53 angelos Exp $ */
+/* $OpenBSD: tcp_input.c,v 1.95 2001/06/23 02:27:10 angelos Exp $ */
/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
/*
@@ -511,9 +511,12 @@ tcp_input(m, va_alist)
bzero(ti->ti_x1, sizeof ti->ti_x1);
ti->ti_len = (u_int16_t)tlen;
HTONS(ti->ti_len);
- if ((ti->ti_sum = in_cksum(m, len)) != 0) {
- tcpstat.tcps_rcvbadsum++;
- goto drop;
+ if ((m->m_pkthdr.csum & M_TCP_CSUM_IN_OK) == 0) {
+ if (m->m_pkthdr.csum & M_TCP_CSUM_IN_BAD ||
+ (ti->ti_sum = in_cksum(m, len)) != 0) {
+ tcpstat.tcps_rcvbadsum++;
+ goto drop;
+ }
}
break;
}
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 568fd453545..0a25339bbe3 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: udp_usrreq.c,v 1.63 2001/06/19 00:48:23 deraadt Exp $ */
+/* $OpenBSD: udp_usrreq.c,v 1.64 2001/06/23 02:27:11 angelos Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
/*
@@ -300,10 +300,15 @@ udp_input(m, va_alist)
bzero(((struct ipovly *)ip)->ih_x1,
sizeof ((struct ipovly *)ip)->ih_x1);
((struct ipovly *)ip)->ih_len = uh->uh_ulen;
- if ((uh->uh_sum = in_cksum(m, len + sizeof (struct ip))) != 0) {
- udpstat.udps_badsum++;
- m_freem(m);
- return;
+
+ if ((m->m_pkthdr.csum & M_UDP_CSUM_IN_OK) == 0) {
+ if (m->m_pkthdr.csum & M_UDP_CSUM_IN_BAD ||
+ (uh->uh_sum = in_cksum(m, len +
+ sizeof (struct ip))) != 0) {
+ udpstat.udps_badsum++;
+ m_freem(m);
+ return;
+ }
}
} else
udpstat.udps_nosum++;