1e7096c13SJason A. Donenfeld /* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR MIT */ 2e7096c13SJason A. Donenfeld /* 3e7096c13SJason A. Donenfeld * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. 4e7096c13SJason A. Donenfeld * 5e7096c13SJason A. Donenfeld * Documentation 6e7096c13SJason A. Donenfeld * ============= 7e7096c13SJason A. Donenfeld * 8e7096c13SJason A. Donenfeld * The below enums and macros are for interfacing with WireGuard, using generic 9e7096c13SJason A. Donenfeld * netlink, with family WG_GENL_NAME and version WG_GENL_VERSION. It defines two 10e7096c13SJason A. Donenfeld * methods: get and set. Note that while they share many common attributes, 11e7096c13SJason A. Donenfeld * these two functions actually accept a slightly different set of inputs and 12e7096c13SJason A. Donenfeld * outputs. 13e7096c13SJason A. Donenfeld * 14e7096c13SJason A. Donenfeld * WG_CMD_GET_DEVICE 15e7096c13SJason A. Donenfeld * ----------------- 16e7096c13SJason A. Donenfeld * 17e7096c13SJason A. Donenfeld * May only be called via NLM_F_REQUEST | NLM_F_DUMP. The command should contain 18e7096c13SJason A. Donenfeld * one but not both of: 19e7096c13SJason A. Donenfeld * 20e7096c13SJason A. Donenfeld * WGDEVICE_A_IFINDEX: NLA_U32 21*a2ec8b57SJosh Soref * WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMSIZ - 1 22e7096c13SJason A. Donenfeld * 23e7096c13SJason A. Donenfeld * The kernel will then return several messages (NLM_F_MULTI) containing the 24e7096c13SJason A. Donenfeld * following tree of nested items: 25e7096c13SJason A. Donenfeld * 26e7096c13SJason A. Donenfeld * WGDEVICE_A_IFINDEX: NLA_U32 27*a2ec8b57SJosh Soref * WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMSIZ - 1 28e7096c13SJason A. Donenfeld * WGDEVICE_A_PRIVATE_KEY: NLA_EXACT_LEN, len WG_KEY_LEN 29e7096c13SJason A. Donenfeld * WGDEVICE_A_PUBLIC_KEY: NLA_EXACT_LEN, len WG_KEY_LEN 30e7096c13SJason A. Donenfeld * WGDEVICE_A_LISTEN_PORT: NLA_U16 31e7096c13SJason A. Donenfeld * WGDEVICE_A_FWMARK: NLA_U32 32e7096c13SJason A. Donenfeld * WGDEVICE_A_PEERS: NLA_NESTED 33e7096c13SJason A. Donenfeld * 0: NLA_NESTED 34e7096c13SJason A. Donenfeld * WGPEER_A_PUBLIC_KEY: NLA_EXACT_LEN, len WG_KEY_LEN 35e7096c13SJason A. Donenfeld * WGPEER_A_PRESHARED_KEY: NLA_EXACT_LEN, len WG_KEY_LEN 36e7096c13SJason A. Donenfeld * WGPEER_A_ENDPOINT: NLA_MIN_LEN(struct sockaddr), struct sockaddr_in or struct sockaddr_in6 37e7096c13SJason A. Donenfeld * WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL: NLA_U16 38e7096c13SJason A. Donenfeld * WGPEER_A_LAST_HANDSHAKE_TIME: NLA_EXACT_LEN, struct __kernel_timespec 39e7096c13SJason A. Donenfeld * WGPEER_A_RX_BYTES: NLA_U64 40e7096c13SJason A. Donenfeld * WGPEER_A_TX_BYTES: NLA_U64 41e7096c13SJason A. Donenfeld * WGPEER_A_ALLOWEDIPS: NLA_NESTED 42e7096c13SJason A. Donenfeld * 0: NLA_NESTED 43e7096c13SJason A. Donenfeld * WGALLOWEDIP_A_FAMILY: NLA_U16 44e7096c13SJason A. Donenfeld * WGALLOWEDIP_A_IPADDR: NLA_MIN_LEN(struct in_addr), struct in_addr or struct in6_addr 45e7096c13SJason A. Donenfeld * WGALLOWEDIP_A_CIDR_MASK: NLA_U8 46e7096c13SJason A. Donenfeld * 0: NLA_NESTED 47e7096c13SJason A. Donenfeld * ... 48e7096c13SJason A. Donenfeld * 0: NLA_NESTED 49e7096c13SJason A. Donenfeld * ... 50e7096c13SJason A. Donenfeld * ... 51e7096c13SJason A. Donenfeld * WGPEER_A_PROTOCOL_VERSION: NLA_U32 52e7096c13SJason A. Donenfeld * 0: NLA_NESTED 53e7096c13SJason A. Donenfeld * ... 54e7096c13SJason A. Donenfeld * ... 55e7096c13SJason A. Donenfeld * 56e7096c13SJason A. Donenfeld * It is possible that all of the allowed IPs of a single peer will not 57e7096c13SJason A. Donenfeld * fit within a single netlink message. In that case, the same peer will 58e7096c13SJason A. Donenfeld * be written in the following message, except it will only contain 59e7096c13SJason A. Donenfeld * WGPEER_A_PUBLIC_KEY and WGPEER_A_ALLOWEDIPS. This may occur several 60e7096c13SJason A. Donenfeld * times in a row for the same peer. It is then up to the receiver to 61e7096c13SJason A. Donenfeld * coalesce adjacent peers. Likewise, it is possible that all peers will 62e7096c13SJason A. Donenfeld * not fit within a single message. So, subsequent peers will be sent 63e7096c13SJason A. Donenfeld * in following messages, except those will only contain WGDEVICE_A_IFNAME 64e7096c13SJason A. Donenfeld * and WGDEVICE_A_PEERS. It is then up to the receiver to coalesce these 65e7096c13SJason A. Donenfeld * messages to form the complete list of peers. 66e7096c13SJason A. Donenfeld * 67e7096c13SJason A. Donenfeld * Since this is an NLA_F_DUMP command, the final message will always be 68e7096c13SJason A. Donenfeld * NLMSG_DONE, even if an error occurs. However, this NLMSG_DONE message 69e7096c13SJason A. Donenfeld * contains an integer error code. It is either zero or a negative error 70e7096c13SJason A. Donenfeld * code corresponding to the errno. 71e7096c13SJason A. Donenfeld * 72e7096c13SJason A. Donenfeld * WG_CMD_SET_DEVICE 73e7096c13SJason A. Donenfeld * ----------------- 74e7096c13SJason A. Donenfeld * 75e7096c13SJason A. Donenfeld * May only be called via NLM_F_REQUEST. The command should contain the 76e7096c13SJason A. Donenfeld * following tree of nested items, containing one but not both of 77e7096c13SJason A. Donenfeld * WGDEVICE_A_IFINDEX and WGDEVICE_A_IFNAME: 78e7096c13SJason A. Donenfeld * 79e7096c13SJason A. Donenfeld * WGDEVICE_A_IFINDEX: NLA_U32 80*a2ec8b57SJosh Soref * WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMSIZ - 1 81e7096c13SJason A. Donenfeld * WGDEVICE_A_FLAGS: NLA_U32, 0 or WGDEVICE_F_REPLACE_PEERS if all current 82e7096c13SJason A. Donenfeld * peers should be removed prior to adding the list below. 83e7096c13SJason A. Donenfeld * WGDEVICE_A_PRIVATE_KEY: len WG_KEY_LEN, all zeros to remove 84e7096c13SJason A. Donenfeld * WGDEVICE_A_LISTEN_PORT: NLA_U16, 0 to choose randomly 85e7096c13SJason A. Donenfeld * WGDEVICE_A_FWMARK: NLA_U32, 0 to disable 86e7096c13SJason A. Donenfeld * WGDEVICE_A_PEERS: NLA_NESTED 87e7096c13SJason A. Donenfeld * 0: NLA_NESTED 88e7096c13SJason A. Donenfeld * WGPEER_A_PUBLIC_KEY: len WG_KEY_LEN 89e7096c13SJason A. Donenfeld * WGPEER_A_FLAGS: NLA_U32, 0 and/or WGPEER_F_REMOVE_ME if the 90e7096c13SJason A. Donenfeld * specified peer should not exist at the end of the 91e7096c13SJason A. Donenfeld * operation, rather than added/updated and/or 92e7096c13SJason A. Donenfeld * WGPEER_F_REPLACE_ALLOWEDIPS if all current allowed 93e7096c13SJason A. Donenfeld * IPs of this peer should be removed prior to adding 94e7096c13SJason A. Donenfeld * the list below and/or WGPEER_F_UPDATE_ONLY if the 95e7096c13SJason A. Donenfeld * peer should only be set if it already exists. 96e7096c13SJason A. Donenfeld * WGPEER_A_PRESHARED_KEY: len WG_KEY_LEN, all zeros to remove 97e7096c13SJason A. Donenfeld * WGPEER_A_ENDPOINT: struct sockaddr_in or struct sockaddr_in6 98e7096c13SJason A. Donenfeld * WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL: NLA_U16, 0 to disable 99e7096c13SJason A. Donenfeld * WGPEER_A_ALLOWEDIPS: NLA_NESTED 100e7096c13SJason A. Donenfeld * 0: NLA_NESTED 101e7096c13SJason A. Donenfeld * WGALLOWEDIP_A_FAMILY: NLA_U16 102e7096c13SJason A. Donenfeld * WGALLOWEDIP_A_IPADDR: struct in_addr or struct in6_addr 103e7096c13SJason A. Donenfeld * WGALLOWEDIP_A_CIDR_MASK: NLA_U8 104e7096c13SJason A. Donenfeld * 0: NLA_NESTED 105e7096c13SJason A. Donenfeld * ... 106e7096c13SJason A. Donenfeld * 0: NLA_NESTED 107e7096c13SJason A. Donenfeld * ... 108e7096c13SJason A. Donenfeld * ... 109e7096c13SJason A. Donenfeld * WGPEER_A_PROTOCOL_VERSION: NLA_U32, should not be set or used at 110e7096c13SJason A. Donenfeld * all by most users of this API, as the 111e7096c13SJason A. Donenfeld * most recent protocol will be used when 112e7096c13SJason A. Donenfeld * this is unset. Otherwise, must be set 113e7096c13SJason A. Donenfeld * to 1. 114e7096c13SJason A. Donenfeld * 0: NLA_NESTED 115e7096c13SJason A. Donenfeld * ... 116e7096c13SJason A. Donenfeld * ... 117e7096c13SJason A. Donenfeld * 118e7096c13SJason A. Donenfeld * It is possible that the amount of configuration data exceeds that of 119e7096c13SJason A. Donenfeld * the maximum message length accepted by the kernel. In that case, several 120e7096c13SJason A. Donenfeld * messages should be sent one after another, with each successive one 121e7096c13SJason A. Donenfeld * filling in information not contained in the prior. Note that if 122e7096c13SJason A. Donenfeld * WGDEVICE_F_REPLACE_PEERS is specified in the first message, it probably 123e7096c13SJason A. Donenfeld * should not be specified in fragments that come after, so that the list 124*a2ec8b57SJosh Soref * of peers is only cleared the first time but appended after. Likewise for 125e7096c13SJason A. Donenfeld * peers, if WGPEER_F_REPLACE_ALLOWEDIPS is specified in the first message 126e7096c13SJason A. Donenfeld * of a peer, it likely should not be specified in subsequent fragments. 127e7096c13SJason A. Donenfeld * 128e7096c13SJason A. Donenfeld * If an error occurs, NLMSG_ERROR will reply containing an errno. 129e7096c13SJason A. Donenfeld */ 130e7096c13SJason A. Donenfeld 131e7096c13SJason A. Donenfeld #ifndef _WG_UAPI_WIREGUARD_H 132e7096c13SJason A. Donenfeld #define _WG_UAPI_WIREGUARD_H 133e7096c13SJason A. Donenfeld 134e7096c13SJason A. Donenfeld #define WG_GENL_NAME "wireguard" 135e7096c13SJason A. Donenfeld #define WG_GENL_VERSION 1 136e7096c13SJason A. Donenfeld 137e7096c13SJason A. Donenfeld #define WG_KEY_LEN 32 138e7096c13SJason A. Donenfeld 139e7096c13SJason A. Donenfeld enum wg_cmd { 140e7096c13SJason A. Donenfeld WG_CMD_GET_DEVICE, 141e7096c13SJason A. Donenfeld WG_CMD_SET_DEVICE, 142e7096c13SJason A. Donenfeld __WG_CMD_MAX 143e7096c13SJason A. Donenfeld }; 144e7096c13SJason A. Donenfeld #define WG_CMD_MAX (__WG_CMD_MAX - 1) 145e7096c13SJason A. Donenfeld 146e7096c13SJason A. Donenfeld enum wgdevice_flag { 147e7096c13SJason A. Donenfeld WGDEVICE_F_REPLACE_PEERS = 1U << 0, 148e7096c13SJason A. Donenfeld __WGDEVICE_F_ALL = WGDEVICE_F_REPLACE_PEERS 149e7096c13SJason A. Donenfeld }; 150e7096c13SJason A. Donenfeld enum wgdevice_attribute { 151e7096c13SJason A. Donenfeld WGDEVICE_A_UNSPEC, 152e7096c13SJason A. Donenfeld WGDEVICE_A_IFINDEX, 153e7096c13SJason A. Donenfeld WGDEVICE_A_IFNAME, 154e7096c13SJason A. Donenfeld WGDEVICE_A_PRIVATE_KEY, 155e7096c13SJason A. Donenfeld WGDEVICE_A_PUBLIC_KEY, 156e7096c13SJason A. Donenfeld WGDEVICE_A_FLAGS, 157e7096c13SJason A. Donenfeld WGDEVICE_A_LISTEN_PORT, 158e7096c13SJason A. Donenfeld WGDEVICE_A_FWMARK, 159e7096c13SJason A. Donenfeld WGDEVICE_A_PEERS, 160e7096c13SJason A. Donenfeld __WGDEVICE_A_LAST 161e7096c13SJason A. Donenfeld }; 162e7096c13SJason A. Donenfeld #define WGDEVICE_A_MAX (__WGDEVICE_A_LAST - 1) 163e7096c13SJason A. Donenfeld 164e7096c13SJason A. Donenfeld enum wgpeer_flag { 165e7096c13SJason A. Donenfeld WGPEER_F_REMOVE_ME = 1U << 0, 166e7096c13SJason A. Donenfeld WGPEER_F_REPLACE_ALLOWEDIPS = 1U << 1, 167e7096c13SJason A. Donenfeld WGPEER_F_UPDATE_ONLY = 1U << 2, 168e7096c13SJason A. Donenfeld __WGPEER_F_ALL = WGPEER_F_REMOVE_ME | WGPEER_F_REPLACE_ALLOWEDIPS | 169e7096c13SJason A. Donenfeld WGPEER_F_UPDATE_ONLY 170e7096c13SJason A. Donenfeld }; 171e7096c13SJason A. Donenfeld enum wgpeer_attribute { 172e7096c13SJason A. Donenfeld WGPEER_A_UNSPEC, 173e7096c13SJason A. Donenfeld WGPEER_A_PUBLIC_KEY, 174e7096c13SJason A. Donenfeld WGPEER_A_PRESHARED_KEY, 175e7096c13SJason A. Donenfeld WGPEER_A_FLAGS, 176e7096c13SJason A. Donenfeld WGPEER_A_ENDPOINT, 177e7096c13SJason A. Donenfeld WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL, 178e7096c13SJason A. Donenfeld WGPEER_A_LAST_HANDSHAKE_TIME, 179e7096c13SJason A. Donenfeld WGPEER_A_RX_BYTES, 180e7096c13SJason A. Donenfeld WGPEER_A_TX_BYTES, 181e7096c13SJason A. Donenfeld WGPEER_A_ALLOWEDIPS, 182e7096c13SJason A. Donenfeld WGPEER_A_PROTOCOL_VERSION, 183e7096c13SJason A. Donenfeld __WGPEER_A_LAST 184e7096c13SJason A. Donenfeld }; 185e7096c13SJason A. Donenfeld #define WGPEER_A_MAX (__WGPEER_A_LAST - 1) 186e7096c13SJason A. Donenfeld 187e7096c13SJason A. Donenfeld enum wgallowedip_attribute { 188e7096c13SJason A. Donenfeld WGALLOWEDIP_A_UNSPEC, 189e7096c13SJason A. Donenfeld WGALLOWEDIP_A_FAMILY, 190e7096c13SJason A. Donenfeld WGALLOWEDIP_A_IPADDR, 191e7096c13SJason A. Donenfeld WGALLOWEDIP_A_CIDR_MASK, 192e7096c13SJason A. Donenfeld __WGALLOWEDIP_A_LAST 193e7096c13SJason A. Donenfeld }; 194e7096c13SJason A. Donenfeld #define WGALLOWEDIP_A_MAX (__WGALLOWEDIP_A_LAST - 1) 195e7096c13SJason A. Donenfeld 196e7096c13SJason A. Donenfeld #endif /* _WG_UAPI_WIREGUARD_H */ 197