diff options
-rw-r--r-- | sys/net/if_wg.c | 77 |
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++) { |