lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <cfd45410-a7b2-4304-a376-1d7a3b443a13@openvpn.net>
Date: Fri, 15 Nov 2024 14:00:31 +0100
From: Antonio Quartulli <antonio@...nvpn.net>
To: Sergey Ryazanov <ryazanov.s.a@...il.com>
Cc: netdev@...r.kernel.org, Eric Dumazet <edumazet@...gle.com>,
 linux-kernel@...r.kernel.org, linux-kselftest@...r.kernel.org,
 Jakub Kicinski <kuba@...nel.org>, Paolo Abeni <pabeni@...hat.com>,
 Donald Hunter <donald.hunter@...il.com>, Shuah Khan <shuah@...nel.org>,
 sd@...asysnail.net, Andrew Lunn <andrew@...n.ch>
Subject: Re: [PATCH net-next v11 04/23] ovpn: add basic interface
 creation/destruction/management routines

On 09/11/2024 02:01, Sergey Ryazanov wrote:
> On 29.10.2024 12:47, Antonio Quartulli wrote:
>> Add basic infrastructure for handling ovpn interfaces.
>>
>> Signed-off-by: Antonio Quartulli <antonio@...nvpn.net>
>> ---
>>   drivers/net/ovpn/main.c       | 115 ++++++++++++++++++++++++++++++++ 
>> ++++++++--
>>   drivers/net/ovpn/main.h       |   7 +++
>>   drivers/net/ovpn/ovpnstruct.h |   8 +++
>>   drivers/net/ovpn/packet.h     |  40 +++++++++++++++
>>   include/uapi/linux/if_link.h  |  15 ++++++
>>   5 files changed, 180 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/net/ovpn/main.c b/drivers/net/ovpn/main.c
>> index 
>> d5bdb0055f4dd3a6e32dc6e792bed1e7fd59e101..eead7677b8239eb3c48bb26ca95492d88512b8d4 100644
>> --- a/drivers/net/ovpn/main.c
>> +++ b/drivers/net/ovpn/main.c
>> @@ -10,18 +10,52 @@
>>   #include <linux/genetlink.h>
>>   #include <linux/module.h>
>>   #include <linux/netdevice.h>
>> +#include <linux/inetdevice.h>
>> +#include <net/ip.h>
>>   #include <net/rtnetlink.h>
>> -#include <uapi/linux/ovpn.h>
>> +#include <uapi/linux/if_arp.h>
>>   #include "ovpnstruct.h"
>>   #include "main.h"
>>   #include "netlink.h"
>>   #include "io.h"
>> +#include "packet.h"
>>   /* Driver info */
>>   #define DRV_DESCRIPTION    "OpenVPN data channel offload (ovpn)"
>>   #define DRV_COPYRIGHT    "(C) 2020-2024 OpenVPN, Inc."
>> +static void ovpn_struct_free(struct net_device *net)
>> +{
>> +}
> 
> nit: since this handler is not mandatory, its introduction can be moved 
> to the later patch, which actually fills it with meaningful operations.


ehmm sure I will move it



> 
>> +static int ovpn_net_open(struct net_device *dev)
>> +{
>> +    netif_tx_start_all_queues(dev);
>> +    return 0;
>> +}
>> +
>> +static int ovpn_net_stop(struct net_device *dev)
>> +{
>> +    netif_tx_stop_all_queues(dev);
>> +    return 0;
>> +}
>> +
>> +static const struct net_device_ops ovpn_netdev_ops = {
>> +    .ndo_open        = ovpn_net_open,
>> +    .ndo_stop        = ovpn_net_stop,
>> +    .ndo_start_xmit        = ovpn_net_xmit,
>> +};
>> +
>> +static const struct device_type ovpn_type = {
>> +    .name = OVPN_FAMILY_NAME,
> 
> nit: same question here regarding name deriviation. Are you sure that 
> the device type name is the same as the GENL family name?

Like I said in the previous patch, I want all representative strings to 
be "ovpn", that is already the netlink family name.
But I can create another constant to document this explicitly.


> 
>> +};
>> +
>> +static const struct nla_policy ovpn_policy[IFLA_OVPN_MAX + 1] = {
>> +    [IFLA_OVPN_MODE] = NLA_POLICY_RANGE(NLA_U8, OVPN_MODE_P2P,
>> +                        OVPN_MODE_MP),
>> +};
>> +
>>   /**
>>    * ovpn_dev_is_valid - check if the netdevice is of type 'ovpn'
>>    * @dev: the interface to check
>> @@ -33,16 +67,76 @@ bool ovpn_dev_is_valid(const struct net_device *dev)
>>       return dev->netdev_ops->ndo_start_xmit == ovpn_net_xmit;
>>   }
>> +static void ovpn_setup(struct net_device *dev)
>> +{
>> +    /* compute the overhead considering AEAD encryption */
>> +    const int overhead = sizeof(u32) + NONCE_WIRE_SIZE + 16 +
> 
> Where are these magic sizeof(u32) and '16' came from?

It's in the "nice diagram" you commented later in this patch :-)
But I can extend the comment.

[...]


