Page MenuHomeFreeBSD

D46616.diff
No OneTemporary

D46616.diff

diff --git a/sys/net/if_ovpn.c b/sys/net/if_ovpn.c
--- a/sys/net/if_ovpn.c
+++ b/sys/net/if_ovpn.c
@@ -390,15 +390,11 @@
has_peers = ovpn_has_peers(sc);
- /* Only remove the tunnel function if we're releasing the socket for
- * the last peer. */
- if (! has_peers)
- (void)udp_set_kernel_tunneling(sc->so, NULL, NULL, NULL);
-
- sorele(sc->so);
-
- if (! has_peers)
- sc->so = NULL;
+ if (! has_peers) {
+ MPASS(sc->peercount == 0);
+ } else {
+ MPASS(sc->peercount > 0);
+ }
}
static void
@@ -628,26 +624,23 @@
if (sc->so != NULL && so != sc->so)
goto error_locked;
- if (sc->so == NULL)
+ if (sc->so == NULL) {
sc->so = so;
+ /*
+ * Maintain one extra ref so the socket doesn't go away until
+ * we're destroying the ifp.
+ */
+ soref(sc->so);
+ }
/* Insert the peer into the list. */
RB_INSERT(ovpn_kpeers, &sc->peers, peer);
sc->peercount++;
- soref(sc->so);
-
- ret = udp_set_kernel_tunneling(sc->so, ovpn_udp_input, NULL, sc);
- if (ret == EBUSY) {
- /* Fine, another peer already set the input function. */
- ret = 0;
- }
- if (ret != 0) {
- RB_REMOVE(ovpn_kpeers, &sc->peers, peer);
- sc->peercount--;
- goto error_locked;
- }
OVPN_WUNLOCK(sc);
+ ret = udp_set_kernel_tunneling(sc->so, ovpn_udp_input, NULL, sc);
+ MPASS(ret == 0 || ret == EBUSY);
+ ret = 0;
goto done;
@@ -2493,12 +2486,21 @@
ovpn_clone_destroy_cb(struct epoch_context *ctx)
{
struct ovpn_softc *sc;
+ int ret __diagused;
sc = __containerof(ctx, struct ovpn_softc, epoch_ctx);
MPASS(sc->peercount == 0);
MPASS(RB_EMPTY(&sc->peers));
+ if (sc->so != NULL) {
+ CURVNET_SET(sc->ifp->if_vnet);
+ ret = udp_set_kernel_tunneling(sc->so, NULL, NULL, NULL);
+ MPASS(ret == 0);
+ sorele(sc->so);
+ CURVNET_RESTORE();
+ }
+
COUNTER_ARRAY_FREE(sc->counters, OVPN_COUNTER_SIZE);
if_free(sc->ifp);

File Metadata

Mime Type
text/plain
Expires
Thu, Jan 16, 3:59 PM (21 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15826973
Default Alt Text
D46616.diff (1 KB)

Event Timeline