mbox series

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

Message ID 20241209-b4-ovpn-v14-0-ea243cf16417@openvpn.net
Headers show
Series Introducing OpenVPN Data Channel Offload | expand

Message

Antonio Quartulli Dec. 9, 2024, 8:53 a.m. UTC
Notable changes since v13:
* included linux/ipv6.h in 07/22 to fix build on nios2
  (reported by kernel test robot)

Please note that some patches were already reviewed by Andre Lunn,
Donald Hunter and Shuah Khan. They have retained the Reviewed-by tag
since no major code modification has happened since the review.

The latest code can also be found at:

https://github.com/OpenVPN/linux-kernel-ovpn

Thanks a lot!
Best Regards,

Antonio Quartulli
OpenVPN Inc.

---
Antonio Quartulli (22):
      net: introduce OpenVPN Data Channel Offload (ovpn)
      ovpn: add basic netlink support
      ovpn: add basic interface creation/destruction/management routines
      ovpn: keep carrier always on for MP interfaces
      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/get/dump/delete via netlink
      ovpn: implement key add/get/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
      testing/selftests: add test tool and scripts for ovpn module

 Documentation/netlink/specs/ovpn.yaml              |  368 +++
 MAINTAINERS                                        |   11 +
 drivers/net/Kconfig                                |   14 +
 drivers/net/Makefile                               |    1 +
 drivers/net/ovpn/Makefile                          |   22 +
 drivers/net/ovpn/bind.c                            |   55 +
 drivers/net/ovpn/bind.h                            |  101 +
 drivers/net/ovpn/crypto.c                          |  211 ++
 drivers/net/ovpn/crypto.h                          |  145 ++
 drivers/net/ovpn/crypto_aead.c                     |  383 ++++
 drivers/net/ovpn/crypto_aead.h                     |   33 +
 drivers/net/ovpn/io.c                              |  445 ++++
 drivers/net/ovpn/io.h                              |   34 +
 drivers/net/ovpn/main.c                            |  339 +++
 drivers/net/ovpn/main.h                            |   14 +
 drivers/net/ovpn/netlink-gen.c                     |  212 ++
 drivers/net/ovpn/netlink-gen.h                     |   41 +
 drivers/net/ovpn/netlink.c                         | 1180 ++++++++++
 drivers/net/ovpn/netlink.h                         |   18 +
 drivers/net/ovpn/ovpnstruct.h                      |   57 +
 drivers/net/ovpn/peer.c                            | 1266 +++++++++++
 drivers/net/ovpn/peer.h                            |  163 ++
 drivers/net/ovpn/pktid.c                           |  129 ++
 drivers/net/ovpn/pktid.h                           |   87 +
 drivers/net/ovpn/proto.h                           |  118 +
 drivers/net/ovpn/skb.h                             |   59 +
 drivers/net/ovpn/socket.c                          |  180 ++
 drivers/net/ovpn/socket.h                          |   55 +
 drivers/net/ovpn/stats.c                           |   21 +
 drivers/net/ovpn/stats.h                           |   47 +
 drivers/net/ovpn/tcp.c                             |  578 +++++
 drivers/net/ovpn/tcp.h                             |   33 +
 drivers/net/ovpn/udp.c                             |  398 ++++
 drivers/net/ovpn/udp.h                             |   23 +
 include/uapi/linux/if_link.h                       |   15 +
 include/uapi/linux/ovpn.h                          |  110 +
 include/uapi/linux/udp.h                           |    1 +
 net/ipv6/af_inet6.c                                |    1 +
 tools/testing/selftests/Makefile                   |    1 +
 tools/testing/selftests/net/ovpn/.gitignore        |    2 +
 tools/testing/selftests/net/ovpn/Makefile          |   17 +
 tools/testing/selftests/net/ovpn/config            |   10 +
 tools/testing/selftests/net/ovpn/data64.key        |    5 +
 tools/testing/selftests/net/ovpn/ovpn-cli.c        | 2370 ++++++++++++++++++++
 tools/testing/selftests/net/ovpn/tcp_peers.txt     |    5 +
 .../testing/selftests/net/ovpn/test-chachapoly.sh  |    9 +
 tools/testing/selftests/net/ovpn/test-float.sh     |    9 +
 tools/testing/selftests/net/ovpn/test-tcp.sh       |    9 +
 tools/testing/selftests/net/ovpn/test.sh           |  182 ++
 tools/testing/selftests/net/ovpn/udp_peers.txt     |    5 +
 50 files changed, 9592 insertions(+)
