History

ovpn: add basic interface creation/destruction/management routines

Add basic infrastructure for handling ovpn interfaces.

Antonio Quartulli committed 1 year ago

Commit c2d950c1 parent b7a63398 files · +201 −2Browse files

Unified · Split

8 files
  1. Documentation/netlink/specs/rt-link.yaml +16 −0
  2. drivers/net/ovpn/Makefile +1 −0
  3. drivers/net/ovpn/io.c +22 −0
  4. drivers/net/ovpn/io.h +24 −0
  5. drivers/net/ovpn/main.c +80 −2
  6. drivers/net/ovpn/ovpnpriv.h +5 −0
  7. drivers/net/ovpn/proto.h +38 −0
  8. include/uapi/linux/if_link.h +15 −0
Documentation/netlink/specs/rt-link.yaml+16−0
@@ -938,6 +938,12 @@ definitions: · 937 unmodified lines
938938 entries:
939939 - name: none
940940 - name: default
941+ -
942+ name: ovpn-mode
943+ type: enum
944+ entries:
945+ - p2p
946+ - mp
941947
942948 attribute-sets:
943949 -
@@ -2272,6 +2278,13 @@ attribute-sets: · 1328 unmodified lines
22722278 -
22732279 name: tailroom
22742280 type: u16
2281+ -
2282+ name: linkinfo-ovpn-attrs
2283+ attributes:
2284+ -
2285+ name: mode
2286+ type: u8
2287+ enum: ovpn-mode
22752288
22762289 sub-messages:
22772290 -
@@ -2322,6 +2335,9 @@ sub-messages: · 44 unmodified lines
23222335 -
23232336 value: netkit
23242337 attribute-set: linkinfo-netkit-attrs
2338+ -
2339+ value: ovpn
2340+ attribute-set: linkinfo-ovpn-attrs
23252341 -
23262342 name: linkinfo-member-data-msg
23272343 formats:
drivers/net/ovpn/Makefile+1−0
@@ -8,5 +8,6 @@ · 7 unmodified lines
88
99 obj-$(CONFIG_OVPN) := ovpn.o
1010 ovpn-y += main.o
11+ovpn-y += io.o
1112 ovpn-y += netlink.o
1213 ovpn-y += netlink-gen.o
drivers/net/ovpn/io.c+22−0
@@ -0,0 +1,22 @@
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+}
drivers/net/ovpn/io.h+24−0
@@ -0,0 +1,24 @@
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_ */
drivers/net/ovpn/main.c+80−2
@@ -10,14 +10,28 @@ · 9 unmodified lines
1010 #include <linux/genetlink.h>
1111 #include <linux/module.h>
1212 #include <linux/netdevice.h>
13+#include <linux/inetdevice.h>
14+#include <net/ip.h>
1315 #include <net/rtnetlink.h>
14−#include <uapi/linux/ovpn.h>
16+#include <uapi/linux/if_arp.h>
1517
1618 #include "ovpnpriv.h"
1719 #include "main.h"
1820 #include "netlink.h"
21+#include "io.h"
22+#include "proto.h"
1923
2024 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),
2135 };
2236
2337 /**
@@ -31,18 +45,82 @@ bool ovpn_dev_is_valid(const struct net_device *dev) · 7 unmodified lines
3145 return dev->netdev_ops == &ovpn_netdev_ops;
3246 }
3347
48+static void ovpn_setup(struct net_device *dev)
49+{
50+ netdev_features_t feat = NETIF_F_SG | NETIF_F_GSO |
51+ NETIF_F_GSO_SOFTWARE | NETIF_F_HIGHDMA;
52+
53+ dev->needs_free_netdev = true;
54+
55+ dev->pcpu_stat_type = NETDEV_PCPU_STAT_DSTATS;
56+
57+ dev->netdev_ops = &ovpn_netdev_ops;
58+
59+ dev->hard_header_len = 0;
60+ dev->addr_len = 0;
61+ dev->mtu = ETH_DATA_LEN - OVPN_HEAD_ROOM;
62+ dev->min_mtu = IPV4_MIN_MTU;
63+ dev->max_mtu = IP_MAX_MTU - OVPN_HEAD_ROOM;
64+
65+ dev->type = ARPHRD_NONE;
66+ dev->flags = IFF_POINTOPOINT | IFF_NOARP;
67+ dev->priv_flags |= IFF_NO_QUEUE;
68+
69+ dev->lltx = true;
70+ dev->features |= feat;
71+ dev->hw_features |= feat;
72+ dev->hw_enc_features |= feat;
73+
74+ dev->needed_headroom = ALIGN(OVPN_HEAD_ROOM, 4);
75+ dev->needed_tailroom = OVPN_MAX_PADDING;
76+
77+ SET_NETDEV_DEVTYPE(dev, &ovpn_type);
78+}
79+
3480 static int ovpn_newlink(struct net_device *dev,
3581 struct rtnl_newlink_params *params,
3682 struct netlink_ext_ack *extack)
3783 {
38− return -EOPNOTSUPP;
84+ struct ovpn_priv *ovpn = netdev_priv(dev);
85+ struct nlattr **data = params->data;
86+ enum ovpn_mode mode = OVPN_MODE_P2P;
87+
88+ if (data && data[IFLA_OVPN_MODE]) {
89+ mode = nla_get_u8(data[IFLA_OVPN_MODE]);
90+ netdev_dbg(dev, "setting device mode: %u\n", mode);
91+ }
92+
93+ ovpn->dev = dev;
94+ ovpn->mode = mode;
95+
96+ /* turn carrier explicitly off after registration, this way state is
97+ * clearly defined
98+ */
99+ netif_carrier_off(dev);
100+
101+ return register_netdevice(dev);
102+}
103+
104+static int ovpn_fill_info(struct sk_buff *skb, const struct net_device *dev)
105+{
106+ struct ovpn_priv *ovpn = netdev_priv(dev);
107+
108+ if (nla_put_u8(skb, IFLA_OVPN_MODE, ovpn->mode))
109+ return -EMSGSIZE;
110+
111+ return 0;
39112 }
40113
41114 static struct rtnl_link_ops ovpn_link_ops = {
42115 .kind = "ovpn",
43116 .netns_refund = false,
117+ .priv_size = sizeof(struct ovpn_priv),
118+ .setup = ovpn_setup,
119+ .policy = ovpn_policy,
120+ .maxtype = IFLA_OVPN_MAX,
44121 .newlink = ovpn_newlink,
45122 .dellink = unregister_netdevice_queue,
123+ .fill_info = ovpn_fill_info,
46124 };
47125
48126 static int __init ovpn_init(void)
drivers/net/ovpn/ovpnpriv.h+5−0
@@ -10,12 +10,17 @@ · 9 unmodified lines
1010 #ifndef _NET_OVPN_OVPNSTRUCT_H_
1111 #define _NET_OVPN_OVPNSTRUCT_H_
1212
13+#include <uapi/linux/if_link.h>
14+#include <uapi/linux/ovpn.h>
15+
1316 /**
1417 * struct ovpn_priv - per ovpn interface state
1518 * @dev: the actual netdev representing the tunnel
19+ * @mode: device operation mode (i.e. p2p, mp, ..)
1620 */
1721 struct ovpn_priv {
1822 struct net_device *dev;
23+ enum ovpn_mode mode;
1924 };
2025
2126 #endif /* _NET_OVPN_OVPNSTRUCT_H_ */
drivers/net/ovpn/proto.h+38−0
@@ -0,0 +1,38 @@
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_ */
include/uapi/linux/if_link.h+15−0
@@ -1986,4 +1986,19 @@ enum { · 1985 unmodified lines
19861986
19871987 #define IFLA_DSA_MAX (__IFLA_DSA_MAX - 1)
19881988
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+
19892004 #endif /* _UAPI_LINUX_IF_LINK_H */