Hello, I did some proof-of-concept tests and got nice results. Here is my current script (https://github.com/luizluca/wireguard-ipv6-pmtu)
It runs as a shell script and updates allowed_ips routes (ipv4 and ipv6) when there is a cached PMTU to that endpoint (or the local interface is using a smaller MTU). It just works as expected, avoiding the fragmentation on the fly for IPv6-connected peers. It must run periodically as "ip monitor" does not emit events for cached routes. The best result is when you run it on both sides as it can only fix the traffic from that endpoint. As we have already discussed, standard IPv4 has a smaller header and the default wireguard MTU has some room to fit most tunneling protocols). I hit some interesting problems along the way: 1) "ip route get" might fail if all routes that would match also include a "from". You need to find out the source address wireguard is using before testing the route. I'm digging it from the conntrack table but I wish there was a better way. 2) PMTU runs in cycles. It generates a temporary cached route with MTU once it receives a "packet too big" answer. However, until the route is gone (expiring, for example), there is no way to generate a traffic that will retrigger that "packet too big" or refresh the route. Once the route is gone, the script will remove the MTU limitation, wireguard might eventually trigger a new "packet too big" and, on its next run, the script can adjust the MTU. We would need to add some state to the script to know that a cached route is gone and try to retrigger the PMTU before removing the MTU limitations. We could also do some brute force approach like pinging every peer using a large packet (1500-40-8) before each cycle or simply keep the MTU limitation forever as it would not hurt that much. For those who want to play with it, have fun! Regards, Luiz
