Put checksum flags in bpf_hdr to use them in userland dhcpleased.
authorjan <jan@openbsd.org>
Fri, 26 Jan 2024 21:14:08 +0000 (21:14 +0000)
committerjan <jan@openbsd.org>
Fri, 26 Jan 2024 21:14:08 +0000 (21:14 +0000)
Thus, dhcpleased accept non-calculated checksums which were verified by
hardware/hypervisor.

With tweaks from dlg@

ok bluhm@
mkay tobhe@

sbin/dhcpleased/dhcpleased.h
sbin/dhcpleased/engine.c
sbin/dhcpleased/frontend.c
sys/net/bpf.c
sys/net/bpf.h

index 80fe9dc..41749fc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dhcpleased.h,v 1.15 2023/11/25 12:00:39 florian Exp $ */
+/*     $OpenBSD: dhcpleased.h,v 1.16 2024/01/26 21:14:08 jan Exp $     */
 
 /*
  * Copyright (c) 2017, 2021 Florian Obser <florian@openbsd.org>
@@ -287,7 +287,7 @@ struct imsg_propose_rdns {
 struct imsg_dhcp {
        uint32_t                if_index;
        ssize_t                 len;
-       uint8_t                 ether_align[2];
+       uint16_t                csumflags;
        uint8_t                 packet[1500];
 };
 
index cc6610f..6d371a5 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: engine.c,v 1.41 2023/12/14 09:58:37 claudio Exp $     */
+/*     $OpenBSD: engine.c,v 1.42 2024/01/26 21:14:08 jan Exp $ */
 
 /*
  * Copyright (c) 2017, 2021 Florian Obser <florian@openbsd.org>
@@ -24,6 +24,7 @@
 #include <sys/socket.h>
 #include <sys/syslog.h>
 #include <sys/uio.h>
+#include <sys/mbuf.h>
 
 #include <net/if.h>
 #include <net/route.h>
@@ -788,7 +789,8 @@ parse_dhcp(struct dhcpleased_iface *iface, struct imsg_dhcp *dhcp)
        if (rem < (size_t)ip->ip_hl << 2)
                goto too_short;
 
-       if (wrapsum(checksum((uint8_t *)ip, ip->ip_hl << 2, 0)) != 0) {
+       if ((dhcp->csumflags & M_IPV4_CSUM_IN_OK) == 0 &&
+           wrapsum(checksum((uint8_t *)ip, ip->ip_hl << 2, 0)) != 0) {
                log_warnx("%s: bad IP checksum", __func__);
                return;
        }
@@ -834,16 +836,19 @@ parse_dhcp(struct dhcpleased_iface *iface, struct imsg_dhcp *dhcp)
        p += sizeof(*udp);
        rem -= sizeof(*udp);
 
-       usum = udp->uh_sum;
-       udp->uh_sum = 0;
+       if ((dhcp->csumflags & M_UDP_CSUM_IN_OK) == 0) {
+               usum = udp->uh_sum;
+               udp->uh_sum = 0;
 
-       sum = wrapsum(checksum((uint8_t *)udp, sizeof(*udp), checksum(p, rem,
-           checksum((uint8_t *)&ip->ip_src, 2 * sizeof(ip->ip_src),
-           IPPROTO_UDP + ntohs(udp->uh_ulen)))));
+               sum = wrapsum(checksum((uint8_t *)udp, sizeof(*udp),
+                   checksum(p, rem,
+                   checksum((uint8_t *)&ip->ip_src, 2 * sizeof(ip->ip_src),
+                   IPPROTO_UDP + ntohs(udp->uh_ulen)))));
 
-       if (usum != 0 && usum != sum) {
-               log_warnx("%s: bad UDP checksum", __func__);
-               return;
+               if (usum != 0 && usum != sum) {
+                       log_warnx("%s: bad UDP checksum", __func__);
+                       return;
+               }
        }
 
        if (log_getverbose() > 1) {
index 74335b8..b80b808 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: frontend.c,v 1.32 2023/12/14 09:58:37 claudio Exp $   */
+/*     $OpenBSD: frontend.c,v 1.33 2024/01/26 21:14:08 jan Exp $       */
 
 /*
  * Copyright (c) 2017, 2021 Florian Obser <florian@openbsd.org>
@@ -890,6 +890,7 @@ bpf_receive(int fd, short events, void *arg)
                }
                memcpy(&imsg_dhcp.packet, p + hdr->bh_hdrlen, hdr->bh_caplen);
                imsg_dhcp.len = hdr->bh_caplen;
+               imsg_dhcp.csumflags = hdr->bh_csumflags;
                frontend_imsg_compose_engine(IMSG_DHCP, 0, 0, &imsg_dhcp,
                    sizeof(imsg_dhcp));
  cont:
index b05c517..51a1ed6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bpf.c,v 1.221 2023/03/09 05:56:58 dlg Exp $   */
+/*     $OpenBSD: bpf.c,v 1.222 2024/01/26 21:14:08 jan Exp $   */
 /*     $NetBSD: bpf.c,v 1.33 1997/02/21 23:59:35 thorpej Exp $ */
 
 /*
@@ -1397,6 +1397,8 @@ _bpf_mtap(caddr_t arg, const struct mbuf *mp, const struct mbuf *m,
                                        if (ISSET(mp->m_pkthdr.csum_flags,
                                            M_FLOWID))
                                                SET(tbh.bh_flags, BPF_F_FLOWID);
+                                       tbh.bh_csumflags =
+                                           mp->m_pkthdr.csum_flags;
 
                                        m_microtime(mp, &tv);
                                } else
index 9ce4dcd..ab64061 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bpf.h,v 1.71 2023/03/09 05:56:58 dlg Exp $    */
+/*     $OpenBSD: bpf.h,v 1.72 2024/01/26 21:14:08 jan Exp $    */
 /*     $NetBSD: bpf.h,v 1.15 1996/12/13 07:57:33 mikel Exp $   */
 
 /*
@@ -161,6 +161,7 @@ struct bpf_hdr {
 #define BPF_F_DIR_IN           (BPF_DIRECTION_IN << BPF_F_DIR_SHIFT)
 #define BPF_F_DIR_OUT          (BPF_DIRECTION_OUT << BPF_F_DIR_SHIFT)
        u_int8_t        bh_drops;
+       u_int16_t       bh_csumflags;   /* checksum flags */
 };
 
 #ifdef _KERNEL