Hi,

Instead of implementing IPv4 header checksum everywhere differently,
introduce in_hdr_cksum_out().  It is used like in_proto_cksum_out().

ok?

bluhm

Index: net/if_bridge.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/if_bridge.c,v
retrieving revision 1.366
diff -u -p -r1.366 if_bridge.c
--- net/if_bridge.c     7 May 2023 16:23:23 -0000       1.366
+++ net/if_bridge.c     12 May 2023 20:43:06 -0000
@@ -1735,15 +1735,8 @@ bridge_ip(struct ifnet *brifp, int dir, 
                        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: net/if_gre.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/if_gre.c,v
retrieving revision 1.173
diff -u -p -r1.173 if_gre.c
--- net/if_gre.c        13 Apr 2023 02:19:05 -0000      1.173
+++ net/if_gre.c        12 May 2023 20:43:06 -0000
@@ -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: net/pf.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/pf.c,v
retrieving revision 1.1178
diff -u -p -r1.1178 pf.c
--- net/pf.c    10 May 2023 12:07:16 -0000      1.1178
+++ net/pf.c    12 May 2023 20:43:06 -0000
@@ -2868,7 +2868,7 @@ pf_change_icmp_af(struct mbuf *m, int ip
                        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_
        }
 
        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: netinet/in.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/in.h,v
retrieving revision 1.143
diff -u -p -r1.143 in.h
--- netinet/in.h        10 May 2023 12:07:16 -0000      1.143
+++ netinet/in.h        12 May 2023 20:43:06 -0000
@@ -779,6 +779,7 @@ int    in_broadcast(struct in_addr, u_in
 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: netinet/ip_divert.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_divert.c,v
retrieving revision 1.90
diff -u -p -r1.90 ip_divert.c
--- netinet/ip_divert.c 4 Apr 2023 10:12:03 -0000       1.90
+++ netinet/ip_divert.c 12 May 2023 20:43:06 -0000
@@ -157,8 +157,7 @@ divert_output(struct inpcb *inp, struct 
                 * 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
        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
                 * 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: netinet/ip_output.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_output.c,v
retrieving revision 1.385
diff -u -p -r1.385 ip_output.c
--- netinet/ip_output.c 10 May 2023 12:07:16 -0000      1.385
+++ netinet/ip_output.c 12 May 2023 20:45:34 -0000
@@ -81,8 +81,7 @@ int ip_pcbopts(struct mbuf **, struct mb
 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
                        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
        }
        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 m
                 * 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: netinet/ipsec_input.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ipsec_input.c,v
retrieving revision 1.203
diff -u -p -r1.203 ipsec_input.c
--- netinet/ipsec_input.c       22 Feb 2022 01:35:40 -0000      1.203
+++ netinet/ipsec_input.c       12 May 2023 20:43:06 -0000
@@ -389,8 +389,7 @@ ipsec_common_input_cb(struct mbuf **mp, 
 
                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: netinet/tcp_output.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_output.c,v
retrieving revision 1.136
diff -u -p -r1.136 tcp_output.c
--- netinet/tcp_output.c        10 May 2023 12:07:16 -0000      1.136
+++ netinet/tcp_output.c        12 May 2023 20:43:06 -0000
@@ -1302,13 +1302,7 @@ tcp_chopper(struct mbuf *m0, struct mbuf
                        *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
        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: netmpls/mpls_input.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netmpls/mpls_input.c,v
retrieving revision 1.78
diff -u -p -r1.78 mpls_input.c
--- netmpls/mpls_input.c        22 Jul 2021 11:07:17 -0000      1.78
+++ netmpls/mpls_input.c        12 May 2023 20:43:06 -0000
@@ -416,8 +416,7 @@ mpls_do_error(struct mbuf *m, int type, 
                /* 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: netmpls/mpls_output.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netmpls/mpls_output.c,v
retrieving revision 1.28
diff -u -p -r1.28 mpls_output.c
--- netmpls/mpls_output.c       3 Sep 2019 10:39:08 -0000       1.28
+++ netmpls/mpls_output.c       12 May 2023 20:43:06 -0000
@@ -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 mb
        }
 
        /* 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));
@@ -141,22 +142,6 @@ mpls_output(struct ifnet *ifp, struct mb
 bad:
        m_freem(m);
        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

Reply via email to