diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index 7e6a52c711..ed765e1b9c 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -1700,9 +1700,10 @@ AllowedIPs= - Sets a comma-separated list of IP (v4 or v6) addresses with CIDR masks - from which this peer is allowed to send incoming traffic and to - which outgoing traffic for this peer is directed. + Sets a comma-separated list of IP (v4 or v6) addresses with CIDR masks from which this peer + is allowed to send incoming traffic and to which outgoing traffic for this peer is directed. This + setting can be specified multiple times. If an empty string is assigned, then the all previous + assignments are cleared. The catch-all 0.0.0.0/0 may be specified for matching all IPv4 addresses, and ::/0 may be specified for matching all IPv6 addresses. diff --git a/src/network/netdev/wireguard.c b/src/network/netdev/wireguard.c index 51e7e02990..ffc6452bbf 100644 --- a/src/network/netdev/wireguard.c +++ b/src/network/netdev/wireguard.c @@ -34,9 +34,18 @@ static void wireguard_resolve_endpoints(NetDev *netdev); static int peer_resolve_endpoint(WireguardPeer *peer); -static WireguardPeer* wireguard_peer_free(WireguardPeer *peer) { +static void wireguard_peer_clear_ipmasks(WireguardPeer *peer) { WireguardIPmask *mask; + assert(peer); + + while ((mask = peer->ipmasks)) { + LIST_REMOVE(ipmasks, peer->ipmasks, mask); + free(mask); + } +} + +static WireguardPeer* wireguard_peer_free(WireguardPeer *peer) { if (!peer) return NULL; @@ -49,10 +58,7 @@ static WireguardPeer* wireguard_peer_free(WireguardPeer *peer) { config_section_free(peer->section); - while ((mask = peer->ipmasks)) { - LIST_REMOVE(ipmasks, peer->ipmasks, mask); - free(mask); - } + wireguard_peer_clear_ipmasks(peer); free(peer->endpoint_host); free(peer->endpoint_port); @@ -685,6 +691,12 @@ int config_parse_wireguard_allowed_ips( if (r < 0) return log_oom(); + if (isempty(rvalue)) { + wireguard_peer_clear_ipmasks(peer); + TAKE_PTR(peer); + return 0; + } + for (const char *p = rvalue;;) { _cleanup_free_ char *word = NULL; union in_addr_union masked;