On 2025-01-07, Joel Mawhorter <j...@mawhorter.org> wrote:
> My apologies for the overzealous snipping.

thanks.

I suspect that "ifconfig vio0 -tcplro" might workaround the problem.

I would expect that it's fixed in -current by this commit:

---------------------
PatchSet 6865 
Date: 2024/10/31 12:33:11
Author: claudio
Branch: HEAD
Tag: (none) 
Log:
Rewrite mbuf handling in wg(4).

. Use m_align() to ensure that mbufs are packed towards the end so that
additional headers don't require costly m_prepends.
. Stop using m_copyback(), the way it was used there was actually wrong,
instead just use memcpy since this is just a single mbuf.
. Kill all usage of m_calchdrlen(), again this is not needed or can simply
be m->m_pkthdr.len = m->m_len since all this code uses a single buffer.
. In wg_encap() remove the min() with t->t_mtu when calculating plaintext_len
and out_len. The code does not correctly cope with this min() at all with
severe consequences.
Initial diff by dhill@ who found the m_prepend() issue.
Tested by various people.
OK dhill@ mvs@ bluhm@ sthen@

Members: 
        if_wg.c:1.38->1.39 

Index: src/sys/net/if_wg.c
diff -u src/sys/net/if_wg.c:1.38 src/sys/net/if_wg.c:1.39
--- src/sys/net/if_wg.c:1.38    Tue Apr  9 12:53:08 2024
+++ src/sys/net/if_wg.c Thu Oct 31 12:33:11 2024
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_wg.c,v 1.38 2024/04/09 12:53:08 claudio Exp $ */
+/*     $OpenBSD: if_wg.c,v 1.39 2024/10/31 12:33:11 claudio Exp $ */
 
 /*
  * Copyright (C) 2015-2020 Jason A. Donenfeld <ja...@zx2c4.com>. All Rights 
Reserved.
@@ -860,11 +860,15 @@
 {
        struct mbuf     *m;
        int              ret = 0;
+       size_t           mlen = len + max_hdr;
 
 retry:
        m = m_gethdr(M_WAIT, MT_DATA);
-       m->m_len = 0;
-       m_copyback(m, 0, len, buf, M_WAIT);
+       if (mlen > MHLEN)
+               MCLGETL(m, M_WAIT, mlen);
+       m_align(m, len);
+       m->m_pkthdr.len = m->m_len = len;
+       memcpy(mtod(m, void *), buf, len);
 
        /* As we're sending a handshake packet here, we want high priority */
        m->m_pkthdr.pf.prio = IFQ_MAXPRIO;
@@ -1304,9 +1308,6 @@
                return;
        }
 
-       m->m_len = 0;
-       m_calchdrlen(m);
-
        t->t_peer = peer;
        t->t_mbuf = NULL;
        t->t_done = 0;
@@ -1508,9 +1509,10 @@
        t = wg_tag_get(m);
        peer = t->t_peer;
 
-       plaintext_len = min(WG_PKT_WITH_PADDING(m->m_pkthdr.len), t->t_mtu);
+       plaintext_len = WG_PKT_WITH_PADDING(m->m_pkthdr.len);
        padding_len = plaintext_len - m->m_pkthdr.len;
-       out_len = sizeof(struct wg_pkt_data) + plaintext_len + 
NOISE_AUTHTAG_LEN;
+       out_len = sizeof(struct wg_pkt_data) + plaintext_len +
+           NOISE_AUTHTAG_LEN;
 
        /*
         * For the time being we allocate a new packet with sufficient size to
@@ -1522,8 +1524,9 @@
         * noise_remote_encrypt about mbufs, but we would need to sort out the
         * p_encap_queue situation first.
         */
-       if ((mc = m_clget(NULL, M_NOWAIT, out_len)) == NULL)
+       if ((mc = m_clget(NULL, M_NOWAIT, out_len + max_hdr)) == NULL)
                goto error;
+       m_align(mc, out_len);
 
        data = mtod(mc, struct wg_pkt_data *);
        m_copydata(m, 0, m->m_pkthdr.len, data->buf);
@@ -1560,8 +1563,7 @@
 
        mc->m_pkthdr.ph_loopcnt = m->m_pkthdr.ph_loopcnt;
        mc->m_flags &= ~(M_MCAST | M_BCAST);
-       mc->m_len = out_len;
-       m_calchdrlen(mc);
+       mc->m_pkthdr.len = mc->m_len = out_len;
 
        /*
         * We would count ifc_opackets, ifc_obytes of m here, except if_snd

Reply via email to