Hey Toke, On Fri, Jun 18, 2021 at 1:05 AM Toke Høiland-Jørgensen <[email protected]> wrote: > > I think you can achieve something similar using BPF filters, by relying > > on wireguard passing through the skb->hash value when encrypting. > > > > Simply attach a TC-BPF filter to the wireguard netdev, pull out the DSCP > > value and store it in a map keyed on skb->hash. Then, run a second BPF > > filter on the physical interface that shares that same map, lookup the > > DSCP value based on the skb->hash value, and rewrite the outer IP > > header. > > > > The read-side filter will need to use bpf_get_hash_recalc() to make sure > > the hash is calculated before the packet gets handed to wireguard, and > > it'll be subject to hash collisions, but I think it should generally > > work fairly well (for anything that's flow-based of course). And it can > > be done without patching wireguard itself :) > > Just for fun I implemented such a pair of eBPF filters, and tested that > it does indeed work for preserving DSCP marks on a Wireguard tunnel. The > PoC is here: > > https://github.com/xdp-project/bpf-examples/tree/master/preserve-dscp > > To try it out (you'll need a recent-ish kernel and clang version) run: > > git clone --recurse-submodules https://github.com/xdp-project/bpf-examples > cd bpf-examples/preserve-dscp > make > ./preserve-dscp wg0 eth0 > > (assuming wg0 and eth0 are the wireguard and physical interfaces in > question, respectively). > > To actually deploy this it would probably need a few tweaks; in > particular the second filter that rewrites packets should probably check > that the packets are actually part of the Wireguard tunnel in question > (by parsing the UDP header and checking the source port) before writing > anything to the packet. > > -Toke
That is a super cool approach. Thanks for writing that! Sounds like a good approach, and one pretty easy to deploy, without the need to patch kernels and such. Also, nice usage of BPF_MAP_TYPE_LRU_HASH for this. Daniel -- can you let the list know if this works for your use case? Jason
