On Sat, May 13, 2023 at 01:38:07AM +0200, Alexander Bluhm wrote: > Hi, > > Instead of implementing IPv4 header checksum everywhere differently, > introduce in_hdr_cksum_out(). It is used like in_proto_cksum_out(). > > ok?
OK claudio@ > 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, ðer_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 > -- :wq Claudio