17513SDarren.Reed@Sun.COM /*
27513SDarren.Reed@Sun.COM * CDDL HEADER START
37513SDarren.Reed@Sun.COM *
47513SDarren.Reed@Sun.COM * The contents of this file are subject to the terms of the
57513SDarren.Reed@Sun.COM * Common Development and Distribution License (the "License").
67513SDarren.Reed@Sun.COM * You may not use this file except in compliance with the License.
77513SDarren.Reed@Sun.COM *
87513SDarren.Reed@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97513SDarren.Reed@Sun.COM * or http://www.opensolaris.org/os/licensing.
107513SDarren.Reed@Sun.COM * See the License for the specific language governing permissions
117513SDarren.Reed@Sun.COM * and limitations under the License.
127513SDarren.Reed@Sun.COM *
137513SDarren.Reed@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
147513SDarren.Reed@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157513SDarren.Reed@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
167513SDarren.Reed@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
177513SDarren.Reed@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
187513SDarren.Reed@Sun.COM *
197513SDarren.Reed@Sun.COM * CDDL HEADER END
207513SDarren.Reed@Sun.COM */
217513SDarren.Reed@Sun.COM /*
227513SDarren.Reed@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
237513SDarren.Reed@Sun.COM * Use is subject to license terms.
247513SDarren.Reed@Sun.COM */
257513SDarren.Reed@Sun.COM
267513SDarren.Reed@Sun.COM #include <sys/param.h>
277513SDarren.Reed@Sun.COM #include <sys/atomic.h>
287513SDarren.Reed@Sun.COM #include <sys/kmem.h>
297513SDarren.Reed@Sun.COM #include <sys/rwlock.h>
307513SDarren.Reed@Sun.COM #include <sys/errno.h>
317513SDarren.Reed@Sun.COM #include <sys/queue.h>
327513SDarren.Reed@Sun.COM #include <inet/common.h>
337513SDarren.Reed@Sun.COM #include <inet/led.h>
347513SDarren.Reed@Sun.COM #include <inet/ip.h>
357513SDarren.Reed@Sun.COM #include <sys/neti.h>
367513SDarren.Reed@Sun.COM #include <sys/zone.h>
377513SDarren.Reed@Sun.COM
387513SDarren.Reed@Sun.COM static net_handle_t net_find(const char *protocol, neti_stack_t *ns);
397513SDarren.Reed@Sun.COM
407513SDarren.Reed@Sun.COM static net_handle_t
net_find(const char * protocol,neti_stack_t * nts)417513SDarren.Reed@Sun.COM net_find(const char *protocol, neti_stack_t *nts)
427513SDarren.Reed@Sun.COM {
437513SDarren.Reed@Sun.COM struct net_data *n;
447513SDarren.Reed@Sun.COM
457513SDarren.Reed@Sun.COM ASSERT(protocol != NULL);
467513SDarren.Reed@Sun.COM ASSERT(nts != NULL);
477513SDarren.Reed@Sun.COM
487513SDarren.Reed@Sun.COM LIST_FOREACH(n, &nts->nts_netd_head, netd_list) {
497513SDarren.Reed@Sun.COM ASSERT(n->netd_info.netp_name != NULL);
507513SDarren.Reed@Sun.COM /*
517513SDarren.Reed@Sun.COM * If they're trying to find a protocol that is being
527513SDarren.Reed@Sun.COM * shutdown, just ignore it..
537513SDarren.Reed@Sun.COM */
547513SDarren.Reed@Sun.COM if (n->netd_condemned != 0)
557513SDarren.Reed@Sun.COM continue;
567513SDarren.Reed@Sun.COM if (strcmp(n->netd_info.netp_name, protocol) == 0) {
577513SDarren.Reed@Sun.COM break;
587513SDarren.Reed@Sun.COM }
597513SDarren.Reed@Sun.COM }
607513SDarren.Reed@Sun.COM
617513SDarren.Reed@Sun.COM return (n);
627513SDarren.Reed@Sun.COM }
637513SDarren.Reed@Sun.COM
647513SDarren.Reed@Sun.COM net_handle_t
net_protocol_register(netid_t id,const net_protocol_t * info)657513SDarren.Reed@Sun.COM net_protocol_register(netid_t id, const net_protocol_t *info)
667513SDarren.Reed@Sun.COM {
677513SDarren.Reed@Sun.COM struct net_data *n, *new;
687513SDarren.Reed@Sun.COM neti_stack_t *nts;
697513SDarren.Reed@Sun.COM
707513SDarren.Reed@Sun.COM ASSERT(info != NULL);
717513SDarren.Reed@Sun.COM
727513SDarren.Reed@Sun.COM nts = net_getnetistackbyid(id);
737513SDarren.Reed@Sun.COM if (nts == NULL)
747513SDarren.Reed@Sun.COM return (NULL);
757513SDarren.Reed@Sun.COM
767513SDarren.Reed@Sun.COM new = kmem_alloc(sizeof (*new), KM_SLEEP);
777513SDarren.Reed@Sun.COM new->netd_refcnt = 1;
787513SDarren.Reed@Sun.COM new->netd_hooks = NULL;
797513SDarren.Reed@Sun.COM new->netd_info = *info;
807513SDarren.Reed@Sun.COM new->netd_stack = nts;
817513SDarren.Reed@Sun.COM new->netd_condemned = 0;
827513SDarren.Reed@Sun.COM
837513SDarren.Reed@Sun.COM mutex_enter(&nts->nts_lock);
847513SDarren.Reed@Sun.COM n = net_find(info->netp_name, nts);
857513SDarren.Reed@Sun.COM if (n != NULL) {
867513SDarren.Reed@Sun.COM mutex_exit(&nts->nts_lock);
877513SDarren.Reed@Sun.COM kmem_free(new, sizeof (*new));
887513SDarren.Reed@Sun.COM return (NULL);
897513SDarren.Reed@Sun.COM }
907513SDarren.Reed@Sun.COM
917513SDarren.Reed@Sun.COM if (LIST_EMPTY(&nts->nts_netd_head)) {
927513SDarren.Reed@Sun.COM LIST_INSERT_HEAD(&nts->nts_netd_head, new, netd_list);
937513SDarren.Reed@Sun.COM } else {
947513SDarren.Reed@Sun.COM LIST_INSERT_AFTER(LIST_FIRST(&nts->nts_netd_head),
957513SDarren.Reed@Sun.COM new, netd_list);
967513SDarren.Reed@Sun.COM }
977513SDarren.Reed@Sun.COM mutex_exit(&nts->nts_lock);
987513SDarren.Reed@Sun.COM
997513SDarren.Reed@Sun.COM return (new);
1007513SDarren.Reed@Sun.COM }
1017513SDarren.Reed@Sun.COM
1027513SDarren.Reed@Sun.COM int
net_protocol_unregister(net_handle_t info)1037513SDarren.Reed@Sun.COM net_protocol_unregister(net_handle_t info)
1047513SDarren.Reed@Sun.COM {
1057513SDarren.Reed@Sun.COM neti_stack_t *nts;
1067513SDarren.Reed@Sun.COM
1077513SDarren.Reed@Sun.COM ASSERT(info != NULL);
1087513SDarren.Reed@Sun.COM
1097513SDarren.Reed@Sun.COM nts = info->netd_stack;
1107513SDarren.Reed@Sun.COM ASSERT(nts != NULL);
1117513SDarren.Reed@Sun.COM
1127513SDarren.Reed@Sun.COM mutex_enter(&nts->nts_lock);
1137513SDarren.Reed@Sun.COM LIST_REMOVE(info, netd_list);
1147513SDarren.Reed@Sun.COM info->netd_stack = NULL;
1157513SDarren.Reed@Sun.COM mutex_exit(&nts->nts_lock);
1167513SDarren.Reed@Sun.COM
1177513SDarren.Reed@Sun.COM (void) net_protocol_release(info);
1187513SDarren.Reed@Sun.COM
1197513SDarren.Reed@Sun.COM return (0);
1207513SDarren.Reed@Sun.COM }
1217513SDarren.Reed@Sun.COM
1227513SDarren.Reed@Sun.COM net_handle_t
net_protocol_lookup(netid_t netid,const char * protocol)1237513SDarren.Reed@Sun.COM net_protocol_lookup(netid_t netid, const char *protocol)
1247513SDarren.Reed@Sun.COM {
1257513SDarren.Reed@Sun.COM neti_stack_t *nts;
1267513SDarren.Reed@Sun.COM net_handle_t nd;
1277513SDarren.Reed@Sun.COM
1287513SDarren.Reed@Sun.COM ASSERT(protocol != NULL);
1297513SDarren.Reed@Sun.COM
1307513SDarren.Reed@Sun.COM nts = net_getnetistackbyid(netid);
1317513SDarren.Reed@Sun.COM if (nts == NULL)
1327513SDarren.Reed@Sun.COM return (NULL);
1337513SDarren.Reed@Sun.COM
1347513SDarren.Reed@Sun.COM mutex_enter(&nts->nts_lock);
1357513SDarren.Reed@Sun.COM nd = net_find(protocol, nts);
1367513SDarren.Reed@Sun.COM if (nd != NULL)
1377513SDarren.Reed@Sun.COM atomic_add_32((uint_t *)&nd->netd_refcnt, 1);
1387513SDarren.Reed@Sun.COM mutex_exit(&nts->nts_lock);
1397513SDarren.Reed@Sun.COM return (nd);
1407513SDarren.Reed@Sun.COM }
1417513SDarren.Reed@Sun.COM
1427513SDarren.Reed@Sun.COM /*
1437513SDarren.Reed@Sun.COM * Note: the man page specifies "returns -1 if the value passed in is unknown
1447513SDarren.Reed@Sun.COM * to this framework". We are not doing a lookup in this function, just a
1457513SDarren.Reed@Sun.COM * simply add to the netd_refcnt of the net_handle_t passed in, so -1 is never a
1467513SDarren.Reed@Sun.COM * return value.
1477513SDarren.Reed@Sun.COM */
1487513SDarren.Reed@Sun.COM int
net_protocol_release(net_handle_t info)1497513SDarren.Reed@Sun.COM net_protocol_release(net_handle_t info)
1507513SDarren.Reed@Sun.COM {
1517513SDarren.Reed@Sun.COM
1527513SDarren.Reed@Sun.COM ASSERT(info->netd_refcnt > 0);
1537513SDarren.Reed@Sun.COM /*
1547513SDarren.Reed@Sun.COM * Is this safe? No hold on nts_lock? Consider that if the caller
1557513SDarren.Reed@Sun.COM * of net_protocol_release() is going to free this structure then
1567513SDarren.Reed@Sun.COM * it is now the only owner (refcnt==1) and it will have been
1577513SDarren.Reed@Sun.COM * removed from the nts_netd_head list on the neti_stack_t from a
1587513SDarren.Reed@Sun.COM * call to net_protocol_unregister already, so it is thus an orphan.
1597513SDarren.Reed@Sun.COM */
1607513SDarren.Reed@Sun.COM if (atomic_add_32_nv((uint_t *)&info->netd_refcnt, -1) == 0) {
1617513SDarren.Reed@Sun.COM ASSERT(info->netd_hooks == NULL);
1627513SDarren.Reed@Sun.COM ASSERT(info->netd_stack == NULL);
1637513SDarren.Reed@Sun.COM kmem_free(info, sizeof (struct net_data));
1647513SDarren.Reed@Sun.COM }
1657513SDarren.Reed@Sun.COM
1667513SDarren.Reed@Sun.COM return (0);
1677513SDarren.Reed@Sun.COM }
1687513SDarren.Reed@Sun.COM
1697513SDarren.Reed@Sun.COM net_handle_t
net_protocol_walk(netid_t netid,net_handle_t info)1707513SDarren.Reed@Sun.COM net_protocol_walk(netid_t netid, net_handle_t info)
1717513SDarren.Reed@Sun.COM {
1727513SDarren.Reed@Sun.COM struct net_data *n = NULL;
1737513SDarren.Reed@Sun.COM boolean_t found = B_FALSE;
1747513SDarren.Reed@Sun.COM neti_stack_t *nts;
1757513SDarren.Reed@Sun.COM
1767513SDarren.Reed@Sun.COM nts = net_getnetistackbyid(netid);
1777513SDarren.Reed@Sun.COM ASSERT(nts != NULL);
1787513SDarren.Reed@Sun.COM
1797513SDarren.Reed@Sun.COM if (info == NULL)
1807513SDarren.Reed@Sun.COM found = B_TRUE;
1817513SDarren.Reed@Sun.COM
1827513SDarren.Reed@Sun.COM mutex_enter(&nts->nts_lock);
1837513SDarren.Reed@Sun.COM LIST_FOREACH(n, &nts->nts_netd_head, netd_list) {
1847513SDarren.Reed@Sun.COM if (found) {
1857513SDarren.Reed@Sun.COM /*
1867513SDarren.Reed@Sun.COM * We are only interested in finding protocols that
1877513SDarren.Reed@Sun.COM * are not in some sort of shutdown state. There is
1887513SDarren.Reed@Sun.COM * no need to check for netd_stack==NULL because
1897513SDarren.Reed@Sun.COM * that implies it is no longer on this list.
1907513SDarren.Reed@Sun.COM */
1917513SDarren.Reed@Sun.COM if (n->netd_condemned == 0)
1927513SDarren.Reed@Sun.COM continue;
1937513SDarren.Reed@Sun.COM break;
1947513SDarren.Reed@Sun.COM }
1957513SDarren.Reed@Sun.COM
1967513SDarren.Reed@Sun.COM if (n == info)
1977513SDarren.Reed@Sun.COM found = B_TRUE;
1987513SDarren.Reed@Sun.COM }
1997513SDarren.Reed@Sun.COM
2007513SDarren.Reed@Sun.COM if (info != NULL)
2017513SDarren.Reed@Sun.COM (void) net_protocol_release(info);
2027513SDarren.Reed@Sun.COM
2037513SDarren.Reed@Sun.COM if (n != NULL)
2047513SDarren.Reed@Sun.COM atomic_add_32((uint_t *)&n->netd_refcnt, 1);
2057513SDarren.Reed@Sun.COM
2067513SDarren.Reed@Sun.COM mutex_exit(&nts->nts_lock);
2077513SDarren.Reed@Sun.COM
2087513SDarren.Reed@Sun.COM return (n);
2097513SDarren.Reed@Sun.COM }
2107513SDarren.Reed@Sun.COM
2117513SDarren.Reed@Sun.COM /*
2127513SDarren.Reed@Sun.COM * Public accessor functions
2137513SDarren.Reed@Sun.COM */
2147513SDarren.Reed@Sun.COM int
net_getifname(net_handle_t info,phy_if_t nic,char * buffer,const size_t buflen)2157513SDarren.Reed@Sun.COM net_getifname(net_handle_t info, phy_if_t nic, char *buffer,
2167513SDarren.Reed@Sun.COM const size_t buflen)
2177513SDarren.Reed@Sun.COM {
2187513SDarren.Reed@Sun.COM
2197513SDarren.Reed@Sun.COM ASSERT(info != NULL);
2207513SDarren.Reed@Sun.COM
2217513SDarren.Reed@Sun.COM if (info->netd_condemned != 0 || info->netd_stack == NULL)
2227513SDarren.Reed@Sun.COM return (-1);
2237513SDarren.Reed@Sun.COM
2247513SDarren.Reed@Sun.COM return (info->netd_info.netp_getifname(info, nic, buffer, buflen));
2257513SDarren.Reed@Sun.COM }
2267513SDarren.Reed@Sun.COM
2277513SDarren.Reed@Sun.COM int
net_getmtu(net_handle_t info,phy_if_t nic,lif_if_t ifdata)2287513SDarren.Reed@Sun.COM net_getmtu(net_handle_t info, phy_if_t nic, lif_if_t ifdata)
2297513SDarren.Reed@Sun.COM {
2307513SDarren.Reed@Sun.COM
2317513SDarren.Reed@Sun.COM ASSERT(info != NULL);
2327513SDarren.Reed@Sun.COM
2337513SDarren.Reed@Sun.COM if (info->netd_condemned != 0 || info->netd_stack == NULL)
2347513SDarren.Reed@Sun.COM return (-1);
2357513SDarren.Reed@Sun.COM
2367513SDarren.Reed@Sun.COM return (info->netd_info.netp_getmtu(info, nic, ifdata));
2377513SDarren.Reed@Sun.COM }
2387513SDarren.Reed@Sun.COM
2397513SDarren.Reed@Sun.COM int
net_getpmtuenabled(net_handle_t info)2407513SDarren.Reed@Sun.COM net_getpmtuenabled(net_handle_t info)
2417513SDarren.Reed@Sun.COM {
2427513SDarren.Reed@Sun.COM
2437513SDarren.Reed@Sun.COM ASSERT(info != NULL);
2447513SDarren.Reed@Sun.COM
2457513SDarren.Reed@Sun.COM if (info->netd_condemned != 0 || info->netd_stack == NULL)
2467513SDarren.Reed@Sun.COM return (-1);
2477513SDarren.Reed@Sun.COM
2487513SDarren.Reed@Sun.COM return (info->netd_info.netp_getpmtuenabled(info));
2497513SDarren.Reed@Sun.COM }
2507513SDarren.Reed@Sun.COM
2517513SDarren.Reed@Sun.COM int
net_getlifaddr(net_handle_t info,phy_if_t nic,lif_if_t ifdata,int nelem,net_ifaddr_t type[],void * storage)2527513SDarren.Reed@Sun.COM net_getlifaddr(net_handle_t info, phy_if_t nic, lif_if_t ifdata,
2537513SDarren.Reed@Sun.COM int nelem, net_ifaddr_t type[], void *storage)
2547513SDarren.Reed@Sun.COM {
2557513SDarren.Reed@Sun.COM
2567513SDarren.Reed@Sun.COM ASSERT(info != NULL);
2577513SDarren.Reed@Sun.COM
2587513SDarren.Reed@Sun.COM if (info->netd_condemned != 0 || info->netd_stack == NULL)
2597513SDarren.Reed@Sun.COM return (-1);
2607513SDarren.Reed@Sun.COM
2617513SDarren.Reed@Sun.COM return (info->netd_info.netp_getlifaddr(info, nic, ifdata,
2627513SDarren.Reed@Sun.COM nelem, type, storage));
2637513SDarren.Reed@Sun.COM }
2647513SDarren.Reed@Sun.COM
2658023SPhil.Kirk@Sun.COM int
net_getlifzone(net_handle_t info,phy_if_t phy_ifdata,lif_if_t ifdata,zoneid_t * zoneid)2668023SPhil.Kirk@Sun.COM net_getlifzone(net_handle_t info, phy_if_t phy_ifdata, lif_if_t ifdata,
2678023SPhil.Kirk@Sun.COM zoneid_t *zoneid)
2688023SPhil.Kirk@Sun.COM {
2698023SPhil.Kirk@Sun.COM ASSERT(info != NULL);
2708023SPhil.Kirk@Sun.COM
2718023SPhil.Kirk@Sun.COM if (info->netd_condemned != 0 || info->netd_stack == NULL)
2728023SPhil.Kirk@Sun.COM return (-1);
2738023SPhil.Kirk@Sun.COM
2748023SPhil.Kirk@Sun.COM return (info->netd_info.neti_getlifzone(info, phy_ifdata, ifdata,
2758023SPhil.Kirk@Sun.COM zoneid));
2768023SPhil.Kirk@Sun.COM }
2778023SPhil.Kirk@Sun.COM
2788023SPhil.Kirk@Sun.COM int
net_getlifflags(net_handle_t info,phy_if_t phy_ifdata,lif_if_t ifdata,uint64_t * flags)2798023SPhil.Kirk@Sun.COM net_getlifflags(net_handle_t info, phy_if_t phy_ifdata, lif_if_t ifdata,
2808023SPhil.Kirk@Sun.COM uint64_t *flags)
2818023SPhil.Kirk@Sun.COM {
2828023SPhil.Kirk@Sun.COM ASSERT(info != NULL);
2838023SPhil.Kirk@Sun.COM
2848023SPhil.Kirk@Sun.COM if (info->netd_condemned != 0 || info->netd_stack == NULL)
2858023SPhil.Kirk@Sun.COM return (-1);
2868023SPhil.Kirk@Sun.COM
2878023SPhil.Kirk@Sun.COM return (info->netd_info.neti_getlifflags(info, phy_ifdata, ifdata,
2888023SPhil.Kirk@Sun.COM flags));
2898023SPhil.Kirk@Sun.COM }
2908023SPhil.Kirk@Sun.COM
2917513SDarren.Reed@Sun.COM phy_if_t
net_phygetnext(net_handle_t info,phy_if_t nic)2927513SDarren.Reed@Sun.COM net_phygetnext(net_handle_t info, phy_if_t nic)
2937513SDarren.Reed@Sun.COM {
2947513SDarren.Reed@Sun.COM
2957513SDarren.Reed@Sun.COM ASSERT(info != NULL);
2967513SDarren.Reed@Sun.COM
2977513SDarren.Reed@Sun.COM if (info->netd_condemned != 0 || info->netd_stack == NULL)
2987513SDarren.Reed@Sun.COM return ((phy_if_t)-1);
2997513SDarren.Reed@Sun.COM
3007513SDarren.Reed@Sun.COM return (info->netd_info.netp_phygetnext(info, nic));
3017513SDarren.Reed@Sun.COM }
3027513SDarren.Reed@Sun.COM
3037513SDarren.Reed@Sun.COM phy_if_t
net_phylookup(net_handle_t info,const char * name)3047513SDarren.Reed@Sun.COM net_phylookup(net_handle_t info, const char *name)
3057513SDarren.Reed@Sun.COM {
3067513SDarren.Reed@Sun.COM
3077513SDarren.Reed@Sun.COM ASSERT(info != NULL);
3087513SDarren.Reed@Sun.COM
3097513SDarren.Reed@Sun.COM if (info->netd_condemned != 0 || info->netd_stack == NULL)
3107513SDarren.Reed@Sun.COM return ((phy_if_t)-1);
3117513SDarren.Reed@Sun.COM
3127513SDarren.Reed@Sun.COM return (info->netd_info.netp_phylookup(info, name));
3137513SDarren.Reed@Sun.COM }
3147513SDarren.Reed@Sun.COM
3157513SDarren.Reed@Sun.COM lif_if_t
net_lifgetnext(net_handle_t info,phy_if_t ifidx,lif_if_t ifdata)3167513SDarren.Reed@Sun.COM net_lifgetnext(net_handle_t info, phy_if_t ifidx, lif_if_t ifdata)
3177513SDarren.Reed@Sun.COM {
3187513SDarren.Reed@Sun.COM
3197513SDarren.Reed@Sun.COM ASSERT(info != NULL);
3207513SDarren.Reed@Sun.COM
3217513SDarren.Reed@Sun.COM if (info->netd_condemned != 0 || info->netd_stack == NULL)
3227513SDarren.Reed@Sun.COM return ((lif_if_t)-1);
3237513SDarren.Reed@Sun.COM
3247513SDarren.Reed@Sun.COM return (info->netd_info.netp_lifgetnext(info, ifidx, ifdata));
3257513SDarren.Reed@Sun.COM }
3267513SDarren.Reed@Sun.COM
3277513SDarren.Reed@Sun.COM int
net_inject(net_handle_t info,inject_t style,net_inject_t * packet)3287513SDarren.Reed@Sun.COM net_inject(net_handle_t info, inject_t style, net_inject_t *packet)
3297513SDarren.Reed@Sun.COM {
3307513SDarren.Reed@Sun.COM
3317513SDarren.Reed@Sun.COM ASSERT(info != NULL);
3327513SDarren.Reed@Sun.COM
3337513SDarren.Reed@Sun.COM if (info->netd_condemned != 0 || info->netd_stack == NULL)
3347513SDarren.Reed@Sun.COM return (-1);
3357513SDarren.Reed@Sun.COM
3367513SDarren.Reed@Sun.COM return (info->netd_info.netp_inject(info, style, packet));
3377513SDarren.Reed@Sun.COM }
3387513SDarren.Reed@Sun.COM
3397513SDarren.Reed@Sun.COM phy_if_t
net_routeto(net_handle_t info,struct sockaddr * address,struct sockaddr * next)3407513SDarren.Reed@Sun.COM net_routeto(net_handle_t info, struct sockaddr *address, struct sockaddr *next)
3417513SDarren.Reed@Sun.COM {
3427513SDarren.Reed@Sun.COM
3437513SDarren.Reed@Sun.COM ASSERT(info != NULL);
3447513SDarren.Reed@Sun.COM
3457513SDarren.Reed@Sun.COM if (info->netd_condemned != 0 || info->netd_stack == NULL)
3467513SDarren.Reed@Sun.COM return ((phy_if_t)-1);
3477513SDarren.Reed@Sun.COM
3487513SDarren.Reed@Sun.COM return (info->netd_info.netp_routeto(info, address, next));
3497513SDarren.Reed@Sun.COM }
3507513SDarren.Reed@Sun.COM
3517513SDarren.Reed@Sun.COM int
net_ispartialchecksum(net_handle_t info,mblk_t * mp)3527513SDarren.Reed@Sun.COM net_ispartialchecksum(net_handle_t info, mblk_t *mp)
3537513SDarren.Reed@Sun.COM {
3547513SDarren.Reed@Sun.COM
3557513SDarren.Reed@Sun.COM ASSERT(info != NULL);
3567513SDarren.Reed@Sun.COM ASSERT(mp != NULL);
3577513SDarren.Reed@Sun.COM
3587513SDarren.Reed@Sun.COM if (info->netd_condemned != 0 || info->netd_stack == NULL)
3597513SDarren.Reed@Sun.COM return (-1);
3607513SDarren.Reed@Sun.COM
3617513SDarren.Reed@Sun.COM return (info->netd_info.netp_ispartialchecksum(info, mp));
3627513SDarren.Reed@Sun.COM }
3637513SDarren.Reed@Sun.COM
3647513SDarren.Reed@Sun.COM int
net_isvalidchecksum(net_handle_t info,mblk_t * mp)3657513SDarren.Reed@Sun.COM net_isvalidchecksum(net_handle_t info, mblk_t *mp)
3667513SDarren.Reed@Sun.COM {
3677513SDarren.Reed@Sun.COM
3687513SDarren.Reed@Sun.COM ASSERT(info != NULL);
3697513SDarren.Reed@Sun.COM ASSERT(mp != NULL);
3707513SDarren.Reed@Sun.COM
3717513SDarren.Reed@Sun.COM if (info->netd_condemned != 0 || info->netd_stack == NULL)
3727513SDarren.Reed@Sun.COM return (-1);
3737513SDarren.Reed@Sun.COM
3747513SDarren.Reed@Sun.COM return (info->netd_info.netp_isvalidchecksum(info, mp));
3757513SDarren.Reed@Sun.COM }
3767513SDarren.Reed@Sun.COM
3777513SDarren.Reed@Sun.COM /*
3787513SDarren.Reed@Sun.COM * Hooks related functions
3797513SDarren.Reed@Sun.COM */
3807513SDarren.Reed@Sun.COM
3817513SDarren.Reed@Sun.COM /*
3827513SDarren.Reed@Sun.COM * Function: net_family_register
3837513SDarren.Reed@Sun.COM * Returns: int - 0 = Succ, Else = Fail
3847513SDarren.Reed@Sun.COM * Parameters: info(I) - protocol
3857513SDarren.Reed@Sun.COM * hf(I) - family pointer
3867513SDarren.Reed@Sun.COM *
3877513SDarren.Reed@Sun.COM * Call hook_family_add to register family
3887513SDarren.Reed@Sun.COM *
3897513SDarren.Reed@Sun.COM * There is no need to bump netd_refcnt in the two functions
3907513SDarren.Reed@Sun.COM * net_family_register and net_family_unregister because the caller of these
3917513SDarren.Reed@Sun.COM * two functions is assumed to "own" a reference on 'info' via an earlier
3927513SDarren.Reed@Sun.COM * call to net_protocol_register(). Thus the owner is expected to do a
3937513SDarren.Reed@Sun.COM * call to net_protocol_unregister() after having done a
3947513SDarren.Reed@Sun.COM * net_family_unregister() to make sure things are properly cleaned up.
395*12263SDarren.Reed@Sun.COM * Passing a pointer to info->netd_hooks into hook_family_add is required
396*12263SDarren.Reed@Sun.COM * so that this can be set before the notify functions are called. If this
397*12263SDarren.Reed@Sun.COM * does not happen, the notify function may do something that seems fine,
398*12263SDarren.Reed@Sun.COM * like add a notify function to the family but cause a panic because
399*12263SDarren.Reed@Sun.COM * netd_hooks is NULL when we get to hook_family_notify_register.
4007513SDarren.Reed@Sun.COM */
4017513SDarren.Reed@Sun.COM int
net_family_register(net_handle_t info,hook_family_t * hf)4027513SDarren.Reed@Sun.COM net_family_register(net_handle_t info, hook_family_t *hf)
4037513SDarren.Reed@Sun.COM {
4047513SDarren.Reed@Sun.COM netstack_t *ns;
4057513SDarren.Reed@Sun.COM
4067513SDarren.Reed@Sun.COM ASSERT(info != NULL);
4077513SDarren.Reed@Sun.COM ASSERT(hf != NULL);
4087513SDarren.Reed@Sun.COM
4097513SDarren.Reed@Sun.COM if (info->netd_condemned != 0 || info->netd_stack == NULL)
4107513SDarren.Reed@Sun.COM return (ESHUTDOWN);
4117513SDarren.Reed@Sun.COM
4127513SDarren.Reed@Sun.COM if (info->netd_hooks != NULL)
4137513SDarren.Reed@Sun.COM return (EEXIST);
4147513SDarren.Reed@Sun.COM
4157513SDarren.Reed@Sun.COM ns = info->netd_stack->nts_netstack;
4167513SDarren.Reed@Sun.COM ASSERT(ns != NULL);
417*12263SDarren.Reed@Sun.COM if (hook_family_add(hf, ns->netstack_hook,
418*12263SDarren.Reed@Sun.COM (void **)&info->netd_hooks) == NULL)
4197513SDarren.Reed@Sun.COM return (EEXIST);
4207513SDarren.Reed@Sun.COM
4217513SDarren.Reed@Sun.COM return (0);
4227513SDarren.Reed@Sun.COM }
4237513SDarren.Reed@Sun.COM
4247513SDarren.Reed@Sun.COM /*
4257513SDarren.Reed@Sun.COM * Function: net_family_unregister
4267513SDarren.Reed@Sun.COM * Returns: int - transparent value, explained by caller
4277513SDarren.Reed@Sun.COM * Parameters: info(I) - protocol
4287513SDarren.Reed@Sun.COM * hf(I) - family pointer
4297513SDarren.Reed@Sun.COM *
4307513SDarren.Reed@Sun.COM * Call hook_family_remove to unregister family
4317513SDarren.Reed@Sun.COM */
4327513SDarren.Reed@Sun.COM int
net_family_unregister(net_handle_t info,hook_family_t * hf)4337513SDarren.Reed@Sun.COM net_family_unregister(net_handle_t info, hook_family_t *hf)
4347513SDarren.Reed@Sun.COM {
4357513SDarren.Reed@Sun.COM int ret;
4367513SDarren.Reed@Sun.COM
4377513SDarren.Reed@Sun.COM ASSERT(info != NULL);
4387513SDarren.Reed@Sun.COM ASSERT(hf != NULL);
4397513SDarren.Reed@Sun.COM
4407513SDarren.Reed@Sun.COM if (info->netd_hooks == NULL)
4417513SDarren.Reed@Sun.COM return (ENXIO);
4427513SDarren.Reed@Sun.COM
4437513SDarren.Reed@Sun.COM if (strcmp(info->netd_hooks->hfi_family.hf_name,
4447513SDarren.Reed@Sun.COM hf->hf_name) != 0)
4457513SDarren.Reed@Sun.COM return (EINVAL);
4467513SDarren.Reed@Sun.COM
4477513SDarren.Reed@Sun.COM ret = hook_family_remove(info->netd_hooks);
4487513SDarren.Reed@Sun.COM if (ret == 0)
4497513SDarren.Reed@Sun.COM info->netd_hooks = NULL;
4507513SDarren.Reed@Sun.COM
4517513SDarren.Reed@Sun.COM return (ret);
4527513SDarren.Reed@Sun.COM }
4537513SDarren.Reed@Sun.COM
4547915SDarren.Reed@Sun.COM int
net_family_shutdown(net_handle_t info,hook_family_t * hf)4557915SDarren.Reed@Sun.COM net_family_shutdown(net_handle_t info, hook_family_t *hf)
4567915SDarren.Reed@Sun.COM {
4577915SDarren.Reed@Sun.COM
4587915SDarren.Reed@Sun.COM ASSERT(info != NULL);
4597915SDarren.Reed@Sun.COM ASSERT(hf != NULL);
4607915SDarren.Reed@Sun.COM
4617915SDarren.Reed@Sun.COM if (info->netd_hooks == NULL)
4627915SDarren.Reed@Sun.COM return (ENXIO);
4637915SDarren.Reed@Sun.COM
4647915SDarren.Reed@Sun.COM if (strcmp(info->netd_hooks->hfi_family.hf_name,
4657915SDarren.Reed@Sun.COM hf->hf_name) != 0)
4667915SDarren.Reed@Sun.COM return (EINVAL);
4677915SDarren.Reed@Sun.COM
4687915SDarren.Reed@Sun.COM return (hook_family_shutdown(info->netd_hooks));
4697915SDarren.Reed@Sun.COM }
4707915SDarren.Reed@Sun.COM
4717513SDarren.Reed@Sun.COM /*
4727513SDarren.Reed@Sun.COM * Function: net_event_register
4737513SDarren.Reed@Sun.COM * Returns: internal event pointer - NULL = Fail
4747513SDarren.Reed@Sun.COM * Parameters: info(I) - protocol
4757513SDarren.Reed@Sun.COM * he(I) - event pointer
4767513SDarren.Reed@Sun.COM *
4777513SDarren.Reed@Sun.COM * Call hook_event_add to register event on specific family
4787513SDarren.Reed@Sun.COM * Internal event pointer is returned so caller can get
4797513SDarren.Reed@Sun.COM * handle to run hooks
4807513SDarren.Reed@Sun.COM */
4817513SDarren.Reed@Sun.COM hook_event_token_t
net_event_register(net_handle_t info,hook_event_t * he)4827513SDarren.Reed@Sun.COM net_event_register(net_handle_t info, hook_event_t *he)
4837513SDarren.Reed@Sun.COM {
4847513SDarren.Reed@Sun.COM hook_event_int_t *hei;
4857513SDarren.Reed@Sun.COM
4867513SDarren.Reed@Sun.COM ASSERT(info != NULL);
4877513SDarren.Reed@Sun.COM ASSERT(he != NULL);
4887513SDarren.Reed@Sun.COM
4897513SDarren.Reed@Sun.COM if (info->netd_hooks == NULL || info->netd_condemned != 0 ||
4907513SDarren.Reed@Sun.COM info->netd_stack == NULL)
4917513SDarren.Reed@Sun.COM return (NULL);
4927513SDarren.Reed@Sun.COM
4937513SDarren.Reed@Sun.COM hei = hook_event_add(info->netd_hooks, he);
4947513SDarren.Reed@Sun.COM return ((hook_event_token_t)hei);
4957513SDarren.Reed@Sun.COM }
4967513SDarren.Reed@Sun.COM
4977513SDarren.Reed@Sun.COM /*
4987513SDarren.Reed@Sun.COM * Function: net_event_unregister
4997513SDarren.Reed@Sun.COM * Returns: int - transparent value, explained by caller
5007513SDarren.Reed@Sun.COM * Parameters: info(I) - protocol
5017513SDarren.Reed@Sun.COM * he(I) - event pointer
5027513SDarren.Reed@Sun.COM *
5037513SDarren.Reed@Sun.COM * Call hook_event_remove to unregister event on specific family
5047513SDarren.Reed@Sun.COM */
5057513SDarren.Reed@Sun.COM int
net_event_unregister(net_handle_t info,hook_event_t * he)5067513SDarren.Reed@Sun.COM net_event_unregister(net_handle_t info, hook_event_t *he)
5077513SDarren.Reed@Sun.COM {
5087513SDarren.Reed@Sun.COM
5097513SDarren.Reed@Sun.COM ASSERT(info != NULL);
5107513SDarren.Reed@Sun.COM ASSERT(he != NULL);
5117513SDarren.Reed@Sun.COM
5127513SDarren.Reed@Sun.COM if (info->netd_hooks == NULL)
5137513SDarren.Reed@Sun.COM return (ENXIO);
5147513SDarren.Reed@Sun.COM
5157513SDarren.Reed@Sun.COM return (hook_event_remove(info->netd_hooks, he));
5167513SDarren.Reed@Sun.COM }
5177513SDarren.Reed@Sun.COM
5187915SDarren.Reed@Sun.COM int
net_event_shutdown(net_handle_t info,hook_event_t * he)5197915SDarren.Reed@Sun.COM net_event_shutdown(net_handle_t info, hook_event_t *he)
5207915SDarren.Reed@Sun.COM {
5217915SDarren.Reed@Sun.COM
5227915SDarren.Reed@Sun.COM ASSERT(info != NULL);
5237915SDarren.Reed@Sun.COM ASSERT(he != NULL);
5247915SDarren.Reed@Sun.COM
5257915SDarren.Reed@Sun.COM if (info->netd_hooks == NULL)
5267915SDarren.Reed@Sun.COM return (ENXIO);
5277915SDarren.Reed@Sun.COM
5287915SDarren.Reed@Sun.COM return (hook_event_shutdown(info->netd_hooks, he));
5297915SDarren.Reed@Sun.COM }
5307915SDarren.Reed@Sun.COM
5317513SDarren.Reed@Sun.COM /*
5327513SDarren.Reed@Sun.COM * Function: net_hook_register
5337513SDarren.Reed@Sun.COM * Returns: int - transparent value, explained by caller
5347513SDarren.Reed@Sun.COM * Parameters: info(I) - protocol
5357513SDarren.Reed@Sun.COM * event(I) - event name
5367513SDarren.Reed@Sun.COM * h(I) - hook pointer
5377513SDarren.Reed@Sun.COM *
5387513SDarren.Reed@Sun.COM * Call hook_register to add hook on specific family/event
5397513SDarren.Reed@Sun.COM */
5407513SDarren.Reed@Sun.COM int
net_hook_register(net_handle_t info,char * event,hook_t * h)5417513SDarren.Reed@Sun.COM net_hook_register(net_handle_t info, char *event, hook_t *h)
5427513SDarren.Reed@Sun.COM {
5437513SDarren.Reed@Sun.COM
5447513SDarren.Reed@Sun.COM ASSERT(info != NULL);
5457513SDarren.Reed@Sun.COM ASSERT(event != NULL);
5467513SDarren.Reed@Sun.COM ASSERT(h != NULL);
5477513SDarren.Reed@Sun.COM
5487513SDarren.Reed@Sun.COM if (info->netd_condemned != 0 || info->netd_stack == NULL)
5497513SDarren.Reed@Sun.COM return (ESHUTDOWN);
5507513SDarren.Reed@Sun.COM
5517513SDarren.Reed@Sun.COM if (info->netd_hooks == NULL)
5527513SDarren.Reed@Sun.COM return (ENXIO);
5537513SDarren.Reed@Sun.COM
5547513SDarren.Reed@Sun.COM return (hook_register(info->netd_hooks, event, h));
5557513SDarren.Reed@Sun.COM }
5567513SDarren.Reed@Sun.COM
5577513SDarren.Reed@Sun.COM /*
5587513SDarren.Reed@Sun.COM * Function: net_hook_unregister
5597513SDarren.Reed@Sun.COM * Returns: int - transparent value, explained by caller
5607513SDarren.Reed@Sun.COM * Parameters: info(I) - protocol
5617513SDarren.Reed@Sun.COM * event(I) - event name
5627513SDarren.Reed@Sun.COM * h(I) - hook pointer
5637513SDarren.Reed@Sun.COM *
5647513SDarren.Reed@Sun.COM * Call hook_unregister to remove hook on specific family/event
5657513SDarren.Reed@Sun.COM */
5667513SDarren.Reed@Sun.COM int
net_hook_unregister(net_handle_t info,char * event,hook_t * h)5677513SDarren.Reed@Sun.COM net_hook_unregister(net_handle_t info, char *event, hook_t *h)
5687513SDarren.Reed@Sun.COM {
5697513SDarren.Reed@Sun.COM
5707513SDarren.Reed@Sun.COM ASSERT(info != NULL);
5717513SDarren.Reed@Sun.COM ASSERT(event != NULL);
5727513SDarren.Reed@Sun.COM ASSERT(h != NULL);
5737513SDarren.Reed@Sun.COM
5747513SDarren.Reed@Sun.COM if (info->netd_hooks == NULL)
5757513SDarren.Reed@Sun.COM return (ENXIO);
5767513SDarren.Reed@Sun.COM
5777513SDarren.Reed@Sun.COM return (hook_unregister(info->netd_hooks, event, h));
5787513SDarren.Reed@Sun.COM }
5797513SDarren.Reed@Sun.COM
5807513SDarren.Reed@Sun.COM netid_t
net_getnetid(net_handle_t netd)5817513SDarren.Reed@Sun.COM net_getnetid(net_handle_t netd)
5827513SDarren.Reed@Sun.COM {
5837513SDarren.Reed@Sun.COM
5847513SDarren.Reed@Sun.COM if (netd->netd_stack == NULL)
5857513SDarren.Reed@Sun.COM return (-1);
5867513SDarren.Reed@Sun.COM return (netd->netd_stack->nts_id);
5877513SDarren.Reed@Sun.COM }
5887513SDarren.Reed@Sun.COM
5897513SDarren.Reed@Sun.COM net_inject_t *
net_inject_alloc(const int version)5907513SDarren.Reed@Sun.COM net_inject_alloc(const int version)
5917513SDarren.Reed@Sun.COM {
5927513SDarren.Reed@Sun.COM net_inject_t *ni;
5937513SDarren.Reed@Sun.COM
5947513SDarren.Reed@Sun.COM ni = kmem_zalloc(sizeof (*ni), KM_NOSLEEP);
5957513SDarren.Reed@Sun.COM if (ni == NULL)
5967513SDarren.Reed@Sun.COM return (NULL);
5977513SDarren.Reed@Sun.COM
5987513SDarren.Reed@Sun.COM ni->ni_version = version;
5997513SDarren.Reed@Sun.COM return (ni);
6007513SDarren.Reed@Sun.COM }
6017513SDarren.Reed@Sun.COM
6027513SDarren.Reed@Sun.COM void
net_inject_free(net_inject_t * ni)6037513SDarren.Reed@Sun.COM net_inject_free(net_inject_t *ni)
6047513SDarren.Reed@Sun.COM {
6057513SDarren.Reed@Sun.COM kmem_free(ni, sizeof (*ni));
6067513SDarren.Reed@Sun.COM }
6077513SDarren.Reed@Sun.COM
6087513SDarren.Reed@Sun.COM kstat_t *
net_kstat_create(netid_t netid,char * module,int instance,char * name,char * class,uchar_t type,ulong_t ndata,uchar_t ks_flag)6097513SDarren.Reed@Sun.COM net_kstat_create(netid_t netid, char *module, int instance, char *name,
6107513SDarren.Reed@Sun.COM char *class, uchar_t type, ulong_t ndata, uchar_t ks_flag)
6117513SDarren.Reed@Sun.COM {
6127513SDarren.Reed@Sun.COM netstackid_t stackid = net_getnetstackidbynetid(netid);
6137513SDarren.Reed@Sun.COM
6147513SDarren.Reed@Sun.COM if (stackid == -1)
6157513SDarren.Reed@Sun.COM return (NULL);
6167513SDarren.Reed@Sun.COM
6177513SDarren.Reed@Sun.COM return (kstat_create_netstack(module, instance, name, class, type,
6187513SDarren.Reed@Sun.COM ndata, ks_flag, stackid));
6197513SDarren.Reed@Sun.COM }
6207513SDarren.Reed@Sun.COM
6217513SDarren.Reed@Sun.COM void
net_kstat_delete(netid_t netid,kstat_t * ks)6227513SDarren.Reed@Sun.COM net_kstat_delete(netid_t netid, kstat_t *ks)
6237513SDarren.Reed@Sun.COM {
6247513SDarren.Reed@Sun.COM netstackid_t stackid = net_getnetstackidbynetid(netid);
6257513SDarren.Reed@Sun.COM
6267513SDarren.Reed@Sun.COM if (stackid != -1)
6277513SDarren.Reed@Sun.COM kstat_delete_netstack(ks, stackid);
6287513SDarren.Reed@Sun.COM }
6297513SDarren.Reed@Sun.COM
6307513SDarren.Reed@Sun.COM int
net_event_notify_register(net_handle_t family,char * event,hook_notify_fn_t callback,void * arg)6317513SDarren.Reed@Sun.COM net_event_notify_register(net_handle_t family, char *event,
6327513SDarren.Reed@Sun.COM hook_notify_fn_t callback, void *arg)
6337513SDarren.Reed@Sun.COM {
6347513SDarren.Reed@Sun.COM int error;
6357513SDarren.Reed@Sun.COM
6367513SDarren.Reed@Sun.COM if (family->netd_condemned != 0 || family->netd_stack == NULL)
6377513SDarren.Reed@Sun.COM return (ESHUTDOWN);
6387513SDarren.Reed@Sun.COM
6397513SDarren.Reed@Sun.COM error = hook_event_notify_register(family->netd_hooks, event,
6407513SDarren.Reed@Sun.COM callback, arg);
6417513SDarren.Reed@Sun.COM
6427513SDarren.Reed@Sun.COM return (error);
6437513SDarren.Reed@Sun.COM }
6447513SDarren.Reed@Sun.COM
6457513SDarren.Reed@Sun.COM int
net_event_notify_unregister(net_handle_t family,char * event,hook_notify_fn_t callback)6467513SDarren.Reed@Sun.COM net_event_notify_unregister(net_handle_t family, char *event,
6477513SDarren.Reed@Sun.COM hook_notify_fn_t callback)
6487513SDarren.Reed@Sun.COM {
6497513SDarren.Reed@Sun.COM int error;
6507513SDarren.Reed@Sun.COM
6517513SDarren.Reed@Sun.COM error = hook_event_notify_unregister(family->netd_hooks, event,
6527513SDarren.Reed@Sun.COM callback);
6537513SDarren.Reed@Sun.COM
6547513SDarren.Reed@Sun.COM return (error);
6557513SDarren.Reed@Sun.COM }
6567513SDarren.Reed@Sun.COM
6577513SDarren.Reed@Sun.COM int
net_protocol_notify_register(net_handle_t family,hook_notify_fn_t callback,void * arg)6587513SDarren.Reed@Sun.COM net_protocol_notify_register(net_handle_t family, hook_notify_fn_t callback,
6597513SDarren.Reed@Sun.COM void *arg)
6607513SDarren.Reed@Sun.COM {
6617513SDarren.Reed@Sun.COM int error;
6627513SDarren.Reed@Sun.COM
6637513SDarren.Reed@Sun.COM if (family->netd_condemned != 0 || family->netd_stack == NULL)
6647513SDarren.Reed@Sun.COM return (ESHUTDOWN);
6657513SDarren.Reed@Sun.COM
6667513SDarren.Reed@Sun.COM error = hook_family_notify_register(family->netd_hooks, callback,
6677513SDarren.Reed@Sun.COM arg);
6687513SDarren.Reed@Sun.COM
6697513SDarren.Reed@Sun.COM return (error);
6707513SDarren.Reed@Sun.COM }
6717513SDarren.Reed@Sun.COM
6727513SDarren.Reed@Sun.COM int
net_protocol_notify_unregister(net_handle_t family,hook_notify_fn_t callback)6737513SDarren.Reed@Sun.COM net_protocol_notify_unregister(net_handle_t family, hook_notify_fn_t callback)
6747513SDarren.Reed@Sun.COM {
6757513SDarren.Reed@Sun.COM int error;
6767513SDarren.Reed@Sun.COM
6777513SDarren.Reed@Sun.COM error = hook_family_notify_unregister(family->netd_hooks, callback);
6787513SDarren.Reed@Sun.COM
6797513SDarren.Reed@Sun.COM return (error);
6807513SDarren.Reed@Sun.COM }
681