---
base-commit: 7ea2745766d776866cfbc981b21ed3cfdf50124e
change-id: 20241002-b4-ovpn-eeee35c694a2

Best regards,

Comments

Simon Horman Dec. 10, 2024, 4:44 p.m. UTC | #1
On Mon, Dec 09, 2024 at 09:53:17AM +0100, Antonio Quartulli wrote:
> Packets received over the socket are forwarded to the user device.
> 
> Implementation is UDP only. TCP will be added by a later patch.
> 
> Note: no decryption/decapsulation exists yet, packets are forwarded as
> they arrive without much processing.
> 
> Signed-off-by: Antonio Quartulli <antonio@openvpn.net>

...

> diff --git a/drivers/net/ovpn/udp.c b/drivers/net/ovpn/udp.c
> index c0e7aa289ad3345fcd91e7c890f70961300c356f..975392fc39bc4c0107a07a53795afecd88d72c53 100644
> --- a/drivers/net/ovpn/udp.c
> +++ b/drivers/net/ovpn/udp.c
> @@ -23,9 +23,83 @@
>  #include "bind.h"
>  #include "io.h"
>  #include "peer.h"
> +#include "proto.h"
>  #include "socket.h"
>  #include "udp.h"
>  
> +/**
> + * ovpn_udp_encap_recv - Start processing a received UDP packet.
> + * @sk: socket over which the packet was received
> + * @skb: the received packet
> + *
> + * If the first byte of the payload is DATA_V2, the packet is further processed,
> + * otherwise it is forwarded to the UDP stack for delivery to user space.
> + *
> + * Return:
> + *  0 if skb was consumed or dropped
> + * >0 if skb should be passed up to userspace as UDP (packet not consumed)
> + * <0 if skb should be resubmitted as proto -N (packet not consumed)
> + */
> +static int ovpn_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
> +{
> +	struct ovpn_priv *ovpn;
> +	struct ovpn_peer *peer;
> +	u32 peer_id;
> +	u8 opcode;
> +
> +	ovpn = ovpn_from_udp_sock(sk);
> +	if (unlikely(!ovpn)) {
> +		net_err_ratelimited("%s: cannot obtain ovpn object from UDP socket\n",
> +				    netdev_name(ovpn->dev));

Hi Antonio,

If we reach here then ovpn is NULL.
But the like above dereferences it.

Flagged by Smatch.

> +		goto drop_noovpn;
> +	}

...
Simon Horman Dec. 10, 2024, 4:47 p.m. UTC | #2
On Mon, Dec 09, 2024 at 09:53:31AM +0100, Antonio Quartulli wrote:
> The ovpn-cli tool can be compiled and used as selftest for the ovpn
> kernel module.
> 
> [NOTE: it depends on libmedtls for decoding base64-encoded keys]
> 
> ovpn-cli implements the netlink and RTNL APIs and can thus be integrated
> in any script for more automated testing.
> 
> Along with the tool, 4 scripts are provided that perform basic
> functionality tests by means of network namespaces.
> These scripts take part to the kselftest automation.
> 
> The output of the scripts, which will appear in the kselftest
> reports, is a list of steps performed by the scripts plus some
> output coming from the execution of `ping`, `iperf` and `ovpn-cli`
> itself.
> In general it is useful only in case of failure, in order to
> understand which step has failed and why.
> 
> Cc: linux-kselftest@vger.kernel.org
> Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
> Reviewed-by: Shuah Khan <skhan@linuxfoundation.org>

...

> +/**
> + * Helper function used to easily add attributes to a rtnl message
> + */

Hi Antonio,

This comment starts with a '/**' but is otherwise not formatted as
a Kernel doc. Probably it is best to simply start the comment with '/*'.

Likewise elsewhere in this patch.

Flagged by ./scripts/kernel-doc -none

> +static int ovpn_addattr(struct nlmsghdr *n, int maxlen, int type,
> +			const void *data, int alen)

...
Antonio Quartulli Dec. 11, 2024, 10 a.m. UTC | #3
On 10/12/2024 17:44, Simon Horman wrote:
> On Mon, Dec 09, 2024 at 09:53:17AM +0100, Antonio Quartulli wrote:
>> Packets received over the socket are forwarded to the user device.
>>
>> Implementation is UDP only. TCP will be added by a later patch.
>>
>> Note: no decryption/decapsulation exists yet, packets are forwarded as
>> they arrive without much processing.
>>
>> Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
> 
> ...
> 
>> diff --git a/drivers/net/ovpn/udp.c b/drivers/net/ovpn/udp.c
>> index c0e7aa289ad3345fcd91e7c890f70961300c356f..975392fc39bc4c0107a07a53795afecd88d72c53 100644
>> --- a/drivers/net/ovpn/udp.c
>> +++ b/drivers/net/ovpn/udp.c
>> @@ -23,9 +23,83 @@
>>   #include "bind.h"
>>   #include "io.h"
>>   #include "peer.h"
>> +#include "proto.h"
>>   #include "socket.h"
>>   #include "udp.h"
>>   
>> +/**
>> + * ovpn_udp_encap_recv - Start processing a received UDP packet.
>> + * @sk: socket over which the packet was received
>> + * @skb: the received packet
>> + *
>> + * If the first byte of the payload is DATA_V2, the packet is further processed,
>> + * otherwise it is forwarded to the UDP stack for delivery to user space.
>> + *
>> + * Return:
>> + *  0 if skb was consumed or dropped
>> + * >0 if skb should be passed up to userspace as UDP (packet not consumed)
>> + * <0 if skb should be resubmitted as proto -N (packet not consumed)
>> + */
>> +static int ovpn_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
>> +{
>> +	struct ovpn_priv *ovpn;
>> +	struct ovpn_peer *peer;
>> +	u32 peer_id;
>> +	u8 opcode;
>> +
>> +	ovpn = ovpn_from_udp_sock(sk);
>> +	if (unlikely(!ovpn)) {
>> +		net_err_ratelimited("%s: cannot obtain ovpn object from UDP socket\n",
>> +				    netdev_name(ovpn->dev));
> 
> Hi Antonio,
> 
> If we reach here then ovpn is NULL.
> But the like above dereferences it.
> 
> Flagged by Smatch.

Hi Simon,
Thanks for pointing this out. I will get this fixed and add smatch to my 
test battery.

Regards,

> 
>> +		goto drop_noovpn;
>> +	}
> 
> ...
>
Antonio Quartulli Dec. 11, 2024, 10:01 a.m. UTC | #4
On 10/12/2024 17:47, Simon Horman wrote:
> On Mon, Dec 09, 2024 at 09:53:31AM +0100, Antonio Quartulli wrote:
>> The ovpn-cli tool can be compiled and used as selftest for the ovpn
>> kernel module.
>>
>> [NOTE: it depends on libmedtls for decoding base64-encoded keys]
>>
>> ovpn-cli implements the netlink and RTNL APIs and can thus be integrated
>> in any script for more automated testing.
>>
>> Along with the tool, 4 scripts are provided that perform basic
>> functionality tests by means of network namespaces.
>> These scripts take part to the kselftest automation.
>>
>> The output of the scripts, which will appear in the kselftest
>> reports, is a list of steps performed by the scripts plus some
>> output coming from the execution of `ping`, `iperf` and `ovpn-cli`
>> itself.
>> In general it is useful only in case of failure, in order to
>> understand which step has failed and why.
>>
>> Cc: linux-kselftest@vger.kernel.org
>> Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
>> Reviewed-by: Shuah Khan <skhan@linuxfoundation.org>
> 
> ...
> 
>> +/**
>> + * Helper function used to easily add attributes to a rtnl message
>> + */
> 
> Hi Antonio,
> 
> This comment starts with a '/**' but is otherwise not formatted as
> a Kernel doc. Probably it is best to simply start the comment with '/*'.
> 
> Likewise elsewhere in this patch.

Will fix all instances of this issue.

> 
> Flagged by ./scripts/kernel-doc -none

Darn, I have been running kernel-doc only against drivers/net/ovpn.
Thanks for pointing this out.

Regards,

> 
>> +static int ovpn_addattr(struct nlmsghdr *n, int maxlen, int type,
>> +			const void *data, int alen)
> 
> ...