>> @@ -51,26 +145,37 @@ static int ovpn_netdev_notifier_call(struct 
>> notifier_block *nb,
>>                        unsigned long state, void *ptr)
>>   {
>>       struct net_device *dev = netdev_notifier_info_to_dev(ptr);
>> +    struct ovpn_struct *ovpn;
>>       if (!ovpn_dev_is_valid(dev))
>>           return NOTIFY_DONE;
>> +    ovpn = netdev_priv(dev);
> 
> nit: netdev_priv() returns only a pointer, it is safe to fetch the 
> pointer in advance, but do not dereference it until we are sure that an 
> event references the desired interface type. Takin this into 
> consideration, the assignment of private data pointer can be moved above 
> to the variable declaration. Just to make code couple of lines shorter.

I do it here because it seems more "logically correct" to retrieve the 
priv pointer after having confirmed that this is a ovpn interface with 
ovpn_dev_is_valid().

Moving it above kinda says "I already know there is a ovpn object here", 
but this is not the case until after the valid() check. So I prefer to 
keep it here.

[...]

>> --- a/drivers/net/ovpn/main.h
>> +++ b/drivers/net/ovpn/main.h
>> @@ -12,4 +12,11 @@
>>   bool ovpn_dev_is_valid(const struct net_device *dev);
>> +#define SKB_HEADER_LEN                                       \
>> +    (max(sizeof(struct iphdr), sizeof(struct ipv6hdr)) + \
>> +     sizeof(struct udphdr) + NET_SKB_PAD)
>> +
>> +#define OVPN_HEAD_ROOM ALIGN(16 + SKB_HEADER_LEN, 4)
> 
> Where is this magic '16' came from?

should be the same 16 af the over head above (it's the auth tag len)
Will make this more explicit with a comment.

> 
>> +#define OVPN_MAX_PADDING 16
>> +
>>   #endif /* _NET_OVPN_MAIN_H_ */
>> diff --git a/drivers/net/ovpn/ovpnstruct.h b/drivers/net/ovpn/ 
>> ovpnstruct.h
>> index 
>> e3e4df6418b081436378fc51d98db5bd7b5d1fbe..211df871538d34fdff90d182f21a0b0fb11b28ad 100644
>> --- a/drivers/net/ovpn/ovpnstruct.h
>> +++ b/drivers/net/ovpn/ovpnstruct.h
>> @@ -11,15 +11,23 @@
>>   #define _NET_OVPN_OVPNSTRUCT_H_
>>   #include <net/net_trackers.h>
>> +#include <uapi/linux/if_link.h>
>> +#include <uapi/linux/ovpn.h>
>>   /**
>>    * struct ovpn_struct - per ovpn interface state
>>    * @dev: the actual netdev representing the tunnel
>>    * @dev_tracker: reference tracker for associated dev
>> + * @registered: whether dev is still registered with netdev or not
>> + * @mode: device operation mode (i.e. p2p, mp, ..)
>> + * @dev_list: entry for the module wide device list
>>    */
>>   struct ovpn_struct {
>>       struct net_device *dev;
>>       netdevice_tracker dev_tracker;
>> +    bool registered;
>> +    enum ovpn_mode mode;
>> +    struct list_head dev_list;
> 
> dev_list is no more used and should be deleted.

ACK

[...]

>> +
>> +/* OpenVPN nonce size */
>> +#define NONCE_SIZE 12
> 
> nit: is using the common 'OVPN_' prefix here and for other constants any 
> good idea? E.g. OVPN_NONCE_SIZE. It can give some hints where it comes 
> from for a code reader.

ACK

> 
> And another one question. Could you clarify in the comment to this 
> constant where it came from? AFAIU, these 12 bytes is the expectation of 
> the nonce size of AEAD crypto protocol, rigth?

Correct: 12bytes/96bits. Will extend the comment.

> 
>> +
>> +/* OpenVPN nonce size reduced by 8-byte nonce tail -- this is the
>> + * size of the AEAD Associated Data (AD) sent over the wire
>> + * and is normally the head of the IV
>> + */
>> +#define NONCE_WIRE_SIZE (NONCE_SIZE - sizeof(struct ovpn_nonce_tail))
> 
> If the headers and IV are defined as structures, we no more need this 
> constant since the header construction will be done by a compiler 
> according to the structure layout.

yap yap. Will do this later as explained in the other email.

> 
>> +/* Last 8 bytes of AEAD nonce
>> + * Provided by userspace and usually derived from
>> + * key material generated during TLS handshake
>> + */
>> +struct ovpn_nonce_tail {
>> +    u8 u8[OVPN_NONCE_TAIL_SIZE];
>> +};
> 
> Why do you need a dadicated structure for this array? Can we declare the 
> corresponding fields like this:
> 
> u8 nonce_tail_xmit[OVPN_NONCE_TAIL_SIZE];
> u8 nonce_tail_recv[OVPN_NONCE_TAIL_SIZE];
> 

I think the original reason was to have something to pass to sizeof() 
without making it harder for the reader.

At some point I also wanted to get rid of the struct,but something 
stopped me. Not sure what was though. Will give it a try.


Thanks a lot.
Regards,

-- 
Antonio Quartulli
OpenVPN Inc.


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