Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys For controllers (eg: hme & gem) that can only perform li...
details: https://anonhg.NetBSD.org/src/rev/c590aefef65d
branches: trunk
changeset: 573864:c590aefef65d
user: heas <heas%NetBSD.org@localhost>
date: Sat Feb 12 23:25:29 2005 +0000
description:
For controllers (eg: hme & gem) that can only perform linear hardware checksums
(from an offset to the end of the packet), the pseudo-header checksum must be
calculated by software. So, provide it in the TCP/UDP header when
M_CSUM_NO_PSEUDOHDR is set in the interface's if_csum_flags_tx.
The start offset, the end of the IP header, is also provided in the high 16
bits of pkthdr.csum_data. Such that the driver need not examine the packet
at all.
XXX At the request of Jonathan Stone, note that sharing of if_csum_flags_tx &
pkthdr.csum_flags for checksum quirks should be re-evaluated.
diffstat:
sys/netinet/ip_output.c | 35 +++++++++++++++++++++++++++++++++--
sys/sys/mbuf.h | 23 +++++++++++++++++------
2 files changed, 50 insertions(+), 8 deletions(-)
diffs (93 lines):
diff -r 9abd4943b369 -r c590aefef65d sys/netinet/ip_output.c
--- a/sys/netinet/ip_output.c Sat Feb 12 23:14:03 2005 +0000
+++ b/sys/netinet/ip_output.c Sat Feb 12 23:25:29 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ip_output.c,v 1.141 2005/02/12 12:31:07 manu Exp $ */
+/* $NetBSD: ip_output.c,v 1.142 2005/02/12 23:25:29 heas 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.141 2005/02/12 12:31:07 manu Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.142 2005/02/12 23:25:29 heas Exp $");
#include "opt_pfil_hooks.h"
#include "opt_inet.h"
@@ -799,6 +799,37 @@
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 if (ifp->if_csum_flags_tx & M_CSUM_NO_PSEUDOHDR &&
+ m->m_pkthdr.csum_flags & (M_CSUM_UDPv4|M_CSUM_TCPv4)) {
+ /* add pseudo-header sum */
+ uint16_t sum;
+
+ ip = mtod(m, struct ip *);
+ hlen = ip->ip_hl << 2;
+ m->m_pkthdr.csum_data = (hlen << 16) |
+ (m->m_pkthdr.csum_data & 0xffff);
+
+ if (ip->ip_p == IPPROTO_TCP) {
+ sum = in_cksum_phdr(ip->ip_src.s_addr,
+ ip->ip_dst.s_addr,
+ htons(ntohs(ip->ip_len) - hlen +
+ IPPROTO_TCP));
+ /* offset of TCP checksum field */
+ hlen += (m->m_pkthdr.csum_data & 0xffff);
+ } else if (ip->ip_p == IPPROTO_UDP) {
+ sum = in_cksum_phdr(ip->ip_src.s_addr,
+ ip->ip_dst.s_addr,
+ htons(ntohs(ip->ip_len) - hlen +
+ IPPROTO_UDP));
+ /* offset of UDP checksum field */
+ hlen += (m->m_pkthdr.csum_data & 0xffff);
+ }
+ if ((hlen + sizeof(uint16_t)) > m->m_len) {
+ /* This happens when ip options were inserted */
+ m_copyback(m, hlen, sizeof(sum), (caddr_t)&sum);
+ } else
+ *(u_int16_t *)(mtod(m, caddr_t) + hlen) = sum;
+
}
#ifdef IPSEC
diff -r 9abd4943b369 -r c590aefef65d sys/sys/mbuf.h
--- a/sys/sys/mbuf.h Sat Feb 12 23:14:03 2005 +0000
+++ b/sys/sys/mbuf.h Sat Feb 12 23:25:29 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: mbuf.h,v 1.100 2005/01/31 23:49:36 kim Exp $ */
+/* $NetBSD: mbuf.h,v 1.101 2005/02/12 23:25:29 heas Exp $ */
/*-
* Copyright (c) 1996, 1997, 1999, 2001 The NetBSD Foundation, Inc.
@@ -171,11 +171,22 @@
#define M_CSUM_IPv4 0x00000040 /* IPv4 header */
#define M_CSUM_IPv4_BAD 0x00000080 /* IPv4 header checksum bad */
-/* Checksum-assist quirks: keep separate from jump-table bits. */
-#define M_CSUM_NO_PSEUDOHDR 0x80000000 /* Rx M_CSUM_DATA does not include
- * the UDP/TCP pseudo-hdr, and
- * is not yet 1s-complemented.
- */
+/*
+ * Checksum-assist quirks: keep separate from jump-table bits.
+ *
+ * M_CSUM_NO_PSEUDOHDR:
+ * Rx: M_CSUM_DATA does not include the UDP/TCP pseudo-hdr, and is not yet
+ * 1s-complemented.
+ * Tx: Set in ifnet.if_csum_flags_tx, indicates that the controller only
+ * does linear checksums (ie: from some offset to end of the packet),
+ * the IP module should stuff the pseudo-hdr checksum in the TCP/UDP
+ * header. The high 16 bits of M_CSUM_DATA is the start offset (ie:
+ * end of the IP header).
+ *
+ * XXX The use of pkthdr.csum_flags & ifnet.if_csum_flags_{rx,tx} for
+ * hardware checksum quirks needs further consideration.
+ */
+#define M_CSUM_NO_PSEUDOHDR 0x80000000
/*
* Max # of pages we can attach to m_ext. This is carefully chosen
Home |
Main Index |
Thread Index |
Old Index