summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2023-05-22 16:08:35 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2023-05-22 16:08:35 +0000
commit547e964b0eef57a117579e50c5046d37f044dfac (patch)
tree85dc6444c49b11c55cc779e82a35a5b16f765418
parent747b0fb764016cef36ad296891ccfb5b048a58e0 (diff)
Fix TSO for traffic to a local address on a physical interface.
When sending TCP packets with software TSO to the local address of a physical interface, the TCP checksum was miscalculated. As the small MSS is taken from the physical interface, but the large MTU of the loopback interface is used, large TSO packets are generated, but sent directly to the loopback interface. There we need the regular pseudo header checksum and not the modified without packet length. To avoid this confusion, use the same decision for checksum generation in in_proto_cksum_out() as for using hardware TSO in tcp_if_output_tso(). bug reported and tested by robert@ bket@ Hrvoje Popovski OK claudio@ jan@
-rw-r--r--sys/netinet/ip_output.c5
-rw-r--r--sys/netinet6/ip6_output.c5
2 files changed, 6 insertions, 4 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index a44ee063d06..86288bc8892 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_output.c,v 1.387 2023/05/15 16:34:56 bluhm Exp $ */
+/* $OpenBSD: ip_output.c,v 1.388 2023/05/22 16:08:34 bluhm Exp $ */
/* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */
/*
@@ -1882,7 +1882,8 @@ in_proto_cksum_out(struct mbuf *m, struct ifnet *ifp)
u_int16_t csum = 0, offset;
offset = ip->ip_hl << 2;
- if (ISSET(m->m_pkthdr.csum_flags, M_TCP_TSO)) {
+ if (ISSET(m->m_pkthdr.csum_flags, M_TCP_TSO) &&
+ in_ifcap_cksum(m, ifp, IFCAP_TSOv4)) {
csum = in_cksum_phdr(ip->ip_src.s_addr,
ip->ip_dst.s_addr, htonl(ip->ip_p));
} else if (ISSET(m->m_pkthdr.csum_flags,
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index add8fb22c66..05c11898e01 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_output.c,v 1.276 2023/05/15 16:34:57 bluhm Exp $ */
+/* $OpenBSD: ip6_output.c,v 1.277 2023/05/22 16:08:34 bluhm Exp $ */
/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
/*
@@ -2710,7 +2710,8 @@ in6_proto_cksum_out(struct mbuf *m, struct ifnet *ifp)
u_int16_t csum;
offset = ip6_lasthdr(m, 0, IPPROTO_IPV6, &nxt);
- if (ISSET(m->m_pkthdr.csum_flags, M_TCP_TSO)) {
+ if (ISSET(m->m_pkthdr.csum_flags, M_TCP_TSO) &&
+ in_ifcap_cksum(m, ifp, IFCAP_TSOv6)) {
csum = in6_cksum_phdr(&ip6->ip6_src, &ip6->ip6_dst,
htonl(0), htonl(nxt));
} else {