summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Dunwoodie <ncon@noconroy.net>2021-04-13 09:35:54 +1000
committerMatt Dunwoodie <ncon@noconroy.net>2021-04-13 15:47:31 +1000
commit5454705cf72a3461162b614f345f015dfc830414 (patch)
treef3dcbcb91d95255b862ef335f7a5f4bd0c73bbbd
parentMerge wg_timers and wg_peer (diff)
downloadwireguard-openbsd-master.tar.xz
wireguard-openbsd-master.zip
Delete all peer allowed IPs at onceHEADmaster
This simplifies the deletion process, so we do not require a lookup of the node before deletion.
-rw-r--r--sys/net/if_wg.c77
1 files changed, 34 insertions, 43 deletions
diff --git a/sys/net/if_wg.c b/sys/net/if_wg.c
index b1dd3dd7c19..2e286fc9a74 100644
--- a/sys/net/if_wg.c
+++ b/sys/net/if_wg.c
@@ -245,8 +245,7 @@ void wg_peer_counters_add(struct wg_peer *, uint64_t, uint64_t);
int wg_aip_add(struct wg_softc *, struct wg_peer *, struct wg_aip_io *);
struct wg_peer *
wg_aip_lookup(struct art_root *, void *);
-int wg_aip_remove(struct wg_softc *, struct wg_peer *,
- struct wg_aip_io *);
+void wg_aip_remove_all(struct wg_softc *, struct wg_peer *);
int wg_socket_open(struct socket **, int, in_port_t *, int *, void *);
void wg_socket_close(struct socket **);
@@ -412,16 +411,13 @@ void
wg_peer_destroy(struct wg_peer *peer)
{
struct wg_softc *sc = peer->p_sc;
- struct wg_aip *aip, *taip;
rw_assert_wrlock(&sc->sc_lock);
TAILQ_REMOVE(&sc->sc_peers, peer, p_entry);
sc->sc_peer_num--;
- LIST_FOREACH_SAFE(aip, &peer->p_aip, a_entry, taip)
- wg_aip_remove(sc, peer, &aip->a_data);
-
+ wg_aip_remove_all(sc, peer);
wg_timers_disable(peer);
noise_remote_free(peer->p_remote, wg_peer_free);
@@ -542,41 +538,40 @@ wg_aip_lookup(struct art_root *root, void *addr)
return node == NULL ? NULL : ((struct wg_aip *) node)->a_peer;
}
-int
-wg_aip_remove(struct wg_softc *sc, struct wg_peer *peer, struct wg_aip_io *d)
+void
+wg_aip_remove_all(struct wg_softc *sc, struct wg_peer *peer)
{
- struct srp_ref sr;
- struct art_root *root;
- struct art_node *node;
- struct wg_aip *aip;
- int ret = 0;
-
- switch (d->a_af) {
- case AF_INET: root = sc->sc_aip4; break;
-#ifdef INET6
- case AF_INET6: root = sc->sc_aip6; break;
-#endif
- default: return EAFNOSUPPORT;
+ struct wg_aip *aip, *taip;
+ struct wg_aip_io *io;
+
+ rw_enter_write(&sc->sc_aip4->ar_lock);
+ LIST_FOREACH_SAFE(aip, &peer->p_aip, a_entry, taip) {
+ io = &aip->a_data;
+ if (io->a_af == AF_INET) {
+ if (art_delete(sc->sc_aip4, &aip->a_node, &io->a_addr, io->a_cidr) == NULL)
+ panic("art_delete failed to delete aip %p", aip);
+ sc->sc_aip_num--;
+ LIST_REMOVE(aip, a_entry);
+ free(aip, M_DEVBUF, sizeof(*aip));
+ }
}
-
- rw_enter_write(&root->ar_lock);
- if ((node = art_lookup(root, &d->a_addr, d->a_cidr, &sr)) == NULL) {
- ret = ENOENT;
- } else if (((struct wg_aip *) node)->a_peer != peer) {
- ret = EXDEV;
- } else {
- aip = (struct wg_aip *)node;
- if (art_delete(root, node, &d->a_addr, d->a_cidr) == NULL)
- panic("art_delete failed to delete node %p", node);
-
- sc->sc_aip_num--;
- LIST_REMOVE(aip, a_entry);
- free(aip, M_DEVBUF, sizeof(*aip));
+ rw_exit_write(&sc->sc_aip4->ar_lock);
+
+ rw_enter_write(&sc->sc_aip6->ar_lock);
+ LIST_FOREACH_SAFE(aip, &peer->p_aip, a_entry, taip) {
+ io = &aip->a_data;
+ if (io->a_af == AF_INET6) {
+ if (art_delete(sc->sc_aip6, &aip->a_node, &io->a_addr, io->a_cidr) == NULL)
+ panic("art_delete failed to delete aip %p", aip);
+ sc->sc_aip_num--;
+ LIST_REMOVE(aip, a_entry);
+ free(aip, M_DEVBUF, sizeof(*aip));
+ }
}
+ rw_exit_write(&sc->sc_aip6->ar_lock);
- srp_leave(&sr);
- rw_exit_write(&root->ar_lock);
- return ret;
+ if (!LIST_EMPTY(&peer->p_aip))
+ panic("wg_aip_delete_all could not delete all %p", peer);
}
int
@@ -1946,7 +1941,6 @@ wg_ioctl_set(struct wg_softc *sc, struct wg_data_io *data)
struct wg_aip_io *aip_p, aip_o;
struct wg_peer *peer, *tpeer;
- struct wg_aip *aip, *taip;
struct noise_remote *remote;
@@ -2068,11 +2062,8 @@ wg_ioctl_set(struct wg_softc *sc, struct wg_data_io *data)
if (peer_o.p_flags & WG_PEER_HAS_PKA)
wg_timers_set_persistent_keepalive(peer, peer_o.p_pka);
- if (peer_o.p_flags & WG_PEER_REPLACE_AIPS) {
- LIST_FOREACH_SAFE(aip, &peer->p_aip, a_entry, taip) {
- wg_aip_remove(sc, peer, &aip->a_data);
- }
- }
+ if (peer_o.p_flags & WG_PEER_REPLACE_AIPS)
+ wg_aip_remove_all(sc, peer);
aip_p = &peer_p->p_aips[0];
for (j = 0; j < peer_o.p_aips_count; j++) {