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