diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-09-28 20:04:17 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-10-11 12:34:54 +0200 |
commit | 6d176914a91d03589177e69d934c12dffdfe5855 (patch) | |
tree | 764c66e95aa4dddfd961c7bfaa762984ed6e0a9f /src | |
parent | 4c14ec2fb949f31966e61247b1c7b432857ab13d (diff) |
netlink: allow preventing creation of new peers when updating
This enables race-free updates for wg-dynamic and similar tools.
Suggested-by: Thomas Gschwantner <tharre3@gmail.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/netlink.c | 7 | ||||
-rw-r--r-- | src/uapi/wireguard.h | 14 |
2 files changed, 12 insertions, 9 deletions
diff --git a/src/netlink.c b/src/netlink.c index 0805a26..190e405 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -389,10 +389,10 @@ static int set_peer(struct wg_device *wg, struct nlattr **attrs) peer = wg_pubkey_hashtable_lookup(wg->peer_hashtable, nla_data(attrs[WGPEER_A_PUBLIC_KEY])); + ret = 0; if (!peer) { /* Peer doesn't exist yet. Add a new one. */ - ret = -ENODEV; - if (flags & WGPEER_F_REMOVE_ME) - goto out; /* Tried to remove a non-existing peer. */ + if (flags & (WGPEER_F_REMOVE_ME | WGPEER_F_UPDATE_ONLY)) + goto out; /* The peer is new, so there aren't allowed IPs to remove. */ flags &= ~WGPEER_F_REPLACE_ALLOWEDIPS; @@ -429,7 +429,6 @@ static int set_peer(struct wg_device *wg, struct nlattr **attrs) wg_peer_get(peer); } - ret = 0; if (flags & WGPEER_F_REMOVE_ME) { wg_peer_remove(peer); goto out; diff --git a/src/uapi/wireguard.h b/src/uapi/wireguard.h index 5a3e5a7..dd8a47c 100644 --- a/src/uapi/wireguard.h +++ b/src/uapi/wireguard.h @@ -87,10 +87,12 @@ * 0: NLA_NESTED * WGPEER_A_PUBLIC_KEY: len WG_KEY_LEN * WGPEER_A_FLAGS: NLA_U32, 0 and/or WGPEER_F_REMOVE_ME if the - * specified peer should be removed rather than - * added/updated and/or WGPEER_F_REPLACE_ALLOWEDIPS - * if all current allowed IPs of this peer should be - * removed prior to adding the list below. + * specified peer should not exist at the end of the + * operation, rather than added/updated and/or + * WGPEER_F_REPLACE_ALLOWEDIPS if all current allowed + * IPs of this peer should be removed prior to adding + * the list below and/or WGPEER_F_UPDATE_ONLY if the + * peer should only be set if it already exists. * WGPEER_A_PRESHARED_KEY: len WG_KEY_LEN, all zeros to remove * WGPEER_A_ENDPOINT: struct sockaddr_in or struct sockaddr_in6 * WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL: NLA_U16, 0 to disable @@ -162,7 +164,9 @@ enum wgdevice_attribute { enum wgpeer_flag { WGPEER_F_REMOVE_ME = 1U << 0, WGPEER_F_REPLACE_ALLOWEDIPS = 1U << 1, - __WGPEER_F_ALL = WGPEER_F_REMOVE_ME | WGPEER_F_REPLACE_ALLOWEDIPS + WGPEER_F_UPDATE_ONLY = 1U << 2, + __WGPEER_F_ALL = WGPEER_F_REMOVE_ME | WGPEER_F_REPLACE_ALLOWEDIPS | + WGPEER_F_UPDATE_ONLY }; enum wgpeer_attribute { WGPEER_A_UNSPEC, |