neti_impl.c revision 7ddc9b1afd18f260b9fb78ec7732facd91769131
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * CDDL HEADER START
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 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * See the License for the specific language governing permissions
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * and limitations under the License.
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 * CDDL HEADER END
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Use is subject to license terms.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic net_handle_t net_find(const char *protocol, neti_stack_t *ns);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_find(const char *protocol, neti_stack_t *nts)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_FOREACH(n, &nts->nts_netd_head, netd_list) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * If they're trying to find a protocol that is being
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * shutdown, just ignore it..
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (strcmp(n->netd_info.netp_name, protocol) == 0) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_protocol_register(netid_t id, const net_protocol_t *info)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_INSERT_HEAD(&nts->nts_netd_head, new, netd_list);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_INSERT_AFTER(LIST_FIRST(&nts->nts_netd_head),
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_protocol_lookup(netid_t netid, const char *protocol)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Note: the man page specifies "returns -1 if the value passed in is unknown
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * to this framework". We are not doing a lookup in this function, just a
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * simply add to the netd_refcnt of the net_handle_t passed in, so -1 is never a
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * return value.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Is this safe? No hold on nts_lock? Consider that if the caller
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * of net_protocol_release() is going to free this structure then
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * it is now the only owner (refcnt==1) and it will have been
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * removed from the nts_netd_head list on the neti_stack_t from a
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * call to net_protocol_unregister already, so it is thus an orphan.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (atomic_add_32_nv((uint_t *)&info->netd_refcnt, -1) == 0) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_protocol_walk(netid_t netid, net_handle_t info)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed LIST_FOREACH(n, &nts->nts_netd_head, netd_list) {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * We are only interested in finding protocols that
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * are not in some sort of shutdown state. There is
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * no need to check for netd_stack==NULL because
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * that implies it is no longer on this list.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Public accessor functions
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_getifname(net_handle_t info, phy_if_t nic, char *buffer,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (info->netd_condemned != 0 || info->netd_stack == NULL)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (-1);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (info->netd_info.netp_getifname(info, nic, buffer, buflen));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_getmtu(net_handle_t info, phy_if_t nic, lif_if_t ifdata)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (info->netd_condemned != 0 || info->netd_stack == NULL)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (-1);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (info->netd_info.netp_getmtu(info, nic, ifdata));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (info->netd_condemned != 0 || info->netd_stack == NULL)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (-1);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (info->netd_info.netp_getpmtuenabled(info));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_getlifaddr(net_handle_t info, phy_if_t nic, lif_if_t ifdata,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (info->netd_condemned != 0 || info->netd_stack == NULL)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (-1);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (info->netd_info.netp_getlifaddr(info, nic, ifdata,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (info->netd_condemned != 0 || info->netd_stack == NULL)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (info->netd_info.netp_phygetnext(info, nic));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_phylookup(net_handle_t info, const char *name)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (info->netd_condemned != 0 || info->netd_stack == NULL)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (info->netd_info.netp_phylookup(info, name));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_lifgetnext(net_handle_t info, phy_if_t ifidx, lif_if_t ifdata)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (info->netd_condemned != 0 || info->netd_stack == NULL)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (info->netd_info.netp_lifgetnext(info, ifidx, ifdata));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_inject(net_handle_t info, inject_t style, net_inject_t *packet)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (info->netd_condemned != 0 || info->netd_stack == NULL)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (-1);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (info->netd_info.netp_inject(info, style, packet));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_routeto(net_handle_t info, struct sockaddr *address, struct sockaddr *next)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (info->netd_condemned != 0 || info->netd_stack == NULL)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (info->netd_info.netp_routeto(info, address, next));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_ispartialchecksum(net_handle_t info, mblk_t *mp)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (info->netd_condemned != 0 || info->netd_stack == NULL)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (-1);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (info->netd_info.netp_ispartialchecksum(info, mp));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_isvalidchecksum(net_handle_t info, mblk_t *mp)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (info->netd_condemned != 0 || info->netd_stack == NULL)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (-1);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (info->netd_info.netp_isvalidchecksum(info, mp));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Hooks related functions
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Function: net_family_register
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Returns: int - 0 = Succ, Else = Fail
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Parameters: info(I) - protocol
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * hf(I) - family pointer
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Call hook_family_add to register family
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * There is no need to bump netd_refcnt in the two functions
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * net_family_register and net_family_unregister because the caller of these
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * two functions is assumed to "own" a reference on 'info' via an earlier
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * call to net_protocol_register(). Thus the owner is expected to do a
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * call to net_protocol_unregister() after having done a
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * net_family_unregister() to make sure things are properly cleaned up.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_family_register(net_handle_t info, hook_family_t *hf)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (info->netd_condemned != 0 || info->netd_stack == NULL)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Function: net_family_unregister
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Returns: int - transparent value, explained by caller
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Parameters: info(I) - protocol
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * hf(I) - family pointer
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Call hook_family_remove to unregister family
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_family_unregister(net_handle_t info, hook_family_t *hf)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (strcmp(info->netd_hooks->hfi_family.hf_name,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Function: net_event_register
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Returns: internal event pointer - NULL = Fail
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Parameters: info(I) - protocol
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * he(I) - event pointer
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Call hook_event_add to register event on specific family
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Internal event pointer is returned so caller can get
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * handle to run hooks
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_event_register(net_handle_t info, hook_event_t *he)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (info->netd_hooks == NULL || info->netd_condemned != 0 ||
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Function: net_event_unregister
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Returns: int - transparent value, explained by caller
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Parameters: info(I) - protocol
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * he(I) - event pointer
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Call hook_event_remove to unregister event on specific family
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_event_unregister(net_handle_t info, hook_event_t *he)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (hook_event_remove(info->netd_hooks, he));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Function: net_hook_register
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Returns: int - transparent value, explained by caller
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Parameters: info(I) - protocol
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * event(I) - event name
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * h(I) - hook pointer
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Call hook_register to add hook on specific family/event
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_hook_register(net_handle_t info, char *event, hook_t *h)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (info->netd_condemned != 0 || info->netd_stack == NULL)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (hook_register(info->netd_hooks, event, h));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Function: net_hook_unregister
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Returns: int - transparent value, explained by caller
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Parameters: info(I) - protocol
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * event(I) - event name
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * h(I) - hook pointer
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Call hook_unregister to remove hook on specific family/event
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_hook_unregister(net_handle_t info, char *event, hook_t *h)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (hook_unregister(info->netd_hooks, event, h));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (-1);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_kstat_create(netid_t netid, char *module, int instance, char *name,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed char *class, uchar_t type, ulong_t ndata, uchar_t ks_flag)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed netstackid_t stackid = net_getnetstackidbynetid(netid);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return (kstat_create_netstack(module, instance, name, class, type,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed netstackid_t stackid = net_getnetstackidbynetid(netid);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_event_notify_register(net_handle_t family, char *event,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (family->netd_condemned != 0 || family->netd_stack == NULL)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed error = hook_event_notify_register(family->netd_hooks, event,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_event_notify_unregister(net_handle_t family, char *event,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed error = hook_event_notify_unregister(family->netd_hooks, event,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_protocol_notify_register(net_handle_t family, hook_notify_fn_t callback,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (family->netd_condemned != 0 || family->netd_stack == NULL)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed error = hook_family_notify_register(family->netd_hooks, callback,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reednet_protocol_notify_unregister(net_handle_t family, hook_notify_fn_t callback)