From: bluhm Date: Sat, 13 May 2023 13:35:17 +0000 (+0000) Subject: Instead of implementing IPv4 header checksum creation everywhere, X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=55055d619d36cc45f8c6891404c51cd405214e86;p=openbsd Instead of implementing IPv4 header checksum creation everywhere, introduce in_hdr_cksum_out(). It is used like in_proto_cksum_out(). OK claudio@ --- diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 463ca9cf96c..a5ad2281a70 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bridge.c,v 1.366 2023/05/07 16:23:23 bluhm Exp $ */ +/* $OpenBSD: if_bridge.c,v 1.367 2023/05/13 13:35:17 bluhm Exp $ */ /* * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net) @@ -1735,15 +1735,8 @@ bridge_ip(struct ifnet *brifp, int dir, struct ifnet *ifp, return (NULL); if (m->m_len < sizeof(struct ip)) goto dropit; + in_hdr_cksum_out(m, ifp); in_proto_cksum_out(m, ifp); - ip = mtod(m, struct ip *); - ip->ip_sum = 0; - if (0 && (ifp->if_capabilities & IFCAP_CSUM_IPv4)) - m->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT; - else { - ipstat_inc(ips_outswcsum); - ip->ip_sum = in_cksum(m, hlen); - } #if NPF > 0 if (dir == BRIDGE_IN && @@ -1993,8 +1986,7 @@ bridge_send_icmp_err(struct ifnet *ifp, ip->ip_off &= htons(IP_DF); ip->ip_id = htons(ip_randomid()); ip->ip_ttl = MAXTTL; - ip->ip_sum = 0; - ip->ip_sum = in_cksum(m, hlen); + in_hdr_cksum_out(m, NULL); /* Swap ethernet addresses */ bcopy(&eh->ether_dhost, ðer_tmp, sizeof(ether_tmp)); diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c index 6aebed6ee9d..cac48bb8f3d 100644 --- a/sys/net/if_gre.c +++ b/sys/net/if_gre.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_gre.c,v 1.173 2023/04/13 02:19:05 jsg Exp $ */ +/* $OpenBSD: if_gre.c,v 1.174 2023/05/13 13:35:17 bluhm Exp $ */ /* $NetBSD: if_gre.c,v 1.9 1999/10/25 19:18:11 drochner Exp $ */ /* @@ -3028,8 +3028,7 @@ gre_keepalive_send(void *arg) ip = mtod(m, struct ip *); ip->ip_id = htons(ip_randomid()); - ip->ip_sum = 0; - ip->ip_sum = in_cksum(m, sizeof(*ip)); + in_hdr_cksum_out(m, NULL); proto = htons(ETHERTYPE_IP); break; diff --git a/sys/net/pf.c b/sys/net/pf.c index ee979d9e8e5..7c395644c9b 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.1178 2023/05/10 12:07:16 bluhm Exp $ */ +/* $OpenBSD: pf.c,v 1.1179 2023/05/13 13:35:17 bluhm Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -2868,7 +2868,7 @@ pf_change_icmp_af(struct mbuf *m, int ipoff2, struct pf_pdesc *pd, ip4->ip_p = pd2->proto; ip4->ip_src = src->v4; ip4->ip_dst = dst->v4; - ip4->ip_sum = in_cksum(n, ip4->ip_hl << 2); + in_hdr_cksum_out(n, NULL); break; case AF_INET6: ip6 = mtod(n, struct ip6_hdr *); @@ -6549,13 +6549,7 @@ pf_route(struct pf_pdesc *pd, struct pf_state *st) } if (ntohs(ip->ip_len) <= ifp->if_mtu) { - ip->ip_sum = 0; - if (ifp->if_capabilities & IFCAP_CSUM_IPv4) - m0->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT; - else { - ipstat_inc(ips_outswcsum); - ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); - } + in_hdr_cksum_out(m0, ifp); in_proto_cksum_out(m0, ifp); ifp->if_output(ifp, m0, sintosa(dst), rt); goto done; diff --git a/sys/netinet/in.h b/sys/netinet/in.h index 16dcdb24ca0..359be65f650 100644 --- a/sys/netinet/in.h +++ b/sys/netinet/in.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in.h,v 1.143 2023/05/10 12:07:16 bluhm Exp $ */ +/* $OpenBSD: in.h,v 1.144 2023/05/13 13:35:17 bluhm Exp $ */ /* $NetBSD: in.h,v 1.20 1996/02/13 23:41:47 christos Exp $ */ /* @@ -779,6 +779,7 @@ int in_broadcast(struct in_addr, u_int); int in_canforward(struct in_addr); int in_cksum(struct mbuf *, int); int in4_cksum(struct mbuf *, u_int8_t, int, int); +void in_hdr_cksum_out(struct mbuf *, struct ifnet *); void in_proto_cksum_out(struct mbuf *, struct ifnet *); int in_ifcap_cksum(struct mbuf *, struct ifnet *, int); void in_ifdetach(struct ifnet *); diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index 77d7698076a..acb00eb853c 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_divert.c,v 1.90 2023/04/04 10:12:03 bluhm Exp $ */ +/* $OpenBSD: ip_divert.c,v 1.91 2023/05/13 13:35:17 bluhm Exp $ */ /* * Copyright (c) 2009 Michele Marchetto @@ -157,8 +157,7 @@ divert_output(struct inpcb *inp, struct mbuf *m, struct mbuf *nam, * since the userspace application may have modified the packet * prior to reinjection. */ - ip->ip_sum = 0; - ip->ip_sum = in_cksum(m, off); + in_hdr_cksum_out(m, NULL); in_proto_cksum_out(m, NULL); ifp = if_get(m->m_pkthdr.ph_ifidx); @@ -190,8 +189,6 @@ divert_packet(struct mbuf *m, int dir, u_int16_t divert_port) struct inpcb *inp = NULL; struct socket *so; struct sockaddr_in sin; - struct ip *ip; - int off; divstat_inc(divs_ipackets); @@ -239,11 +236,7 @@ divert_packet(struct mbuf *m, int dir, u_int16_t divert_port) * Calculate IP and protocol checksums for outbound packet * diverted to userland. pf rule diverts before cksum offload. */ - ip = mtod(m, struct ip *); - off = ip->ip_hl << 2; - - ip->ip_sum = 0; - ip->ip_sum = in_cksum(m, off); + in_hdr_cksum_out(m, NULL); in_proto_cksum_out(m, NULL); } diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index f5b1173a299..394da08ad9f 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_output.c,v 1.385 2023/05/10 12:07:16 bluhm Exp $ */ +/* $OpenBSD: ip_output.c,v 1.386 2023/05/13 13:35:17 bluhm Exp $ */ /* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */ /* @@ -81,8 +81,7 @@ int ip_pcbopts(struct mbuf **, struct mbuf *); int ip_multicast_if(struct ip_mreqn *, u_int, unsigned int *); int ip_setmoptions(int, struct ip_moptions **, struct mbuf *, u_int); void ip_mloopback(struct ifnet *, struct mbuf *, struct sockaddr_in *); -static __inline u_int16_t __attribute__((__unused__)) - in_cksum_phdr(u_int32_t, u_int32_t, u_int32_t); +static u_int16_t in_cksum_phdr(u_int32_t, u_int32_t, u_int32_t); void in_delayed_cksum(struct mbuf *); int ip_output_ipsec_lookup(struct mbuf *m, int hlen, struct inpcb *inp, @@ -455,13 +454,7 @@ sendit: * If small enough for interface, can just send directly. */ if (ntohs(ip->ip_len) <= mtu) { - ip->ip_sum = 0; - if (in_ifcap_cksum(m, ifp, IFCAP_CSUM_IPv4)) - m->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT; - else { - ipstat_inc(ips_outswcsum); - ip->ip_sum = in_cksum(m, hlen); - } + in_hdr_cksum_out(m, ifp); in_proto_cksum_out(m, ifp); error = ifp->if_output(ifp, m, sintosa(dst), ro->ro_rt); goto done; @@ -772,13 +765,7 @@ ip_fragment(struct mbuf *m0, struct mbuf_list *ml, struct ifnet *ifp, goto bad; } - mhip->ip_sum = 0; - if (in_ifcap_cksum(m, ifp, IFCAP_CSUM_IPv4)) - m->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT; - else { - ipstat_inc(ips_outswcsum); - mhip->ip_sum = in_cksum(m, mhlen); - } + in_hdr_cksum_out(m, ifp); } /* @@ -791,13 +778,7 @@ ip_fragment(struct mbuf *m0, struct mbuf_list *ml, struct ifnet *ifp, } ip->ip_len = htons(m0->m_pkthdr.len); - ip->ip_sum = 0; - if (in_ifcap_cksum(m0, ifp, IFCAP_CSUM_IPv4)) - m0->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT; - else { - ipstat_inc(ips_outswcsum); - ip->ip_sum = in_cksum(m0, hlen); - } + in_hdr_cksum_out(m0, ifp); ipstat_add(ips_ofragments, ml_len(ml)); return (0); @@ -1806,7 +1787,6 @@ ip_freemoptions(struct ip_moptions *imo) void ip_mloopback(struct ifnet *ifp, struct mbuf *m, struct sockaddr_in *dst) { - struct ip *ip; struct mbuf *copym; copym = m_dup_pkt(m, max_linkhdr, M_DONTWAIT); @@ -1815,18 +1795,31 @@ ip_mloopback(struct ifnet *ifp, struct mbuf *m, struct sockaddr_in *dst) * We don't bother to fragment if the IP length is greater * than the interface's MTU. Can this possibly matter? */ - ip = mtod(copym, struct ip *); - ip->ip_sum = 0; - ip->ip_sum = in_cksum(copym, ip->ip_hl << 2); + in_hdr_cksum_out(copym, NULL); if_input_local(ifp, copym, dst->sin_family); } } +void +in_hdr_cksum_out(struct mbuf *m, struct ifnet *ifp) +{ + struct ip *ip = mtod(m, struct ip *); + + ip->ip_sum = 0; + if (ifp && in_ifcap_cksum(m, ifp, IFCAP_CSUM_IPv4)) { + SET(m->m_pkthdr.csum_flags, M_IPV4_CSUM_OUT); + } else { + ipstat_inc(ips_outswcsum); + ip->ip_sum = in_cksum(m, ip->ip_hl << 2); + CLR(m->m_pkthdr.csum_flags, M_IPV4_CSUM_OUT); + } +} + /* * Compute significant parts of the IPv4 checksum pseudo-header * for use in a delayed TCP/UDP checksum calculation. */ -static __inline u_int16_t __attribute__((__unused__)) +static u_int16_t in_cksum_phdr(u_int32_t src, u_int32_t dst, u_int32_t lenproto) { u_int32_t sum; diff --git a/sys/netinet/ipsec_input.c b/sys/netinet/ipsec_input.c index 353466af1f3..5df9a4f9634 100644 --- a/sys/netinet/ipsec_input.c +++ b/sys/netinet/ipsec_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipsec_input.c,v 1.203 2022/02/22 01:35:40 guenther Exp $ */ +/* $OpenBSD: ipsec_input.c,v 1.204 2023/05/13 13:35:17 bluhm Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and @@ -389,8 +389,7 @@ ipsec_common_input_cb(struct mbuf **mp, struct tdb *tdbp, int skip, int protoff) ip = mtod(m, struct ip *); ip->ip_len = htons(m->m_pkthdr.len); - ip->ip_sum = 0; - ip->ip_sum = in_cksum(m, ip->ip_hl << 2); + in_hdr_cksum_out(m, NULL); prot = ip->ip_p; } diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c index 84adc729bf8..752b485ba27 100644 --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_output.c,v 1.136 2023/05/10 12:07:16 bluhm Exp $ */ +/* $OpenBSD: tcp_output.c,v 1.137 2023/05/13 13:35:18 bluhm Exp $ */ /* $NetBSD: tcp_output.c,v 1.16 1997/06/03 16:17:09 kml Exp $ */ /* @@ -1302,13 +1302,7 @@ tcp_chopper(struct mbuf *m0, struct mbuf_list *ml, struct ifnet *ifp, *mhip = *ip; mhip->ip_len = htons(hlen + len); mhip->ip_id = htons(ip_randomid()); - mhip->ip_sum = 0; - if (ifp && in_ifcap_cksum(m, ifp, IFCAP_CSUM_IPv4)) { - m->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT; - } else { - ipstat_inc(ips_outswcsum); - mhip->ip_sum = in_cksum(m, iphlen); - } + in_hdr_cksum_out(m, ifp); in_proto_cksum_out(m, ifp); } #ifdef INET6 @@ -1337,12 +1331,7 @@ tcp_chopper(struct mbuf *m0, struct mbuf_list *ml, struct ifnet *ifp, if (ip) { ip->ip_len = htons(m0->m_pkthdr.len); ip->ip_sum = 0; - if (ifp && in_ifcap_cksum(m0, ifp, IFCAP_CSUM_IPv4)) { - m0->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT; - } else { - ipstat_inc(ips_outswcsum); - ip->ip_sum = in_cksum(m0, iphlen); - } + in_hdr_cksum_out(m0, ifp); in_proto_cksum_out(m0, ifp); } #ifdef INET6 diff --git a/sys/netmpls/mpls_input.c b/sys/netmpls/mpls_input.c index a307499ff95..b25a9806a5f 100644 --- a/sys/netmpls/mpls_input.c +++ b/sys/netmpls/mpls_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mpls_input.c,v 1.78 2021/07/22 11:07:17 mvs Exp $ */ +/* $OpenBSD: mpls_input.c,v 1.79 2023/05/13 13:35:18 bluhm Exp $ */ /* * Copyright (c) 2008 Claudio Jeker @@ -416,8 +416,7 @@ mpls_do_error(struct mbuf *m, int type, int code, int destmtu) /* stuff to fix up which is normally done in ip_output */ ip->ip_v = IPVERSION; ip->ip_id = htons(ip_randomid()); - ip->ip_sum = 0; - ip->ip_sum = in_cksum(m, sizeof(*ip)); + in_hdr_cksum_out(m, NULL); /* stolen from icmp_send() */ icp = (struct icmp *)(mtod(m, caddr_t) + sizeof(*ip)); diff --git a/sys/netmpls/mpls_output.c b/sys/netmpls/mpls_output.c index 44c48eaefaa..ff7696cfcea 100644 --- a/sys/netmpls/mpls_output.c +++ b/sys/netmpls/mpls_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mpls_output.c,v 1.28 2019/09/03 10:39:08 jsg Exp $ */ +/* $OpenBSD: mpls_output.c,v 1.29 2023/05/13 13:35:18 bluhm Exp $ */ /* * Copyright (c) 2008 Claudio Jeker @@ -39,7 +39,6 @@ #define MPLS_LABEL_GET(l) ((ntohl((l) & MPLS_LABEL_MASK)) >> MPLS_LABEL_OFFSET) #endif -void mpls_do_cksum(struct mbuf *); u_int8_t mpls_getttl(struct mbuf *, sa_family_t); int @@ -62,7 +61,9 @@ mpls_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, } /* need to calculate checksums now if necessary */ - mpls_do_cksum(m); + if (m->m_pkthdr.csum_flags & M_IPV4_CSUM_OUT) + in_hdr_cksum_out(m, NULL); + in_proto_cksum_out(m, NULL); /* initialize sockaddr_mpls */ bzero(&sa_mpls, sizeof(sa_mpls)); @@ -143,22 +144,6 @@ bad: return (error); } -void -mpls_do_cksum(struct mbuf *m) -{ - struct ip *ip; - u_int16_t hlen; - - in_proto_cksum_out(m, NULL); - - if (m->m_pkthdr.csum_flags & M_IPV4_CSUM_OUT) { - ip = mtod(m, struct ip *); - hlen = ip->ip_hl << 2; - ip->ip_sum = in_cksum(m, hlen); - m->m_pkthdr.csum_flags &= ~M_IPV4_CSUM_OUT; - } -} - u_int8_t mpls_getttl(struct mbuf *m, sa_family_t af) {