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

ovpn: add basic netlink support

This commit introduces basic netlink support with family
registration/unregistration functionalities and stub pre/post-doit.

More importantly it introduces the YAML uAPI description along
with its auto-generated files:
- include/uapi/linux/ovpn.h
- drivers/net/ovpn/netlink-gen.c
- drivers/net/ovpn/netlink-gen.h

Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
Link: https://patch.msgid.link/20250415-b4-ovpn-v26-2-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
b7a63391 9f23d943

+975
+367
Documentation/netlink/specs/ovpn.yaml
··· 1 + # SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) 2 + # 3 + # Author: Antonio Quartulli <antonio@openvpn.net> 4 + # 5 + # Copyright (c) 2024-2025, OpenVPN Inc. 6 + # 7 + 8 + name: ovpn 9 + 10 + protocol: genetlink 11 + 12 + doc: Netlink protocol to control OpenVPN network devices 13 + 14 + definitions: 15 + - 16 + type: const 17 + name: nonce-tail-size 18 + value: 8 19 + - 20 + type: enum 21 + name: cipher-alg 22 + entries: [ none, aes-gcm, chacha20-poly1305 ] 23 + - 24 + type: enum 25 + name: del-peer-reason 26 + entries: 27 + - teardown 28 + - userspace 29 + - expired 30 + - transport-error 31 + - transport-disconnect 32 + - 33 + type: enum 34 + name: key-slot 35 + entries: [ primary, secondary ] 36 + 37 + attribute-sets: 38 + - 39 + name: peer 40 + attributes: 41 + - 42 + name: id 43 + type: u32 44 + doc: >- 45 + The unique ID of the peer in the device context. To be used to identify 46 + peers during operations for a specific device 47 + checks: 48 + max: 0xFFFFFF 49 + - 50 + name: remote-ipv4 51 + type: u32 52 + doc: The remote IPv4 address of the peer 53 + byte-order: big-endian 54 + display-hint: ipv4 55 + - 56 + name: remote-ipv6 57 + type: binary 58 + doc: The remote IPv6 address of the peer 59 + display-hint: ipv6 60 + checks: 61 + exact-len: 16 62 + - 63 + name: remote-ipv6-scope-id 64 + type: u32 65 + doc: The scope id of the remote IPv6 address of the peer (RFC2553) 66 + - 67 + name: remote-port 68 + type: u16 69 + doc: The remote port of the peer 70 + byte-order: big-endian 71 + checks: 72 + min: 1 73 + - 74 + name: socket 75 + type: u32 76 + doc: The socket to be used to communicate with the peer 77 + - 78 + name: socket-netnsid 79 + type: s32 80 + doc: The ID of the netns the socket assigned to this peer lives in 81 + - 82 + name: vpn-ipv4 83 + type: u32 84 + doc: The IPv4 address assigned to the peer by the server 85 + byte-order: big-endian 86 + display-hint: ipv4 87 + - 88 + name: vpn-ipv6 89 + type: binary 90 + doc: The IPv6 address assigned to the peer by the server 91 + display-hint: ipv6 92 + checks: 93 + exact-len: 16 94 + - 95 + name: local-ipv4 96 + type: u32 97 + doc: The local IPv4 to be used to send packets to the peer (UDP only) 98 + byte-order: big-endian 99 + display-hint: ipv4 100 + - 101 + name: local-ipv6 102 + type: binary 103 + doc: The local IPv6 to be used to send packets to the peer (UDP only) 104 + display-hint: ipv6 105 + checks: 106 + exact-len: 16 107 + - 108 + name: local-port 109 + type: u16 110 + doc: The local port to be used to send packets to the peer (UDP only) 111 + byte-order: big-endian 112 + checks: 113 + min: 1 114 + - 115 + name: keepalive-interval 116 + type: u32 117 + doc: >- 118 + The number of seconds after which a keep alive message is sent to the 119 + peer 120 + - 121 + name: keepalive-timeout 122 + type: u32 123 + doc: >- 124 + The number of seconds from the last activity after which the peer is 125 + assumed dead 126 + - 127 + name: del-reason 128 + type: u32 129 + doc: The reason why a peer was deleted 130 + enum: del-peer-reason 131 + - 132 + name: vpn-rx-bytes 133 + type: uint 134 + doc: Number of bytes received over the tunnel 135 + - 136 + name: vpn-tx-bytes 137 + type: uint 138 + doc: Number of bytes transmitted over the tunnel 139 + - 140 + name: vpn-rx-packets 141 + type: uint 142 + doc: Number of packets received over the tunnel 143 + - 144 + name: vpn-tx-packets 145 + type: uint 146 + doc: Number of packets transmitted over the tunnel 147 + - 148 + name: link-rx-bytes 149 + type: uint 150 + doc: Number of bytes received at the transport level 151 + - 152 + name: link-tx-bytes 153 + type: uint 154 + doc: Number of bytes transmitted at the transport level 155 + - 156 + name: link-rx-packets 157 + type: uint 158 + doc: Number of packets received at the transport level 159 + - 160 + name: link-tx-packets 161 + type: uint 162 + doc: Number of packets transmitted at the transport level 163 + - 164 + name: keyconf 165 + attributes: 166 + - 167 + name: peer-id 168 + type: u32 169 + doc: >- 170 + The unique ID of the peer in the device context. To be used to 171 + identify peers during key operations 172 + checks: 173 + max: 0xFFFFFF 174 + - 175 + name: slot 176 + type: u32 177 + doc: The slot where the key should be stored 178 + enum: key-slot 179 + - 180 + name: key-id 181 + doc: >- 182 + The unique ID of the key in the peer context. Used to fetch the 183 + correct key upon decryption 184 + type: u32 185 + checks: 186 + max: 7 187 + - 188 + name: cipher-alg 189 + type: u32 190 + doc: The cipher to be used when communicating with the peer 191 + enum: cipher-alg 192 + - 193 + name: encrypt-dir 194 + type: nest 195 + doc: Key material for encrypt direction 196 + nested-attributes: keydir 197 + - 198 + name: decrypt-dir 199 + type: nest 200 + doc: Key material for decrypt direction 201 + nested-attributes: keydir 202 + - 203 + name: keydir 204 + attributes: 205 + - 206 + name: cipher-key 207 + type: binary 208 + doc: The actual key to be used by the cipher 209 + checks: 210 + max-len: 256 211 + - 212 + name: nonce-tail 213 + type: binary 214 + doc: >- 215 + Random nonce to be concatenated to the packet ID, in order to 216 + obtain the actual cipher IV 217 + checks: 218 + exact-len: nonce-tail-size 219 + - 220 + name: ovpn 221 + attributes: 222 + - 223 + name: ifindex 224 + type: u32 225 + doc: Index of the ovpn interface to operate on 226 + - 227 + name: peer 228 + type: nest 229 + doc: >- 230 + The peer object containing the attributed of interest for the specific 231 + operation 232 + nested-attributes: peer 233 + - 234 + name: keyconf 235 + type: nest 236 + doc: Peer specific cipher configuration 237 + nested-attributes: keyconf 238 + 239 + operations: 240 + list: 241 + - 242 + name: peer-new 243 + attribute-set: ovpn 244 + flags: [ admin-perm ] 245 + doc: Add a remote peer 246 + do: 247 + pre: ovpn-nl-pre-doit 248 + post: ovpn-nl-post-doit 249 + request: 250 + attributes: 251 + - ifindex 252 + - peer 253 + - 254 + name: peer-set 255 + attribute-set: ovpn 256 + flags: [ admin-perm ] 257 + doc: modify a remote peer 258 + do: 259 + pre: ovpn-nl-pre-doit 260 + post: ovpn-nl-post-doit 261 + request: 262 + attributes: 263 + - ifindex 264 + - peer 265 + - 266 + name: peer-get 267 + attribute-set: ovpn 268 + flags: [ admin-perm ] 269 + doc: Retrieve data about existing remote peers (or a specific one) 270 + do: 271 + pre: ovpn-nl-pre-doit 272 + post: ovpn-nl-post-doit 273 + request: 274 + attributes: 275 + - ifindex 276 + - peer 277 + reply: 278 + attributes: 279 + - peer 280 + dump: 281 + request: 282 + attributes: 283 + - ifindex 284 + reply: 285 + attributes: 286 + - peer 287 + - 288 + name: peer-del 289 + attribute-set: ovpn 290 + flags: [ admin-perm ] 291 + doc: Delete existing remote peer 292 + do: 293 + pre: ovpn-nl-pre-doit 294 + post: ovpn-nl-post-doit 295 + request: 296 + attributes: 297 + - ifindex 298 + - peer 299 + - 300 + name: peer-del-ntf 301 + doc: Notification about a peer being deleted 302 + notify: peer-get 303 + mcgrp: peers 304 + 305 + - 306 + name: key-new 307 + attribute-set: ovpn 308 + flags: [ admin-perm ] 309 + doc: Add a cipher key for a specific peer 310 + do: 311 + pre: ovpn-nl-pre-doit 312 + post: ovpn-nl-post-doit 313 + request: 314 + attributes: 315 + - ifindex 316 + - keyconf 317 + - 318 + name: key-get 319 + attribute-set: ovpn 320 + flags: [ admin-perm ] 321 + doc: Retrieve non-sensitive data about peer key and cipher 322 + do: 323 + pre: ovpn-nl-pre-doit 324 + post: ovpn-nl-post-doit 325 + request: 326 + attributes: 327 + - ifindex 328 + - keyconf 329 + reply: 330 + attributes: 331 + - keyconf 332 + - 333 + name: key-swap 334 + attribute-set: ovpn 335 + flags: [ admin-perm ] 336 + doc: Swap primary and secondary session keys for a specific peer 337 + do: 338 + pre: ovpn-nl-pre-doit 339 + post: ovpn-nl-post-doit 340 + request: 341 + attributes: 342 + - ifindex 343 + - keyconf 344 + - 345 + name: key-swap-ntf 346 + notify: key-get 347 + doc: >- 348 + Notification about key having exhausted its IV space and requiring 349 + renegotiation 350 + mcgrp: peers 351 + - 352 + name: key-del 353 + attribute-set: ovpn 354 + flags: [ admin-perm ] 355 + doc: Delete cipher key for a specific peer 356 + do: 357 + pre: ovpn-nl-pre-doit 358 + post: ovpn-nl-post-doit 359 + request: 360 + attributes: 361 + - ifindex 362 + - keyconf 363 + 364 + mcast-groups: 365 + list: 366 + - 367 + name: peers
+2
MAINTAINERS
··· 18131 18131 L: netdev@vger.kernel.org 18132 18132 S: Supported 18133 18133 T: git https://github.com/OpenVPN/linux-kernel-ovpn.git 18134 + F: Documentation/netlink/specs/ovpn.yaml 18134 18135 F: drivers/net/ovpn/ 18136 + F: include/uapi/linux/ovpn.h 18135 18137 18136 18138 OPENVSWITCH 18137 18139 M: Aaron Conole <aconole@redhat.com>
+2
drivers/net/ovpn/Makefile
··· 8 8 9 9 obj-$(CONFIG_OVPN) := ovpn.o 10 10 ovpn-y += main.o 11 + ovpn-y += netlink.o 12 + ovpn-y += netlink-gen.o
+31
drivers/net/ovpn/main.c
··· 7 7 * James Yonan <james@openvpn.net> 8 8 */ 9 9 10 + #include <linux/genetlink.h> 10 11 #include <linux/module.h> 11 12 #include <linux/netdevice.h> 12 13 #include <net/rtnetlink.h> 14 + #include <uapi/linux/ovpn.h> 15 + 16 + #include "ovpnpriv.h" 17 + #include "main.h" 18 + #include "netlink.h" 19 + 20 + static const struct net_device_ops ovpn_netdev_ops = { 21 + }; 22 + 23 + /** 24 + * ovpn_dev_is_valid - check if the netdevice is of type 'ovpn' 25 + * @dev: the interface to check 26 + * 27 + * Return: whether the netdevice is of type 'ovpn' 28 + */ 29 + bool ovpn_dev_is_valid(const struct net_device *dev) 30 + { 31 + return dev->netdev_ops == &ovpn_netdev_ops; 32 + } 13 33 14 34 static int ovpn_newlink(struct net_device *dev, 15 35 struct rtnl_newlink_params *params, ··· 54 34 return err; 55 35 } 56 36 37 + err = ovpn_nl_register(); 38 + if (err) { 39 + pr_err("ovpn: can't register netlink family: %d\n", err); 40 + goto unreg_rtnl; 41 + } 42 + 57 43 return 0; 44 + 45 + unreg_rtnl: 46 + rtnl_link_unregister(&ovpn_link_ops); 47 + return err; 58 48 } 59 49 60 50 static __exit void ovpn_cleanup(void) 61 51 { 52 + ovpn_nl_unregister(); 62 53 rtnl_link_unregister(&ovpn_link_ops); 63 54 64 55 rcu_barrier();
+14
drivers/net/ovpn/main.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 + */ 8 + 9 + #ifndef _NET_OVPN_MAIN_H_ 10 + #define _NET_OVPN_MAIN_H_ 11 + 12 + bool ovpn_dev_is_valid(const struct net_device *dev); 13 + 14 + #endif /* _NET_OVPN_MAIN_H_ */
+160
drivers/net/ovpn/netlink.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* OpenVPN data channel offload 3 + * 4 + * Copyright (C) 2020-2025 OpenVPN, Inc. 5 + * 6 + * Author: Antonio Quartulli <antonio@openvpn.net> 7 + */ 8 + 9 + #include <linux/netdevice.h> 10 + #include <net/genetlink.h> 11 + 12 + #include <uapi/linux/ovpn.h> 13 + 14 + #include "ovpnpriv.h" 15 + #include "main.h" 16 + #include "netlink.h" 17 + #include "netlink-gen.h" 18 + 19 + MODULE_ALIAS_GENL_FAMILY(OVPN_FAMILY_NAME); 20 + 21 + /** 22 + * ovpn_get_dev_from_attrs - retrieve the ovpn private data from the netdevice 23 + * a netlink message is targeting 24 + * @net: network namespace where to look for the interface 25 + * @info: generic netlink info from the user request 26 + * @tracker: tracker object to be used for the netdev reference acquisition 27 + * 28 + * Return: the ovpn private data, if found, or an error otherwise 29 + */ 30 + static struct ovpn_priv * 31 + ovpn_get_dev_from_attrs(struct net *net, const struct genl_info *info, 32 + netdevice_tracker *tracker) 33 + { 34 + struct ovpn_priv *ovpn; 35 + struct net_device *dev; 36 + int ifindex; 37 + 38 + if (GENL_REQ_ATTR_CHECK(info, OVPN_A_IFINDEX)) 39 + return ERR_PTR(-EINVAL); 40 + 41 + ifindex = nla_get_u32(info->attrs[OVPN_A_IFINDEX]); 42 + 43 + rcu_read_lock(); 44 + dev = dev_get_by_index_rcu(net, ifindex); 45 + if (!dev) { 46 + rcu_read_unlock(); 47 + NL_SET_ERR_MSG_MOD(info->extack, 48 + "ifindex does not match any interface"); 49 + return ERR_PTR(-ENODEV); 50 + } 51 + 52 + if (!ovpn_dev_is_valid(dev)) { 53 + rcu_read_unlock(); 54 + NL_SET_ERR_MSG_MOD(info->extack, 55 + "specified interface is not ovpn"); 56 + NL_SET_BAD_ATTR(info->extack, info->attrs[OVPN_A_IFINDEX]); 57 + return ERR_PTR(-EINVAL); 58 + } 59 + 60 + ovpn = netdev_priv(dev); 61 + netdev_hold(dev, tracker, GFP_ATOMIC); 62 + rcu_read_unlock(); 63 + 64 + return ovpn; 65 + } 66 + 67 + int ovpn_nl_pre_doit(const struct genl_split_ops *ops, struct sk_buff *skb, 68 + struct genl_info *info) 69 + { 70 + netdevice_tracker *tracker = (netdevice_tracker *)&info->user_ptr[1]; 71 + struct ovpn_priv *ovpn = ovpn_get_dev_from_attrs(genl_info_net(info), 72 + info, tracker); 73 + 74 + if (IS_ERR(ovpn)) 75 + return PTR_ERR(ovpn); 76 + 77 + info->user_ptr[0] = ovpn; 78 + 79 + return 0; 80 + } 81 + 82 + void ovpn_nl_post_doit(const struct genl_split_ops *ops, struct sk_buff *skb, 83 + struct genl_info *info) 84 + { 85 + netdevice_tracker *tracker = (netdevice_tracker *)&info->user_ptr[1]; 86 + struct ovpn_priv *ovpn = info->user_ptr[0]; 87 + 88 + if (ovpn) 89 + netdev_put(ovpn->dev, tracker); 90 + } 91 + 92 + int ovpn_nl_peer_new_doit(struct sk_buff *skb, struct genl_info *info) 93 + { 94 + return -EOPNOTSUPP; 95 + } 96 + 97 + int ovpn_nl_peer_set_doit(struct sk_buff *skb, struct genl_info *info) 98 + { 99 + return -EOPNOTSUPP; 100 + } 101 + 102 + int ovpn_nl_peer_get_doit(struct sk_buff *skb, struct genl_info *info) 103 + { 104 + return -EOPNOTSUPP; 105 + } 106 + 107 + int ovpn_nl_peer_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb) 108 + { 109 + return -EOPNOTSUPP; 110 + } 111 + 112 + int ovpn_nl_peer_del_doit(struct sk_buff *skb, struct genl_info *info) 113 + { 114 + return -EOPNOTSUPP; 115 + } 116 + 117 + int ovpn_nl_key_new_doit(struct sk_buff *skb, struct genl_info *info) 118 + { 119 + return -EOPNOTSUPP; 120 + } 121 + 122 + int ovpn_nl_key_get_doit(struct sk_buff *skb, struct genl_info *info) 123 + { 124 + return -EOPNOTSUPP; 125 + } 126 + 127 + int ovpn_nl_key_swap_doit(struct sk_buff *skb, struct genl_info *info) 128 + { 129 + return -EOPNOTSUPP; 130 + } 131 + 132 + int ovpn_nl_key_del_doit(struct sk_buff *skb, struct genl_info *info) 133 + { 134 + return -EOPNOTSUPP; 135 + } 136 + 137 + /** 138 + * ovpn_nl_register - perform any needed registration in the NL subsustem 139 + * 140 + * Return: 0 on success, a negative error code otherwise 141 + */ 142 + int __init ovpn_nl_register(void) 143 + { 144 + int ret = genl_register_family(&ovpn_nl_family); 145 + 146 + if (ret) { 147 + pr_err("ovpn: genl_register_family failed: %d\n", ret); 148 + return ret; 149 + } 150 + 151 + return 0; 152 + } 153 + 154 + /** 155 + * ovpn_nl_unregister - undo any module wide netlink registration 156 + */ 157 + void ovpn_nl_unregister(void) 158 + { 159 + genl_unregister_family(&ovpn_nl_family); 160 + }
+15
drivers/net/ovpn/netlink.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 + */ 8 + 9 + #ifndef _NET_OVPN_NETLINK_H_ 10 + #define _NET_OVPN_NETLINK_H_ 11 + 12 + int ovpn_nl_register(void); 13 + void ovpn_nl_unregister(void); 14 + 15 + #endif /* _NET_OVPN_NETLINK_H_ */
+21
drivers/net/ovpn/ovpnpriv.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_OVPNSTRUCT_H_ 11 + #define _NET_OVPN_OVPNSTRUCT_H_ 12 + 13 + /** 14 + * struct ovpn_priv - per ovpn interface state 15 + * @dev: the actual netdev representing the tunnel 16 + */ 17 + struct ovpn_priv { 18 + struct net_device *dev; 19 + }; 20 + 21 + #endif /* _NET_OVPN_OVPNSTRUCT_H_ */
+109
include/uapi/linux/ovpn.h
··· 1 + /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ 2 + /* Do not edit directly, auto-generated from: */ 3 + /* Documentation/netlink/specs/ovpn.yaml */ 4 + /* YNL-GEN uapi header */ 5 + 6 + #ifndef _UAPI_LINUX_OVPN_H 7 + #define _UAPI_LINUX_OVPN_H 8 + 9 + #define OVPN_FAMILY_NAME "ovpn" 10 + #define OVPN_FAMILY_VERSION 1 11 + 12 + #define OVPN_NONCE_TAIL_SIZE 8 13 + 14 + enum ovpn_cipher_alg { 15 + OVPN_CIPHER_ALG_NONE, 16 + OVPN_CIPHER_ALG_AES_GCM, 17 + OVPN_CIPHER_ALG_CHACHA20_POLY1305, 18 + }; 19 + 20 + enum ovpn_del_peer_reason { 21 + OVPN_DEL_PEER_REASON_TEARDOWN, 22 + OVPN_DEL_PEER_REASON_USERSPACE, 23 + OVPN_DEL_PEER_REASON_EXPIRED, 24 + OVPN_DEL_PEER_REASON_TRANSPORT_ERROR, 25 + OVPN_DEL_PEER_REASON_TRANSPORT_DISCONNECT, 26 + }; 27 + 28 + enum ovpn_key_slot { 29 + OVPN_KEY_SLOT_PRIMARY, 30 + OVPN_KEY_SLOT_SECONDARY, 31 + }; 32 + 33 + enum { 34 + OVPN_A_PEER_ID = 1, 35 + OVPN_A_PEER_REMOTE_IPV4, 36 + OVPN_A_PEER_REMOTE_IPV6, 37 + OVPN_A_PEER_REMOTE_IPV6_SCOPE_ID, 38 + OVPN_A_PEER_REMOTE_PORT, 39 + OVPN_A_PEER_SOCKET, 40 + OVPN_A_PEER_SOCKET_NETNSID, 41 + OVPN_A_PEER_VPN_IPV4, 42 + OVPN_A_PEER_VPN_IPV6, 43 + OVPN_A_PEER_LOCAL_IPV4, 44 + OVPN_A_PEER_LOCAL_IPV6, 45 + OVPN_A_PEER_LOCAL_PORT, 46 + OVPN_A_PEER_KEEPALIVE_INTERVAL, 47 + OVPN_A_PEER_KEEPALIVE_TIMEOUT, 48 + OVPN_A_PEER_DEL_REASON, 49 + OVPN_A_PEER_VPN_RX_BYTES, 50 + OVPN_A_PEER_VPN_TX_BYTES, 51 + OVPN_A_PEER_VPN_RX_PACKETS, 52 + OVPN_A_PEER_VPN_TX_PACKETS, 53 + OVPN_A_PEER_LINK_RX_BYTES, 54 + OVPN_A_PEER_LINK_TX_BYTES, 55 + OVPN_A_PEER_LINK_RX_PACKETS, 56 + OVPN_A_PEER_LINK_TX_PACKETS, 57 + 58 + __OVPN_A_PEER_MAX, 59 + OVPN_A_PEER_MAX = (__OVPN_A_PEER_MAX - 1) 60 + }; 61 + 62 + enum { 63 + OVPN_A_KEYCONF_PEER_ID = 1, 64 + OVPN_A_KEYCONF_SLOT, 65 + OVPN_A_KEYCONF_KEY_ID, 66 + OVPN_A_KEYCONF_CIPHER_ALG, 67 + OVPN_A_KEYCONF_ENCRYPT_DIR, 68 + OVPN_A_KEYCONF_DECRYPT_DIR, 69 + 70 + __OVPN_A_KEYCONF_MAX, 71 + OVPN_A_KEYCONF_MAX = (__OVPN_A_KEYCONF_MAX - 1) 72 + }; 73 + 74 + enum { 75 + OVPN_A_KEYDIR_CIPHER_KEY = 1, 76 + OVPN_A_KEYDIR_NONCE_TAIL, 77 + 78 + __OVPN_A_KEYDIR_MAX, 79 + OVPN_A_KEYDIR_MAX = (__OVPN_A_KEYDIR_MAX - 1) 80 + }; 81 + 82 + enum { 83 + OVPN_A_IFINDEX = 1, 84 + OVPN_A_PEER, 85 + OVPN_A_KEYCONF, 86 + 87 + __OVPN_A_MAX, 88 + OVPN_A_MAX = (__OVPN_A_MAX - 1) 89 + }; 90 + 91 + enum { 92 + OVPN_CMD_PEER_NEW = 1, 93 + OVPN_CMD_PEER_SET, 94 + OVPN_CMD_PEER_GET, 95 + OVPN_CMD_PEER_DEL, 96 + OVPN_CMD_PEER_DEL_NTF, 97 + OVPN_CMD_KEY_NEW, 98 + OVPN_CMD_KEY_GET, 99 + OVPN_CMD_KEY_SWAP, 100 + OVPN_CMD_KEY_SWAP_NTF, 101 + OVPN_CMD_KEY_DEL, 102 + 103 + __OVPN_CMD_MAX, 104 + OVPN_CMD_MAX = (__OVPN_CMD_MAX - 1) 105 + }; 106 + 107 + #define OVPN_MCGRP_PEERS "peers" 108 + 109 + #endif /* _UAPI_LINUX_OVPN_H */