4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan/*
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * CDDL HEADER START
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan *
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * The contents of this file are subject to the terms of the
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * Common Development and Distribution License (the "License").
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * You may not use this file except in compliance with the License.
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan *
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * or http://www.opensolaris.org/os/licensing.
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * See the License for the specific language governing permissions
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * and limitations under the License.
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan *
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * When distributing Covered Code, include this CDDL HEADER in each
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * If applicable, add the following below this CDDL HEADER, with the
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * fields enclosed by brackets "[]" replaced with your own identifying
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * information: Portions Copyright [yyyy] [name of copyright owner]
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan *
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * CDDL HEADER END
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan/*
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * Use is subject to license terms.
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan */
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan/*
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * Functions to implement IP address -> link layer address (PSARC 2006/482)
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan */
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan#include <inet/ip2mac.h>
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan#include <inet/ip2mac_impl.h>
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan#include <sys/zone.h>
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan#include <inet/ip_ndp.h>
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan#include <inet/ip_if.h>
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan#include <inet/ip6.h>
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan/*
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * dispatch pending callbacks.
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan */
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhanvoid
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmarkncec_cb_dispatch(ncec_t *ncec)
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan{
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ncec_cb_t *ncec_cb;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ip2mac_t ip2m;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark mutex_enter(&ncec->ncec_lock);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (list_is_empty(&ncec->ncec_cb)) {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark mutex_exit(&ncec->ncec_lock);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan return;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan }
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ncec_ip2mac_response(&ip2m, ncec);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ncec_cb_refhold_locked(ncec);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan /*
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * IP does not hold internal locks like nce_lock across calls to
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * other subsystems for fear of recursive lock entry and lock
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * hierarchy violation. The caller may be holding locks across
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * the call to IP. (It would be ideal if no subsystem holds locks
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * across calls into another subsystem, especially if calls can
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * happen in either direction).
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ncec_cb = list_head(&ncec->ncec_cb);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark for (; ncec_cb != NULL; ncec_cb = list_next(&ncec->ncec_cb, ncec_cb)) {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (ncec_cb->ncec_cb_flags & NCE_CB_DISPATCHED)
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan continue;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ncec_cb->ncec_cb_flags |= NCE_CB_DISPATCHED;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark mutex_exit(&ncec->ncec_lock);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark (*ncec_cb->ncec_cb_func)(&ip2m, ncec_cb->ncec_cb_arg);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark mutex_enter(&ncec->ncec_lock);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan }
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ncec_cb_refrele(ncec);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark mutex_exit(&ncec->ncec_lock);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan}
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan/*
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * fill up the ip2m response fields with inforamation from the nce.
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan */
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhanvoid
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmarkncec_ip2mac_response(ip2mac_t *ip2m, ncec_t *ncec)
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan{
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark boolean_t isv6 = (ncec->ncec_ipversion == IPV6_VERSION);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark sin_t *sin;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan sin6_t *sin6;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan struct sockaddr_dl *sdl;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ASSERT(MUTEX_HELD(&ncec->ncec_lock));
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan bzero(ip2m, sizeof (*ip2m));
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (NCE_ISREACHABLE(ncec) && !NCE_ISCONDEMNED(ncec))
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ip2m->ip2mac_err = 0;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan else
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ip2m->ip2mac_err = ESRCH;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan if (isv6) {
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan sin6 = (sin6_t *)&ip2m->ip2mac_pa;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan sin6->sin6_family = AF_INET6;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark sin6->sin6_addr = ncec->ncec_addr;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark } else {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark sin = (sin_t *)&ip2m->ip2mac_pa;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark sin->sin_family = AF_INET;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark IN6_V4MAPPED_TO_INADDR(&ncec->ncec_addr, &sin->sin_addr);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan }
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan if (ip2m->ip2mac_err == 0) {
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan sdl = &ip2m->ip2mac_ha;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan sdl->sdl_family = AF_LINK;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark sdl->sdl_type = ncec->ncec_ill->ill_type;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark /*
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * should we put ncec_ill->ill_name in there? why?
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * likewise for the sdl_index
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark */
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan sdl->sdl_nlen = 0;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark sdl->sdl_alen = ncec->ncec_ill->ill_phys_addr_length;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (ncec->ncec_lladdr != NULL)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark bcopy(ncec->ncec_lladdr, LLADDR(sdl), sdl->sdl_alen);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan }
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan}
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhanvoid
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmarkncec_cb_refhold_locked(ncec_t *ncec)
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan{
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ASSERT(MUTEX_HELD(&ncec->ncec_lock));
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ncec->ncec_cb_walker_cnt++;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan}
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhanvoid
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmarkncec_cb_refrele(ncec_t *ncec)
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan{
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ncec_cb_t *ncec_cb, *ncec_cb_next = NULL;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ASSERT(MUTEX_HELD(&ncec->ncec_lock));
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (--ncec->ncec_cb_walker_cnt == 0) {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark for (ncec_cb = list_head(&ncec->ncec_cb); ncec_cb != NULL;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ncec_cb = ncec_cb_next) {
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ncec_cb_next = list_next(&ncec->ncec_cb, ncec_cb);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if ((ncec_cb->ncec_cb_flags & NCE_CB_DISPATCHED) == 0)
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan continue;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark list_remove(&ncec->ncec_cb, ncec_cb);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark kmem_free(ncec_cb, sizeof (*ncec_cb));
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan }
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan }
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan}
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan/*
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * add a callback to the nce, so that the callback can be invoked
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * after address resolution succeeds/fails.
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan */
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhanstatic ip2mac_id_t
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmarkncec_add_cb(ncec_t *ncec, ip2mac_callback_t *cb, void *cbarg)
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan{
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ncec_cb_t *nce_cb;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ip2mac_id_t ip2mid = NULL;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ASSERT(MUTEX_HELD(&ncec->ncec_lock));
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan if ((nce_cb = kmem_zalloc(sizeof (*nce_cb), KM_NOSLEEP)) == NULL)
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan return (ip2mid);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark nce_cb->ncec_cb_func = cb;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark nce_cb->ncec_cb_arg = cbarg;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan /*
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * We identify the ncec_cb_t during cancellation by the address
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * of the nce_cb_t itself, and, as a short-cut for eliminating
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * clear mismatches, only look in the callback list of ncec's
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * whose address is equal to the nce_cb_id.
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark nce_cb->ncec_cb_id = ncec; /* no refs! just an address */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark list_insert_tail(&ncec->ncec_cb, nce_cb);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ip2mid = ncec; /* this is the id to be used in ip2mac_cancel */
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan return (nce_cb);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan}
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan/*
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * Resolve an IP address to a link-layer address using the data-structures
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * defined in PSARC 2006/482. If the current link-layer address for the
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * IP address is not known, the state-machine for resolving the resolution
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * will be triggered, and the callback function (*cb) will be invoked after
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * the resolution completes.
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan */
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhanip2mac_id_t
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmarkip2mac(uint_t op, ip2mac_t *ip2m, ip2mac_callback_t *cb, void *cbarg,
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan zoneid_t zoneid)
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan{
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ncec_t *ncec;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark nce_t *nce = NULL;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan boolean_t isv6;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ill_t *ill;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan netstack_t *ns;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ip_stack_t *ipst;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ip2mac_id_t ip2mid = NULL;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark sin_t *sin;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan sin6_t *sin6;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan int err;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan uint64_t delta;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark boolean_t need_resolve = B_FALSE;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan isv6 = (ip2m->ip2mac_pa.ss_family == AF_INET6);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ns = netstack_find_by_zoneid(zoneid);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan if (ns == NULL) {
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ip2m->ip2mac_err = EINVAL;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan return (NULL);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan }
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan /*
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * For exclusive stacks we reset the zoneid to zero
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * since IP uses the global zoneid in the exclusive stacks.
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan */
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan if (ns->netstack_stackid != GLOBAL_NETSTACKID)
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan zoneid = GLOBAL_ZONEID;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ipst = ns->netstack_ip;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan /*
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * find the ill from the ip2m->ip2mac_ifindex
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ill = ill_lookup_on_ifindex(ip2m->ip2mac_ifindex, isv6, ipst);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan if (ill == NULL) {
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ip2m->ip2mac_err = ENXIO;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan netstack_rele(ns);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan return (NULL);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan }
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan if (isv6) {
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan sin6 = (sin6_t *)&ip2m->ip2mac_pa;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (op == IP2MAC_LOOKUP) {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark nce = nce_lookup_v6(ill, &sin6->sin6_addr);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan } else {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark err = nce_lookup_then_add_v6(ill, NULL,
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ill->ill_phys_addr_length,
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark &sin6->sin6_addr, 0, ND_UNCHANGED, &nce);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan }
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan } else {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark sin = (sin_t *)&ip2m->ip2mac_pa;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (op == IP2MAC_LOOKUP) {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark nce = nce_lookup_v4(ill, &sin->sin_addr.s_addr);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark } else {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark err = nce_lookup_then_add_v4(ill, NULL,
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ill->ill_phys_addr_length,
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark &sin->sin_addr.s_addr, 0, ND_UNCHANGED, &nce);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark }
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan }
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (op == IP2MAC_LOOKUP) {
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan if (nce == NULL) {
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ip2m->ip2mac_err = ESRCH;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan goto done;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan }
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ncec = nce->nce_common;
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni delta = TICK_TO_MSEC(ddi_get_lbolt64()) - ncec->ncec_last;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark mutex_enter(&ncec->ncec_lock);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (NCE_ISREACHABLE(ncec) &&
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark delta < (uint64_t)ill->ill_reachable_time) {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ncec_ip2mac_response(ip2m, ncec);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ip2m->ip2mac_err = 0;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan } else {
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ip2m->ip2mac_err = ESRCH;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan }
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark mutex_exit(&ncec->ncec_lock);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan goto done;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan } else {
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan if (err != 0 && err != EEXIST) {
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ip2m->ip2mac_err = err;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan goto done;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan }
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan }
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ncec = nce->nce_common;
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni delta = TICK_TO_MSEC(ddi_get_lbolt64()) - ncec->ncec_last;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark mutex_enter(&ncec->ncec_lock);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (NCE_ISCONDEMNED(ncec)) {
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ip2m->ip2mac_err = ESRCH;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark } else {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (NCE_ISREACHABLE(ncec)) {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (NCE_MYADDR(ncec) ||
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark delta < (uint64_t)ill->ill_reachable_time) {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ncec_ip2mac_response(ip2m, ncec);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ip2m->ip2mac_err = 0;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark mutex_exit(&ncec->ncec_lock);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark goto done;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark }
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan /*
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * Since we do not control the packet output
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * path for ip2mac() callers, we need to verify
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * if the existing information in the nce is
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * very old, and retrigger resolution if necessary.
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * We will not return the existing stale
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * information until it is verified through a
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * resolver request/response exchange.
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan *
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * In the future, we may want to support extensions
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * that do additional callbacks on link-layer updates,
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * so that we can return the stale information but
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * also update the caller if the lladdr changes.
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ncec->ncec_rcnt = ill->ill_xmit_count;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ncec->ncec_state = ND_PROBE;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark need_resolve = B_TRUE; /* reachable but very old nce */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark } else if (ncec->ncec_state == ND_INITIAL) {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark need_resolve = B_TRUE; /* ND_INITIAL nce */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ncec->ncec_state = ND_INCOMPLETE;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan }
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark /*
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * NCE not known to be reachable in the recent past. We must
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * reconfirm the information before returning it to the caller
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (ncec->ncec_rcnt > 0) {
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan /*
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * Still resolving this ncec, so we can queue the
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * callback information in ncec->ncec_cb
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ip2mid = ncec_add_cb(ncec, cb, cbarg);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ip2m->ip2mac_err = EINPROGRESS;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan } else {
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan /*
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * No more retransmits allowed -- resolution failed.
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan */
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ip2m->ip2mac_err = ESRCH;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan }
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan }
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark mutex_exit(&ncec->ncec_lock);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhandone:
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark /*
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * if NCE_ISREACHABLE(ncec) but very old, or if it is ND_INITIAL,
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * trigger resolve.
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (need_resolve)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ip_ndp_resolve(ncec);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (nce != NULL)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark nce_refrele(nce);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan netstack_rele(ns);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ill_refrele(ill);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan return (ip2mid);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan}
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan/*
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * data passed to ncec_walk for canceling outstanding callbacks.
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan */
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhantypedef struct ip2mac_cancel_data_s {
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ip2mac_id_t ip2m_cancel_id;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan int ip2m_cancel_err;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan} ip2mac_cancel_data_t;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan/*
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * callback invoked for each active ncec. If the ip2mac_id_t corresponds
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * to an active nce_cb_t in the ncec's callback list, we want to remove
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * the callback (if there are no walkers) or return EBUSY to the caller
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan */
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhanstatic int
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmarkip2mac_cancel_callback(ncec_t *ncec, void *arg)
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan{
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ip2mac_cancel_data_t *ip2m_wdata = arg;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ncec_cb_t *ip2m_nce_cb = ip2m_wdata->ip2m_cancel_id;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ncec_cb_t *ncec_cb;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (ip2m_nce_cb->ncec_cb_id != ncec)
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan return (0);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark mutex_enter(&ncec->ncec_lock);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (list_is_empty(&ncec->ncec_cb)) {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark mutex_exit(&ncec->ncec_lock);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan return (0);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan }
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan /*
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * IP does not hold internal locks like nce_lock across calls to
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * other subsystems for fear of recursive lock entry and lock
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * hierarchy violation. The caller may be holding locks across
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * the call to IP. (It would be ideal if no subsystem holds locks
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * across calls into another subsystem, especially if calls can
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * happen in either direction).
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ncec_cb = list_head(&ncec->ncec_cb);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark for (; ncec_cb != NULL; ncec_cb = list_next(&ncec->ncec_cb, ncec_cb)) {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (ncec_cb != ip2m_nce_cb)
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan continue;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan /*
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * If there are no walkers we can remove the nce_cb.
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * Otherwise the exiting walker will clean up.
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan */
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (ncec->ncec_cb_walker_cnt == 0) {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark list_remove(&ncec->ncec_cb, ncec_cb);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan } else {
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ip2m_wdata->ip2m_cancel_err = EBUSY;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan }
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan break;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan }
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark mutex_exit(&ncec->ncec_lock);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan return (0);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan}
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan/*
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * cancel an outstanding timeout set up via ip2mac
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan */
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhanint
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhanip2mac_cancel(ip2mac_id_t ip2mid, zoneid_t zoneid)
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan{
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan netstack_t *ns;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ip_stack_t *ipst;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ip2mac_cancel_data_t ip2m_wdata;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ns = netstack_find_by_zoneid(zoneid);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan if (ns == NULL) {
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ip2m_wdata.ip2m_cancel_err = EINVAL;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan return (ip2m_wdata.ip2m_cancel_err);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan }
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan /*
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * For exclusive stacks we reset the zoneid to zero
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * since IP uses the global zoneid in the exclusive stacks.
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan */
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan if (ns->netstack_stackid != GLOBAL_NETSTACKID)
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan zoneid = GLOBAL_ZONEID;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ipst = ns->netstack_ip;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ip2m_wdata.ip2m_cancel_id = ip2mid;
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan ip2m_wdata.ip2m_cancel_err = 0;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark ncec_walk(NULL, ip2mac_cancel_callback, &ip2m_wdata, ipst);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan /*
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * We may return EBUSY if a walk to dispatch callbacks is
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * in progress, in which case the caller needs to synchronize
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * with the registered callback function to make sure the
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan * module does not exit when there is a callback pending.
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan */
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan netstack_rele(ns);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan return (ip2m_wdata.ip2m_cancel_err);
4b7cbb468ccaa93f260f3964b823da34e5b0e1e5Sowmini Varadhan}