Implement support for IP/TCP/UDP checksum offloading provided by
network interfaces. This works by pre-computing the pseudo-header checksum and caching it, delaying the actual checksum to ip_output() if the hardware cannot perform the sum for us. In-bound checksums can either be fully-checked by hardware, or summed up for final verification by software. This method was modeled after how this is done in FreeBSD, although the code is significantly different in most places. We don't delay checksums for IPv6/TCP, but we do take advantage of the cached pseudo-header checksum. Note: hardware-assisted checksumming defaults to "off". It is enabled with ifconfig(8). See the manual page for details. Implement hardware-assisted checksumming on the DP83820 Gigabit Ethernet, 3c90xB/3c90xC 10/100 Ethernet, and Alteon Tigon/Tigon2 Gigabit Ethernet.
This commit is contained in:
parent
45bc184ebb
commit
ad9d3794b0
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: fil.c,v 1.46 2001/03/26 06:13:12 mike Exp $ */
|
||||
/* $NetBSD: fil.c,v 1.47 2001/06/02 16:17:09 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1993-2000 by Darren Reed.
|
||||
@ -9,7 +9,7 @@
|
||||
*/
|
||||
#if !defined(lint)
|
||||
#if defined(__NetBSD__)
|
||||
static const char rcsid[] = "$NetBSD: fil.c,v 1.46 2001/03/26 06:13:12 mike Exp $";
|
||||
static const char rcsid[] = "$NetBSD: fil.c,v 1.47 2001/06/02 16:17:09 thorpej Exp $";
|
||||
#else
|
||||
static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-2000 Darren Reed";
|
||||
static const char rcsid[] = "@(#)Id: fil.c,v 2.35.2.30 2000/12/17 05:49:22 darrenr Exp";
|
||||
@ -764,6 +764,21 @@ fr_check_wrapper(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir)
|
||||
struct ip *ip = mtod(*mp, struct ip *);
|
||||
int rv, hlen = ip->ip_hl << 2;
|
||||
|
||||
#if defined(M_CSUM_TCPv4)
|
||||
/*
|
||||
* If the packet is out-bound, we can't delay checksums
|
||||
* here. For in-bound, the checksum has already been
|
||||
* validated.
|
||||
*/
|
||||
if (dir == PFIL_OUT) {
|
||||
if ((*mp)->m_pkthdr.csum_flags & (M_CSUM_TCPv4|M_CSUM_UDPv4)) {
|
||||
in_delayed_cksum(*mp);
|
||||
(*mp)->m_pkthdr.csum_flags &=
|
||||
~(M_CSUM_TCPv4|M_CSUM_UDPv4);
|
||||
}
|
||||
}
|
||||
#endif /* M_CSUM_TCPv4 */
|
||||
|
||||
/*
|
||||
* We get the packet with all fields in network byte
|
||||
* order. We expect ip_len and ip_off to be in host
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: in.h,v 1.54 2001/05/27 23:46:51 itojun Exp $ */
|
||||
/* $NetBSD: in.h,v 1.55 2001/06/02 16:17:09 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1990, 1993
|
||||
@ -387,6 +387,53 @@ struct ip_mreq {
|
||||
#undef __KAME_NETINET_IN_H_INCLUDED_
|
||||
|
||||
#ifdef _KERNEL
|
||||
/*
|
||||
* in_cksum_phdr:
|
||||
*
|
||||
* Compute significant parts of the IPv4 checksum pseudo-header
|
||||
* for use in a delayed TCP/UDP checksum calculation.
|
||||
*
|
||||
* Args:
|
||||
*
|
||||
* src Source IP address
|
||||
* dst Destination IP address
|
||||
* lenproto htons(proto-hdr-len + proto-number)
|
||||
*/
|
||||
static __inline u_int16_t __attribute__((__unused__))
|
||||
in_cksum_phdr(u_int32_t src, u_int32_t dst, u_int32_t lenproto)
|
||||
{
|
||||
u_int32_t sum;
|
||||
|
||||
sum = lenproto +
|
||||
(u_int16_t)(src >> 16) +
|
||||
(u_int16_t)(src /*& 0xffff*/) +
|
||||
(u_int16_t)(dst >> 16) +
|
||||
(u_int16_t)(dst /*& 0xffff*/);
|
||||
|
||||
sum = (u_int16_t)(sum >> 16) + (u_int16_t)(sum /*& 0xffff*/);
|
||||
|
||||
if (sum > 0xffff)
|
||||
sum -= 0xffff;
|
||||
|
||||
return (sum);
|
||||
}
|
||||
|
||||
/*
|
||||
* in_cksum_addword:
|
||||
*
|
||||
* Add the two 16-bit network-order values, carry, and return.
|
||||
*/
|
||||
static __inline u_int16_t __attribute__((__unused__))
|
||||
in_cksum_addword(u_int16_t a, u_int16_t b)
|
||||
{
|
||||
u_int32_t sum = a + b;
|
||||
|
||||
if (sum > 0xffff)
|
||||
sum -= 0xffff;
|
||||
|
||||
return (sum);
|
||||
}
|
||||
|
||||
extern struct in_addr zeroin_addr;
|
||||
extern u_char ip_protox[];
|
||||
|
||||
@ -394,6 +441,7 @@ int in_broadcast __P((struct in_addr, struct ifnet *));
|
||||
int in_canforward __P((struct in_addr));
|
||||
int in_cksum __P((struct mbuf *, int));
|
||||
int in4_cksum __P((struct mbuf *, u_int8_t, int, int));
|
||||
void in_delayed_cksum __P((struct mbuf *));
|
||||
int in_localaddr __P((struct in_addr));
|
||||
void in_socktrim __P((struct sockaddr_in *));
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ip_fil.c,v 1.67 2001/05/12 19:21:57 christos Exp $ */
|
||||
/* $NetBSD: ip_fil.c,v 1.68 2001/06/02 16:17:09 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1993-2000 by Darren Reed.
|
||||
@ -9,7 +9,7 @@
|
||||
*/
|
||||
#if !defined(lint)
|
||||
#if defined(__NetBSD__)
|
||||
static const char rcsid[] = "$NetBSD: ip_fil.c,v 1.67 2001/05/12 19:21:57 christos Exp $";
|
||||
static const char rcsid[] = "$NetBSD: ip_fil.c,v 1.68 2001/06/02 16:17:09 thorpej Exp $";
|
||||
#else
|
||||
static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed";
|
||||
static const char rcsid[] = "@(#)Id: ip_fil.c,v 2.42.2.17 2000/10/19 15:39:42 darrenr Exp";
|
||||
@ -1384,6 +1384,13 @@ frdest_t *fdp;
|
||||
struct route iproute;
|
||||
frentry_t *fr;
|
||||
|
||||
#if defined(__NetBSD__) && defined(M_CSUM_IPv4)
|
||||
/*
|
||||
* Clear any in-bound checksum flags for this packet.
|
||||
*/
|
||||
m0->m_pkthdr.csum_flags = 0;
|
||||
#endif /* __NetBSD__ && M_CSUM_IPv4 */
|
||||
|
||||
hlen = fin->fin_hlen;
|
||||
ip = mtod(m0, struct ip *);
|
||||
|
||||
@ -1491,8 +1498,15 @@ frdest_t *fdp;
|
||||
# endif
|
||||
ip->ip_len = htons(ip->ip_len);
|
||||
ip->ip_off = htons(ip->ip_off);
|
||||
# if defined(__NetBSD__) && defined(M_CSUM_IPv4)
|
||||
if (ifp->if_csum_flags & M_CSUM_IPv4)
|
||||
m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
|
||||
else if (ip->ip_sum == 0)
|
||||
ip->ip_sum = in_cksum(m, hlen);
|
||||
# else
|
||||
if (!ip->ip_sum)
|
||||
ip->ip_sum = in_cksum(m, hlen);
|
||||
# endif /* __NetBSD__ && M_CSUM_IPv4 */
|
||||
# if BSD >= 199306
|
||||
error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst,
|
||||
ro->ro_rt);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ip_flow.c,v 1.17 2001/04/13 23:30:22 thorpej Exp $ */
|
||||
/* $NetBSD: ip_flow.c,v 1.18 2001/06/02 16:17:09 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
@ -179,10 +179,24 @@ ipflow_fastforward(
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Veryify the IP header checksum.
|
||||
* Verify the IP header checksum.
|
||||
*/
|
||||
if (in_cksum(m, sizeof(struct ip)) != 0)
|
||||
return 0;
|
||||
switch (m->m_pkthdr.csum_flags &
|
||||
((m->m_pkthdr.rcvif->if_csum_flags & M_CSUM_IPv4) |
|
||||
M_CSUM_IPv4_BAD)) {
|
||||
case M_CSUM_IPv4|M_CSUM_IPv4_BAD:
|
||||
return (0);
|
||||
|
||||
case M_CSUM_IPv4:
|
||||
/* Checksum was okay. */
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Must compute it ourselves. */
|
||||
if (in_cksum(m, sizeof(struct ip)) != 0)
|
||||
return (0);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Route and interface still up?
|
||||
@ -198,6 +212,11 @@ ipflow_fastforward(
|
||||
if (m->m_pkthdr.len > rt->rt_ifp->if_mtu || ip->ip_ttl <= IPTTLDEC)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Clear any in-bound checksum flags for this packet.
|
||||
*/
|
||||
m->m_pkthdr.csum_flags = 0;
|
||||
|
||||
/*
|
||||
* Everything checks out and so we can forward this packet.
|
||||
* Modify the TTL and incrementally change the checksum.
|
||||
@ -205,6 +224,9 @@ ipflow_fastforward(
|
||||
* This method of adding the checksum works on either endian CPU.
|
||||
* If htons() is inlined, all the arithmetic is folded; otherwise
|
||||
* the htons()s are combined by CSE due to the __const__ attribute.
|
||||
*
|
||||
* Don't bother using HW checksumming here -- the incremental
|
||||
* update is pretty fast.
|
||||
*/
|
||||
ip->ip_ttl -= IPTTLDEC;
|
||||
if (ip->ip_sum >= (u_int16_t) ~htons(IPTTLDEC << 8))
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ip_input.c,v 1.134 2001/05/21 03:31:36 lukem Exp $ */
|
||||
/* $NetBSD: ip_input.c,v 1.135 2001/06/02 16:17:09 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -105,6 +105,7 @@
|
||||
#include "opt_pfil_hooks.h"
|
||||
#include "opt_ipsec.h"
|
||||
#include "opt_mrouting.h"
|
||||
#include "opt_inet_csum.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -270,6 +271,24 @@ do { \
|
||||
|
||||
struct pool ipqent_pool;
|
||||
|
||||
#ifdef INET_CSUM_COUNTERS
|
||||
#include <sys/device.h>
|
||||
|
||||
struct evcnt ip_hwcsum_bad = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
|
||||
NULL, "inet", "hwcsum bad");
|
||||
struct evcnt ip_hwcsum_ok = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
|
||||
NULL, "inet", "hwcsum ok");
|
||||
struct evcnt ip_swcsum = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
|
||||
NULL, "inet", "swcsum");
|
||||
|
||||
#define INET_CSUM_COUNTER_INCR(ev) (ev)->ev_count++
|
||||
|
||||
#else
|
||||
|
||||
#define INET_CSUM_COUNTER_INCR(ev) /* nothing */
|
||||
|
||||
#endif /* INET_CSUM_COUNTERS */
|
||||
|
||||
/*
|
||||
* We need to save the IP options in case a protocol wants to respond
|
||||
* to an incoming packet over the same route if the packet got here
|
||||
@ -332,6 +351,12 @@ ip_init()
|
||||
printf("ip_init: WARNING: unable to register pfil hook, "
|
||||
"error %d\n", i);
|
||||
#endif /* PFIL_HOOKS */
|
||||
|
||||
#ifdef INET_CSUM_COUNTERS
|
||||
evcnt_attach_static(&ip_hwcsum_bad);
|
||||
evcnt_attach_static(&ip_hwcsum_ok);
|
||||
evcnt_attach_static(&ip_swcsum);
|
||||
#endif /* INET_CSUM_COUNTERS */
|
||||
}
|
||||
|
||||
struct sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET };
|
||||
@ -433,9 +458,24 @@ ip_input(struct mbuf *m)
|
||||
}
|
||||
}
|
||||
|
||||
if (in_cksum(m, hlen) != 0) {
|
||||
ipstat.ips_badsum++;
|
||||
goto bad;
|
||||
switch (m->m_pkthdr.csum_flags &
|
||||
((m->m_pkthdr.rcvif->if_csum_flags & M_CSUM_IPv4) |
|
||||
M_CSUM_IPv4_BAD)) {
|
||||
case M_CSUM_IPv4|M_CSUM_IPv4_BAD:
|
||||
INET_CSUM_COUNTER_INCR(&ip_hwcsum_bad);
|
||||
goto badcsum;
|
||||
|
||||
case M_CSUM_IPv4:
|
||||
/* Checksum was okay. */
|
||||
INET_CSUM_COUNTER_INCR(&ip_hwcsum_ok);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Must compute it ourselves. */
|
||||
INET_CSUM_COUNTER_INCR(&ip_swcsum);
|
||||
if (in_cksum(m, hlen) != 0)
|
||||
goto bad;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Retrieve the packet length. */
|
||||
@ -754,6 +794,11 @@ found:
|
||||
}
|
||||
bad:
|
||||
m_freem(m);
|
||||
return;
|
||||
|
||||
badcsum:
|
||||
ipstat.ips_badsum++;
|
||||
m_freem(m);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1434,6 +1479,11 @@ ip_forward(m, srcrt)
|
||||
struct ifnet dummyifp;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Clear any in-bound checksum flags for this packet.
|
||||
*/
|
||||
m->m_pkthdr.csum_flags = 0;
|
||||
|
||||
dest = 0;
|
||||
#ifdef DIAGNOSTIC
|
||||
if (ipprintfs)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ip_mroute.c,v 1.54 2001/05/08 10:07:15 itojun Exp $ */
|
||||
/* $NetBSD: ip_mroute.c,v 1.55 2001/06/02 16:17:10 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* IP multicast forwarding procedures
|
||||
@ -997,6 +997,11 @@ ip_mforward(m, ifp)
|
||||
vifi_t vifi;
|
||||
#endif /* RSVP_ISI */
|
||||
|
||||
/*
|
||||
* Clear any in-bound checksum flags for this packet.
|
||||
*/
|
||||
m->m_pkthdr.csum_flags = 0;
|
||||
|
||||
if (mrtdebug & DEBUG_FORWARD)
|
||||
log(LOG_DEBUG, "ip_mforward: src %x, dst %x, ifp %p\n",
|
||||
ntohl(ip->ip_src.s_addr), ntohl(ip->ip_dst.s_addr), ifp);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ip_output.c,v 1.85 2001/05/26 21:27:09 ragge Exp $ */
|
||||
/* $NetBSD: ip_output.c,v 1.86 2001/06/02 16:17:10 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -172,7 +172,7 @@ ip_output(m0, va_alist)
|
||||
struct in_ifaddr *ia;
|
||||
struct mbuf *opt;
|
||||
struct route *ro;
|
||||
int flags;
|
||||
int flags, sw_csum;
|
||||
int *mtu_p;
|
||||
int mtu;
|
||||
struct ip_moptions *imo;
|
||||
@ -213,7 +213,7 @@ ip_output(m0, va_alist)
|
||||
*/
|
||||
if ((flags & (IP_FORWARDING|IP_RAWOUTPUT)) == 0) {
|
||||
ip->ip_v = IPVERSION;
|
||||
ip->ip_off &= IP_DF;
|
||||
ip->ip_off = 0;
|
||||
ip->ip_id = htons(ip_id++);
|
||||
ip->ip_hl = hlen >> 2;
|
||||
ipstat.ips_localout++;
|
||||
@ -484,6 +484,20 @@ sendit:
|
||||
state.ro = ro;
|
||||
state.dst = (struct sockaddr *)dst;
|
||||
|
||||
/*
|
||||
* We can't defer the checksum of payload data if
|
||||
* we're about to encrypt/authenticate it.
|
||||
*
|
||||
* XXX When we support crypto offloading functions of
|
||||
* XXX network interfaces, we need to reconsider this,
|
||||
* XXX since it's likely that they'll support checksumming,
|
||||
* XXX as well.
|
||||
*/
|
||||
if (m->m_pkthdr.csum_flags & (M_CSUM_TCPv4|M_CSUM_UDPv4)) {
|
||||
in_delayed_cksum(m);
|
||||
m->m_pkthdr.csum_flags &= ~(M_CSUM_TCPv4|M_CSUM_UDPv4);
|
||||
}
|
||||
|
||||
error = ipsec4_output(&state, sp, flags);
|
||||
|
||||
m = state.m;
|
||||
@ -571,8 +585,30 @@ skip_ipsec:
|
||||
if (ia)
|
||||
ia->ia_ifa.ifa_data.ifad_outbytes += ip_len;
|
||||
#endif
|
||||
/*
|
||||
* Always initialize the sum to 0! Some HW assisted
|
||||
* checksumming requires this.
|
||||
*/
|
||||
ip->ip_sum = 0;
|
||||
ip->ip_sum = in_cksum(m, hlen);
|
||||
m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
|
||||
|
||||
sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_csum_flags;
|
||||
|
||||
/*
|
||||
* Perform any checksums that the hardware can't do
|
||||
* for us.
|
||||
*
|
||||
* XXX Does any hardware require the {th,uh}_sum
|
||||
* XXX fields to be 0?
|
||||
*/
|
||||
if (sw_csum & M_CSUM_IPv4)
|
||||
ip->ip_sum = in_cksum(m, hlen);
|
||||
if (sw_csum & (M_CSUM_TCPv4|M_CSUM_UDPv4)) {
|
||||
in_delayed_cksum(m);
|
||||
sw_csum &= ~(M_CSUM_TCPv4|M_CSUM_UDPv4);
|
||||
}
|
||||
m->m_pkthdr.csum_flags &= ifp->if_csum_flags;
|
||||
|
||||
#ifdef IPSEC
|
||||
/* clean ipsec history once it goes out of the node */
|
||||
ipsec_delaux(m);
|
||||
@ -581,6 +617,17 @@ skip_ipsec:
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* We can't use HW checksumming if we're about to
|
||||
* to fragment the packet.
|
||||
*
|
||||
* XXX Some hardware can do this.
|
||||
*/
|
||||
if (m->m_pkthdr.csum_flags & (M_CSUM_TCPv4|M_CSUM_UDPv4)) {
|
||||
in_delayed_cksum(m);
|
||||
m->m_pkthdr.csum_flags &= ~(M_CSUM_TCPv4|M_CSUM_UDPv4);
|
||||
}
|
||||
|
||||
/*
|
||||
* Too large for interface; fragment if possible.
|
||||
* Must be able to put at least 8 bytes per fragment.
|
||||
@ -727,6 +774,32 @@ bad:
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a delayed payload checksum calculation.
|
||||
*/
|
||||
void
|
||||
in_delayed_cksum(struct mbuf *m)
|
||||
{
|
||||
struct ip *ip;
|
||||
u_int16_t csum, offset;
|
||||
|
||||
ip = mtod(m, struct ip *);
|
||||
offset = ip->ip_hl << 2;
|
||||
csum = in4_cksum(m, 0, offset, ntohs(ip->ip_len) - offset);
|
||||
if (csum == 0 && (m->m_pkthdr.csum_flags & M_CSUM_UDPv4) != 0)
|
||||
csum = 0xffff;
|
||||
|
||||
offset += m->m_pkthdr.csum_data; /* checksum offset */
|
||||
|
||||
if ((offset + sizeof(u_int16_t)) > m->m_len) {
|
||||
/* XXX This should basically never happen. */
|
||||
printf("in_delayed_cksum: pullup len %d off %d proto %d\n",
|
||||
m->m_len, offset, ip->ip_p);
|
||||
m_copyback(m, offset, sizeof(csum), (caddr_t) &csum);
|
||||
} else
|
||||
*(u_int16_t *)(mtod(m, caddr_t) + offset) = csum;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine the maximum length of the options to be inserted;
|
||||
* we would far rather allocate too much space rather than too little.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tcp_input.c,v 1.124 2001/05/08 10:15:13 itojun Exp $ */
|
||||
/* $NetBSD: tcp_input.c,v 1.125 2001/06/02 16:17:10 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
%%% portions-copyright-nrl-95
|
||||
@ -126,6 +126,7 @@ didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
#include "opt_inet_csum.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -243,6 +244,22 @@ do { \
|
||||
NTOHS((th)->th_urp); \
|
||||
} while (0)
|
||||
|
||||
#ifdef TCP_CSUM_COUNTERS
|
||||
#include <sys/device.h>
|
||||
|
||||
extern struct evcnt tcp_hwcsum_ok;
|
||||
extern struct evcnt tcp_hwcsum_bad;
|
||||
extern struct evcnt tcp_hwcsum_data;
|
||||
extern struct evcnt tcp_swcsum;
|
||||
|
||||
#define TCP_CSUM_COUNTER_INCR(ev) (ev)->ev_count++
|
||||
|
||||
#else
|
||||
|
||||
#define TCP_CSUM_COUNTER_INCR(ev) /* nothing */
|
||||
|
||||
#endif /* TCP_CSUM_COUNTERS */
|
||||
|
||||
int
|
||||
tcp_reass(tp, th, m, tlen)
|
||||
struct tcpcb *tp;
|
||||
@ -949,35 +966,52 @@ findpcb:
|
||||
switch (af) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
#ifndef PULLDOWN_TEST
|
||||
{
|
||||
struct ipovly *ipov;
|
||||
ipov = (struct ipovly *)ip;
|
||||
bzero(ipov->ih_x1, sizeof ipov->ih_x1);
|
||||
ipov->ih_len = htons(tlen + off);
|
||||
switch (m->m_pkthdr.csum_flags &
|
||||
((m->m_pkthdr.rcvif->if_csum_flags & M_CSUM_TCPv4) |
|
||||
M_CSUM_TCP_UDP_BAD | M_CSUM_DATA)) {
|
||||
case M_CSUM_TCPv4|M_CSUM_TCP_UDP_BAD:
|
||||
TCP_CSUM_COUNTER_INCR(&tcp_hwcsum_bad);
|
||||
goto badcsum;
|
||||
|
||||
if (in_cksum(m, len) != 0) {
|
||||
tcpstat.tcps_rcvbadsum++;
|
||||
goto drop;
|
||||
}
|
||||
}
|
||||
case M_CSUM_TCPv4|M_CSUM_DATA:
|
||||
TCP_CSUM_COUNTER_INCR(&tcp_hwcsum_data);
|
||||
if ((m->m_pkthdr.csum_data ^ 0xffff) != 0)
|
||||
goto badcsum;
|
||||
break;
|
||||
|
||||
case M_CSUM_TCPv4:
|
||||
/* Checksum was okay. */
|
||||
TCP_CSUM_COUNTER_INCR(&tcp_hwcsum_ok);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Must compute it ourselves. */
|
||||
TCP_CSUM_COUNTER_INCR(&tcp_swcsum);
|
||||
#ifndef PULLDOWN_TEST
|
||||
{
|
||||
struct ipovly *ipov;
|
||||
ipov = (struct ipovly *)ip;
|
||||
bzero(ipov->ih_x1, sizeof ipov->ih_x1);
|
||||
ipov->ih_len = htons(tlen + off);
|
||||
|
||||
if (in_cksum(m, len) != 0)
|
||||
goto badcsum;
|
||||
}
|
||||
#else
|
||||
if (in4_cksum(m, IPPROTO_TCP, toff, tlen + off) != 0) {
|
||||
tcpstat.tcps_rcvbadsum++;
|
||||
goto drop;
|
||||
if (in4_cksum(m, IPPROTO_TCP, toff, tlen + off) != 0)
|
||||
goto badcsum;
|
||||
#endif /* ! PULLDOWN_TEST */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
#endif /* INET4 */
|
||||
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
if (in6_cksum(m, IPPROTO_TCP, toff, tlen + off) != 0) {
|
||||
tcpstat.tcps_rcvbadsum++;
|
||||
goto drop;
|
||||
}
|
||||
if (in6_cksum(m, IPPROTO_TCP, toff, tlen + off) != 0)
|
||||
goto badcsum;
|
||||
break;
|
||||
#endif
|
||||
#endif /* INET6 */
|
||||
}
|
||||
|
||||
TCP_FIELDS_TO_HOST(th);
|
||||
@ -2204,6 +2238,8 @@ dropwithreset:
|
||||
m_freem(tcp_saveti);
|
||||
return;
|
||||
|
||||
badcsum:
|
||||
tcpstat.tcps_rcvbadsum++;
|
||||
drop:
|
||||
/*
|
||||
* Drop space held by incoming segment and return.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tcp_output.c,v 1.65 2001/04/03 06:14:31 itojun Exp $ */
|
||||
/* $NetBSD: tcp_output.c,v 1.66 2001/06/02 16:17:10 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
%%% portions-copyright-nrl-95
|
||||
@ -857,32 +857,47 @@ send:
|
||||
tp->snd_up = tp->snd_una; /* drag it along */
|
||||
|
||||
/*
|
||||
* Put TCP length in extended header, and then
|
||||
* checksum extended header and data.
|
||||
* Set ourselves up to be checksummed just before the packet
|
||||
* hits the wire.
|
||||
*/
|
||||
switch (af) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
{
|
||||
struct ipovly *ipov = (struct ipovly *)ip;
|
||||
if (len + optlen)
|
||||
ipov->ih_len = htons((u_int16_t)(sizeof(struct tcphdr) +
|
||||
optlen + len));
|
||||
bzero(ipov->ih_x1, sizeof(ipov->ih_x1));
|
||||
th->th_sum = 0;
|
||||
th->th_sum = in_cksum(m, (int)(hdrlen + len));
|
||||
m->m_pkthdr.csum_flags = M_CSUM_TCPv4;
|
||||
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
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
/*
|
||||
* XXX Actually delaying the checksum is Hard
|
||||
* XXX (well, maybe not for Itojun, but it is
|
||||
* XXX for me), but we can still take advantage
|
||||
* XXX of the cached pseudo-header checksum.
|
||||
*/
|
||||
/* equals to hdrlen + len */
|
||||
m->m_pkthdr.len = sizeof(struct ip6_hdr)
|
||||
+ sizeof(struct tcphdr) + optlen + len;
|
||||
th->th_sum = 0;
|
||||
th->th_sum = in6_cksum(m, IPPROTO_TCP,
|
||||
sizeof(struct ip6_hdr),
|
||||
sizeof(struct tcphdr) + optlen + len);
|
||||
#ifdef notyet
|
||||
m->m_pkthdr.csum_flags = M_CSUM_TCPv6;
|
||||
m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum);
|
||||
#endif
|
||||
if (len + optlen) {
|
||||
/* Fixup the pseudo-header checksum. */
|
||||
/* XXXJRT: Not IPv6 Jumbogram safe. */
|
||||
th->th_sum = in_cksum_addword(th->th_sum,
|
||||
htons((u_int16_t) (len + optlen)));
|
||||
}
|
||||
#ifndef notyet
|
||||
th->th_sum = in6_cksum(m, 0, sizeof(struct ip6_hdr),
|
||||
sizeof(struct tcphdr) + optlen + len);
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tcp_subr.c,v 1.110 2001/05/24 07:22:27 itojun Exp $ */
|
||||
/* $NetBSD: tcp_subr.c,v 1.111 2001/06/02 16:17:10 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -104,6 +104,7 @@
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
#include "opt_tcp_compat_42.h"
|
||||
#include "opt_inet_csum.h"
|
||||
#include "rnd.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -211,6 +212,19 @@ void tcp6_mtudisc __P((struct in6pcb *, int));
|
||||
|
||||
struct pool tcpcb_pool;
|
||||
|
||||
#ifdef TCP_CSUM_COUNTERS
|
||||
#include <sys/device.h>
|
||||
|
||||
struct evcnt tcp_hwcsum_bad = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
|
||||
NULL, "tcp", "hwcsum bad");
|
||||
struct evcnt tcp_hwcsum_ok = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
|
||||
NULL, "tcp", "hwcsum ok");
|
||||
struct evcnt tcp_hwcsum_data = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
|
||||
NULL, "tcp", "hwcsum data");
|
||||
struct evcnt tcp_swcsum = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
|
||||
NULL, "tcp", "swcsum");
|
||||
#endif /* TCP_CSUM_COUNTERS */
|
||||
|
||||
/*
|
||||
* Tcp initialization
|
||||
*/
|
||||
@ -246,6 +260,13 @@ tcp_init()
|
||||
|
||||
/* Initialize the compressed state engine. */
|
||||
syn_cache_init();
|
||||
|
||||
#ifdef TCP_CSUM_COUNTERS
|
||||
evcnt_attach_static(&tcp_hwcsum_bad);
|
||||
evcnt_attach_static(&tcp_hwcsum_ok);
|
||||
evcnt_attach_static(&tcp_hwcsum_data);
|
||||
evcnt_attach_static(&tcp_swcsum);
|
||||
#endif /* TCP_CSUM_COUNTERS */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -316,7 +337,11 @@ tcp_template(tp)
|
||||
return NULL;
|
||||
m->m_pkthdr.len = m->m_len = hlen + sizeof(struct tcphdr);
|
||||
}
|
||||
|
||||
bzero(mtod(m, caddr_t), m->m_len);
|
||||
|
||||
n = (struct tcphdr *)(mtod(m, caddr_t) + hlen);
|
||||
|
||||
switch (tp->t_family) {
|
||||
case AF_INET:
|
||||
{
|
||||
@ -338,6 +363,16 @@ tcp_template(tp)
|
||||
sizeof(ipov->ih_dst));
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Compute the pseudo-header portion of the checksum
|
||||
* now. We incrementally add in the TCP option and
|
||||
* payload lengths later, and then compute the TCP
|
||||
* checksum right before the packet is sent off onto
|
||||
* the wire.
|
||||
*/
|
||||
n->th_sum = in_cksum_phdr(ipov->ih_src.s_addr,
|
||||
ipov->ih_dst.s_addr,
|
||||
htons(sizeof(struct tcphdr) + IPPROTO_TCP));
|
||||
break;
|
||||
}
|
||||
#ifdef INET6
|
||||
@ -358,11 +393,21 @@ tcp_template(tp)
|
||||
}
|
||||
ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
|
||||
ip6->ip6_vfc |= IPV6_VERSION;
|
||||
|
||||
/*
|
||||
* Compute the pseudo-header portion of the checksum
|
||||
* now. We incrementally add in the TCP option and
|
||||
* payload lengths later, and then compute the TCP
|
||||
* checksum right before the packet is sent off onto
|
||||
* the wire.
|
||||
*/
|
||||
n->th_sum = in6_cksum_phdr(&in6p->in6p_laddr,
|
||||
&in6p->in6p_faddr, htonl(sizeof(struct tcphdr)),
|
||||
htonl(IPPROTO_TCP));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
n = (struct tcphdr *)(mtod(m, caddr_t) + hlen);
|
||||
if (inp) {
|
||||
n->th_sport = inp->inp_lport;
|
||||
n->th_dport = inp->inp_fport;
|
||||
@ -379,7 +424,6 @@ tcp_template(tp)
|
||||
n->th_off = 5;
|
||||
n->th_flags = 0;
|
||||
n->th_win = 0;
|
||||
n->th_sum = 0;
|
||||
n->th_urp = 0;
|
||||
return (m);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udp_usrreq.c,v 1.77 2001/05/31 19:56:13 soda Exp $ */
|
||||
/* $NetBSD: udp_usrreq.c,v 1.78 2001/06/02 16:17:11 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -66,6 +66,7 @@
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
#include "opt_inet_csum.h"
|
||||
#include "opt_ipkdb.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -160,6 +161,26 @@ static void udp_notify __P((struct inpcb *, int));
|
||||
#endif
|
||||
int udbhashsize = UDBHASHSIZE;
|
||||
|
||||
#ifdef UDP_CSUM_COUNTERS
|
||||
#include <sys/device.h>
|
||||
|
||||
struct evcnt udp_hwcsum_bad = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
|
||||
NULL, "udp", "hwcsum bad");
|
||||
struct evcnt udp_hwcsum_ok = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
|
||||
NULL, "udp", "hwcsum ok");
|
||||
struct evcnt udp_hwcsum_data = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
|
||||
NULL, "udp", "hwcsum data");
|
||||
struct evcnt udp_swcsum = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
|
||||
NULL, "udp", "swcsum");
|
||||
|
||||
#define UDP_CSUM_COUNTER_INCR(ev) (ev)->ev_count++
|
||||
|
||||
#else
|
||||
|
||||
#define UDP_CSUM_COUNTER_INCR(ev) /* nothing */
|
||||
|
||||
#endif /* UDP_CSUM_COUNTERS */
|
||||
|
||||
void
|
||||
udp_init()
|
||||
{
|
||||
@ -167,6 +188,13 @@ udp_init()
|
||||
#ifdef INET
|
||||
in_pcbinit(&udbtable, udbhashsize, udbhashsize);
|
||||
#endif
|
||||
|
||||
#ifdef UDP_CSUM_COUNTERS
|
||||
evcnt_attach_static(&udp_hwcsum_bad);
|
||||
evcnt_attach_static(&udp_hwcsum_ok);
|
||||
evcnt_attach_static(&udp_hwcsum_data);
|
||||
evcnt_attach_static(&udp_swcsum);
|
||||
#endif /* UDP_CSUM_COUNTERS */
|
||||
}
|
||||
|
||||
#ifndef UDP6
|
||||
@ -255,10 +283,30 @@ udp_input(m, va_alist)
|
||||
* Checksum extended UDP header and data.
|
||||
*/
|
||||
if (uh->uh_sum) {
|
||||
if (in4_cksum(m, IPPROTO_UDP, iphlen, len) != 0) {
|
||||
udpstat.udps_badsum++;
|
||||
m_freem(m);
|
||||
return;
|
||||
switch (m->m_pkthdr.csum_flags &
|
||||
((m->m_pkthdr.rcvif->if_csum_flags & M_CSUM_UDPv4) |
|
||||
M_CSUM_TCP_UDP_BAD | M_CSUM_DATA)) {
|
||||
case M_CSUM_UDPv4|M_CSUM_TCP_UDP_BAD:
|
||||
UDP_CSUM_COUNTER_INCR(&udp_hwcsum_bad);
|
||||
goto badcsum;
|
||||
|
||||
case M_CSUM_UDPv4|M_CSUM_DATA:
|
||||
UDP_CSUM_COUNTER_INCR(&udp_hwcsum_data);
|
||||
if ((m->m_pkthdr.csum_data ^ 0xffff) != 0)
|
||||
goto badcsum;
|
||||
break;
|
||||
|
||||
case M_CSUM_UDPv4:
|
||||
/* Checksum was okay. */
|
||||
UDP_CSUM_COUNTER_INCR(&udp_hwcsum_ok);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Need to compute it ourselves. */
|
||||
UDP_CSUM_COUNTER_INCR(&udp_swcsum);
|
||||
if (in4_cksum(m, IPPROTO_UDP, iphlen, len) != 0)
|
||||
goto badcsum;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -322,6 +370,11 @@ udp_input(m, va_alist)
|
||||
bad:
|
||||
if (m)
|
||||
m_freem(m);
|
||||
return;
|
||||
|
||||
badcsum:
|
||||
m_freem(m);
|
||||
udpstat.udps_badsum++;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -946,13 +999,33 @@ udp_input(m, va_alist)
|
||||
* Checksum extended UDP header and data.
|
||||
*/
|
||||
if (uh->uh_sum) {
|
||||
bzero(((struct ipovly *)ip)->ih_x1,
|
||||
sizeof ((struct ipovly *)ip)->ih_x1);
|
||||
((struct ipovly *)ip)->ih_len = uh->uh_ulen;
|
||||
if (in_cksum(m, len + sizeof (struct ip)) != 0) {
|
||||
udpstat.udps_badsum++;
|
||||
m_freem(m);
|
||||
return;
|
||||
switch (m->m_pkthdr.csum_flags &
|
||||
((m->m_pkthdr.rcvif->if_csum_flags & M_CSUM_UDPv4) |
|
||||
M_CSUM_TCP_UDP_BAD | M_CSUM_DATA)) {
|
||||
case M_CSUM_UDPv4|M_CSUM_TCP_UDP_BAD:
|
||||
UDP_CSUM_COUNTER_INCR(&udp_hwcsum_bad);
|
||||
goto badcsum;
|
||||
|
||||
case M_CSUM_UDPv4|M_CSUM_DATA:
|
||||
UDP_CSUM_COUNTER_INCR(&udp_hwcsum_data);
|
||||
if ((m->m_pkthdr.csum_data ^ 0xffff) != 0)
|
||||
goto badcsum;
|
||||
break;
|
||||
|
||||
case M_CSUM_UDPv4:
|
||||
/* Checksum was okay. */
|
||||
UDP_CSUM_COUNTER_INCR(&udp_hwcsum_ok);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Need to compute it ourselves. */
|
||||
UDP_CSUM_COUNTER_INCR(&udp_swcsum);
|
||||
bzero(((struct ipovly *)ip)->ih_x1,
|
||||
sizeof ((struct ipovly *)ip)->ih_x1);
|
||||
((struct ipovly *)ip)->ih_len = uh->uh_ulen;
|
||||
if (in_cksum(m, len + sizeof (struct ip)) != 0)
|
||||
goto badcsum;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1140,6 +1213,11 @@ bad:
|
||||
m_freem(m);
|
||||
if (opts)
|
||||
m_freem(opts);
|
||||
return;
|
||||
|
||||
badcsum:
|
||||
udpstat.udps_badsum++;
|
||||
m_freem(m);
|
||||
}
|
||||
#endif /*UDP6*/
|
||||
|
||||
@ -1237,23 +1315,28 @@ udp_output(m, va_alist)
|
||||
* and addresses and length put into network format.
|
||||
*/
|
||||
ui = mtod(m, struct udpiphdr *);
|
||||
bzero(ui->ui_x1, sizeof ui->ui_x1);
|
||||
ui->ui_pr = IPPROTO_UDP;
|
||||
ui->ui_len = htons((u_int16_t)len + sizeof (struct udphdr));
|
||||
ui->ui_src = inp->inp_laddr;
|
||||
ui->ui_dst = inp->inp_faddr;
|
||||
ui->ui_sport = inp->inp_lport;
|
||||
ui->ui_dport = inp->inp_fport;
|
||||
ui->ui_ulen = ui->ui_len;
|
||||
ui->ui_ulen = htons((u_int16_t)len + sizeof(struct udphdr));
|
||||
|
||||
/*
|
||||
* Stuff checksum and output datagram.
|
||||
* Set up checksum and output datagram.
|
||||
*/
|
||||
ui->ui_sum = 0;
|
||||
if (udpcksum) {
|
||||
if ((ui->ui_sum = in_cksum(m, sizeof (struct udpiphdr) + len)) == 0)
|
||||
ui->ui_sum = 0xffff;
|
||||
}
|
||||
/*
|
||||
* XXX Cache pseudo-header checksum part for
|
||||
* XXX "connected" UDP sockets.
|
||||
*/
|
||||
ui->ui_sum = in_cksum_phdr(ui->ui_src.s_addr,
|
||||
ui->ui_dst.s_addr, htons((u_int16_t)len +
|
||||
sizeof(struct udphdr) + IPPROTO_UDP));
|
||||
m->m_pkthdr.csum_flags = M_CSUM_UDPv4;
|
||||
m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum);
|
||||
} else
|
||||
ui->ui_sum = 0;
|
||||
((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len;
|
||||
((struct ip *)ui)->ip_ttl = inp->inp_ip.ip_ttl; /* XXX */
|
||||
((struct ip *)ui)->ip_tos = inp->inp_ip.ip_tos; /* XXX */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: in6.h,v 1.25 2001/03/30 05:53:52 itojun Exp $ */
|
||||
/* $NetBSD: in6.h,v 1.26 2001/06/02 16:17:11 thorpej Exp $ */
|
||||
/* $KAME: in6.h,v 1.83 2001/03/29 02:55:07 jinmei Exp $ */
|
||||
|
||||
/*
|
||||
@ -577,6 +577,55 @@ struct in6_pktinfo {
|
||||
#ifdef _KERNEL
|
||||
struct cmsghdr;
|
||||
|
||||
/*
|
||||
* in6_cksum_phdr:
|
||||
*
|
||||
* Compute significant parts of the IPv6 checksum pseudo-header
|
||||
* for use in a delayed TCP/UDP checksum calculation.
|
||||
*
|
||||
* Args:
|
||||
*
|
||||
* src Source IPv6 address
|
||||
* dst Destination IPv6 address
|
||||
* len htonl(proto-hdr-len)
|
||||
* nxt htonl(next-proto-number)
|
||||
*
|
||||
* NOTE: We expect the src and dst addresses to be 16-bit
|
||||
* aligned!
|
||||
*/
|
||||
static __inline u_int16_t __attribute__((__unused__))
|
||||
in6_cksum_phdr(const struct in6_addr *src, const struct in6_addr *dst,
|
||||
u_int32_t len, u_int32_t nxt)
|
||||
{
|
||||
u_int32_t sum = 0;
|
||||
const u_int16_t *w;
|
||||
|
||||
w = (u_int16_t *) src;
|
||||
sum += w[0];
|
||||
if (!IN6_IS_SCOPE_LINKLOCAL(src))
|
||||
sum += w[1];
|
||||
sum += w[2]; sum += w[3]; sum += w[4]; sum += w[5];
|
||||
sum += w[6]; sum += w[7];
|
||||
|
||||
w = (u_int16_t *) dst;
|
||||
sum += w[0];
|
||||
if (!IN6_IS_SCOPE_LINKLOCAL(dst))
|
||||
sum += w[1];
|
||||
sum += w[2]; sum += w[3]; sum += w[4]; sum += w[5];
|
||||
sum += w[6]; sum += w[7];
|
||||
|
||||
sum += (u_int16_t)(len >> 16) + (u_int16_t)(len /*& 0xffff*/);
|
||||
|
||||
sum += (u_int16_t)(nxt >> 16) + (u_int16_t)(nxt /*& 0xffff*/);
|
||||
|
||||
sum = (u_int16_t)(sum >> 16) + (u_int16_t)(sum /*& 0xffff*/);
|
||||
|
||||
if (sum > 0xffff)
|
||||
sum -= 0xffff;
|
||||
|
||||
return (sum);
|
||||
}
|
||||
|
||||
int in6_cksum __P((struct mbuf *, u_int8_t, u_int32_t, u_int32_t));
|
||||
int in6_localaddr __P((struct in6_addr *));
|
||||
int in6_addrscope __P((struct in6_addr *));
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: mbuf.h,v 1.57 2001/04/30 01:13:21 lukem Exp $ */
|
||||
/* $NetBSD: mbuf.h,v 1.58 2001/06/02 16:17:11 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996, 1997, 1999 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1996, 1997, 1999, 2001 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
@ -111,13 +111,41 @@ struct m_hdr {
|
||||
short mh_flags; /* flags; see below */
|
||||
};
|
||||
|
||||
/* record/packet header in first mbuf of chain; valid if M_PKTHDR set */
|
||||
/*
|
||||
* record/packet header in first mbuf of chain; valid if M_PKTHDR set
|
||||
*
|
||||
* A note about csum_data: For the out-bound direction, this indicates the
|
||||
* offset after the L3 header where the final L4 checksum value is to be
|
||||
* stored. For the in-bound direction, it is only valid if the M_CSUM_DATA
|
||||
* flag is set. In this case, an L4 checksum has been calculated by
|
||||
* hardware, but it is up to software to perform final verification.
|
||||
*
|
||||
* Note for in-bound TCP/UDP checksums, we expect the csum_data to NOT
|
||||
* be bit-wise inverted (the final step in the calculation of an IP
|
||||
* checksum) -- this is so we can accumulate the checksum for fragmented
|
||||
* packets during reassembly.
|
||||
*/
|
||||
struct pkthdr {
|
||||
struct ifnet *rcvif; /* rcv interface */
|
||||
int len; /* total packet length */
|
||||
int csum_flags; /* checksum flags */
|
||||
u_int32_t csum_data; /* checksum data */
|
||||
struct mbuf *aux; /* extra data buffer; ipsec/others */
|
||||
};
|
||||
|
||||
/*
|
||||
* Note: These bits are carefully arrange so that the compiler can have
|
||||
* a prayer of generating a jump table.
|
||||
*/
|
||||
#define M_CSUM_TCPv4 0x00000001 /* TCP header/payload */
|
||||
#define M_CSUM_UDPv4 0x00000002 /* UDP header/payload */
|
||||
#define M_CSUM_TCP_UDP_BAD 0x00000004 /* TCP/UDP checksum bad */
|
||||
#define M_CSUM_DATA 0x00000008 /* consult csum_data */
|
||||
#define M_CSUM_TCPv6 0x00000010 /* IPv6 TCP header/payload */
|
||||
#define M_CSUM_UDPv6 0x00000020 /* IPv6 UDP header/payload */
|
||||
#define M_CSUM_IPv4 0x00000040 /* IPv4 header */
|
||||
#define M_CSUM_IPv4_BAD 0x00000080 /* IPv4 header checksum bad */
|
||||
|
||||
/* description of external storage mapped into mbuf, valid if M_EXT set */
|
||||
struct m_ext {
|
||||
caddr_t ext_buf; /* start of buffer */
|
||||
@ -246,6 +274,8 @@ struct mbuf {
|
||||
(m)->m_nextpkt = (struct mbuf *)NULL; \
|
||||
(m)->m_data = (m)->m_pktdat; \
|
||||
(m)->m_flags = M_PKTHDR; \
|
||||
(m)->m_pkthdr.csum_flags = 0; \
|
||||
(m)->m_pkthdr.csum_data = 0; \
|
||||
(m)->m_pkthdr.aux = (struct mbuf *)NULL; \
|
||||
} else \
|
||||
(m) = m_retryhdr((how), (type)); \
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sockio.h,v 1.17 2001/02/20 15:35:19 itojun Exp $ */
|
||||
/* $NetBSD: sockio.h,v 1.18 2001/06/02 16:17:11 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1990, 1993, 1994
|
||||
@ -121,5 +121,7 @@
|
||||
#define SIOCIFGCLONERS _IOWR('i', 120, struct if_clonereq) /* get cloners */
|
||||
|
||||
#define SIOCGIFDLT _IOWR('i', 119, struct ifreq) /* get DLT */
|
||||
#define SIOCGIFCAP _IOWR('i', 118, struct ifcapreq)/* get capabilities */
|
||||
#define SIOCSIFCAP _IOW('i', 117, struct ifcapreq)/* set capabilities */
|
||||
|
||||
#endif /* !_SYS_SOCKIO_H_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user