summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikael Magnusson <mikma@users.sourceforge.net>2019-09-29 15:39:00 +0200
committerMikael Magnusson <mikma@users.sourceforge.net>2020-05-08 18:52:55 +0200
commitf8abb113fc0630bc6469252db126f6cbc5f0deeb (patch)
tree88a0ca7221b243fcc332278b196e5dd5b303195a
parent31ad8c90ce074910dcad7535cd5f56f0e5b1e958 (diff)
Wireguard: Fix duplicate allowedip entries
-rw-r--r--proto/wireguard/wireguard.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/proto/wireguard/wireguard.c b/proto/wireguard/wireguard.c
index eabaa79c..90740490 100644
--- a/proto/wireguard/wireguard.c
+++ b/proto/wireguard/wireguard.c
@@ -392,8 +392,14 @@ wg_rt_notify(struct proto *P, struct channel *CH, struct network *n,
}
if (t && t->u.ptr && decode_tunnel_encap(t, &encap, P->pool) == 0 && encap.type == c->tunnel_type && encap.encap_len == sizeof(wg_key)) {
const wg_key *pubkey = encap.encap;
+ bool add_ip = true;
+ struct wg_entry *en = fib_find(&ch->rtable, n->n.addr);
- if (!fib_find(&ch->rtable, n->n.addr)) {
+ if (en) {
+ if (memcpy(en->public_key, pubkey, sizeof(wg_key) == 0)) {
+ add_ip = false;
+ }
+ } else {
struct wg_entry *en = fib_get(&ch->rtable, n->n.addr);
en->is_tunnel_ep = is_tunnel_ep;
memcpy(en->public_key, pubkey, sizeof(wg_key));
@@ -418,20 +424,18 @@ wg_rt_notify(struct proto *P, struct channel *CH, struct network *n,
log(L_TRACE "WG: Found");
found = true;
-
- set_peer_tunnel_ep(peer, encap.ep.ip, encap.udp_dest_port);
- add_allowed_ip(ch->c.net_type, n, peer);
dirty = true;
-
break;
}
if (!found) {
- wg_peer *peer = add_peer(dev, pubkey);
+ peer = add_peer(dev, pubkey);
+ }
+ if (is_tunnel_ep)
set_peer_tunnel_ep(peer, encap.ep.ip, encap.udp_dest_port);
+ if (add_ip)
add_allowed_ip(ch->c.net_type, n, peer);
- dirty = true;
- }
+ dirty = true;
if (dirty) {
int res = set_device(p);
@@ -546,9 +550,11 @@ wg_rt_notify(struct proto *P, struct channel *CH, struct network *n,
if (found) {
struct wg_allowedip *allowedip = alloca(sizeof(struct wg_allowedip));
init_allowed_ip(allowedip, ch->c.net_type, n);
- remove_allowed_ip(peer, allowedip);
-
- peer->flags |= WGPEER_REPLACE_ALLOWEDIPS;
+ if (remove_allowed_ip(peer, allowedip)) {
+ ip_addr ip = allowedip_to_ipa(allowedip);
+ log(L_TRACE "WG: removed %I/%d", ip, allowedip->cidr);
+ peer->flags |= WGPEER_REPLACE_ALLOWEDIPS;
+ }
}
}