mbox series

[net-next,v2,00/22] Introducing OpenVPN Data Channel Offload

Message ID 20240304150914.11444-1-antonio@openvpn.net (mailing list archive)
Headers show
Series Introducing OpenVPN Data Channel Offload | expand

Message

Antonio Quartulli March 4, 2024, 3:08 p.m. UTC
Hi all!

After the comments received last month, I reworked the large patch that
I have previously sent and I came up with this patchset hoping to make
the review process more human and less cumbersome.

Some features are stricly intertwined with each other, therefore I
couldn't split everything up to the very last grain of salt, but I did
my best to create a reasonable set of features that add up on top of
each other.

I don't expect the kernel module to work between intermediate
patches, therefore it is important that all patches are applied if you
want to see something meaningful happening.


The following is just the introductory text from v1. It's a useful
summary of what this new kernel module represents.

As an intereting note, an earlier version of this kernel module is already
being used by quite some OpenVPN users out there claiming important
improvements in terms of performance. By merging the ovpn kernel module
upstream we were hoping to extend cooperation beyond the mere OpenVPN
community.

===================================================================

`ovpn` is essentialy a device driver that allows creating a virtual
network interface to handle the OpenVPN data channel. Any traffic
entering the interface is encrypted, encapsulated and sent to the
appropriate destination.

`ovpn` requires OpenVPN in userspace
to run along its side in order to be properly configured and maintained
during its life cycle.

The `ovpn` interface can be created/destroyed and then
configured via Netlink API.

Specifically OpenVPN in userspace will:
* create the `ovpn` interface
* establish the connection with one or more peers
* perform TLS handshake and negotiate any protocol parameter
* configure the `ovpn` interface with peer data (ip/port, keys, etc.)
* handle any subsequent control channel communication

I'd like to point out the control channel is fully handles in userspace.
The idea is to keep the `ovpn` kernel module as simple as possible and
let userspace handle all the non-data (non-fast-path) features.

NOTE: some of you may already know `ovpn-dco` the out-of-tree predecessor
of `ovpn`. However, be aware that the two are not API compatible and
therefore OpenVPN 2.6 will not work with this new `ovpn` module.
More adjustments are required.

If you want to test the `ovpn` kernel module, for the time being you can
use the testing tool `ovpn-cli` available here:
https://github.com/OpenVPN/ovpn-dco/tree/master/tests

The `ovpn` code can also be built as out-of-tree module and its code is
available here https://github.com/OpenVPN/ovpn-dco (currently in the dev
branch).

For more technical details please refer to the actual patches.

Any comment, concern or statement will be appreciated!
Thanks a lot!!

Best Regards,

Antonio Quartulli
OpenVPN Inc.

======================

