Instead of implementing IPv4 header checksum creation everywhere,
authorbluhm <bluhm@openbsd.org>
Sat, 13 May 2023 13:35:17 +0000 (13:35 +0000)
committerbluhm <bluhm@openbsd.org>
Sat, 13 May 2023 13:35:17 +0000 (13:35 +0000)
introduce in_hdr_cksum_out().  It is used like in_proto_cksum_out().
OK claudio@

sys/net/if_bridge.c
sys/net/if_gre.c
sys/net/pf.c
sys/netinet/in.h
sys/netinet/ip_divert.c
sys/netinet/ip_output.c
sys/netinet/ipsec_input.c
sys/netinet/tcp_output.c
sys/netmpls/mpls_input.c
sys/netmpls/mpls_output.c

index 463ca9c..a5ad228 100644 (file)
@@ -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, &ether_tmp, sizeof(ether_tmp));
index 6aebed6..cac48bb 100644 (file)
@@ -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;
index ee979d9..7c39564 100644 (file)
@@ -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;
index 16dcdb2..359be65 100644 (file)
@@ -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 *);
index 77d7698..acb00eb 100644 (file)
@@ -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 <michele@openbsd.org>
@@ -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);
        }
 
index f5b1173..394da08 100644 (file)
@@ -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;
index 353466a..5df9a4f 100644 (file)
@@ -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;
        }
 
index 84adc72..752b485 100644 (file)
@@ -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
index a307499..b25a980 100644 (file)
@@ -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 <claudio@openbsd.org>
@@ -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));
index 44c48ea..ff7696c 100644 (file)
@@ -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 <claudio@openbsd.org>
@@ -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)
 {