|
| 1 | +# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) |
| 2 | +--- |
| 3 | +name: wireguard |
| 4 | +protocol: genetlink-legacy |
| 5 | + |
| 6 | +doc: | |
| 7 | + **Netlink protocol to control WireGuard network devices.** |
| 8 | +
|
| 9 | + The below enums and macros are for interfacing with WireGuard, using generic |
| 10 | + netlink, with family ``WG_GENL_NAME`` and version ``WG_GENL_VERSION``. It |
| 11 | + defines two commands: get and set. Note that while they share many common |
| 12 | + attributes, these two commands actually accept a slightly different set of |
| 13 | + inputs and outputs. These differences are noted under the individual |
| 14 | + attributes. |
| 15 | +c-family-name: wg-genl-name |
| 16 | +c-version-name: wg-genl-version |
| 17 | +max-by-define: true |
| 18 | + |
| 19 | +definitions: |
| 20 | + - |
| 21 | + name-prefix: wg- |
| 22 | + name: key-len |
| 23 | + type: const |
| 24 | + value: 32 |
| 25 | + - |
| 26 | + name: --kernel-timespec |
| 27 | + type: struct |
| 28 | + header: linux/time_types.h |
| 29 | + members: |
| 30 | + - |
| 31 | + name: sec |
| 32 | + type: u64 |
| 33 | + doc: Number of seconds, since UNIX epoch. |
| 34 | + - |
| 35 | + name: nsec |
| 36 | + type: u64 |
| 37 | + doc: Number of nanoseconds, after the second began. |
| 38 | + - |
| 39 | + name: wgdevice-flags |
| 40 | + name-prefix: wgdevice-f- |
| 41 | + enum-name: wgdevice-flag |
| 42 | + type: flags |
| 43 | + entries: |
| 44 | + - replace-peers |
| 45 | + - |
| 46 | + name: wgpeer-flags |
| 47 | + name-prefix: wgpeer-f- |
| 48 | + enum-name: wgpeer-flag |
| 49 | + type: flags |
| 50 | + entries: |
| 51 | + - remove-me |
| 52 | + - replace-allowedips |
| 53 | + - update-only |
| 54 | + - |
| 55 | + name: wgallowedip-flags |
| 56 | + name-prefix: wgallowedip-f- |
| 57 | + enum-name: wgallowedip-flag |
| 58 | + type: flags |
| 59 | + entries: |
| 60 | + - remove-me |
| 61 | + |
| 62 | +attribute-sets: |
| 63 | + - |
| 64 | + name: wgdevice |
| 65 | + enum-name: wgdevice-attribute |
| 66 | + name-prefix: wgdevice-a- |
| 67 | + attr-cnt-name: --wgdevice-a-last |
| 68 | + attributes: |
| 69 | + - |
| 70 | + name: unspec |
| 71 | + type: unused |
| 72 | + value: 0 |
| 73 | + - |
| 74 | + name: ifindex |
| 75 | + type: u32 |
| 76 | + - |
| 77 | + name: ifname |
| 78 | + type: string |
| 79 | + checks: |
| 80 | + max-len: 15 |
| 81 | + - |
| 82 | + name: private-key |
| 83 | + type: binary |
| 84 | + doc: Set to all zeros to remove. |
| 85 | + display-hint: hex |
| 86 | + checks: |
| 87 | + exact-len: wg-key-len |
| 88 | + - |
| 89 | + name: public-key |
| 90 | + type: binary |
| 91 | + display-hint: hex |
| 92 | + checks: |
| 93 | + exact-len: wg-key-len |
| 94 | + - |
| 95 | + name: flags |
| 96 | + type: u32 |
| 97 | + doc: | |
| 98 | + ``0`` or ``WGDEVICE_F_REPLACE_PEERS`` if all current peers should be |
| 99 | + removed prior to adding the list below. |
| 100 | + enum: wgdevice-flags |
| 101 | + - |
| 102 | + name: listen-port |
| 103 | + type: u16 |
| 104 | + doc: Set as ``0`` to choose randomly. |
| 105 | + - |
| 106 | + name: fwmark |
| 107 | + type: u32 |
| 108 | + doc: Set as ``0`` to disable. |
| 109 | + - |
| 110 | + name: peers |
| 111 | + type: indexed-array |
| 112 | + sub-type: nest |
| 113 | + nested-attributes: wgpeer |
| 114 | + doc: | |
| 115 | + The index/type parameter is unused on ``SET_DEVICE`` operations and is |
| 116 | + zero on ``GET_DEVICE`` operations. |
| 117 | + - |
| 118 | + name: wgpeer |
| 119 | + enum-name: wgpeer-attribute |
| 120 | + name-prefix: wgpeer-a- |
| 121 | + attr-cnt-name: --wgpeer-a-last |
| 122 | + attributes: |
| 123 | + - |
| 124 | + name: unspec |
| 125 | + type: unused |
| 126 | + value: 0 |
| 127 | + - |
| 128 | + name: public-key |
| 129 | + type: binary |
| 130 | + display-hint: hex |
| 131 | + checks: |
| 132 | + exact-len: wg-key-len |
| 133 | + - |
| 134 | + name: preshared-key |
| 135 | + type: binary |
| 136 | + doc: Set as all zeros to remove. |
| 137 | + display-hint: hex |
| 138 | + checks: |
| 139 | + exact-len: wg-key-len |
| 140 | + - |
| 141 | + name: flags |
| 142 | + type: u32 |
| 143 | + doc: | |
| 144 | + ``0`` and/or ``WGPEER_F_REMOVE_ME`` if the specified peer should not |
| 145 | + exist at the end of the operation, rather than added/updated and/or |
| 146 | + ``WGPEER_F_REPLACE_ALLOWEDIPS`` if all current allowed IPs of this |
| 147 | + peer should be removed prior to adding the list below and/or |
| 148 | + ``WGPEER_F_UPDATE_ONLY`` if the peer should only be set if it already |
| 149 | + exists. |
| 150 | + enum: wgpeer-flags |
| 151 | + - |
| 152 | + name: endpoint |
| 153 | + type: binary |
| 154 | + doc: struct sockaddr_in or struct sockaddr_in6 |
| 155 | + checks: |
| 156 | + min-len: 16 |
| 157 | + - |
| 158 | + name: persistent-keepalive-interval |
| 159 | + type: u16 |
| 160 | + doc: Set as ``0`` to disable. |
| 161 | + - |
| 162 | + name: last-handshake-time |
| 163 | + type: binary |
| 164 | + struct: --kernel-timespec |
| 165 | + checks: |
| 166 | + exact-len: 16 |
| 167 | + - |
| 168 | + name: rx-bytes |
| 169 | + type: u64 |
| 170 | + - |
| 171 | + name: tx-bytes |
| 172 | + type: u64 |
| 173 | + - |
| 174 | + name: allowedips |
| 175 | + type: indexed-array |
| 176 | + sub-type: nest |
| 177 | + nested-attributes: wgallowedip |
| 178 | + doc: | |
| 179 | + The index/type parameter is unused on ``SET_DEVICE`` operations and is |
| 180 | + zero on ``GET_DEVICE`` operations. |
| 181 | + - |
| 182 | + name: protocol-version |
| 183 | + type: u32 |
| 184 | + doc: | |
| 185 | + Should not be set or used at all by most users of this API, as the |
| 186 | + most recent protocol will be used when this is unset. Otherwise, |
| 187 | + must be set to ``1``. |
| 188 | + - |
| 189 | + name: wgallowedip |
| 190 | + enum-name: wgallowedip-attribute |
| 191 | + name-prefix: wgallowedip-a- |
| 192 | + attr-cnt-name: --wgallowedip-a-last |
| 193 | + attributes: |
| 194 | + - |
| 195 | + name: unspec |
| 196 | + type: unused |
| 197 | + value: 0 |
| 198 | + - |
| 199 | + name: family |
| 200 | + type: u16 |
| 201 | + doc: IP family, either ``AF_INET`` or ``AF_INET6``. |
| 202 | + - |
| 203 | + name: ipaddr |
| 204 | + type: binary |
| 205 | + doc: Either ``struct in_addr`` or ``struct in6_addr``. |
| 206 | + display-hint: ipv4-or-v6 |
| 207 | + checks: |
| 208 | + min-len: 4 |
| 209 | + - |
| 210 | + name: cidr-mask |
| 211 | + type: u8 |
| 212 | + - |
| 213 | + name: flags |
| 214 | + type: u32 |
| 215 | + doc: | |
| 216 | + ``WGALLOWEDIP_F_REMOVE_ME`` if the specified IP should be removed; |
| 217 | + otherwise, this IP will be added if it is not already present. |
| 218 | + enum: wgallowedip-flags |
| 219 | + |
| 220 | +operations: |
| 221 | + enum-name: wg-cmd |
| 222 | + name-prefix: wg-cmd- |
| 223 | + list: |
| 224 | + - |
| 225 | + name: get-device |
| 226 | + value: 0 |
| 227 | + doc: | |
| 228 | + Retrieve WireGuard device |
| 229 | + ~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 230 | +
|
| 231 | + The command should be called with one but not both of: |
| 232 | +
|
| 233 | + - ``WGDEVICE_A_IFINDEX`` |
| 234 | + - ``WGDEVICE_A_IFNAME`` |
| 235 | +
|
| 236 | + The kernel will then return several messages (``NLM_F_MULTI``). It is |
| 237 | + possible that all of the allowed IPs of a single peer will not fit |
| 238 | + within a single netlink message. In that case, the same peer will be |
| 239 | + written in the following message, except it will only contain |
| 240 | + ``WGPEER_A_PUBLIC_KEY`` and ``WGPEER_A_ALLOWEDIPS``. This may occur |
| 241 | + several times in a row for the same peer. It is then up to the receiver |
| 242 | + to coalesce adjacent peers. Likewise, it is possible that all peers will |
| 243 | + not fit within a single message. So, subsequent peers will be sent in |
| 244 | + following messages, except those will only contain ``WGDEVICE_A_IFNAME`` |
| 245 | + and ``WGDEVICE_A_PEERS``. It is then up to the receiver to coalesce |
| 246 | + these messages to form the complete list of peers. |
| 247 | +
|
| 248 | + Since this is an ``NLA_F_DUMP`` command, the final message will always |
| 249 | + be ``NLMSG_DONE``, even if an error occurs. However, this ``NLMSG_DONE`` |
| 250 | + message contains an integer error code. It is either zero or a negative |
| 251 | + error code corresponding to the errno. |
| 252 | + attribute-set: wgdevice |
| 253 | + flags: [uns-admin-perm] |
| 254 | + |
| 255 | + dump: |
| 256 | + pre: wg-get-device-start |
| 257 | + post: wg-get-device-done |
| 258 | + request: |
| 259 | + attributes: |
| 260 | + - ifindex |
| 261 | + - ifname |
| 262 | + reply: &all-attrs |
| 263 | + attributes: |
| 264 | + - ifindex |
| 265 | + - ifname |
| 266 | + - private-key |
| 267 | + - public-key |
| 268 | + - flags |
| 269 | + - listen-port |
| 270 | + - fwmark |
| 271 | + - peers |
| 272 | + - |
| 273 | + name: set-device |
| 274 | + value: 1 |
| 275 | + doc: | |
| 276 | + Set WireGuard device |
| 277 | + ~~~~~~~~~~~~~~~~~~~~ |
| 278 | +
|
| 279 | + This command should be called with a wgdevice set, containing one but |
| 280 | + not both of ``WGDEVICE_A_IFINDEX`` and ``WGDEVICE_A_IFNAME``. |
| 281 | +
|
| 282 | + It is possible that the amount of configuration data exceeds that of the |
| 283 | + maximum message length accepted by the kernel. In that case, several |
| 284 | + messages should be sent one after another, with each successive one |
| 285 | + filling in information not contained in the prior. Note that if |
| 286 | + ``WGDEVICE_F_REPLACE_PEERS`` is specified in the first message, it |
| 287 | + probably should not be specified in fragments that come after, so that |
| 288 | + the list of peers is only cleared the first time but appended after. |
| 289 | + Likewise for peers, if ``WGPEER_F_REPLACE_ALLOWEDIPS`` is specified in |
| 290 | + the first message of a peer, it likely should not be specified in |
| 291 | + subsequent fragments. |
| 292 | +
|
| 293 | + If an error occurs, ``NLMSG_ERROR`` will reply containing an errno. |
| 294 | + attribute-set: wgdevice |
| 295 | + flags: [uns-admin-perm] |
| 296 | + |
| 297 | + do: |
| 298 | + request: *all-attrs |
0 commit comments