On 2023-09-17, Andrew Lemin <andrew.le...@gmail.com> wrote:
> I have been testing the Wireguard implementation on OpenBSD and noticed
> that the ToS field is not being copied from the inner unencrypted header to
> the outer Wireguard header, resulting in ALL packets going into the same PF
> Prio / Queue.
>
> For example, ACKs (for Wireguard encrypted packets) end up in the first
> queue (not the priority queue) despite PF rules;
>
> queue ext_iface on $extif bandwidth 1000M max 1000M
>   queue pri on $extif parent ext_iface flows 1000 bandwidth 25M min 5M
>   queue data on $extif parent ext_iface flows 1000 bandwidth 100M default
>
> match on $extif proto tcp set prio (3, 6) set queue (data, pri)
>
> All unencrypted SYNs and ACKs etc correctly go into the 'pri' queue, and
> payload packets go into 'data' queue.
> However for Wireguard encrypted packets, _all_ packets (including SYNs and
> ACKs) go into the 'data' queue.
>
> I thought maybe you need to force the ToS/prio/queue values, so I also
> tried sledgehammer approach;
> match proto tcp flags A/A set tos lowdelay set prio 7 set queue pri
> match proto tcp flags S/S set tos lowdelay set prio 7 set queue pri
>
> But sadly all encrypted SYNs and ACKs etc still only go into the data queue
> no matter what.
> This can be confirmed with wireshark that all ToS bits are lost
>
> This results in poor Wireguard performance on OpenBSD.

Here's a naive untested diff that might at least use the prio internally
in OpenBSD...

Index: if_wg.c
===================================================================
RCS file: /cvs/src/sys/net/if_wg.c,v
retrieving revision 1.29
diff -u -p -r1.29 if_wg.c
--- if_wg.c     3 Aug 2023 09:49:08 -0000       1.29
+++ if_wg.c     18 Sep 2023 12:47:02 -0000
@@ -1525,6 +1525,8 @@ wg_encap(struct wg_softc *sc, struct mbu
         */
        mc->m_pkthdr.ph_flowid = m->m_pkthdr.ph_flowid;
 
+       mc->m_pkthdr.pf.prio = m->m_pkthdr.pf.prio;
+
        res = noise_remote_encrypt(&peer->p_remote, &data->r_idx, &nonce,
                                   data->buf, plaintext_len);
        nonce = htole64(nonce); /* Wire format is little endian. */


Reply via email to