From patchwork Fri Dec 6 21:18:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 13897759 Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A85F81F3D4C for ; Fri, 6 Dec 2024 21:18:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733519927; cv=none; b=sOLAg5+lRRKPgVyS8GbCz4abLAiy2FJfsaf+Tm6fL7vZUV2zLbdnTCieMZINUfY82QGKSDdKEcqnXiGHm1KIoDAKxP0R6iED2RS3iGPovl4VIhiKG5B1Ym0ukGmsJKhylJedO3v3gaepfjy78UlplMlvP0jEP5b6RD7L56QHmVk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733519927; c=relaxed/simple; bh=Gm3qMOOrhFS5KbClvr5Vuxn/Cz6BoXOHLi0W7qkVsCo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=RljqKjZfJ0BTp8dBd3t66GGEK/fEGbsW2GsVHtWpqYmgWpoVpX/8BTPYTqOvJDc3e+XqQsjy57fjMr9HX4BHsbhcfvKviTvqGqkOkH+4EB1y+eh3ynbSBQVrlIoSFmp6Zj42x8qWPu1m+7aw9qYvCg7JAAl4blB285KhuEUe918= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=openvpn.net; spf=pass smtp.mailfrom=openvpn.com; dkim=pass (2048-bit key) header.d=openvpn.net header.i=@openvpn.net header.b=VXilcwvu; arc=none smtp.client-ip=209.85.128.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=openvpn.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=openvpn.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=openvpn.net header.i=@openvpn.net header.b="VXilcwvu" Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-434e398d28cso3440125e9.3 for ; Fri, 06 Dec 2024 13:18:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvpn.net; s=google; t=1733519923; x=1734124723; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=giwDlU+R5dTUnBam3akNI1X1xsvwSGinfbQy4l6MDTM=; b=VXilcwvulaDQ4wbzVCx2uq/OgdJucWq890nkmJUxdF7MbTtf1ldun0VdfYbShKiN1j V0o/0yHhA7KsnxXYbxGe6HNPElxQUQ0B3PT9Bazcz9vaeZITtLAEX4AM3lGkIKf6SMGR 4W1UJjInEpj+2Kblk7f2CYkvzFYkrpK2xSeEqg9ltnNswom2nawyop8Dz3jDzqlh5ysR TJ73uRNJ3nH3D0nXxVouI5p5Vrf4TMBe4GXSKGLIU1Utfx+dX5/vktN1H987Bq8ZBrTy bGSM5cSBIRAf/bp/xUcL1tOxM+TKTOKpofwIS9x8xLUmPwMeXK6Qh3wBzfRC4XC9/OsU FPPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733519923; x=1734124723; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=giwDlU+R5dTUnBam3akNI1X1xsvwSGinfbQy4l6MDTM=; b=B5Z43wTxYVKRJq90BqmO/MYLQaTi+EnKjzAVEmL33iTkof0uY3K0//TY0xdTwhSeFY zPwK2iGVjF6E/KsILSeev1mSDW59OAAHzOMb3N+kHkHnvd4AI59SagMmM+7C1gmgU7q7 Ym3sc7pBnQ+G0a3cU+zHAk6O3MhadiwMWCACmLiwoRhDy/YA2lEdix7kNH4FX2O3fb3f AVzYwt1sCrpgm3Tf67nrKKAcrEa+viMC+af7SoXwFABF/wMt/Euz114IMg1tYHdxLFWK nGKUb93aRr0w4/Ni8DthD3+cdPdr+uzDC4l3S1janBP9BHxmSo0HeJZXmATBW2Ijp/7B 8OBQ== X-Forwarded-Encrypted: i=1; AJvYcCXZVxhnawM98Sr/EUI9OpiVWiGBl0syWUEoi1xkZOPfCLQ/xwpCQkN/5S/i+eGs5J9ahVjZybcOdRGlZC+AsgY=@vger.kernel.org X-Gm-Message-State: AOJu0Yygg+IXh+Yun8t278A/wRMbT/0iia/XH03p5HV24u7162TeduJ6 BRmhk9a4DfsXVp2t9gt0rVGTTGR7XoRTGPI+QcIAMV2Wrp0GC7AGw8lpq9URUKw= X-Gm-Gg: ASbGncvdSdGM1WlaCeszJ69PaoOri8xDxmaNDmBBG1Jd2orsQOnWx3hBzVfERAJWBKU 4AoXvDF86942lVawjrAmdo8y6oAVoEWg1UeOtWlvZtPT1LR3Y4eX2wZfrtn6uF6VZu75Cehfp4P TA3ET7p7d5cpqTbvyWqbtlzDGW2rugsKwuCKPBMdk+VijPT0xjF06Zj5+Ljx8Vc4h22VBlykHzI 5nVrUB/Ct3+gun4os5eI64htddO24lMNj0cnrinmMrJHgptE6jId+o0KtGZBA== X-Google-Smtp-Source: AGHT+IGEWhlGb5XKuuCx/41TEHLu9agp0Is/Lssessxf73SRttT8AHZQfFbpRZ3ZhlevFoYaqbxfxw== X-Received: by 2002:a5d:6da5:0:b0:385:f195:27f with SMTP id ffacd0b85a97d-3862b33b9d3mr3549648f8f.5.1733519922992; Fri, 06 Dec 2024 13:18:42 -0800 (PST) Received: from serenity.mandelbit.com ([2001:67c:2fbc:1:3cee:9adf:5d38:601e]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3861fd46839sm5441302f8f.52.2024.12.06.13.18.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 06 Dec 2024 13:18:41 -0800 (PST) From: Antonio Quartulli Date: Fri, 06 Dec 2024 22:18:26 +0100 Subject: [PATCH net-next v13 01/22] net: introduce OpenVPN Data Channel Offload (ovpn) Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241206-b4-ovpn-v13-1-67fb4be666e2@openvpn.net> References: <20241206-b4-ovpn-v13-0-67fb4be666e2@openvpn.net> In-Reply-To: <20241206-b4-ovpn-v13-0-67fb4be666e2@openvpn.net> To: netdev@vger.kernel.org, Eric Dumazet , Jakub Kicinski , Paolo Abeni , Donald Hunter , Antonio Quartulli , Shuah Khan , sd@queasysnail.net, ryazanov.s.a@gmail.com, Andrew Lunn Cc: Simon Horman , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, steffen.klassert@secunet.com, antony.antony@secunet.com X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=8900; i=antonio@openvpn.net; h=from:subject:message-id; bh=Gm3qMOOrhFS5KbClvr5Vuxn/Cz6BoXOHLi0W7qkVsCo=; b=owEBbQGS/pANAwAIAQtw5TqgONWHAcsmYgBnU2pWj1Q8YE94FGYLcfJWv/gbDi8NkRFJfD9Dd XpJe14lD+qJATMEAAEIAB0WIQSZq9xs+NQS5N5fwPwLcOU6oDjVhwUCZ1NqVgAKCRALcOU6oDjV hxs1B/41awksTZ7WwhZqzok2yG2b28eQLk5pT7wRnlE0vcB9CRy3j8/840MXkmDmby3X1Z62o9L Sc3O+epKTbZtarzD3nJcpY/Bs4XlauF/GarfKwKBlAShBc2NPZrbjOegr2K0aQR43DbwcQPKom8 jjs98bV7qSrLB8s9Rd8tKUtzv0SkdwOP1mqi2DMTSNH6YjuaMYq8nvmvh5BdH0Oz/mY3DM1CFae w+gAf/+OslmybbuSx5spUqw3X2flp8fquerahE0ePK8d/vtROFKCwNZEPfFWN7yxRrR5mdH4cem U06Enwrh+DmxcBErv64ay4oJa8FbukEk5bALuXeHSRZ1zZwQ X-Developer-Key: i=antonio@openvpn.net; a=openpgp; fpr=CABDA1282017C267219885C748F0CCB68F59D14C OpenVPN is a userspace software existing since around 2005 that allows users to create secure tunnels. So far OpenVPN has implemented all operations in userspace, which implies several back and forth between kernel and user land in order to process packets (encapsulate/decapsulate, encrypt/decrypt, rerouting..). With `ovpn` we intend to move the fast path (data channel) entirely in kernel space and thus improve user measured throughput over the tunnel. `ovpn` is implemented as a simple virtual network device driver, that can be manipulated by means of the standard RTNL APIs. A device of kind `ovpn` allows only IPv4/6 traffic and can be of type: * P2P (peer-to-peer): any packet sent over the interface will be encapsulated and transmitted to the other side (typical OpenVPN client or peer-to-peer behaviour); * P2MP (point-to-multipoint): packets sent over the interface are transmitted to peers based on existing routes (typical OpenVPN server behaviour). After the interface has been created, OpenVPN in userspace can configure it using a new Netlink API. Specifically it is possible to manage peers and their keys. The OpenVPN control channel is multiplexed over the same transport socket by means of OP codes. Anything that is not DATA_V2 (OpenVPN OP code for data traffic) is sent to userspace and handled there. This way the `ovpn` codebase is kept as compact as possible while focusing on handling data traffic only (fast path). Any OpenVPN control feature (like cipher negotiation, TLS handshake, rekeying, etc.) is still fully handled by the userspace process. When userspace establishes a new connection with a peer, it first performs the handshake and then passes the socket to the `ovpn` kernel module, which takes ownership. From this moment on `ovpn` will handle data traffic for the new peer. When control packets are received on the link, they are forwarded to userspace through the same transport socket they were received on, as userspace is still listening to them. Some events (like peer deletion) are sent to a Netlink multicast group. Although it wasn't easy to convince the community, `ovpn` implements only a limited number of the data-channel features supported by the userspace program. Each feature that made it to `ovpn` was attentively vetted to avoid carrying too much legacy along with us (and to give a clear cut to old and probalby-not-so-useful features). Notably, only encryption using AEAD ciphers (specifically ChaCha20Poly1305 and AES-GCM) was implemented. Supporting any other cipher out there was not deemed useful. Both UDP and TCP sockets are supported. As explained above, in case of P2MP mode, OpenVPN will use the main system routing table to decide which packet goes to which peer. This implies that no routing table was re-implemented in the `ovpn` kernel module. This kernel module can be enabled by selecting the CONFIG_OVPN entry in the networking drivers section. NOTE: this first patch introduces the very basic framework only. Features are then added patch by patch, however, although each patch will compile and possibly not break at runtime, only after having applied the full set it is expected to see the ovpn module fully working. Cc: steffen.klassert@secunet.com Cc: antony.antony@secunet.com Signed-off-by: Antonio Quartulli --- MAINTAINERS | 8 ++++ drivers/net/Kconfig | 7 +++ drivers/net/Makefile | 1 + drivers/net/ovpn/Makefile | 10 +++++ drivers/net/ovpn/main.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 138 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 0456a33ef65792bacb5d305a6384d245844fb743..6de1767f7cc80a571e0ab6e9f4dfe5650eb704d4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17472,6 +17472,14 @@ F: arch/openrisc/ F: drivers/irqchip/irq-ompic.c F: drivers/irqchip/irq-or1k-* +OPENVPN DATA CHANNEL OFFLOAD +M: Antonio Quartulli +L: openvpn-devel@lists.sourceforge.net (subscribers-only) +L: netdev@vger.kernel.org +S: Supported +T: git https://github.com/OpenVPN/linux-kernel-ovpn.git +F: drivers/net/ovpn/ + OPENVSWITCH M: Pravin B Shelar L: netdev@vger.kernel.org diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 1fd5acdc73c6af0e1a861867039c3624fc618e25..a7c5c166f9ced748d73843f81efb802072e15434 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -115,6 +115,13 @@ config WIREGUARD_DEBUG Say N here unless you know what you're doing. +config OVPN + tristate "OpenVPN data channel offload" + depends on NET && INET + help + This module enhances the performance of the OpenVPN userspace software + by offloading the data channel processing to kernelspace. + config EQUALIZER tristate "EQL (serial line load balancing) support" help diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 13743d0e83b5fde479e9b30ad736be402d880dee..5152b3330e28da7eaec821018a26c973bb33ce0c 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_IPVLAN) += ipvlan/ obj-$(CONFIG_IPVTAP) += ipvlan/ obj-$(CONFIG_DUMMY) += dummy.o obj-$(CONFIG_WIREGUARD) += wireguard/ +obj-$(CONFIG_OVPN) += ovpn/ obj-$(CONFIG_EQUALIZER) += eql.o obj-$(CONFIG_IFB) += ifb.o obj-$(CONFIG_MACSEC) += macsec.o diff --git a/drivers/net/ovpn/Makefile b/drivers/net/ovpn/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..ae19cf445b29367da680e226f06a341c42c892c2 --- /dev/null +++ b/drivers/net/ovpn/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# ovpn -- OpenVPN data channel offload in kernel space +# +# Copyright (C) 2020-2024 OpenVPN, Inc. +# +# Author: Antonio Quartulli + +obj-$(CONFIG_OVPN) := ovpn.o +ovpn-y += main.o diff --git a/drivers/net/ovpn/main.c b/drivers/net/ovpn/main.c new file mode 100644 index 0000000000000000000000000000000000000000..72c56e73771cdece22e50645b29c79962f06caf3 --- /dev/null +++ b/drivers/net/ovpn/main.c @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0 +/* OpenVPN data channel offload + * + * Copyright (C) 2020-2024 OpenVPN, Inc. + * + * Author: Antonio Quartulli + * James Yonan + */ + +#include +#include +#include + +static const struct net_device_ops ovpn_netdev_ops = { +}; + +/** + * ovpn_dev_is_valid - check if the netdevice is of type 'ovpn' + * @dev: the interface to check + * + * Return: whether the netdevice is of type 'ovpn' + */ +static bool ovpn_dev_is_valid(const struct net_device *dev) +{ + return dev->netdev_ops == &ovpn_netdev_ops; +} + +static int ovpn_newlink(struct net *src_net, struct net_device *dev, + struct nlattr *tb[], struct nlattr *data[], + struct netlink_ext_ack *extack) +{ + return -EOPNOTSUPP; +} + +static struct rtnl_link_ops ovpn_link_ops = { + .kind = "ovpn", + .netns_refund = false, + .newlink = ovpn_newlink, + .dellink = unregister_netdevice_queue, +}; + +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); + + if (!ovpn_dev_is_valid(dev)) + return NOTIFY_DONE; + + switch (state) { + case NETDEV_REGISTER: + /* add device to internal list for later destruction upon + * unregistration + */ + break; + case NETDEV_UNREGISTER: + /* can be delivered multiple times, so check registered flag, + * then destroy the interface + */ + break; + case NETDEV_POST_INIT: + case NETDEV_GOING_DOWN: + case NETDEV_DOWN: + case NETDEV_UP: + case NETDEV_PRE_UP: + default: + return NOTIFY_DONE; + } + + return NOTIFY_OK; +} + +static struct notifier_block ovpn_netdev_notifier = { + .notifier_call = ovpn_netdev_notifier_call, +}; + +static int __init ovpn_init(void) +{ + int err = register_netdevice_notifier(&ovpn_netdev_notifier); + + if (err) { + pr_err("ovpn: can't register netdevice notifier: %d\n", err); + return err; + } + + err = rtnl_link_register(&ovpn_link_ops); + if (err) { + pr_err("ovpn: can't register rtnl link ops: %d\n", err); + goto unreg_netdev; + } + + return 0; + +unreg_netdev: + unregister_netdevice_notifier(&ovpn_netdev_notifier); + return err; +} + +static __exit void ovpn_cleanup(void) +{ + rtnl_link_unregister(&ovpn_link_ops); + unregister_netdevice_notifier(&ovpn_netdev_notifier); + + rcu_barrier(); +} + +module_init(ovpn_init); +module_exit(ovpn_cleanup); + +MODULE_DESCRIPTION("OpenVPN data channel offload (ovpn)"); +MODULE_AUTHOR("(C) 2020-2024 OpenVPN, Inc."); +MODULE_LICENSE("GPL");