diff options
-rw-r--r-- | proto/wireguard/wireguard.c | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/proto/wireguard/wireguard.c b/proto/wireguard/wireguard.c index e66bd7fa..e0756eb8 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; + } } } |