Antonio Quartulli (22):
  netlink: add NLA_POLICY_MAX_LEN macro
  net: introduce OpenVPN Data Channel Offload (ovpn)
  ovpn: add basic netlink support
  ovpn: add basic interface creation/destruction/management routines
  ovpn: implement interface creation/destruction via netlink
  ovpn: introduce the ovpn_peer object
  ovpn: introduce the ovpn_socket object
  ovpn: implement basic TX path (UDP)
  ovpn: implement basic RX path (UDP)
  ovpn: implement packet processing
  ovpn: store tunnel and transport statistics
  ovpn: implement TCP transport
  ovpn: implement multi-peer support
  ovpn: implement peer lookup logic
  ovpn: implement keepalive mechanism
  ovpn: add support for updating local UDP endpoint
  ovpn: add support for peer floating
  ovpn: implement peer add/dump/delete via netlink
  ovpn: implement key add/del/swap via netlink
  ovpn: kill key and notify userspace in case of IV exhaustion
  ovpn: notify userspace when a peer is deleted
  ovpn: add basic ethtool support

 MAINTAINERS                    |    8 +
 drivers/net/Kconfig            |   13 +
 drivers/net/Makefile           |    1 +
 drivers/net/ovpn/Makefile      |   21 +
 drivers/net/ovpn/bind.c        |   60 ++
 drivers/net/ovpn/bind.h        |   91 +++
 drivers/net/ovpn/crypto.c      |  154 +++++
 drivers/net/ovpn/crypto.h      |  144 +++++
 drivers/net/ovpn/crypto_aead.c |  366 +++++++++++
 drivers/net/ovpn/crypto_aead.h |   27 +
 drivers/net/ovpn/io.c          |  533 ++++++++++++++++
 drivers/net/ovpn/io.h          |   29 +
 drivers/net/ovpn/main.c        |  280 +++++++++
 drivers/net/ovpn/main.h        |   38 ++
 drivers/net/ovpn/netlink.c     | 1045 ++++++++++++++++++++++++++++++++
 drivers/net/ovpn/netlink.h     |   22 +
 drivers/net/ovpn/ovpnstruct.h  |   58 ++
 drivers/net/ovpn/packet.h      |   44 ++
 drivers/net/ovpn/peer.c        |  929 ++++++++++++++++++++++++++++
 drivers/net/ovpn/peer.h        |  176 ++++++
 drivers/net/ovpn/pktid.c       |  126 ++++
 drivers/net/ovpn/pktid.h       |   90 +++
 drivers/net/ovpn/proto.h       |  101 +++
 drivers/net/ovpn/skb.h         |   51 ++
 drivers/net/ovpn/socket.c      |  140 +++++
 drivers/net/ovpn/socket.h      |   57 ++
 drivers/net/ovpn/stats.c       |   21 +
 drivers/net/ovpn/stats.h       |   51 ++
 drivers/net/ovpn/tcp.c         |  474 +++++++++++++++
 drivers/net/ovpn/tcp.h         |   41 ++
 drivers/net/ovpn/udp.c         |  355 +++++++++++
 drivers/net/ovpn/udp.h         |   23 +
 include/net/netlink.h          |    1 +
 include/uapi/linux/ovpn.h      |  174 ++++++
 include/uapi/linux/udp.h       |    1 +
 35 files changed, 5745 insertions(+)
 create mode 100644 drivers/net/ovpn/Makefile
 create mode 100644 drivers/net/ovpn/bind.c
 create mode 100644 drivers/net/ovpn/bind.h
 create mode 100644 drivers/net/ovpn/crypto.c
 create mode 100644 drivers/net/ovpn/crypto.h
 create mode 100644 drivers/net/ovpn/crypto_aead.c
 create mode 100644 drivers/net/ovpn/crypto_aead.h
 create mode 100644 drivers/net/ovpn/io.c
 create mode 100644 drivers/net/ovpn/io.h
 create mode 100644 drivers/net/ovpn/main.c
 create mode 100644 drivers/net/ovpn/main.h
 create mode 100644 drivers/net/ovpn/netlink.c
 create mode 100644 drivers/net/ovpn/netlink.h
 create mode 100644 drivers/net/ovpn/ovpnstruct.h
 create mode 100644 drivers/net/ovpn/packet.h
 create mode 100644 drivers/net/ovpn/peer.c
 create mode 100644 drivers/net/ovpn/peer.h
 create mode 100644 drivers/net/ovpn/pktid.c
 create mode 100644 drivers/net/ovpn/pktid.h
 create mode 100644 drivers/net/ovpn/proto.h
 create mode 100644 drivers/net/ovpn/skb.h
 create mode 100644 drivers/net/ovpn/socket.c
 create mode 100644 drivers/net/ovpn/socket.h
 create mode 100644 drivers/net/ovpn/stats.c
 create mode 100644 drivers/net/ovpn/stats.h
 create mode 100644 drivers/net/ovpn/tcp.c
 create mode 100644 drivers/net/ovpn/tcp.h
 create mode 100644 drivers/net/ovpn/udp.c
 create mode 100644 drivers/net/ovpn/udp.h
 create mode 100644 include/uapi/linux/ovpn.h

Comments

Sergey Ryazanov March 4, 2024, 9:07 p.m. UTC | #1
Hello Antonio,

