fix problems related to loopback interface checksum omission. PR/29971.
- for ipv4, defer decision to ip layer as h/w checksum offloading does so that it can check the actual interface the packet is going to. - for ipv6, disable it. (maybe will be revisited when it implements h/w checksum offloading.) ok'ed by Jason Thorpe.
This commit is contained in:
parent
367b093823
commit
e5a2b5a4a4
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ip_input.c,v 1.213 2005/03/29 09:37:08 yamt Exp $ */
|
||||
/* $NetBSD: ip_input.c,v 1.214 2005/04/18 21:50:25 yamt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -98,7 +98,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.213 2005/03/29 09:37:08 yamt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.214 2005/04/18 21:50:25 yamt Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_gateway.h"
|
||||
@ -200,7 +200,6 @@ int ipprintfs = 0;
|
||||
#endif
|
||||
|
||||
int ip_do_randomid = 0;
|
||||
int ip_do_loopback_cksum = 0;
|
||||
|
||||
/*
|
||||
* XXX - Setting ip_checkinterface mostly implements the receive side of
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ip_output.c,v 1.150 2005/04/07 12:22:47 yamt Exp $ */
|
||||
/* $NetBSD: ip_output.c,v 1.151 2005/04/18 21:50:25 yamt 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.150 2005/04/07 12:22:47 yamt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.151 2005/04/18 21:50:25 yamt Exp $");
|
||||
|
||||
#include "opt_pfil_hooks.h"
|
||||
#include "opt_inet.h"
|
||||
@ -158,6 +158,16 @@ static void ip_mloopback(struct ifnet *, struct mbuf *, struct sockaddr_in *);
|
||||
extern struct pfil_head inet_pfil_hook; /* XXX */
|
||||
#endif
|
||||
|
||||
int udp_do_loopback_cksum = 0;
|
||||
int tcp_do_loopback_cksum = 0;
|
||||
int ip_do_loopback_cksum = 0;
|
||||
|
||||
#define IN_NEED_CHECKSUM(ifp, csum_flags) \
|
||||
(__predict_true(((ifp)->if_flags & IFF_LOOPBACK) == 0 || \
|
||||
(((csum_flags) & M_CSUM_UDPv4) != 0 && udp_do_loopback_cksum) || \
|
||||
(((csum_flags) & M_CSUM_TCPv4) != 0 && tcp_do_loopback_cksum) || \
|
||||
(((csum_flags) & M_CSUM_IPv4) != 0 && ip_do_loopback_cksum)))
|
||||
|
||||
/*
|
||||
* IP output. The packet in mbuf chain m contains a skeletal IP
|
||||
* header (with len, off, ttl, proto, tos, src, dst).
|
||||
@ -788,9 +798,9 @@ spd_done:
|
||||
#endif
|
||||
|
||||
/* Maybe skip checksums on loopback interfaces. */
|
||||
if (__predict_true(!(ifp->if_flags & IFF_LOOPBACK) ||
|
||||
ip_do_loopback_cksum))
|
||||
if (IN_NEED_CHECKSUM(ifp, M_CSUM_IPv4)) {
|
||||
m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
|
||||
}
|
||||
sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_csum_flags_tx;
|
||||
/*
|
||||
* If small enough for mtu of path, or if using TCP segmentation
|
||||
@ -817,11 +827,15 @@ spd_done:
|
||||
* XXX fields to be 0?
|
||||
*/
|
||||
if (sw_csum & M_CSUM_IPv4) {
|
||||
KASSERT(IN_NEED_CHECKSUM(ifp, M_CSUM_IPv4));
|
||||
ip->ip_sum = in_cksum(m, hlen);
|
||||
m->m_pkthdr.csum_flags &= ~M_CSUM_IPv4;
|
||||
}
|
||||
if (sw_csum & (M_CSUM_TCPv4|M_CSUM_UDPv4)) {
|
||||
in_delayed_cksum(m);
|
||||
if (IN_NEED_CHECKSUM(ifp,
|
||||
sw_csum & (M_CSUM_TCPv4|M_CSUM_UDPv4))) {
|
||||
in_delayed_cksum(m);
|
||||
}
|
||||
m->m_pkthdr.csum_flags &=
|
||||
~(M_CSUM_TCPv4|M_CSUM_UDPv4);
|
||||
}
|
||||
@ -842,7 +856,10 @@ spd_done:
|
||||
* XXX Some hardware can do this.
|
||||
*/
|
||||
if (m->m_pkthdr.csum_flags & (M_CSUM_TCPv4|M_CSUM_UDPv4)) {
|
||||
in_delayed_cksum(m);
|
||||
if (IN_NEED_CHECKSUM(ifp,
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tcp_output.c,v 1.129 2005/03/29 20:09:24 yamt Exp $ */
|
||||
/* $NetBSD: tcp_output.c,v 1.130 2005/04/18 21:50:25 yamt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -140,7 +140,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_output.c,v 1.129 2005/03/29 20:09:24 yamt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_output.c,v 1.130 2005/04/18 21:50:25 yamt Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
@ -1306,7 +1306,7 @@ send:
|
||||
|
||||
/*
|
||||
* Set ourselves up to be checksummed just before the packet
|
||||
* hits the wire. Maybe skip checksums on loopback interfaces.
|
||||
* hits the wire.
|
||||
*/
|
||||
switch (af) {
|
||||
#ifdef INET
|
||||
@ -1316,13 +1316,7 @@ send:
|
||||
m->m_pkthdr.segsz = txsegsize;
|
||||
m->m_pkthdr.csum_flags = M_CSUM_TSOv4;
|
||||
} else {
|
||||
if (__predict_true(ro->ro_rt == NULL ||
|
||||
!(ro->ro_rt->rt_ifp->if_flags &
|
||||
IFF_LOOPBACK) ||
|
||||
tcp_do_loopback_cksum))
|
||||
m->m_pkthdr.csum_flags = M_CSUM_TCPv4;
|
||||
else
|
||||
m->m_pkthdr.csum_flags = 0;
|
||||
m->m_pkthdr.csum_flags = M_CSUM_TCPv4;
|
||||
if (len + optlen) {
|
||||
/* Fixup the pseudo-header checksum. */
|
||||
/* XXXJRT Not IP Jumbogram safe. */
|
||||
@ -1344,13 +1338,7 @@ send:
|
||||
m->m_pkthdr.len = sizeof(struct ip6_hdr)
|
||||
+ sizeof(struct tcphdr) + optlen + len;
|
||||
#ifdef notyet
|
||||
if (__predict_true(ro->ro_rt == NULL ||
|
||||
!(ro->ro_rt->rt_ifp->if_flags &
|
||||
IFF_LOOPBACK) ||
|
||||
tcp_do_loopback_cksum))
|
||||
m->m_pkthdr.csum_flags = M_CSUM_TCPv6;
|
||||
else
|
||||
m->m_pkthdr.csum_flags = 0;
|
||||
m->m_pkthdr.csum_flags = M_CSUM_TCPv6;
|
||||
m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum);
|
||||
#endif
|
||||
if (len + optlen) {
|
||||
@ -1359,14 +1347,8 @@ send:
|
||||
th->th_sum = in_cksum_addword(th->th_sum,
|
||||
htons((u_int16_t) (len + optlen)));
|
||||
}
|
||||
#ifndef notyet
|
||||
if (__predict_true(ro->ro_rt == NULL ||
|
||||
!(ro->ro_rt->rt_ifp->if_flags &
|
||||
IFF_LOOPBACK) ||
|
||||
tcp_do_loopback_cksum))
|
||||
th->th_sum = in6_cksum(m, 0, sizeof(struct ip6_hdr),
|
||||
sizeof(struct tcphdr) + optlen + len);
|
||||
#endif
|
||||
th->th_sum = in6_cksum(m, 0, sizeof(struct ip6_hdr),
|
||||
sizeof(struct tcphdr) + optlen + len);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tcp_subr.c,v 1.189 2005/04/05 01:07:17 kurahone Exp $ */
|
||||
/* $NetBSD: tcp_subr.c,v 1.190 2005/04/18 21:50:25 yamt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -98,7 +98,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_subr.c,v 1.189 2005/04/05 01:07:17 kurahone Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_subr.c,v 1.190 2005/04/18 21:50:25 yamt Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
@ -200,7 +200,6 @@ int tcp_compat_42 = 0;
|
||||
#endif
|
||||
int tcp_rst_ppslim = 100; /* 100pps */
|
||||
int tcp_ackdrop_ppslim = 100; /* 100pps */
|
||||
int tcp_do_loopback_cksum = 0;
|
||||
int tcp_sack_tp_maxholes = 32;
|
||||
int tcp_sack_globalmaxholes = 1024;
|
||||
int tcp_sack_globalholes = 0;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udp_usrreq.c,v 1.134 2005/03/11 06:16:16 atatat Exp $ */
|
||||
/* $NetBSD: udp_usrreq.c,v 1.135 2005/04/18 21:50:25 yamt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -61,7 +61,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.134 2005/03/11 06:16:16 atatat Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.135 2005/04/18 21:50:25 yamt Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
@ -146,7 +146,6 @@ int udpcksum = 1;
|
||||
#else
|
||||
int udpcksum = 0; /* XXX */
|
||||
#endif
|
||||
int udp_do_loopback_cksum = 0;
|
||||
|
||||
struct inpcbtable udbtable;
|
||||
struct udpstat udpstat;
|
||||
@ -1080,18 +1079,11 @@ udp_output(struct mbuf *m, ...)
|
||||
/*
|
||||
* XXX Cache pseudo-header checksum part for
|
||||
* XXX "connected" UDP sockets.
|
||||
* Maybe skip checksums on loopback interfaces.
|
||||
*/
|
||||
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));
|
||||
if (__predict_true(ro->ro_rt == NULL ||
|
||||
!(ro->ro_rt->rt_ifp->if_flags &
|
||||
IFF_LOOPBACK) ||
|
||||
udp_do_loopback_cksum))
|
||||
m->m_pkthdr.csum_flags = M_CSUM_UDPv4;
|
||||
else
|
||||
m->m_pkthdr.csum_flags = 0;
|
||||
m->m_pkthdr.csum_flags = M_CSUM_UDPv4;
|
||||
m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum);
|
||||
} else
|
||||
ui->ui_sum = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user