On Mon, Oct 28, 2024 at 09:55:53PM +0000, Stuart Henderson wrote: > On 2024/10/29 00:11, Vitaliy Makkoveev wrote: > > > - Set up vio(4) interfaces with -tcplro and enable wg(4) interfaces as > > > usual (In my case, I'm routing IPv4 and IPv6 traffic through wg(4) > > > tunnel). > > > > So, problem lays in vio(4). > > Or perhaps that is a trigger but the problem is elsewhere. > > bentley@ saw similar wg(4) problems on a machine with just em(4): > > em0 at pci0 dev 31 function 6 "Intel I219-V" rev 0x21: msi, address > 94:c6:91:a3:6d:8a > > Now, if I looked at the right files, only ix(4) vm(4) vio(4) have LRO - > em(4) does not. > > We do support TSO on some em(4). Though, while I am not certain, I don't > think we do on I219-V... Anthony, do you still have that machine available? > Can you do an "ifconfig em hwfeatures" please so we can be sure? > > My best guess from the information I have (I don't think it's possible > to map from a dmesg attach line to a mac_type without more information - > the pci id isn't printed) is that it's an em_pch_spt which doesn't do > TSO... >
People should try the following diff. It cleans up some of the mbuf handling and a possible buffer overflow in wg_encap that could be the cause of the pool corruption. -- :wq Claudio Index: net/if_wg.c =================================================================== RCS file: /cvs/src/sys/net/if_wg.c,v diff -u -p -r1.38 if_wg.c --- net/if_wg.c 9 Apr 2024 12:53:08 -0000 1.38 +++ net/if_wg.c 29 Oct 2024 15:46:02 -0000 @@ -860,11 +860,15 @@ wg_send_buf(struct wg_softc *sc, struct { 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 @@ wg_send_keepalive(void *_peer) return; } - m->m_len = 0; - m_calchdrlen(m); - t->t_peer = peer; t->t_mbuf = NULL; t->t_done = 0; @@ -1508,9 +1509,10 @@ wg_encap(struct wg_softc *sc, struct mbu 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 @@ wg_encap(struct wg_softc *sc, struct mbu * 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 @@ wg_encap(struct wg_softc *sc, struct mbu 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