On 04.03.2024 17:08, Antonio Quartulli wrote:
> Hi all!
> 
> After the comments received last month, I reworked the large patch that
> I have previously sent and I came up with this patchset hoping to make
> the review process more human and less cumbersome.
> 
> Some features are stricly intertwined with each other, therefore I
> couldn't split everything up to the very last grain of salt, but I did
> my best to create a reasonable set of features that add up on top of
> each other.
> 
> I don't expect the kernel module to work between intermediate
> patches, therefore it is important that all patches are applied if you
> want to see something meaningful happening.
> 
> 
> The following is just the introductory text from v1. It's a useful
> summary of what this new kernel module represents.
> 
> As an intereting note, an earlier version of this kernel module is already
> being used by quite some OpenVPN users out there claiming important
> improvements in terms of performance. By merging the ovpn kernel module
> upstream we were hoping to extend cooperation beyond the mere OpenVPN
> community.
> 
> ===================================================================
> 
> `ovpn` is essentialy a device driver that allows creating a virtual
> network interface to handle the OpenVPN data channel. Any traffic
> entering the interface is encrypted, encapsulated and sent to the
> appropriate destination.
> 
> `ovpn` requires OpenVPN in userspace
> to run along its side in order to be properly configured and maintained
> during its life cycle.
> 
> The `ovpn` interface can be created/destroyed and then
> configured via Netlink API.
> 
> Specifically OpenVPN in userspace will:
> * create the `ovpn` interface
> * establish the connection with one or more peers
> * perform TLS handshake and negotiate any protocol parameter
> * configure the `ovpn` interface with peer data (ip/port, keys, etc.)
> * handle any subsequent control channel communication
> 
> I'd like to point out the control channel is fully handles in userspace.
> The idea is to keep the `ovpn` kernel module as simple as possible and
> let userspace handle all the non-data (non-fast-path) features.
> 
> NOTE: some of you may already know `ovpn-dco` the out-of-tree predecessor
> of `ovpn`. However, be aware that the two are not API compatible and
> therefore OpenVPN 2.6 will not work with this new `ovpn` module.
> More adjustments are required.
> 
> If you want to test the `ovpn` kernel module, for the time being you can
> use the testing tool `ovpn-cli` available here:
> https://github.com/OpenVPN/ovpn-dco/tree/master/tests
> 
> The `ovpn` code can also be built as out-of-tree module and its code is
> available here https://github.com/OpenVPN/ovpn-dco (currently in the dev
> branch).
> 
> For more technical details please refer to the actual patches.
> 
> Any comment, concern or statement will be appreciated!
> Thanks a lot!!

Thank you for preparing this series. I briefly check it and now it looks 
much more promising!

I will do my best to do a careful review in a reasonable time, but 
please expected a delay in a few weeks :( It still a considerable amount 
of code for checking, despite it's well arrangement.

--
Sergey
Jakub Kicinski March 5, 2024, 7:30 p.m. UTC | #2
On Mon,  4 Mar 2024 16:08:51 +0100 Antonio Quartulli wrote:
>  create mode 100644 drivers/net/ovpn/Makefile
>  create mode 100644 drivers/net/ovpn/bind.c
>  create mode 100644 drivers/net/ovpn/bind.h
>  create mode 100644 drivers/net/ovpn/crypto.c
>  create mode 100644 drivers/net/ovpn/crypto.h
>  create mode 100644 drivers/net/ovpn/crypto_aead.c
>  create mode 100644 drivers/net/ovpn/crypto_aead.h
>  create mode 100644 drivers/net/ovpn/io.c
>  create mode 100644 drivers/net/ovpn/io.h
>  create mode 100644 drivers/net/ovpn/main.c
>  create mode 100644 drivers/net/ovpn/main.h
>  create mode 100644 drivers/net/ovpn/netlink.c
>  create mode 100644 drivers/net/ovpn/netlink.h
>  create mode 100644 drivers/net/ovpn/ovpnstruct.h
>  create mode 100644 drivers/net/ovpn/packet.h
>  create mode 100644 drivers/net/ovpn/peer.c
>  create mode 100644 drivers/net/ovpn/peer.h
>  create mode 100644 drivers/net/ovpn/pktid.c
>  create mode 100644 drivers/net/ovpn/pktid.h
>  create mode 100644 drivers/net/ovpn/proto.h
>  create mode 100644 drivers/net/ovpn/skb.h
>  create mode 100644 drivers/net/ovpn/socket.c
>  create mode 100644 drivers/net/ovpn/socket.h
>  create mode 100644 drivers/net/ovpn/stats.c
>  create mode 100644 drivers/net/ovpn/stats.h
>  create mode 100644 drivers/net/ovpn/tcp.c
>  create mode 100644 drivers/net/ovpn/tcp.h
>  create mode 100644 drivers/net/ovpn/udp.c
>  create mode 100644 drivers/net/ovpn/udp.h
>  create mode 100644 include/uapi/linux/ovpn.h

At a glance you seem to be missing:
 - documentation
 - YAML spec for the netlink protocol -
   https://docs.kernel.org/next/userspace-api/netlink/specs.html
 - some basic set of tests (or mention that you'll run your own CI
   and report results to us: https://netdev.bots.linux.dev/status.html)
:)
Antonio Quartulli March 6, 2024, 3:44 p.m. UTC | #3
On 05/03/2024 20:30, Jakub Kicinski wrote:
> On Mon,  4 Mar 2024 16:08:51 +0100 Antonio Quartulli wrote:
>>   create mode 100644 drivers/net/ovpn/Makefile
>>   create mode 100644 drivers/net/ovpn/bind.c
>>   create mode 100644 drivers/net/ovpn/bind.h
>>   create mode 100644 drivers/net/ovpn/crypto.c
>>   create mode 100644 drivers/net/ovpn/crypto.h
>>   create mode 100644 drivers/net/ovpn/crypto_aead.c
>>   create mode 100644 drivers/net/ovpn/crypto_aead.h
>>   create mode 100644 drivers/net/ovpn/io.c
>>   create mode 100644 drivers/net/ovpn/io.h
>>   create mode 100644 drivers/net/ovpn/main.c
>>   create mode 100644 drivers/net/ovpn/main.h
>>   create mode 100644 drivers/net/ovpn/netlink.c
>>   create mode 100644 drivers/net/ovpn/netlink.h
>>   create mode 100644 drivers/net/ovpn/ovpnstruct.h
>>   create mode 100644 drivers/net/ovpn/packet.h
>>   create mode 100644 drivers/net/ovpn/peer.c
>>   create mode 100644 drivers/net/ovpn/peer.h
>>   create mode 100644 drivers/net/ovpn/pktid.c
>>   create mode 100644 drivers/net/ovpn/pktid.h
>>   create mode 100644 drivers/net/ovpn/proto.h
>>   create mode 100644 drivers/net/ovpn/skb.h
>>   create mode 100644 drivers/net/ovpn/socket.c
>>   create mode 100644 drivers/net/ovpn/socket.h
>>   create mode 100644 drivers/net/ovpn/stats.c
>>   create mode 100644 drivers/net/ovpn/stats.h
>>   create mode 100644 drivers/net/ovpn/tcp.c
>>   create mode 100644 drivers/net/ovpn/tcp.h
>>   create mode 100644 drivers/net/ovpn/udp.c
>>   create mode 100644 drivers/net/ovpn/udp.h
>>   create mode 100644 include/uapi/linux/ovpn.h
> 
> At a glance you seem to be missing:
>   - documentation
>   - YAML spec for the netlink protocol -
>     https://docs.kernel.org/next/userspace-api/netlink/specs.html

triple ACK on the doc :) will add more.

