7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed/*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * CDDL HEADER START
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed *
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * The contents of this file are subject to the terms of the
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Common Development and Distribution License (the "License").
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * You may not use this file except in compliance with the License.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed *
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * or http://www.opensolaris.org/os/licensing.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * See the License for the specific language governing permissions
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * and limitations under the License.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed *
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * When distributing Covered Code, include this CDDL HEADER in each
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * If applicable, add the following below this CDDL HEADER, with the
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * fields enclosed by brackets "[]" replaced with your own identifying
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * information: Portions Copyright [yyyy] [name of copyright owner]
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed *
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * CDDL HEADER END
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed/*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Use is subject to license terms.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed#include <sys/param.h>
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed#include <sys/atomic.h>
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed#include <sys/kmem.h>
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed#include <sys/rwlock.h>
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed#include <sys/errno.h>
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed#include <sys/queue.h>
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed#include <sys/sunddi.h>
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed#include <inet/common.h>
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed#include <inet/led.h>
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed#include <inet/ip.h>
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed#include <sys/neti.h>
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed#include <sys/zone.h>
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed#include <sys/sdt.h>
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reedtypedef boolean_t napplyfn_t(neti_stack_t *, void *);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic void *neti_stack_init(netstackid_t stackid, netstack_t *ns);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic void neti_stack_fini(netstackid_t stackid, void *arg);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic net_instance_int_t *net_instance_int_create(net_instance_t *nin,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed net_instance_int_t *parent);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic void neti_stack_shutdown(netstackid_t stackid, void *arg);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic void net_instance_int_free(net_instance_int_t *nini);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reedstatic boolean_t neti_stack_apply_create(neti_stack_t *, void *);
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reedstatic boolean_t neti_stack_apply_destroy(neti_stack_t *, void *);
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reedstatic boolean_t neti_stack_apply_shutdown(neti_stack_t *, void *);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic void neti_apply_all_instances(neti_stack_t *, napplyfn_t *);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic void neti_apply_all_stacks(void *, napplyfn_t *);
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reedstatic boolean_t wait_for_nini_inprogress(neti_stack_t *,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed net_instance_int_t *, uint32_t);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic nini_head_t neti_instance_list;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic neti_stack_head_t neti_stack_list;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic kmutex_t neti_stack_lock;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedvoid
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedneti_init()
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_init(&neti_stack_lock, NULL, MUTEX_DRIVER, NULL);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_INIT(&neti_instance_list);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_INIT(&neti_stack_list);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * We want to be informed each time a netstack is created or
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * destroyed in the kernel.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed netstack_register(NS_NETI, neti_stack_init, neti_stack_shutdown,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_fini);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedvoid
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedneti_fini()
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed ASSERT(LIST_EMPTY(&neti_instance_list));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed ASSERT(LIST_EMPTY(&neti_stack_list));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed netstack_unregister(NS_NETI);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_destroy(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed/*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Initialize the neti stack instance. Because this is called out of the
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * netstack framework, it is not possible for it to be called twice with
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * the same values for (stackid,ns). The same also applies to the other
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * two functions used with netstack_register: neti_stack_shutdown and
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * neti_stack_fini.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic void *
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedneti_stack_init(netstackid_t stackid, netstack_t *ns)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed net_instance_int_t *dup;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed net_instance_int_t *n;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_t *nts;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nts = kmem_zalloc(sizeof (*nts), KM_SLEEP);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_INIT(&nts->nts_instances);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nts->nts_id = (netid_t)stackid;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nts->nts_stackid = stackid;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nts->nts_netstack = ns;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nts->nts_zoneid = netstackid_to_zoneid(stackid);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nts->nts_flags = NSF_ZONE_CREATE;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed cv_init(&nts->nts_cv, NULL, CV_DRIVER, NULL);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_init(&nts->nts_lock, NULL, MUTEX_DRIVER, NULL);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_INSERT_HEAD(&neti_stack_list, nts, nts_next);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_FOREACH(n, &neti_instance_list, nini_next) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * This function returns with the NSS_CREATE_NEEDED flag
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * set in "dup", so it is adequately prepared for the
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * upcoming apply.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed dup = net_instance_int_create(n->nini_instance, n);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_INSERT_HEAD(&nts->nts_instances, dup, nini_next);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_apply_all_instances(nts, neti_stack_apply_create);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nts->nts_flags &= ~NSF_ZONE_CREATE;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (nts);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed/*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Run the shutdown for all of the hooks.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed/*ARGSUSED*/
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic void
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedneti_stack_shutdown(netstackid_t stackid, void *arg)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_t *nts = arg;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed net_instance_int_t *n;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed struct net_data *nd;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed ASSERT(nts != NULL);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Walk through all of the protocol stacks and mark them as shutting
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * down.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_FOREACH(nd, &nts->nts_netd_head, netd_list) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nd->netd_condemned = 1;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Now proceed to see which callbacks are waiting to hear about the
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * impending shutdown...
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_FOREACH(n, &nts->nts_instances, nini_next) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (n->nini_instance->nin_shutdown == NULL) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * If there is no shutdown function registered,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * fake that we have completed it.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed n->nini_flags |= NSS_SHUTDOWN_COMPLETED;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed continue;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * We need to ensure that we don't try and shutdown something
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * that is already in the process of being shutdown or
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * destroyed. If it is still being created, that's ok, the
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * shtudown flag is added to the mix of things to do.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if ((n->nini_flags & (NSS_DESTROY_ALL|NSS_SHUTDOWN_ALL)) == 0)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed n->nini_flags |= NSS_SHUTDOWN_NEEDED;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nts->nts_flags |= NSF_ZONE_SHUTDOWN;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_apply_all_instances(nts, neti_stack_apply_shutdown);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nts->nts_netstack = NULL;
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed nts->nts_flags &= ~NSF_ZONE_SHUTDOWN;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed ASSERT(nts != NULL);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed/*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Free the neti stack instance.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * This function relies on the netstack framework only calling the _destroy
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * callback once for each stackid. The netstack framework also provides us
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * with assurance that nobody else will be doing any work (_create, _shutdown)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * on it, so there is no need to set and use flags to guard against
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * simultaneous execution (ie. no need to set NSF_CLOSING.)
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed * What is required, however, is to make sure that we don't corrupt the
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * list of neti_stack_t's for other code that walks it.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed/*ARGSUSED*/
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic void
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedneti_stack_fini(netstackid_t stackid, void *arg)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_t *nts = arg;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed net_instance_int_t *n;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed struct net_data *nd;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&neti_stack_lock);
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed mutex_enter(&nts->nts_lock);
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_REMOVE(nts, nts_next);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Walk through all of the protocol stacks and mark them as being
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * destroyed.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_FOREACH(nd, &nts->nts_netd_head, netd_list) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nd->netd_condemned = 2;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_FOREACH(n, &nts->nts_instances, nini_next) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed ASSERT((n->nini_flags & NSS_SHUTDOWN_ALL) != 0);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if ((n->nini_flags & NSS_DESTROY_ALL) == 0)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed n->nini_flags |= NSS_DESTROY_NEEDED;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_apply_all_instances(nts, neti_stack_apply_destroy);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed while (!LIST_EMPTY(&nts->nts_instances)) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed n = LIST_FIRST(&nts->nts_instances);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_REMOVE(n, nini_next);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed net_instance_int_free(n);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed mutex_exit(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed ASSERT(LIST_EMPTY(&nts->nts_netd_head));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_destroy(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed cv_destroy(&nts->nts_cv);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed kmem_free(nts, sizeof (*nts));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic net_instance_int_t *
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_instance_int_create(net_instance_t *nin, net_instance_int_t *parent)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed net_instance_int_t *nini;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nini = kmem_zalloc(sizeof (net_instance_int_t), KM_SLEEP);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nini->nini_instance = nin;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nini->nini_parent = parent;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (parent != NULL) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * If the parent pointer is non-NULL then we take that as
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * an indication that the net_instance_int_t is being
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * created for an active instance and there will expect
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * the create function to be called. In contrast, if
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * parent is NULL then this code assumes the object is
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * being prepared for insertion onto the master list of
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * callbacks to be called when an instance is created, etc.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed parent->nini_ref++;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nini->nini_flags |= NSS_CREATE_NEEDED;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed cv_init(&nini->nini_cv, NULL, CV_DRIVER, NULL);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (nini);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed/*
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed * Free'ing of a net_instance_int_t is only to be done when we know nobody
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed * else has is using it. For both parents and clones, this is indicated by
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed * nini_ref being greater than 0, however, nini_ref is managed differently
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed * for its two uses. For parents, nini_ref is increased when a new clone is
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed * created and it is decremented here. For clones, nini_ref is adjusted by
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed * code elsewhere (e.g. in neti_stack_apply_*) and is not changed here.
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic void
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_instance_int_free(net_instance_int_t *nini)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed /*
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed * This mutex guards the use of nini_ref.
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed */
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed ASSERT(mutex_owned(&neti_stack_lock));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed /*
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed * For 'parent' structures, nini_ref will drop to 0 when
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed * the last clone has been free'd... but for clones, it
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed * is possible for nini_ref to be non-zero if we get in
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed * here when all the locks have been given up to execute
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed * a callback or wait_for_nini_inprogress. In that case,
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed * we do not want to free the structure and just indicate
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed * that it is on the "doomed" list, thus we set the
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed * condemned flag.
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed */
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed if (nini->nini_parent != NULL) {
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed if (nini->nini_ref > 0)
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed nini->nini_condemned = B_TRUE;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nini->nini_parent->nini_ref--;
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed if (nini->nini_parent->nini_ref == 0)
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed net_instance_int_free(nini->nini_parent);
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed nini->nini_parent = NULL;
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed if (nini->nini_ref == 0) {
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed cv_destroy(&nini->nini_cv);
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed kmem_free(nini, sizeof (*nini));
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_instance_t *
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_instance_alloc(const int version)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed net_instance_t *nin;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (version != NETINFO_VERSION)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (NULL);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nin = kmem_zalloc(sizeof (net_instance_t), KM_SLEEP);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nin->nin_version = version;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (nin);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedvoid
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_instance_free(net_instance_t *nin)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed kmem_free(nin, sizeof (*nin));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedint
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_instance_register(net_instance_t *nin)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed net_instance_int_t *parent;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed net_instance_int_t *tmp;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_t *nts;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed ASSERT(nin->nin_name != NULL);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (nin->nin_create == NULL || nin->nin_destroy == NULL)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (DDI_FAILURE);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Search for duplicate, either on the global list or on any
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * of the known instances.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_FOREACH(tmp, &neti_instance_list, nini_next) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (strcmp(nin->nin_name, tmp->nini_instance->nin_name) == 0) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (DDI_FAILURE);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Now insert and activate.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed parent = net_instance_int_create(nin, NULL);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed ASSERT(parent != NULL);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_INSERT_HEAD(&neti_instance_list, parent, nini_next);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_FOREACH(nts, &neti_stack_list, nts_next) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * If shutdown of the zone has begun then do not add a new
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * instance of the object being registered.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if ((nts->nts_flags & NSF_ZONE_SHUTDOWN) ||
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed (nts->nts_netstack == NULL)) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed continue;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * This function returns with the NSS_CREATE_NEEDED flag
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * set in "dup", so it is adequately prepared for the
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * upcoming apply.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed tmp = net_instance_int_create(nin, parent);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed ASSERT(tmp != NULL);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_INSERT_HEAD(&nts->nts_instances, tmp, nini_next);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_apply_all_stacks(parent, neti_stack_apply_create);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (DDI_SUCCESS);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed/*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * While net_instance_register() isn't likely to be racing against itself,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * net_instance_unregister() can be entered from various directions that
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * can compete: shutdown of a zone, unloading of a module (and it calling
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * _unregister() as part of that) and the module doing an _unregister()
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * anyway.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedint
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_instance_unregister(net_instance_t *nin)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed net_instance_int_t *parent;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed net_instance_int_t *tmp;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_t *nts;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_FOREACH(tmp, &neti_instance_list, nini_next) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (strcmp(tmp->nini_instance->nin_name, nin->nin_name) == 0) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_REMOVE(tmp, nini_next);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed break;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (tmp == NULL) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (DDI_FAILURE);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed parent = tmp;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_FOREACH(nts, &neti_stack_list, nts_next) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_FOREACH(tmp, &nts->nts_instances, nini_next) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (tmp->nini_parent != parent)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed continue;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Netstack difference:
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * In netstack.c, there is a check for
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * NSS_CREATE_COMPLETED before setting the other
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * _NEEDED flags. If we consider that a list
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * member must always have at least the _CREATE_NEEDED
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * flag set and that wait_for_nini_inprogress will
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * also wait for that flag to be cleared in both of
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * the shutdown and destroy apply functions.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed *
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * It is possible to optimize out the case where
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * all three _NEEDED flags are set to being able
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * to pretend everything has been done and just
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * set all three _COMPLETE flags. This makes a
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * special case that we then need to consider in
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * other locations, so for the sake of simplicity,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * we leave it as it is.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if ((tmp->nini_flags & NSS_SHUTDOWN_ALL) == 0)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed tmp->nini_flags |= NSS_SHUTDOWN_NEEDED;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if ((tmp->nini_flags & NSS_DESTROY_ALL) == 0)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed tmp->nini_flags |= NSS_DESTROY_NEEDED;
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed break;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Each of these functions ensures that the requisite _COMPLETED
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * flag is present before calling the apply function. So we are
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * guaranteed to have NSS_CREATE_COMPLETED|NSS_SHUTDOWN_COMPLETED
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * both set after the first call here and when the second completes,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * NSS_DESTROY_COMPLETED is also set.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_apply_all_stacks(parent, neti_stack_apply_shutdown);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_apply_all_stacks(parent, neti_stack_apply_destroy);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Remove the instance callback information from each stack.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_FOREACH(nts, &neti_stack_list, nts_next) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_FOREACH(tmp, &nts->nts_instances, nini_next) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if ((tmp->nini_parent == parent) &&
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed (tmp->nini_flags & NSS_SHUTDOWN_COMPLETED) &&
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed (tmp->nini_flags & NSS_DESTROY_COMPLETED)) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * There should only be one entry that has a
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * matching nini_parent so there is no need to
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * worry about continuing a loop where we are
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * free'ing the structure holding the 'next'
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * pointer.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_REMOVE(tmp, nini_next);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed net_instance_int_free(tmp);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed break;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed mutex_exit(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (DDI_SUCCESS);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic void
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedneti_apply_all_instances(neti_stack_t *nts, napplyfn_t *applyfn)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed net_instance_int_t *n;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed ASSERT(mutex_owned(&neti_stack_lock));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed n = LIST_FIRST(&nts->nts_instances);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed while (n != NULL) {
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed if ((applyfn)(nts, n->nini_parent)) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /* Lock dropped - restart at head */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed n = LIST_FIRST(&nts->nts_instances);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed } else {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed n = LIST_NEXT(n, nini_next);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic void
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedneti_apply_all_stacks(void *parent, napplyfn_t *applyfn)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_t *nts;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed ASSERT(mutex_owned(&neti_stack_lock));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nts = LIST_FIRST(&neti_stack_list);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed while (nts != NULL) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * This function differs, in that it doesn't have a call to
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * a "wait_creator" call, from the zsd/netstack code. The
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * waiting is pushed into the apply functions which cause
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * the waiting to be done in wait_for_nini_progress with
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * the passing in of cmask.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed if ((applyfn)(nts, parent)) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /* Lock dropped - restart at head */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nts = LIST_FIRST(&neti_stack_list);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed } else {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nts = LIST_NEXT(nts, nts_next);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic boolean_t
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reedneti_stack_apply_create(neti_stack_t *nts, void *parent)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed void *result;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed boolean_t dropped = B_FALSE;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed net_instance_int_t *tmp;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed net_instance_t *nin;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed ASSERT(parent != NULL);
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed ASSERT(mutex_owned(&neti_stack_lock));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_FOREACH(tmp, &nts->nts_instances, nini_next) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (tmp->nini_parent == parent)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed break;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (tmp == NULL) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (dropped);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed tmp->nini_ref++;
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed if (wait_for_nini_inprogress(nts, tmp, 0))
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed dropped = B_TRUE;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed if ((tmp->nini_flags & NSS_CREATE_NEEDED) && !tmp->nini_condemned) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nin = tmp->nini_instance;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed tmp->nini_flags &= ~NSS_CREATE_NEEDED;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed tmp->nini_flags |= NSS_CREATE_INPROGRESS;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed DTRACE_PROBE2(neti__stack__create__inprogress,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_t *, nts, net_instance_int_t *, tmp);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&nts->nts_lock);
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed mutex_exit(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed dropped = B_TRUE;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed ASSERT(tmp->nini_created == NULL);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed ASSERT(nin->nin_create != NULL);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed DTRACE_PROBE2(neti__stack__create__start,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed netstackid_t, nts->nts_id,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_t *, nts);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed result = (nin->nin_create)(nts->nts_id);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed DTRACE_PROBE2(neti__stack__create__end,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed void *, result, neti_stack_t *, nts);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed ASSERT(result != NULL);
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed mutex_enter(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed tmp->nini_created = result;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed tmp->nini_flags &= ~NSS_CREATE_INPROGRESS;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed tmp->nini_flags |= NSS_CREATE_COMPLETED;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed cv_broadcast(&tmp->nini_cv);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed DTRACE_PROBE2(neti__stack__create__completed,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_t *, nts, net_instance_int_t *, tmp);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed tmp->nini_ref--;
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed if (tmp->nini_condemned) {
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed net_instance_int_free(tmp);
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed dropped = B_TRUE;
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (dropped);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic boolean_t
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reedneti_stack_apply_shutdown(neti_stack_t *nts, void *parent)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed boolean_t dropped = B_FALSE;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed net_instance_int_t *tmp;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed net_instance_t *nin;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed ASSERT(parent != NULL);
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed ASSERT(mutex_owned(&neti_stack_lock));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_FOREACH(tmp, &nts->nts_instances, nini_next) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (tmp->nini_parent == parent)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed break;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (tmp == NULL) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (dropped);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed ASSERT((tmp->nini_flags & NSS_SHUTDOWN_ALL) != 0);
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed tmp->nini_ref++;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed if (wait_for_nini_inprogress(nts, tmp, NSS_CREATE_NEEDED))
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed dropped = B_TRUE;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nin = tmp->nini_instance;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (nin->nin_shutdown == NULL) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * If there is no shutdown function, fake having completed it.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (tmp->nini_flags & NSS_SHUTDOWN_NEEDED) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed tmp->nini_flags &= ~NSS_SHUTDOWN_NEEDED;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed tmp->nini_flags |= NSS_SHUTDOWN_COMPLETED;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed tmp->nini_ref--;
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed if (tmp->nini_condemned) {
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed net_instance_int_free(tmp);
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed dropped = B_TRUE;
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (dropped);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed if ((tmp->nini_flags & NSS_SHUTDOWN_NEEDED) && !tmp->nini_condemned) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed ASSERT((tmp->nini_flags & NSS_CREATE_COMPLETED) != 0);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed tmp->nini_flags &= ~NSS_SHUTDOWN_NEEDED;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed tmp->nini_flags |= NSS_SHUTDOWN_INPROGRESS;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed DTRACE_PROBE2(neti__stack__shutdown__inprogress,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_t *, nts, net_instance_int_t *, tmp);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&nts->nts_lock);
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed mutex_exit(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed dropped = B_TRUE;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed ASSERT(nin->nin_shutdown != NULL);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed DTRACE_PROBE2(neti__stack__shutdown__start,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed netstackid_t, nts->nts_id,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_t *, nts);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed (nin->nin_shutdown)(nts->nts_id, tmp->nini_created);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed DTRACE_PROBE1(neti__stack__shutdown__end,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_t *, nts);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed mutex_enter(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed tmp->nini_flags &= ~NSS_SHUTDOWN_INPROGRESS;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed tmp->nini_flags |= NSS_SHUTDOWN_COMPLETED;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed cv_broadcast(&tmp->nini_cv);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed DTRACE_PROBE2(neti__stack__shutdown__completed,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_t *, nts, net_instance_int_t *, tmp);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed ASSERT((tmp->nini_flags & NSS_SHUTDOWN_COMPLETED) != 0);
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed tmp->nini_ref--;
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed if (tmp->nini_condemned) {
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed net_instance_int_free(tmp);
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed dropped = B_TRUE;
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (dropped);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic boolean_t
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reedneti_stack_apply_destroy(neti_stack_t *nts, void *parent)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed boolean_t dropped = B_FALSE;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed net_instance_int_t *tmp;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed net_instance_t *nin;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed ASSERT(parent != NULL);
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed ASSERT(mutex_owned(&neti_stack_lock));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_FOREACH(tmp, &nts->nts_instances, nini_next) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (tmp->nini_parent == parent)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed break;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (tmp == NULL) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (dropped);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed tmp->nini_ref++;
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * We pause here so that when we continue we know that we're the
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * only one doing anything active with this node.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed if (wait_for_nini_inprogress(nts, tmp,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed NSS_CREATE_NEEDED|NSS_SHUTDOWN_NEEDED))
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed dropped = B_TRUE;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed if ((tmp->nini_flags & NSS_DESTROY_NEEDED) && !tmp->nini_condemned) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed ASSERT((tmp->nini_flags & NSS_SHUTDOWN_COMPLETED) != 0);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed nin = tmp->nini_instance;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed tmp->nini_flags &= ~NSS_DESTROY_NEEDED;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed tmp->nini_flags |= NSS_DESTROY_INPROGRESS;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed DTRACE_PROBE2(neti__stack__destroy__inprogress,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_t *, nts, net_instance_int_t *, tmp);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&nts->nts_lock);
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed mutex_exit(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed dropped = B_TRUE;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed ASSERT(nin->nin_destroy != NULL);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed DTRACE_PROBE2(neti__stack__destroy__start,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed netstackid_t, nts->nts_id,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_t *, nts);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed (nin->nin_destroy)(nts->nts_id, tmp->nini_created);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed DTRACE_PROBE1(neti__stack__destroy__end,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_t *, nts);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed mutex_enter(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed tmp->nini_flags &= ~NSS_DESTROY_INPROGRESS;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed tmp->nini_flags |= NSS_DESTROY_COMPLETED;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed cv_broadcast(&tmp->nini_cv);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed DTRACE_PROBE2(neti__stack__destroy__completed,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_t *, nts, net_instance_int_t *, tmp);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed tmp->nini_ref--;
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed if (tmp->nini_condemned) {
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed net_instance_int_free(tmp);
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed dropped = B_TRUE;
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (dropped);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic boolean_t
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reedwait_for_nini_inprogress(neti_stack_t *nts, net_instance_int_t *nini,
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed uint32_t cmask)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed boolean_t dropped = B_FALSE;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed ASSERT(mutex_owned(&neti_stack_lock));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed while (nini->nini_flags & (NSS_ALL_INPROGRESS|cmask)) {
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed DTRACE_PROBE2(neti__wait__nini__inprogress,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_t *, nts, net_instance_int_t *, nini);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed dropped = B_TRUE;
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed mutex_exit(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed cv_wait(&nini->nini_cv, &nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /* First drop netstack_lock to preserve order */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&nts->nts_lock);
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed DTRACE_PROBE2(wait__nini__inprogress__pause,
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed neti_stack_t *, nts, net_instance_int_t *, nini);
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed mutex_enter(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&nts->nts_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed DTRACE_PROBE2(neti__wait__nini__inprogress__complete,
8ad7418892268f9f0ba29518ab332f6a26f69fc5Darren Reed neti_stack_t *, nts, net_instance_int_t *, nini);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (dropped);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed/* ======================================================================= */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednetid_t
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_zoneidtonetid(zoneid_t zoneid)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_t *nts;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_FOREACH(nts, &neti_stack_list, nts_next) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (nts->nts_zoneid == zoneid) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (nts->nts_id);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (-1);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedzoneid_t
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_getzoneidbynetid(netid_t netid)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_t *nts;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_FOREACH(nts, &neti_stack_list, nts_next) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (nts->nts_id == netid) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (nts->nts_zoneid);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (-1);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednetstackid_t
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_getnetstackidbynetid(netid_t netid)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_t *nts;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_FOREACH(nts, &neti_stack_list, nts_next) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (nts->nts_id == netid) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (nts->nts_stackid);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (-1);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednetid_t
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_getnetidbynetstackid(netstackid_t netstackid)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_t *nts;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_FOREACH(nts, &neti_stack_list, nts_next) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (nts->nts_stackid == netstackid) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (nts->nts_id);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (-1);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedneti_stack_t *
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_getnetistackbyid(netid_t netid)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed neti_stack_t *nts;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_enter(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_FOREACH(nts, &neti_stack_list, nts_next) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (nts->nts_id == netid) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (nts);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed mutex_exit(&neti_stack_lock);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (NULL);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedint
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_instance_notify_register(netid_t netid, hook_notify_fn_t callback,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed void *arg)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (hook_stack_notify_register(net_getnetstackidbynetid(netid),
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed callback, arg));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedint
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_instance_notify_unregister(netid_t netid, hook_notify_fn_t callback)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (hook_stack_notify_unregister(net_getnetstackidbynetid(netid),
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed callback));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}