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
938 entries:938 entries:
939 - name: none939 - name: none
940 - name: default940 - name: default
941 -
942 name: ovpn-mode
943 type: enum
944 entries:
945 - p2p
946 - mp
941 947
942attribute-sets:948attribute-sets:
943 -949 -
@@ -2272,6 +2278,13 @@ attribute-sets: · 1328 unmodified lines
2272 -2278 -
2273 name: tailroom2279 name: tailroom
2274 type: u162280 type: u16
2281 -
2282 name: linkinfo-ovpn-attrs
2283 attributes:
2284 -
2285 name: mode
2286 type: u8
2287 enum: ovpn-mode
2275 2288
2276sub-messages:2289sub-messages:
2277 -2290 -
@@ -2322,6 +2335,9 @@ sub-messages: · 44 unmodified lines
2322 -2335 -
2323 value: netkit2336 value: netkit
2324 attribute-set: linkinfo-netkit-attrs2337 attribute-set: linkinfo-netkit-attrs
2338 -
2339 value: ovpn
2340 attribute-set: linkinfo-ovpn-attrs
2325 -2341 -
2326 name: linkinfo-member-data-msg2342 name: linkinfo-member-data-msg
2327 formats:2343 formats:
drivers/net/ovpn/Makefile+1−0
@@ -8,5 +8,6 @@ · 7 unmodified lines
8 8
9obj-$(CONFIG_OVPN) := ovpn.o9obj-$(CONFIG_OVPN) := ovpn.o
10ovpn-y += main.o10ovpn-y += main.o
11ovpn-y += io.o
11ovpn-y += netlink.o12ovpn-y += netlink.o
12ovpn-y += netlink-gen.o13ovpn-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 */
17netdev_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
22netdev_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
10#include <linux/genetlink.h>10#include <linux/genetlink.h>
11#include <linux/module.h>11#include <linux/module.h>
12#include <linux/netdevice.h>12#include <linux/netdevice.h>
13#include <linux/inetdevice.h>
14#include <net/ip.h>
13#include <net/rtnetlink.h>15#include <net/rtnetlink.h>
14#include <uapi/linux/ovpn.h>16#include <uapi/linux/if_arp.h>
15 17
16#include "ovpnpriv.h"18#include "ovpnpriv.h"
17#include "main.h"19#include "main.h"
18#include "netlink.h"20#include "netlink.h"
21#include "io.h"
22#include "proto.h"
19 23
20static const struct net_device_ops ovpn_netdev_ops = {24static const struct net_device_ops ovpn_netdev_ops = {
25 .ndo_start_xmit = ovpn_net_xmit,
26};
27
28static const struct device_type ovpn_type = {
29 .name = OVPN_FAMILY_NAME,
30};
31
32static 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/**
@@ -31,18 +45,82 @@ bool ovpn_dev_is_valid(const struct net_device *dev) · 7 unmodified lines
31 return dev->netdev_ops == &ovpn_netdev_ops;45 return dev->netdev_ops == &ovpn_netdev_ops;
32}46}
33 47
48static 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
34static int ovpn_newlink(struct net_device *dev,80static int ovpn_newlink(struct net_device *dev,
35 struct rtnl_newlink_params *params,81 struct rtnl_newlink_params *params,
36 struct netlink_ext_ack *extack)82 struct netlink_ext_ack *extack)
37{83{
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
104static 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;
39}112}
40 113
41static struct rtnl_link_ops ovpn_link_ops = {114static struct rtnl_link_ops ovpn_link_ops = {
42 .kind = "ovpn",115 .kind = "ovpn",
43 .netns_refund = false,116 .netns_refund = false,
117 .priv_size = sizeof(struct ovpn_priv),
118 .setup = ovpn_setup,
119 .policy = ovpn_policy,
120 .maxtype = IFLA_OVPN_MAX,
44 .newlink = ovpn_newlink,121 .newlink = ovpn_newlink,
45 .dellink = unregister_netdevice_queue,122 .dellink = unregister_netdevice_queue,
123 .fill_info = ovpn_fill_info,
46};124};
47 125
48static int __init ovpn_init(void)126static int __init ovpn_init(void)
drivers/net/ovpn/ovpnpriv.h+5−0
@@ -10,12 +10,17 @@ · 9 unmodified lines
10#ifndef _NET_OVPN_OVPNSTRUCT_H_10#ifndef _NET_OVPN_OVPNSTRUCT_H_
11#define _NET_OVPN_OVPNSTRUCT_H_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 * struct ovpn_priv - per ovpn interface state17 * struct ovpn_priv - per ovpn interface state
15 * @dev: the actual netdev representing the tunnel18 * @dev: the actual netdev representing the tunnel
19 * @mode: device operation mode (i.e. p2p, mp, ..)
16 */20 */
17struct ovpn_priv {21struct ovpn_priv {
18 struct net_device *dev;22 struct net_device *dev;
23 enum ovpn_mode mode;
19};24};
20 25
21#endif /* _NET_OVPN_OVPNSTRUCT_H_ */26#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
1986 1986
1987#define IFLA_DSA_MAX (__IFLA_DSA_MAX - 1)1987#define IFLA_DSA_MAX (__IFLA_DSA_MAX - 1)
1988 1988
1989/* OVPN section */
1990
1991enum ovpn_mode {
1992 OVPN_MODE_P2P,
1993 OVPN_MODE_MP,
1994};
1995
1996enum {
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#endif /* _UAPI_LINUX_IF_LINK_H */2004#endif /* _UAPI_LINUX_IF_LINK_H */