Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ovpn: add basic interface creation/destruction/management routines

Add basic infrastructure for handling ovpn interfaces.

Tested-by: Donald Hunter <donald.hunter@gmail.com>
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
Link: https://patch.msgid.link/20250415-b4-ovpn-v26-3-577f6097b964@openvpn.net
Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Antonio Quartulli and committed by
Paolo Abeni
c2d950c4 b7a63391

+201 -2
+16
Documentation/netlink/specs/rt-link.yaml
··· 938 938 entries: 939 939 - name: none 940 940 - name: default 941 + - 942 + name: ovpn-mode 943 + type: enum 944 + entries: 945 + - p2p 946 + - mp 941 947 942 948 attribute-sets: 943 949 - ··· 2278 2272 - 2279 2273 name: tailroom 2280 2274 type: u16 2275 + - 2276 + name: linkinfo-ovpn-attrs 2277 + attributes: 2278 + - 2279 + name: mode 2280 + type: u8 2281 + enum: ovpn-mode 2281 2282 2282 2283 sub-messages: 2283 2284 - ··· 2335 2322 - 2336 2323 value: netkit 2337 2324 attribute-set: linkinfo-netkit-attrs 2325 + - 2326 + value: ovpn 2327 + attribute-set: linkinfo-ovpn-attrs 2338 2328 - 2339 2329 name: linkinfo-member-data-msg 2340 2330 formats:
+1
drivers/net/ovpn/Makefile
··· 8 8 9 9 obj-$(CONFIG_OVPN) := ovpn.o 10 10 ovpn-y += main.o 11 + ovpn-y += io.o 11 12 ovpn-y += netlink.o 12 13 ovpn-y += netlink-gen.o
+22
drivers/net/ovpn/io.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* OpenVPN data channel offload 3 + * 4 + * Copyright (C) 2019-2025 OpenVPN, Inc. 5 + * 6 + * Author: James Yonan <james@openvpn.net> 7 + * Antonio Quartulli <antonio@openvpn.net> 8 + */ 9 + 10 + #include <linux/netdevice.h> 11 + #include <linux/skbuff.h> 12 + 13 + #include "io.h" 14 + 15 + /* Send user data to the network 16 + */ 17 + netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev) 18 + { 19 + skb_tx_error(skb); 20 + kfree_skb(skb); 21 + return NET_XMIT_DROP; 22 + }
+24
drivers/net/ovpn/io.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* OpenVPN data channel offload 3 + * 4 + * Copyright (C) 2019-2025 OpenVPN, Inc. 5 + * 6 + * Author: James Yonan <james@openvpn.net> 7 + * Antonio Quartulli <antonio@openvpn.net> 8 + */ 9 + 10 + #ifndef _NET_OVPN_OVPN_H_ 11 + #define _NET_OVPN_OVPN_H_ 12 + 13 + /* DATA_V2 header size with AEAD encryption */ 14 + #define OVPN_HEAD_ROOM (OVPN_OPCODE_SIZE + OVPN_NONCE_WIRE_SIZE + \ 15 + 16 /* AEAD TAG length */ + \ 16 + max(sizeof(struct udphdr), sizeof(struct tcphdr)) +\ 17 + max(sizeof(struct ipv6hdr), sizeof(struct iphdr))) 18 + 19 + /* max padding required by encryption */ 20 + #define OVPN_MAX_PADDING 16 21 + 22 + netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev); 23 + 24 + #endif /* _NET_OVPN_OVPN_H_ */
+80 -2
drivers/net/ovpn/main.c
··· 10 10 #include <linux/genetlink.h> 11 11 #include <linux/module.h> 12 12 #include <linux/netdevice.h> 13 + #include <linux/inetdevice.h> 14 + #include <net/ip.h> 13 15 #include <net/rtnetlink.h> 14 - #include <uapi/linux/ovpn.h> 16 + #include <uapi/linux/if_arp.h> 15 17 16 18 #include "ovpnpriv.h" 17 19 #include "main.h" 18 20 #include "netlink.h" 21 + #include "io.h" 22 + #include "proto.h" 19 23 20 24 static const struct net_device_ops ovpn_netdev_ops = { 25 + .ndo_start_xmit = ovpn_net_xmit, 26 + }; 27 + 28 + static const struct device_type ovpn_type = { 29 + .name = OVPN_FAMILY_NAME, 30 + }; 31 + 32 + static const struct nla_policy ovpn_policy[IFLA_OVPN_MAX + 1] = { 33 + [IFLA_OVPN_MODE] = NLA_POLICY_RANGE(NLA_U8, OVPN_MODE_P2P, 34 + OVPN_MODE_MP), 21 35 }; 22 36 23 37 /** ··· 45 31 return dev->netdev_ops == &ovpn_netdev_ops; 46 32 } 47 33 34 + static void ovpn_setup(struct net_device *dev) 35 + { 36 + netdev_features_t feat = NETIF_F_SG | NETIF_F_GSO | 37 + NETIF_F_GSO_SOFTWARE | NETIF_F_HIGHDMA; 38 + 39 + dev->needs_free_netdev = true; 40 + 41 + dev->pcpu_stat_type = NETDEV_PCPU_STAT_DSTATS; 42 + 43 + dev->netdev_ops = &ovpn_netdev_ops; 44 + 45 + dev->hard_header_len = 0; 46 + dev->addr_len = 0; 47 + dev->mtu = ETH_DATA_LEN - OVPN_HEAD_ROOM; 48 + dev->min_mtu = IPV4_MIN_MTU; 49 + dev->max_mtu = IP_MAX_MTU - OVPN_HEAD_ROOM; 50 + 51 + dev->type = ARPHRD_NONE; 52 + dev->flags = IFF_POINTOPOINT | IFF_NOARP; 53 + dev->priv_flags |= IFF_NO_QUEUE; 54 + 55 + dev->lltx = true; 56 + dev->features |= feat; 57 + dev->hw_features |= feat; 58 + dev->hw_enc_features |= feat; 59 + 60 + dev->needed_headroom = ALIGN(OVPN_HEAD_ROOM, 4); 61 + dev->needed_tailroom = OVPN_MAX_PADDING; 62 + 63 + SET_NETDEV_DEVTYPE(dev, &ovpn_type); 64 + } 65 + 48 66 static int ovpn_newlink(struct net_device *dev, 49 67 struct rtnl_newlink_params *params, 50 68 struct netlink_ext_ack *extack) 51 69 { 52 - return -EOPNOTSUPP; 70 + struct ovpn_priv *ovpn = netdev_priv(dev); 71 + struct nlattr **data = params->data; 72 + enum ovpn_mode mode = OVPN_MODE_P2P; 73 + 74 + if (data && data[IFLA_OVPN_MODE]) { 75 + mode = nla_get_u8(data[IFLA_OVPN_MODE]); 76 + netdev_dbg(dev, "setting device mode: %u\n", mode); 77 + } 78 + 79 + ovpn->dev = dev; 80 + ovpn->mode = mode; 81 + 82 + /* turn carrier explicitly off after registration, this way state is 83 + * clearly defined 84 + */ 85 + netif_carrier_off(dev); 86 + 87 + return register_netdevice(dev); 88 + } 89 + 90 + static int ovpn_fill_info(struct sk_buff *skb, const struct net_device *dev) 91 + { 92 + struct ovpn_priv *ovpn = netdev_priv(dev); 93 + 94 + if (nla_put_u8(skb, IFLA_OVPN_MODE, ovpn->mode)) 95 + return -EMSGSIZE; 96 + 97 + return 0; 53 98 } 54 99 55 100 static struct rtnl_link_ops ovpn_link_ops = { 56 101 .kind = "ovpn", 57 102 .netns_refund = false, 103 + .priv_size = sizeof(struct ovpn_priv), 104 + .setup = ovpn_setup, 105 + .policy = ovpn_policy, 106 + .maxtype = IFLA_OVPN_MAX, 58 107 .newlink = ovpn_newlink, 59 108 .dellink = unregister_netdevice_queue, 109 + .fill_info = ovpn_fill_info, 60 110 }; 61 111 62 112 static int __init ovpn_init(void)
+5
drivers/net/ovpn/ovpnpriv.h
··· 10 10 #ifndef _NET_OVPN_OVPNSTRUCT_H_ 11 11 #define _NET_OVPN_OVPNSTRUCT_H_ 12 12 13 + #include <uapi/linux/if_link.h> 14 + #include <uapi/linux/ovpn.h> 15 + 13 16 /** 14 17 * struct ovpn_priv - per ovpn interface state 15 18 * @dev: the actual netdev representing the tunnel 19 + * @mode: device operation mode (i.e. p2p, mp, ..) 16 20 */ 17 21 struct ovpn_priv { 18 22 struct net_device *dev; 23 + enum ovpn_mode mode; 19 24 }; 20 25 21 26 #endif /* _NET_OVPN_OVPNSTRUCT_H_ */
+38
drivers/net/ovpn/proto.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* OpenVPN data channel offload 3 + * 4 + * Copyright (C) 2020-2025 OpenVPN, Inc. 5 + * 6 + * Author: Antonio Quartulli <antonio@openvpn.net> 7 + * James Yonan <james@openvpn.net> 8 + */ 9 + 10 + #ifndef _NET_OVPN_PROTO_H_ 11 + #define _NET_OVPN_PROTO_H_ 12 + 13 + /* When the OpenVPN protocol is ran in AEAD mode, use 14 + * the OpenVPN packet ID as the AEAD nonce: 15 + * 16 + * 00000005 521c3b01 4308c041 17 + * [seq # ] [ nonce_tail ] 18 + * [ 12-byte full IV ] -> OVPN_NONCE_SIZE 19 + * [4-bytes -> OVPN_NONCE_WIRE_SIZE 20 + * on wire] 21 + */ 22 + 23 + /* nonce size (96bits) as required by AEAD ciphers */ 24 + #define OVPN_NONCE_SIZE 12 25 + /* last 8 bytes of AEAD nonce: provided by userspace and usually derived 26 + * from key material generated during TLS handshake 27 + */ 28 + #define OVPN_NONCE_TAIL_SIZE 8 29 + 30 + /* OpenVPN nonce size reduced by 8-byte nonce tail -- this is the 31 + * size of the AEAD Associated Data (AD) sent over the wire 32 + * and is normally the head of the IV 33 + */ 34 + #define OVPN_NONCE_WIRE_SIZE (OVPN_NONCE_SIZE - OVPN_NONCE_TAIL_SIZE) 35 + 36 + #define OVPN_OPCODE_SIZE 4 /* DATA_V2 opcode size */ 37 + 38 + #endif /* _NET_OVPN_PROTO_H_ */
+15
include/uapi/linux/if_link.h
··· 1986 1986 1987 1987 #define IFLA_DSA_MAX (__IFLA_DSA_MAX - 1) 1988 1988 1989 + /* OVPN section */ 1990 + 1991 + enum ovpn_mode { 1992 + OVPN_MODE_P2P, 1993 + OVPN_MODE_MP, 1994 + }; 1995 + 1996 + enum { 1997 + IFLA_OVPN_UNSPEC, 1998 + IFLA_OVPN_MODE, 1999 + __IFLA_OVPN_MAX, 2000 + }; 2001 + 2002 + #define IFLA_OVPN_MAX (__IFLA_OVPN_MAX - 1) 2003 + 1989 2004 #endif /* _UAPI_LINUX_IF_LINK_H */