Re: It's been some time since I've looked at the OVPN source code but I found some cool TUN interface flags recently!
Jon Chiappetta via Openvpn-devel <[email protected]>
| Newsgroups | gmane.network.openvpn.devel |
|---|---|
| Message-ID | <[email protected]> |
Apologies, I placed the dots ... on the wrong lines, I meant to put them after the if error statements. But yeah, I think you're right about that, I forgot and I remember now there was a part of the OVPN code base where it parses the IPv4 headers out but I forget why and what that part of the code was doing within the framework. So I guess bulk reading packets may not be the best idea also because you'd have to unpack it all anyway!
Thanks for the reply and all the work you folks do on this project,
Jon C (root)
:)
On Thu, Sep 3, 2026, at 6:12 PM, Arne Schwabe wrote:
> Am 03.09.26 um 23:37 schrieb Jon Chiappetta via Openvpn-devel:
>> Hey all,
>>
>> I've been busy in life and I haven't had much time to keep up with the development of the OVPN source code and all the commits and everything (it's been a little while since I last posted). I ended up creating a custom framework for my own personal use that is based on the original modifications I did for OpenVPN (multi-threaded, bulk-reads, TCP-only, standard-MTU). I was able to get over a gigabit speeds on my wifi client with this network-wide VPN solution I have now.
>>
>> I found these 2 new-to-me parameters for TUN interfaces which are really cool and I didn't know existed (I also didn't see them last time I checked the source code here) - IFF_MULTI_QUEUE | IFF_VNET_HDR. Obviously the multi-queue flag wouldn't work by default here (since it's not multi-threaded) however this other one is pretty nice if you adjust your buffer sizes to be much bigger :)
>>
>> For example, I was able to read thousands of bytes of data in one call from TUN if you set the below parameters in C:
>>
>> ifrq.ifr_flags = (IFF_TUN | IFF_NO_PI | IFF_MULTI_QUEUE | IFF_VNET_HDR);
>> TUNF[z] = open("/dev/net/tun", O_RDWR);
>> ...
>> erro = ioctl(TUNF[z], TUNSETIFF, &ifrq);
>> if (erro < 0) { printf("%s ERRO TUNSETIFF [%d]\n", date(), z); }
>> ...
>> int leng = sizeof(struct virtio_net_hdr);
>> erro = ioctl(TUNF[z], TUNSETVNETHDRSZ, &leng);
>> ...
>> if (erro < 0) { printf("%s ERRO TUNSETVNETHDRSZ [%d]\n", date(), z); }
>> unsigned int offl = (TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6);
>> ...
>> erro = ioctl(TUNF[z], TUNSETOFFLOAD, offl);
>> if (erro < 0) { printf("%s ERRO TUNSETOFFLOAD [%d]\n", date(), z); }
>>
>> I don't know the full history here yet and am still learning but was this option ever considered to be implemented for OpenVPN?
>
> I had a quick look into what IFF_VNET_HDR does. And it seem that
> IFF_VNET_HDR does GSO/GRO and basically merging multiple packets into
> one on receive and send. This works probably well on a client as that
> does not forward IP packets. For an OpenVPN server, this will probably
> really mess with the packets as it changes the segmentation of the
> packets traversing the OpenVPN server. This will probably work for 95%
> of traffic and cause extremely hard to debug problems on the rest of them.
>
> Soe this needs a lot more careful consideration when we could use this
> flag as MTU related problem are already often present on connection and
> this flag has the potential to cause more of them.
>
> Arne