>   - some basic set of tests (or mention that you'll run your own CI
>     and report results to us: https://netdev.bots.linux.dev/status.html)

I currently have a small userspace tool (that implements the netlink 
APIs) and a script that by means of netns and this tool runs a bunch of 
tests.

Is there any requirement about how the test should work so that I can 
make it compatible with your harness? I will then push it to 
/tools/testing/selftests/ovpn so that you can pick it up.

Thanks a lot!

Regards,

> :)
Jakub Kicinski March 6, 2024, 4:13 p.m. UTC | #4
On Wed, 6 Mar 2024 16:44:41 +0100 Antonio Quartulli wrote:
> >   - some basic set of tests (or mention that you'll run your own CI
> >     and report results to us: https://netdev.bots.linux.dev/status.html)  
> 
> I currently have a small userspace tool (that implements the netlink 
> APIs) and a script that by means of netns and this tool runs a bunch of 
> tests.
> 
> Is there any requirement about how the test should work so that I can 
> make it compatible with your harness? I will then push it to 
> /tools/testing/selftests/ovpn so that you can pick it up.

Standard kernel selftest rules apply, we try to keep it pretty vanilla.
Test should exit with 0 on success, 1 on fail, and 4 on skip.
Skip if there are any missing dependencies in the test environment.

This has more deets on how we execute the tests:
https://github.com/linux-netdev/nipa/wiki/How-to-run-netdev-selftests-CI-style
Antonio Quartulli March 8, 2024, 12:21 a.m. UTC | #5
On 06/03/2024 17:13, Jakub Kicinski wrote:
> On Wed, 6 Mar 2024 16:44:41 +0100 Antonio Quartulli wrote:
>>>    - some basic set of tests (or mention that you'll run your own CI
>>>      and report results to us: https://netdev.bots.linux.dev/status.html)
>>
>> I currently have a small userspace tool (that implements the netlink
>> APIs) and a script that by means of netns and this tool runs a bunch of
>> tests.
>>
>> Is there any requirement about how the test should work so that I can
>> make it compatible with your harness? I will then push it to
>> /tools/testing/selftests/ovpn so that you can pick it up.
> 
> Standard kernel selftest rules apply, we try to keep it pretty vanilla.
> Test should exit with 0 on success, 1 on fail, and 4 on skip.
> Skip if there are any missing dependencies in the test environment.

Perfect

> 
> This has more deets on how we execute the tests:
> https://github.com/linux-netdev/nipa/wiki/How-to-run-netdev-selftests-CI-style

Thanks a lot for this!

Regards,