summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2023-05-30 19:32:58 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2023-05-30 19:32:58 +0000
commit24bf252a186a52ba22389cd480306efb8eb94ac4 (patch)
tree6908421c656a030b9feda9d6db356dcae95da307
parentb16e9a8fc540a866a07d17271429527e069bafcb (diff)
Use generic checksum calculation for TCP SYN+ACK packets.
Our syn cache did checksum calculation by hand, instead of the established mechanism in ip output. The software-checksummed counter increased once per incoming TCP connection. Just set the flag M_TCP_CSUM_OUT in syn_cache_respond() and let in_proto_cksum_out() do the work later. Then hardware checksumming is used where available. Also remove redundant code. The unhandled af case is handled in the first switch statement of the function. tested by Hrvoje Popovski; OK mvs@
-rw-r--r--sys/netinet/tcp_input.c41
1 files changed, 6 insertions, 35 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 1077746e8dc..5986da0ddb6 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_input.c,v 1.387 2023/03/14 00:24:05 yasuoka Exp $ */
+/* $OpenBSD: tcp_input.c,v 1.388 2023/05/30 19:32:57 bluhm Exp $ */
/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
/*
@@ -3990,14 +3990,11 @@ syn_cache_respond(struct syn_cache *sc, struct mbuf *m, uint32_t now)
ip6->ip6_dst = sc->sc_src.sin6.sin6_addr;
ip6->ip6_src = sc->sc_dst.sin6.sin6_addr;
ip6->ip6_nxt = IPPROTO_TCP;
- /* ip6_plen will be updated in ip6_output() */
th = (struct tcphdr *)(ip6 + 1);
th->th_dport = sc->sc_src.sin6.sin6_port;
th->th_sport = sc->sc_dst.sin6.sin6_port;
break;
#endif
- default:
- unhandled_af(sc->sc_src.sa.sa_family);
}
th->th_seq = htonl(sc->sc_iss);
@@ -4096,21 +4093,7 @@ syn_cache_respond(struct syn_cache *sc, struct mbuf *m, uint32_t now)
}
#endif /* TCP_SIGNATURE */
- /* Compute the packet's checksum. */
- switch (sc->sc_src.sa.sa_family) {
- case AF_INET:
- ip->ip_len = htons(tlen - hlen);
- th->th_sum = 0;
- th->th_sum = in_cksum(m, tlen);
- break;
-#ifdef INET6
- case AF_INET6:
- ip6->ip6_plen = htons(tlen - hlen);
- th->th_sum = 0;
- th->th_sum = in6_cksum(m, IPPROTO_TCP, hlen, tlen - hlen);
- break;
-#endif
- }
+ SET(m->m_pkthdr.csum_flags, M_TCP_CSUM_OUT);
/* use IPsec policy and ttl from listening socket, on SYN ACK */
inp = sc->sc_tp ? sc->sc_tp->t_inpcb : NULL;
@@ -4125,34 +4108,22 @@ syn_cache_respond(struct syn_cache *sc, struct mbuf *m, uint32_t now)
ip->ip_ttl = inp ? inp->inp_ip.ip_ttl : ip_defttl;
if (inp != NULL)
ip->ip_tos = inp->inp_ip.ip_tos;
- break;
-#ifdef INET6
- case AF_INET6:
- ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
- ip6->ip6_vfc |= IPV6_VERSION;
- ip6->ip6_plen = htons(tlen - hlen);
- /* ip6_hlim will be initialized afterwards */
- /* leave flowlabel = 0, it is legal and require no state mgmt */
- break;
-#endif
- }
- switch (sc->sc_src.sa.sa_family) {
- case AF_INET:
error = ip_output(m, sc->sc_ipopts, &sc->sc_route4,
(ip_mtudisc ? IP_MTUDISC : 0), NULL, inp, 0);
break;
#ifdef INET6
case AF_INET6:
+ ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
+ ip6->ip6_vfc |= IPV6_VERSION;
+ /* ip6_plen will be updated in ip6_output() */
ip6->ip6_hlim = in6_selecthlim(inp);
+ /* leave flowlabel = 0, it is legal and require no state mgmt */
error = ip6_output(m, NULL /*XXX*/, &sc->sc_route6, 0,
NULL, NULL);
break;
#endif
- default:
- error = EAFNOSUPPORT;
- break;
}
return (error);
}