[BACK]Return to if.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / net

Annotation of src/sys/net/if.c, Revision 1.277

1.277   ! rmind       1: /*     $NetBSD: if.c,v 1.276 2014/06/05 23:48:16 rmind Exp $   */
1.53      thorpej     2:
                      3: /*-
1.219     ad          4:  * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
1.53      thorpej     5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
1.150     peter       8:  * by William Studenmund and Jason R. Thorpe.
1.53      thorpej     9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     20:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     21:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     22:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     23:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     24:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     25:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     26:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     27:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     28:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     29:  * POSSIBILITY OF SUCH DAMAGE.
                     30:  */
1.49      itojun     31:
                     32: /*
                     33:  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
                     34:  * All rights reserved.
1.154     perry      35:  *
1.49      itojun     36:  * Redistribution and use in source and binary forms, with or without
                     37:  * modification, are permitted provided that the following conditions
                     38:  * are met:
                     39:  * 1. Redistributions of source code must retain the above copyright
                     40:  *    notice, this list of conditions and the following disclaimer.
                     41:  * 2. Redistributions in binary form must reproduce the above copyright
                     42:  *    notice, this list of conditions and the following disclaimer in the
                     43:  *    documentation and/or other materials provided with the distribution.
                     44:  * 3. Neither the name of the project nor the names of its contributors
                     45:  *    may be used to endorse or promote products derived from this software
                     46:  *    without specific prior written permission.
1.154     perry      47:  *
1.49      itojun     48:  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
                     49:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     50:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     51:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
                     52:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     53:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     54:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     55:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     56:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     57:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     58:  * SUCH DAMAGE.
                     59:  */
1.16      cgd        60:
1.1       cgd        61: /*
1.15      mycroft    62:  * Copyright (c) 1980, 1986, 1993
                     63:  *     The Regents of the University of California.  All rights reserved.
1.1       cgd        64:  *
                     65:  * Redistribution and use in source and binary forms, with or without
                     66:  * modification, are permitted provided that the following conditions
                     67:  * are met:
                     68:  * 1. Redistributions of source code must retain the above copyright
                     69:  *    notice, this list of conditions and the following disclaimer.
                     70:  * 2. Redistributions in binary form must reproduce the above copyright
                     71:  *    notice, this list of conditions and the following disclaimer in the
                     72:  *    documentation and/or other materials provided with the distribution.
1.126     agc        73:  * 3. Neither the name of the University nor the names of its contributors
1.1       cgd        74:  *    may be used to endorse or promote products derived from this software
                     75:  *    without specific prior written permission.
                     76:  *
                     77:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     78:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     79:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     80:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     81:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     82:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     83:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     84:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     85:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     86:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     87:  * SUCH DAMAGE.
                     88:  *
1.44      fvdl       89:  *     @(#)if.c        8.5 (Berkeley) 1/9/95
1.1       cgd        90:  */
1.99      lukem      91:
                     92: #include <sys/cdefs.h>
1.277   ! rmind      93: __KERNEL_RCSID(0, "$NetBSD: if.c,v 1.276 2014/06/05 23:48:16 rmind Exp $");
1.50      thorpej    94:
                     95: #include "opt_inet.h"
1.46      thorpej    96:
1.51      bouyer     97: #include "opt_atalk.h"
1.120     martin     98: #include "opt_natm.h"
1.1       cgd        99:
1.8       mycroft   100: #include <sys/param.h>
                    101: #include <sys/mbuf.h>
                    102: #include <sys/systm.h>
1.59      thorpej   103: #include <sys/callout.h>
1.15      mycroft   104: #include <sys/proc.h>
1.8       mycroft   105: #include <sys/socket.h>
                    106: #include <sys/socketvar.h>
1.56      thorpej   107: #include <sys/domain.h>
1.8       mycroft   108: #include <sys/protosw.h>
                    109: #include <sys/kernel.h>
                    110: #include <sys/ioctl.h>
1.133     jonathan  111: #include <sys/sysctl.h>
1.159     dyoung    112: #include <sys/syslog.h>
1.165     elad      113: #include <sys/kauth.h>
1.254     dyoung    114: #include <sys/kmem.h>
1.276     rmind     115: #include <sys/xcall.h>
1.1       cgd       116:
1.8       mycroft   117: #include <net/if.h>
                    118: #include <net/if_dl.h>
1.66      onoe      119: #include <net/if_ether.h>
1.124     dyoung    120: #include <net/if_media.h>
1.132     dyoung    121: #include <net80211/ieee80211.h>
                    122: #include <net80211/ieee80211_ioctl.h>
1.8       mycroft   123: #include <net/if_types.h>
1.24      christos  124: #include <net/radix.h>
1.53      thorpej   125: #include <net/route.h>
1.95      itojun    126: #include <net/netisr.h>
1.262     christos  127: #include <sys/module.h>
1.51      bouyer    128: #ifdef NETATALK
                    129: #include <netatalk/at_extern.h>
                    130: #include <netatalk/at.h>
                    131: #endif
1.143     itojun    132: #include <net/pfil.h>
1.276     rmind     133: #include <netinet/in_var.h>
1.1       cgd       134:
1.49      itojun    135: #ifdef INET6
                    136: #include <netinet/in.h>
1.72      thorpej   137: #include <netinet6/in6_var.h>
1.108     itojun    138: #include <netinet6/nd6.h>
1.49      itojun    139: #endif
1.117     thorpej   140:
1.166     liamjfoy  141: #include "carp.h"
                    142: #if NCARP > 0
                    143: #include <netinet/ip_carp.h>
                    144: #endif
                    145:
1.186     christos  146: #include <compat/sys/sockio.h>
1.161     christos  147: #include <compat/sys/socket.h>
                    148:
1.117     thorpej   149: MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address");
                    150: MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address");
1.49      itojun    151:
1.274     rmind     152: /*
                    153:  * Global list of interfaces.
                    154:  */
                    155: struct ifnet_head              ifnet_list;
                    156: static ifnet_t **              ifindex2ifnet = NULL;
                    157:
                    158: static u_int                   if_index = 1;
                    159: static size_t                  if_indexlim = 0;
                    160: static uint64_t                        index_gen;
                    161: static kmutex_t                        index_gen_mtx;
                    162:
                    163: static struct ifaddr **                ifnet_addrs = NULL;
                    164:
                    165: static callout_t               if_slowtimo_ch;
                    166:
                    167: struct ifnet *lo0ifp;
1.1       cgd       168: int    ifqmaxlen = IFQ_MAXLEN;
1.104     matt      169:
1.192     dyoung    170: static int     if_rt_walktree(struct rtentry *, void *);
1.53      thorpej   171:
1.163     thorpej   172: static struct if_clone *if_clone_lookup(const char *, int *);
                    173: static int     if_clone_list(struct if_clonereq *);
1.63      thorpej   174:
1.163     thorpej   175: static LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners);
                    176: static int if_cloners_count;
1.63      thorpej   177:
1.265     rmind     178: /* Packet filtering hook for interfaces. */
                    179: pfil_head_t *  if_pfil;
1.143     itojun    180:
1.239     elad      181: static kauth_listener_t if_listener;
                    182:
1.273     pooka     183: static int doifioctl(struct socket *, u_long, void *, struct lwp *);
1.252     dyoung    184: static int ifioctl_attach(struct ifnet *);
                    185: static void ifioctl_detach(struct ifnet *);
1.254     dyoung    186: static void ifnet_lock_enter(struct ifnet_lock *);
                    187: static void ifnet_lock_exit(struct ifnet_lock *);
1.163     thorpej   188: static void if_detach_queues(struct ifnet *, struct ifqueue *);
1.234     dyoung    189: static void sysctl_sndq_setup(struct sysctllog **, const char *,
                    190:     struct ifaltq *);
1.95      itojun    191:
1.240     cegger    192: #if defined(INET) || defined(INET6)
1.276     rmind     193: static void sysctl_net_pktq_setup(struct sysctllog **, int);
1.240     cegger    194: #endif
1.237     pooka     195:
1.239     elad      196: static int
                    197: if_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie,
                    198:     void *arg0, void *arg1, void *arg2, void *arg3)
                    199: {
                    200:        int result;
                    201:        enum kauth_network_req req;
                    202:
                    203:        result = KAUTH_RESULT_DEFER;
                    204:        req = (enum kauth_network_req)arg1;
                    205:
                    206:        if (action != KAUTH_NETWORK_INTERFACE)
                    207:                return result;
                    208:
                    209:        if ((req == KAUTH_REQ_NETWORK_INTERFACE_GET) ||
                    210:            (req == KAUTH_REQ_NETWORK_INTERFACE_SET))
                    211:                result = KAUTH_RESULT_ALLOW;
                    212:
                    213:        return result;
                    214: }
                    215:
1.1       cgd       216: /*
                    217:  * Network interface utility routines.
                    218:  *
                    219:  * Routines with ifa_ifwith* names take sockaddr *'s as
                    220:  * parameters.
                    221:  */
1.4       andrew    222: void
1.163     thorpej   223: ifinit(void)
1.1       cgd       224: {
1.276     rmind     225: #if defined(INET)
                    226:        sysctl_net_pktq_setup(NULL, PF_INET);
                    227: #endif
1.237     pooka     228: #ifdef INET6
1.276     rmind     229:        sysctl_net_pktq_setup(NULL, PF_INET6);
                    230: #endif
1.1       cgd       231:
1.193     ad        232:        callout_init(&if_slowtimo_ch, 0);
1.4       andrew    233:        if_slowtimo(NULL);
1.239     elad      234:
                    235:        if_listener = kauth_listen_scope(KAUTH_SCOPE_NETWORK,
                    236:            if_listener_cb, NULL);
1.273     pooka     237:
                    238:        /* interfaces are available, inform socket code */
                    239:        ifioctl = doifioctl;
1.227     yamt      240: }
                    241:
                    242: /*
                    243:  * XXX Initialization before configure().
                    244:  * XXX hack to get pfil_add_hook working in autoconf.
                    245:  */
                    246: void
                    247: ifinit1(void)
                    248: {
1.238     skrll     249:        mutex_init(&index_gen_mtx, MUTEX_DEFAULT, IPL_NONE);
1.274     rmind     250:        TAILQ_INIT(&ifnet_list);
                    251:        if_indexlim = 8;
                    252:
1.265     rmind     253:        if_pfil = pfil_head_create(PFIL_TYPE_IFNET, NULL);
                    254:        KASSERT(if_pfil != NULL);
1.1       cgd       255: }
                    256:
1.274     rmind     257: ifnet_t *
1.226     christos  258: if_alloc(u_char type)
                    259: {
1.274     rmind     260:        return kmem_zalloc(sizeof(ifnet_t), KM_SLEEP);
1.226     christos  261: }
                    262:
                    263: void
1.274     rmind     264: if_free(ifnet_t *ifp)
1.251     dyoung    265: {
1.274     rmind     266:        kmem_free(ifp, sizeof(ifnet_t));
1.251     dyoung    267: }
                    268:
                    269: void
1.226     christos  270: if_initname(struct ifnet *ifp, const char *name, int unit)
                    271: {
                    272:        (void)snprintf(ifp->if_xname, sizeof(ifp->if_xname),
                    273:            "%s%d", name, unit);
                    274: }
                    275:
1.53      thorpej   276: /*
                    277:  * Null routines used while an interface is going away.  These routines
                    278:  * just return an error.
                    279:  */
                    280:
                    281: int
1.177     christos  282: if_nulloutput(struct ifnet *ifp, struct mbuf *m,
1.181     dyoung    283:     const struct sockaddr *so, struct rtentry *rt)
1.53      thorpej   284: {
                    285:
1.185     dyoung    286:        return ENXIO;
1.53      thorpej   287: }
                    288:
                    289: void
1.177     christos  290: if_nullinput(struct ifnet *ifp, struct mbuf *m)
1.53      thorpej   291: {
                    292:
                    293:        /* Nothing. */
                    294: }
                    295:
                    296: void
1.177     christos  297: if_nullstart(struct ifnet *ifp)
1.53      thorpej   298: {
                    299:
                    300:        /* Nothing. */
                    301: }
                    302:
                    303: int
1.183     christos  304: if_nullioctl(struct ifnet *ifp, u_long cmd, void *data)
1.53      thorpej   305: {
                    306:
1.255     dyoung    307:        /* Wake ifioctl_detach(), who may wait for all threads to
                    308:         * quit the critical section.
                    309:         */
1.254     dyoung    310:        cv_signal(&ifp->if_ioctl_lock->il_emptied);
1.185     dyoung    311:        return ENXIO;
1.53      thorpej   312: }
                    313:
                    314: int
1.177     christos  315: if_nullinit(struct ifnet *ifp)
1.53      thorpej   316: {
                    317:
1.185     dyoung    318:        return ENXIO;
1.53      thorpej   319: }
                    320:
                    321: void
1.177     christos  322: if_nullstop(struct ifnet *ifp, int disable)
1.75      thorpej   323: {
                    324:
                    325:        /* Nothing. */
                    326: }
                    327:
                    328: void
1.177     christos  329: if_nullwatchdog(struct ifnet *ifp)
1.53      thorpej   330: {
                    331:
                    332:        /* Nothing. */
                    333: }
                    334:
                    335: void
1.177     christos  336: if_nulldrain(struct ifnet *ifp)
1.53      thorpej   337: {
                    338:
                    339:        /* Nothing. */
                    340: }
                    341:
1.210     dyoung    342: void
1.231     dyoung    343: if_set_sadl(struct ifnet *ifp, const void *lla, u_char addrlen, bool factory)
1.210     dyoung    344: {
                    345:        struct ifaddr *ifa;
                    346:        struct sockaddr_dl *sdl;
                    347:
                    348:        ifp->if_addrlen = addrlen;
                    349:        if_alloc_sadl(ifp);
                    350:        ifa = ifp->if_dl;
                    351:        sdl = satosdl(ifa->ifa_addr);
                    352:
                    353:        (void)sockaddr_dl_setaddr(sdl, sdl->sdl_len, lla, ifp->if_addrlen);
1.231     dyoung    354:        if (factory) {
                    355:                ifp->if_hwdl = ifp->if_dl;
                    356:                IFAREF(ifp->if_hwdl);
                    357:        }
1.223     dyoung    358:        /* TBD routing socket */
1.210     dyoung    359: }
                    360:
1.211     dyoung    361: struct ifaddr *
                    362: if_dl_create(const struct ifnet *ifp, const struct sockaddr_dl **sdlp)
                    363: {
                    364:        unsigned socksize, ifasize;
                    365:        int addrlen, namelen;
                    366:        struct sockaddr_dl *mask, *sdl;
                    367:        struct ifaddr *ifa;
                    368:
                    369:        namelen = strlen(ifp->if_xname);
                    370:        addrlen = ifp->if_addrlen;
                    371:        socksize = roundup(sockaddr_dl_measure(namelen, addrlen), sizeof(long));
                    372:        ifasize = sizeof(*ifa) + 2 * socksize;
                    373:        ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK|M_ZERO);
                    374:
                    375:        sdl = (struct sockaddr_dl *)(ifa + 1);
                    376:        mask = (struct sockaddr_dl *)(socksize + (char *)sdl);
                    377:
                    378:        sockaddr_dl_init(sdl, socksize, ifp->if_index, ifp->if_type,
                    379:            ifp->if_xname, namelen, NULL, addrlen);
                    380:        mask->sdl_len = sockaddr_dl_measure(namelen, 0);
                    381:        memset(&mask->sdl_data[0], 0xff, namelen);
                    382:        ifa->ifa_rtrequest = link_rtrequest;
                    383:        ifa->ifa_addr = (struct sockaddr *)sdl;
                    384:        ifa->ifa_netmask = (struct sockaddr *)mask;
                    385:
                    386:        *sdlp = sdl;
                    387:
                    388:        return ifa;
                    389: }
                    390:
1.223     dyoung    391: static void
                    392: if_sadl_setrefs(struct ifnet *ifp, struct ifaddr *ifa)
                    393: {
                    394:        const struct sockaddr_dl *sdl;
                    395:        ifnet_addrs[ifp->if_index] = ifa;
                    396:        IFAREF(ifa);
                    397:        ifp->if_dl = ifa;
                    398:        IFAREF(ifa);
                    399:        sdl = satosdl(ifa->ifa_addr);
                    400:        ifp->if_sadl = sdl;
                    401: }
                    402:
1.1       cgd       403: /*
1.81      thorpej   404:  * Allocate the link level name for the specified interface.  This
                    405:  * is an attachment helper.  It must be called after ifp->if_addrlen
                    406:  * is initialized, which may not be the case when if_attach() is
                    407:  * called.
                    408:  */
                    409: void
                    410: if_alloc_sadl(struct ifnet *ifp)
                    411: {
                    412:        struct ifaddr *ifa;
1.211     dyoung    413:        const struct sockaddr_dl *sdl;
1.84      thorpej   414:
                    415:        /*
                    416:         * If the interface already has a link name, release it
                    417:         * now.  This is useful for interfaces that can change
                    418:         * link types, and thus switch link names often.
                    419:         */
                    420:        if (ifp->if_sadl != NULL)
                    421:                if_free_sadl(ifp);
1.81      thorpej   422:
1.211     dyoung    423:        ifa = if_dl_create(ifp, &sdl);
1.195     dyoung    424:
1.207     dyoung    425:        ifa_insert(ifp, ifa);
1.223     dyoung    426:        if_sadl_setrefs(ifp, ifa);
                    427: }
                    428:
                    429: static void
                    430: if_deactivate_sadl(struct ifnet *ifp)
                    431: {
                    432:        struct ifaddr *ifa;
                    433:
                    434:        KASSERT(ifp->if_dl != NULL);
                    435:
                    436:        ifa = ifp->if_dl;
                    437:
                    438:        ifp->if_sadl = NULL;
                    439:
                    440:        ifnet_addrs[ifp->if_index] = NULL;
                    441:        IFAFREE(ifa);
                    442:        ifp->if_dl = NULL;
                    443:        IFAFREE(ifa);
                    444: }
                    445:
1.224     dyoung    446: void
1.223     dyoung    447: if_activate_sadl(struct ifnet *ifp, struct ifaddr *ifa,
                    448:     const struct sockaddr_dl *sdl)
                    449: {
                    450:        int s;
                    451:
                    452:        s = splnet();
                    453:
                    454:        if_deactivate_sadl(ifp);
                    455:
                    456:        if_sadl_setrefs(ifp, ifa);
1.231     dyoung    457:        IFADDR_FOREACH(ifa, ifp)
                    458:                rtinit(ifa, RTM_LLINFO_UPD, 0);
1.223     dyoung    459:        splx(s);
1.81      thorpej   460: }
                    461:
                    462: /*
                    463:  * Free the link level name for the specified interface.  This is
                    464:  * a detach helper.  This is called from if_detach() or from
                    465:  * link layer type specific detach functions.
                    466:  */
                    467: void
                    468: if_free_sadl(struct ifnet *ifp)
                    469: {
                    470:        struct ifaddr *ifa;
                    471:        int s;
                    472:
                    473:        ifa = ifnet_addrs[ifp->if_index];
                    474:        if (ifa == NULL) {
                    475:                KASSERT(ifp->if_sadl == NULL);
1.209     dyoung    476:                KASSERT(ifp->if_dl == NULL);
1.81      thorpej   477:                return;
                    478:        }
                    479:
                    480:        KASSERT(ifp->if_sadl != NULL);
1.209     dyoung    481:        KASSERT(ifp->if_dl != NULL);
1.81      thorpej   482:
1.88      thorpej   483:        s = splnet();
1.81      thorpej   484:        rtinit(ifa, RTM_DELETE, 0);
1.207     dyoung    485:        ifa_remove(ifp, ifa);
1.223     dyoung    486:        if_deactivate_sadl(ifp);
1.231     dyoung    487:        if (ifp->if_hwdl == ifa) {
                    488:                IFAFREE(ifa);
                    489:                ifp->if_hwdl = NULL;
                    490:        }
1.81      thorpej   491:        splx(s);
                    492: }
                    493:
1.274     rmind     494: static void
                    495: if_getindex(ifnet_t *ifp)
1.1       cgd       496: {
1.274     rmind     497:        bool hitlimit = false;
1.231     dyoung    498:
1.234     dyoung    499:        mutex_enter(&index_gen_mtx);
                    500:        ifp->if_index_gen = index_gen++;
                    501:        mutex_exit(&index_gen_mtx);
                    502:
1.102     atatat    503:        ifp->if_index = if_index;
1.274     rmind     504:        if (ifindex2ifnet == NULL) {
1.102     atatat    505:                if_index++;
1.274     rmind     506:                goto skip;
                    507:        }
                    508:        while (if_byindex(ifp->if_index)) {
                    509:                /*
                    510:                 * If we hit USHRT_MAX, we skip back to 0 since
                    511:                 * there are a number of places where the value
                    512:                 * of if_index or if_index itself is compared
                    513:                 * to or stored in an unsigned short.  By
                    514:                 * jumping back, we won't botch those assignments
                    515:                 * or comparisons.
                    516:                 */
                    517:                if (++if_index == 0) {
                    518:                        if_index = 1;
                    519:                } else if (if_index == USHRT_MAX) {
1.102     atatat    520:                        /*
1.274     rmind     521:                         * However, if we have to jump back to
                    522:                         * zero *twice* without finding an empty
                    523:                         * slot in ifindex2ifnet[], then there
                    524:                         * there are too many (>65535) interfaces.
1.102     atatat    525:                         */
1.274     rmind     526:                        if (hitlimit) {
                    527:                                panic("too many interfaces");
1.102     atatat    528:                        }
1.274     rmind     529:                        hitlimit = true;
                    530:                        if_index = 1;
1.102     atatat    531:                }
1.274     rmind     532:                ifp->if_index = if_index;
                    533:        }
                    534: skip:
1.49      itojun    535:        /*
                    536:         * We have some arrays that should be indexed by if_index.
                    537:         * since if_index will grow dynamically, they should grow too.
                    538:         *      struct ifadd **ifnet_addrs
                    539:         *      struct ifnet **ifindex2ifnet
                    540:         */
1.185     dyoung    541:        if (ifnet_addrs == NULL || ifindex2ifnet == NULL ||
1.53      thorpej   542:            ifp->if_index >= if_indexlim) {
1.131     itojun    543:                size_t m, n, oldlim;
1.183     christos  544:                void *q;
1.154     perry     545:
1.131     itojun    546:                oldlim = if_indexlim;
1.53      thorpej   547:                while (ifp->if_index >= if_indexlim)
1.49      itojun    548:                        if_indexlim <<= 1;
                    549:
                    550:                /* grow ifnet_addrs */
1.131     itojun    551:                m = oldlim * sizeof(struct ifaddr *);
1.81      thorpej   552:                n = if_indexlim * sizeof(struct ifaddr *);
1.230     dyoung    553:                q = malloc(n, M_IFADDR, M_WAITOK|M_ZERO);
1.185     dyoung    554:                if (ifnet_addrs != NULL) {
                    555:                        memcpy(q, ifnet_addrs, m);
1.230     dyoung    556:                        free(ifnet_addrs, M_IFADDR);
1.1       cgd       557:                }
1.49      itojun    558:                ifnet_addrs = (struct ifaddr **)q;
                    559:
                    560:                /* grow ifindex2ifnet */
1.131     itojun    561:                m = oldlim * sizeof(struct ifnet *);
1.49      itojun    562:                n = if_indexlim * sizeof(struct ifnet *);
1.230     dyoung    563:                q = malloc(n, M_IFADDR, M_WAITOK|M_ZERO);
1.185     dyoung    564:                if (ifindex2ifnet != NULL) {
1.230     dyoung    565:                        memcpy(q, ifindex2ifnet, m);
                    566:                        free(ifindex2ifnet, M_IFADDR);
1.49      itojun    567:                }
                    568:                ifindex2ifnet = (struct ifnet **)q;
1.1       cgd       569:        }
1.274     rmind     570:        ifindex2ifnet[ifp->if_index] = ifp;
                    571: }
                    572:
                    573: /*
                    574:  * Attach an interface to the list of "active" interfaces.
                    575:  */
                    576: void
                    577: if_attach(ifnet_t *ifp)
                    578: {
                    579:        KASSERT(if_indexlim > 0);
                    580:        TAILQ_INIT(&ifp->if_addrlist);
                    581:        TAILQ_INSERT_TAIL(&ifnet_list, ifp, if_list);
                    582:
                    583:        if (ifioctl_attach(ifp) != 0)
                    584:                panic("%s: ifioctl_attach() failed", __func__);
1.49      itojun    585:
1.274     rmind     586:        if_getindex(ifp);
1.49      itojun    587:
1.1       cgd       588:        /*
1.81      thorpej   589:         * Link level name is allocated later by a separate call to
                    590:         * if_alloc_sadl().
1.1       cgd       591:         */
1.81      thorpej   592:
1.40      thorpej   593:        if (ifp->if_snd.ifq_maxlen == 0)
1.94      itojun    594:                ifp->if_snd.ifq_maxlen = ifqmaxlen;
1.234     dyoung    595:
                    596:        sysctl_sndq_setup(&ifp->if_sysctl_log, ifp->if_xname, &ifp->if_snd);
                    597:
1.42      is        598:        ifp->if_broadcastaddr = 0; /* reliably crash if used uninitialized */
1.57      thorpej   599:
                    600:        ifp->if_link_state = LINK_STATE_UNKNOWN;
                    601:
1.89      thorpej   602:        ifp->if_capenable = 0;
1.97      thorpej   603:        ifp->if_csum_flags_tx = 0;
                    604:        ifp->if_csum_flags_rx = 0;
1.89      thorpej   605:
1.86      thorpej   606: #ifdef ALTQ
                    607:        ifp->if_snd.altq_type = 0;
                    608:        ifp->if_snd.altq_disc = NULL;
                    609:        ifp->if_snd.altq_flags &= ALTQF_CANTCHANGE;
                    610:        ifp->if_snd.altq_tbr  = NULL;
                    611:        ifp->if_snd.altq_ifp  = ifp;
                    612: #endif
                    613:
1.265     rmind     614:        ifp->if_pfil = pfil_head_create(PFIL_TYPE_IFNET, ifp);
                    615:        (void)pfil_run_hooks(if_pfil,
1.144     yamt      616:            (struct mbuf **)PFIL_IFNET_ATTACH, ifp, PFIL_IFNET);
1.87      thorpej   617:
1.152     matt      618:        if (!STAILQ_EMPTY(&domains))
1.147     tron      619:                if_attachdomain1(ifp);
                    620:
1.107     itojun    621:        /* Announce the interface. */
                    622:        rt_ifannouncemsg(ifp, IFAN_ARRIVAL);
                    623: }
                    624:
                    625: void
1.163     thorpej   626: if_attachdomain(void)
1.107     itojun    627: {
                    628:        struct ifnet *ifp;
1.110     itojun    629:        int s;
1.107     itojun    630:
1.110     itojun    631:        s = splnet();
1.185     dyoung    632:        IFNET_FOREACH(ifp)
1.107     itojun    633:                if_attachdomain1(ifp);
1.110     itojun    634:        splx(s);
1.107     itojun    635: }
                    636:
                    637: void
1.163     thorpej   638: if_attachdomain1(struct ifnet *ifp)
1.107     itojun    639: {
                    640:        struct domain *dp;
1.109     itojun    641:        int s;
                    642:
                    643:        s = splnet();
1.107     itojun    644:
1.106     itojun    645:        /* address family dependent data region */
                    646:        memset(ifp->if_afdata, 0, sizeof(ifp->if_afdata));
1.152     matt      647:        DOMAIN_FOREACH(dp) {
1.185     dyoung    648:                if (dp->dom_ifattach != NULL)
1.106     itojun    649:                        ifp->if_afdata[dp->dom_family] =
                    650:                            (*dp->dom_ifattach)(ifp);
                    651:        }
1.109     itojun    652:
                    653:        splx(s);
1.1       cgd       654: }
1.53      thorpej   655:
                    656: /*
                    657:  * Deactivate an interface.  This points all of the procedure
                    658:  * handles at error stubs.  May be called from interrupt context.
                    659:  */
                    660: void
1.163     thorpej   661: if_deactivate(struct ifnet *ifp)
1.53      thorpej   662: {
                    663:        int s;
                    664:
1.88      thorpej   665:        s = splnet();
1.53      thorpej   666:
                    667:        ifp->if_output   = if_nulloutput;
                    668:        ifp->if_input    = if_nullinput;
                    669:        ifp->if_start    = if_nullstart;
                    670:        ifp->if_ioctl    = if_nullioctl;
1.75      thorpej   671:        ifp->if_init     = if_nullinit;
                    672:        ifp->if_stop     = if_nullstop;
1.53      thorpej   673:        ifp->if_watchdog = if_nullwatchdog;
                    674:        ifp->if_drain    = if_nulldrain;
                    675:
                    676:        /* No more packets may be enqueued. */
                    677:        ifp->if_snd.ifq_maxlen = 0;
                    678:
                    679:        splx(s);
                    680: }
                    681:
1.206     dyoung    682: void
1.218     dyoung    683: if_purgeaddrs(struct ifnet *ifp, int family, void (*purgeaddr)(struct ifaddr *))
1.206     dyoung    684: {
                    685:        struct ifaddr *ifa, *nifa;
                    686:
                    687:        for (ifa = IFADDR_FIRST(ifp); ifa != NULL; ifa = nifa) {
                    688:                nifa = IFADDR_NEXT(ifa);
                    689:                if (ifa->ifa_addr->sa_family != family)
                    690:                        continue;
                    691:                (*purgeaddr)(ifa);
                    692:        }
                    693: }
                    694:
1.53      thorpej   695: /*
                    696:  * Detach an interface from the list of "active" interfaces,
                    697:  * freeing any resources as we go along.
                    698:  *
                    699:  * NOTE: This routine must be called with a valid thread context,
                    700:  * as it may block.
                    701:  */
                    702: void
1.163     thorpej   703: if_detach(struct ifnet *ifp)
1.53      thorpej   704: {
1.56      thorpej   705:        struct socket so;
1.178     dyoung    706:        struct ifaddr *ifa;
1.53      thorpej   707: #ifdef IFAREF_DEBUG
                    708:        struct ifaddr *last_ifa = NULL;
                    709: #endif
1.56      thorpej   710:        struct domain *dp;
1.141     matt      711:        const struct protosw *pr;
1.56      thorpej   712:        int s, i, family, purged;
1.276     rmind     713:        uint64_t xc;
1.53      thorpej   714:
1.56      thorpej   715:        /*
                    716:         * XXX It's kind of lame that we have to have the
                    717:         * XXX socket structure...
                    718:         */
                    719:        memset(&so, 0, sizeof(so));
1.53      thorpej   720:
1.88      thorpej   721:        s = splnet();
1.53      thorpej   722:
                    723:        /*
                    724:         * Do an if_down() to give protocols a chance to do something.
                    725:         */
                    726:        if_down(ifp);
1.86      thorpej   727:
                    728: #ifdef ALTQ
                    729:        if (ALTQ_IS_ENABLED(&ifp->if_snd))
                    730:                altq_disable(&ifp->if_snd);
                    731:        if (ALTQ_IS_ATTACHED(&ifp->if_snd))
                    732:                altq_detach(&ifp->if_snd);
1.87      thorpej   733: #endif
                    734:
1.234     dyoung    735:        sysctl_teardown(&ifp->if_sysctl_log);
1.166     liamjfoy  736:
                    737: #if NCARP > 0
                    738:        /* Remove the interface from any carp group it is a part of.  */
1.185     dyoung    739:        if (ifp->if_carp != NULL && ifp->if_type != IFT_CARP)
1.166     liamjfoy  740:                carp_ifdetach(ifp);
                    741: #endif
                    742:
1.53      thorpej   743:        /*
                    744:         * Rip all the addresses off the interface.  This should make
                    745:         * all of the routes go away.
1.178     dyoung    746:         *
                    747:         * pr_usrreq calls can remove an arbitrary number of ifaddrs
                    748:         * from the list, including our "cursor", ifa.  For safety,
                    749:         * and to honor the TAILQ abstraction, I just restart the
                    750:         * loop after each removal.  Note that the loop will exit
                    751:         * when all of the remaining ifaddrs belong to the AF_LINK
                    752:         * family.  I am counting on the historical fact that at
                    753:         * least one pr_usrreq in each address domain removes at
                    754:         * least one ifaddr.
1.53      thorpej   755:         */
1.178     dyoung    756: again:
1.204     dyoung    757:        IFADDR_FOREACH(ifa, ifp) {
1.56      thorpej   758:                family = ifa->ifa_addr->sa_family;
1.53      thorpej   759: #ifdef IFAREF_DEBUG
                    760:                printf("if_detach: ifaddr %p, family %d, refcnt %d\n",
1.56      thorpej   761:                    ifa, family, ifa->ifa_refcnt);
1.53      thorpej   762:                if (last_ifa != NULL && ifa == last_ifa)
1.56      thorpej   763:                        panic("if_detach: loop detected");
1.53      thorpej   764:                last_ifa = ifa;
                    765: #endif
1.178     dyoung    766:                if (family == AF_LINK)
1.118     itojun    767:                        continue;
                    768:                dp = pffinddomain(family);
1.56      thorpej   769: #ifdef DIAGNOSTIC
1.118     itojun    770:                if (dp == NULL)
                    771:                        panic("if_detach: no domain for AF %d",
                    772:                            family);
1.56      thorpej   773: #endif
1.160     gdt       774:                /*
                    775:                 * XXX These PURGEIF calls are redundant with the
                    776:                 * purge-all-families calls below, but are left in for
                    777:                 * now both to make a smaller change, and to avoid
                    778:                 * unplanned interactions with clearing of
                    779:                 * ifp->if_addrlist.
                    780:                 */
1.118     itojun    781:                purged = 0;
                    782:                for (pr = dp->dom_protosw;
                    783:                     pr < dp->dom_protoswNPROTOSW; pr++) {
                    784:                        so.so_proto = pr;
1.275     rmind     785:                        if (pr->pr_usrreqs) {
                    786:                                (void) (*pr->pr_usrreqs->pr_generic)(&so,
1.118     itojun    787:                                    PRU_PURGEIF, NULL, NULL,
1.162     christos  788:                                    (struct mbuf *) ifp, curlwp);
1.118     itojun    789:                                purged = 1;
1.53      thorpej   790:                        }
1.118     itojun    791:                }
                    792:                if (purged == 0) {
                    793:                        /*
                    794:                         * XXX What's really the best thing to do
1.135     keihan    795:                         * XXX here?  --thorpej@NetBSD.org
1.118     itojun    796:                         */
                    797:                        printf("if_detach: WARNING: AF %d not purged\n",
                    798:                            family);
1.207     dyoung    799:                        ifa_remove(ifp, ifa);
1.53      thorpej   800:                }
1.178     dyoung    801:                goto again;
1.53      thorpej   802:        }
1.118     itojun    803:
                    804:        if_free_sadl(ifp);
1.53      thorpej   805:
1.180     dyoung    806:        /* Walk the routing table looking for stragglers. */
1.243     dyoung    807:        for (i = 0; i <= AF_MAX; i++) {
                    808:                while (rt_walktree(i, if_rt_walktree, ifp) == ERESTART)
1.260     christos  809:                        continue;
1.243     dyoung    810:        }
1.106     itojun    811:
1.152     matt      812:        DOMAIN_FOREACH(dp) {
1.185     dyoung    813:                if (dp->dom_ifdetach != NULL && ifp->if_afdata[dp->dom_family])
1.260     christos  814:                {
                    815:                        void *p = ifp->if_afdata[dp->dom_family];
                    816:                        if (p) {
                    817:                                ifp->if_afdata[dp->dom_family] = NULL;
                    818:                                (*dp->dom_ifdetach)(ifp, p);
                    819:                        }
                    820:                }
1.160     gdt       821:
                    822:                /*
                    823:                 * One would expect multicast memberships (INET and
                    824:                 * INET6) on UDP sockets to be purged by the PURGEIF
                    825:                 * calls above, but if all addresses were removed from
                    826:                 * the interface prior to destruction, the calls will
                    827:                 * not be made (e.g. ppp, for which pppd(8) generally
                    828:                 * removes addresses before destroying the interface).
                    829:                 * Because there is no invariant that multicast
                    830:                 * memberships only exist for interfaces with IPv4
                    831:                 * addresses, we must call PURGEIF regardless of
                    832:                 * addresses.  (Protocols which might store ifnet
                    833:                 * pointers are marked with PR_PURGEIF.)
                    834:                 */
1.185     dyoung    835:                for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
1.160     gdt       836:                        so.so_proto = pr;
1.275     rmind     837:                        if (pr->pr_usrreqs && pr->pr_flags & PR_PURGEIF)
                    838:                                (void)(*pr->pr_usrreqs->pr_generic)(&so,
                    839:                                    PRU_PURGEIF, NULL, NULL,
                    840:                                    (struct mbuf *)ifp, curlwp);
1.160     gdt       841:                }
1.53      thorpej   842:        }
1.57      thorpej   843:
1.265     rmind     844:        (void)pfil_run_hooks(if_pfil,
1.184     dyoung    845:            (struct mbuf **)PFIL_IFNET_DETACH, ifp, PFIL_IFNET);
1.265     rmind     846:        (void)pfil_head_destroy(ifp->if_pfil);
1.184     dyoung    847:
1.57      thorpej   848:        /* Announce that the interface is gone. */
                    849:        rt_ifannouncemsg(ifp, IFAN_DEPARTURE);
1.93      itojun    850:
                    851:        ifindex2ifnet[ifp->if_index] = NULL;
1.53      thorpej   852:
1.274     rmind     853:        TAILQ_REMOVE(&ifnet_list, ifp, if_list);
1.53      thorpej   854:
1.252     dyoung    855:        ifioctl_detach(ifp);
                    856:
1.95      itojun    857:        /*
1.168     matt      858:         * remove packets that came from ifp, from software interrupt queues.
1.95      itojun    859:         */
1.168     matt      860:        DOMAIN_FOREACH(dp) {
                    861:                for (i = 0; i < __arraycount(dp->dom_ifqueues); i++) {
1.260     christos  862:                        struct ifqueue *iq = dp->dom_ifqueues[i];
                    863:                        if (iq == NULL)
1.168     matt      864:                                break;
1.260     christos  865:                        dp->dom_ifqueues[i] = NULL;
                    866:                        if_detach_queues(ifp, iq);
1.168     matt      867:                }
                    868:        }
1.95      itojun    869:
1.276     rmind     870:        /*
                    871:         * IP queues have to be processed separately: net-queue barrier
                    872:         * ensures that the packets are dequeued while a cross-call will
                    873:         * ensure that the interrupts have completed. FIXME: not quite..
                    874:         */
                    875:        pktq_barrier(ip_pktq);
                    876:        xc = xc_broadcast(0, (xcfunc_t)nullop, NULL, NULL);
                    877:        xc_wait(xc);
                    878:
1.53      thorpej   879:        splx(s);
1.95      itojun    880: }
                    881:
                    882: static void
1.163     thorpej   883: if_detach_queues(struct ifnet *ifp, struct ifqueue *q)
1.95      itojun    884: {
                    885:        struct mbuf *m, *prev, *next;
                    886:
                    887:        prev = NULL;
1.185     dyoung    888:        for (m = q->ifq_head; m != NULL; m = next) {
1.274     rmind     889:                KASSERT((m->m_flags & M_PKTHDR) != 0);
                    890:
1.95      itojun    891:                next = m->m_nextpkt;
1.96      itojun    892:                if (m->m_pkthdr.rcvif != ifp) {
                    893:                        prev = m;
1.95      itojun    894:                        continue;
1.96      itojun    895:                }
1.95      itojun    896:
1.185     dyoung    897:                if (prev != NULL)
1.95      itojun    898:                        prev->m_nextpkt = m->m_nextpkt;
                    899:                else
                    900:                        q->ifq_head = m->m_nextpkt;
                    901:                if (q->ifq_tail == m)
                    902:                        q->ifq_tail = prev;
                    903:                q->ifq_len--;
                    904:
                    905:                m->m_nextpkt = NULL;
                    906:                m_freem(m);
                    907:                IF_DROP(q);
                    908:        }
1.53      thorpej   909: }
                    910:
                    911: /*
                    912:  * Callback for a radix tree walk to delete all references to an
                    913:  * ifnet.
                    914:  */
1.163     thorpej   915: static int
1.192     dyoung    916: if_rt_walktree(struct rtentry *rt, void *v)
1.53      thorpej   917: {
1.55      itojun    918:        struct ifnet *ifp = (struct ifnet *)v;
1.53      thorpej   919:        int error;
                    920:
1.185     dyoung    921:        if (rt->rt_ifp != ifp)
                    922:                return 0;
                    923:
                    924:        /* Delete the entry. */
                    925:        ++rt->rt_refcnt;
1.194     dyoung    926:        error = rtrequest(RTM_DELETE, rt_getkey(rt), rt->rt_gateway,
1.185     dyoung    927:            rt_mask(rt), rt->rt_flags, NULL);
                    928:        KASSERT((rt->rt_flags & RTF_UP) == 0);
                    929:        rt->rt_ifp = NULL;
1.277   ! rmind     930:        rtfree(rt);
1.185     dyoung    931:        if (error != 0)
                    932:                printf("%s: warning: unable to delete rtentry @ %p, "
                    933:                    "error = %d\n", ifp->if_xname, rt, error);
1.243     dyoung    934:        return ERESTART;
1.53      thorpej   935: }
                    936:
1.1       cgd       937: /*
1.63      thorpej   938:  * Create a clone network interface.
                    939:  */
                    940: int
1.163     thorpej   941: if_clone_create(const char *name)
1.63      thorpej   942: {
                    943:        struct if_clone *ifc;
                    944:        int unit;
                    945:
                    946:        ifc = if_clone_lookup(name, &unit);
                    947:        if (ifc == NULL)
1.185     dyoung    948:                return EINVAL;
1.63      thorpej   949:
                    950:        if (ifunit(name) != NULL)
1.185     dyoung    951:                return EEXIST;
1.63      thorpej   952:
1.185     dyoung    953:        return (*ifc->ifc_create)(ifc, unit);
1.63      thorpej   954: }
                    955:
                    956: /*
                    957:  * Destroy a clone network interface.
                    958:  */
                    959: int
1.163     thorpej   960: if_clone_destroy(const char *name)
1.63      thorpej   961: {
                    962:        struct if_clone *ifc;
                    963:        struct ifnet *ifp;
                    964:
                    965:        ifc = if_clone_lookup(name, NULL);
                    966:        if (ifc == NULL)
1.185     dyoung    967:                return EINVAL;
1.63      thorpej   968:
                    969:        ifp = ifunit(name);
                    970:        if (ifp == NULL)
1.185     dyoung    971:                return ENXIO;
1.63      thorpej   972:
                    973:        if (ifc->ifc_destroy == NULL)
1.185     dyoung    974:                return EOPNOTSUPP;
1.63      thorpej   975:
1.185     dyoung    976:        return (*ifc->ifc_destroy)(ifp);
1.63      thorpej   977: }
                    978:
                    979: /*
                    980:  * Look up a network interface cloner.
                    981:  */
1.163     thorpej   982: static struct if_clone *
                    983: if_clone_lookup(const char *name, int *unitp)
1.63      thorpej   984: {
                    985:        struct if_clone *ifc;
                    986:        const char *cp;
1.262     christos  987:        char *dp, ifname[IFNAMSIZ + 3];
1.128     itojun    988:        int unit;
1.63      thorpej   989:
1.262     christos  990:        strcpy(ifname, "if_");
1.128     itojun    991:        /* separate interface name from unit */
1.262     christos  992:        for (dp = ifname + 3, cp = name; cp - name < IFNAMSIZ &&
                    993:            *cp && (*cp < '0' || *cp > '9');)
                    994:                *dp++ = *cp++;
1.128     itojun    995:
                    996:        if (cp == name || cp - name == IFNAMSIZ || !*cp)
1.185     dyoung    997:                return NULL;    /* No name or unit number */
1.262     christos  998:        *dp++ = '\0';
1.128     itojun    999:
1.262     christos 1000: again:
1.128     itojun   1001:        LIST_FOREACH(ifc, &if_cloners, ifc_list) {
1.262     christos 1002:                if (strcmp(ifname + 3, ifc->ifc_name) == 0)
1.128     itojun   1003:                        break;
1.63      thorpej  1004:        }
                   1005:
1.262     christos 1006:        if (ifc == NULL) {
                   1007:                if (*ifname == '\0' ||
1.267     christos 1008:                    module_autoload(ifname, MODULE_CLASS_DRIVER))
1.262     christos 1009:                        return NULL;
                   1010:                *ifname = '\0';
                   1011:                goto again;
                   1012:        }
1.63      thorpej  1013:
1.128     itojun   1014:        unit = 0;
1.129     itojun   1015:        while (cp - name < IFNAMSIZ && *cp) {
1.245     christos 1016:                if (*cp < '0' || *cp > '9' || unit >= INT_MAX / 10) {
1.63      thorpej  1017:                        /* Bogus unit number. */
1.185     dyoung   1018:                        return NULL;
1.63      thorpej  1019:                }
1.128     itojun   1020:                unit = (unit * 10) + (*cp++ - '0');
1.63      thorpej  1021:        }
                   1022:
                   1023:        if (unitp != NULL)
1.128     itojun   1024:                *unitp = unit;
1.185     dyoung   1025:        return ifc;
1.63      thorpej  1026: }
                   1027:
                   1028: /*
                   1029:  * Register a network interface cloner.
                   1030:  */
                   1031: void
1.163     thorpej  1032: if_clone_attach(struct if_clone *ifc)
1.63      thorpej  1033: {
                   1034:
                   1035:        LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list);
1.67      thorpej  1036:        if_cloners_count++;
1.63      thorpej  1037: }
                   1038:
                   1039: /*
                   1040:  * Unregister a network interface cloner.
                   1041:  */
                   1042: void
1.163     thorpej  1043: if_clone_detach(struct if_clone *ifc)
1.63      thorpej  1044: {
                   1045:
                   1046:        LIST_REMOVE(ifc, ifc_list);
1.67      thorpej  1047:        if_cloners_count--;
                   1048: }
                   1049:
                   1050: /*
                   1051:  * Provide list of interface cloners to userspace.
                   1052:  */
1.163     thorpej  1053: static int
                   1054: if_clone_list(struct if_clonereq *ifcr)
1.67      thorpej  1055: {
                   1056:        char outbuf[IFNAMSIZ], *dst;
                   1057:        struct if_clone *ifc;
                   1058:        int count, error = 0;
                   1059:
                   1060:        ifcr->ifcr_total = if_cloners_count;
                   1061:        if ((dst = ifcr->ifcr_buffer) == NULL) {
                   1062:                /* Just asking how many there are. */
1.185     dyoung   1063:                return 0;
1.67      thorpej  1064:        }
                   1065:
                   1066:        if (ifcr->ifcr_count < 0)
1.185     dyoung   1067:                return EINVAL;
1.67      thorpej  1068:
                   1069:        count = (if_cloners_count < ifcr->ifcr_count) ?
                   1070:            if_cloners_count : ifcr->ifcr_count;
                   1071:
                   1072:        for (ifc = LIST_FIRST(&if_cloners); ifc != NULL && count != 0;
                   1073:             ifc = LIST_NEXT(ifc, ifc_list), count--, dst += IFNAMSIZ) {
1.175     christos 1074:                (void)strncpy(outbuf, ifc->ifc_name, sizeof(outbuf));
                   1075:                if (outbuf[sizeof(outbuf) - 1] != '\0')
                   1076:                        return ENAMETOOLONG;
1.172     christos 1077:                error = copyout(outbuf, dst, sizeof(outbuf));
1.185     dyoung   1078:                if (error != 0)
1.67      thorpej  1079:                        break;
                   1080:        }
                   1081:
1.185     dyoung   1082:        return error;
1.63      thorpej  1083: }
                   1084:
1.207     dyoung   1085: void
                   1086: ifa_insert(struct ifnet *ifp, struct ifaddr *ifa)
                   1087: {
                   1088:        ifa->ifa_ifp = ifp;
1.208     dyoung   1089:        TAILQ_INSERT_TAIL(&ifp->if_addrlist, ifa, ifa_list);
1.207     dyoung   1090:        IFAREF(ifa);
                   1091: }
                   1092:
                   1093: void
                   1094: ifa_remove(struct ifnet *ifp, struct ifaddr *ifa)
                   1095: {
                   1096:        KASSERT(ifa->ifa_ifp == ifp);
                   1097:        TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list);
                   1098:        IFAFREE(ifa);
                   1099: }
                   1100:
1.194     dyoung   1101: static inline int
                   1102: equal(const struct sockaddr *sa1, const struct sockaddr *sa2)
                   1103: {
                   1104:        return sockaddr_cmp(sa1, sa2) == 0;
                   1105: }
                   1106:
1.63      thorpej  1107: /*
1.1       cgd      1108:  * Locate an interface based on a complete address.
                   1109:  */
                   1110: /*ARGSUSED*/
                   1111: struct ifaddr *
1.163     thorpej  1112: ifa_ifwithaddr(const struct sockaddr *addr)
1.1       cgd      1113: {
1.61      augustss 1114:        struct ifnet *ifp;
                   1115:        struct ifaddr *ifa;
1.1       cgd      1116:
1.185     dyoung   1117:        IFNET_FOREACH(ifp) {
1.53      thorpej  1118:                if (ifp->if_output == if_nulloutput)
1.1       cgd      1119:                        continue;
1.204     dyoung   1120:                IFADDR_FOREACH(ifa, ifp) {
1.53      thorpej  1121:                        if (ifa->ifa_addr->sa_family != addr->sa_family)
                   1122:                                continue;
                   1123:                        if (equal(addr, ifa->ifa_addr))
1.185     dyoung   1124:                                return ifa;
1.53      thorpej  1125:                        if ((ifp->if_flags & IFF_BROADCAST) &&
                   1126:                            ifa->ifa_broadaddr &&
                   1127:                            /* IP6 doesn't have broadcast */
                   1128:                            ifa->ifa_broadaddr->sa_len != 0 &&
                   1129:                            equal(ifa->ifa_broadaddr, addr))
1.185     dyoung   1130:                                return ifa;
1.53      thorpej  1131:                }
1.1       cgd      1132:        }
1.185     dyoung   1133:        return NULL;
1.1       cgd      1134: }
1.49      itojun   1135:
1.1       cgd      1136: /*
                   1137:  * Locate the point to point interface with a given destination address.
                   1138:  */
                   1139: /*ARGSUSED*/
                   1140: struct ifaddr *
1.163     thorpej  1141: ifa_ifwithdstaddr(const struct sockaddr *addr)
1.1       cgd      1142: {
1.61      augustss 1143:        struct ifnet *ifp;
                   1144:        struct ifaddr *ifa;
1.1       cgd      1145:
1.185     dyoung   1146:        IFNET_FOREACH(ifp) {
1.53      thorpej  1147:                if (ifp->if_output == if_nulloutput)
                   1148:                        continue;
1.185     dyoung   1149:                if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
                   1150:                        continue;
1.204     dyoung   1151:                IFADDR_FOREACH(ifa, ifp) {
1.185     dyoung   1152:                        if (ifa->ifa_addr->sa_family != addr->sa_family ||
                   1153:                            ifa->ifa_dstaddr == NULL)
                   1154:                                continue;
                   1155:                        if (equal(addr, ifa->ifa_dstaddr))
                   1156:                                return ifa;
1.53      thorpej  1157:                }
1.1       cgd      1158:        }
1.185     dyoung   1159:        return NULL;
1.1       cgd      1160: }
                   1161:
                   1162: /*
                   1163:  * Find an interface on a specific network.  If many, choice
1.15      mycroft  1164:  * is most specific found.
1.1       cgd      1165:  */
                   1166: struct ifaddr *
1.163     thorpej  1167: ifa_ifwithnet(const struct sockaddr *addr)
1.1       cgd      1168: {
1.61      augustss 1169:        struct ifnet *ifp;
                   1170:        struct ifaddr *ifa;
1.140     matt     1171:        const struct sockaddr_dl *sdl;
1.15      mycroft  1172:        struct ifaddr *ifa_maybe = 0;
1.1       cgd      1173:        u_int af = addr->sa_family;
1.171     pooka    1174:        const char *addr_data = addr->sa_data, *cplim;
1.1       cgd      1175:
                   1176:        if (af == AF_LINK) {
1.195     dyoung   1177:                sdl = satocsdl(addr);
1.137     itojun   1178:                if (sdl->sdl_index && sdl->sdl_index < if_indexlim &&
                   1179:                    ifindex2ifnet[sdl->sdl_index] &&
1.53      thorpej  1180:                    ifindex2ifnet[sdl->sdl_index]->if_output != if_nulloutput)
1.185     dyoung   1181:                        return ifnet_addrs[sdl->sdl_index];
1.1       cgd      1182:        }
1.51      bouyer   1183: #ifdef NETATALK
                   1184:        if (af == AF_APPLETALK) {
1.140     matt     1185:                const struct sockaddr_at *sat, *sat2;
1.158     christos 1186:                sat = (const struct sockaddr_at *)addr;
1.185     dyoung   1187:                IFNET_FOREACH(ifp) {
1.53      thorpej  1188:                        if (ifp->if_output == if_nulloutput)
                   1189:                                continue;
1.158     christos 1190:                        ifa = at_ifawithnet((const struct sockaddr_at *)addr, ifp);
1.62      bouyer   1191:                        if (ifa == NULL)
                   1192:                                continue;
                   1193:                        sat2 = (struct sockaddr_at *)ifa->ifa_addr;
                   1194:                        if (sat2->sat_addr.s_net == sat->sat_addr.s_net)
1.185     dyoung   1195:                                return ifa; /* exact match */
1.62      bouyer   1196:                        if (ifa_maybe == NULL) {
1.112     wiz      1197:                                /* else keep the if with the right range */
1.62      bouyer   1198:                                ifa_maybe = ifa;
                   1199:                        }
1.51      bouyer   1200:                }
1.185     dyoung   1201:                return ifa_maybe;
1.51      bouyer   1202:        }
                   1203: #endif
1.185     dyoung   1204:        IFNET_FOREACH(ifp) {
1.53      thorpej  1205:                if (ifp->if_output == if_nulloutput)
                   1206:                        continue;
1.204     dyoung   1207:                IFADDR_FOREACH(ifa, ifp) {
1.171     pooka    1208:                        const char *cp, *cp2, *cp3;
1.15      mycroft  1209:
                   1210:                        if (ifa->ifa_addr->sa_family != af ||
1.185     dyoung   1211:                            ifa->ifa_netmask == NULL)
1.53      thorpej  1212:  next:                         continue;
1.15      mycroft  1213:                        cp = addr_data;
                   1214:                        cp2 = ifa->ifa_addr->sa_data;
                   1215:                        cp3 = ifa->ifa_netmask->sa_data;
1.171     pooka    1216:                        cplim = (const char *)ifa->ifa_netmask +
1.53      thorpej  1217:                            ifa->ifa_netmask->sa_len;
                   1218:                        while (cp3 < cplim) {
                   1219:                                if ((*cp++ ^ *cp2++) & *cp3++) {
                   1220:                                        /* want to continue for() loop */
1.32      mrg      1221:                                        goto next;
1.53      thorpej  1222:                                }
                   1223:                        }
1.185     dyoung   1224:                        if (ifa_maybe == NULL ||
1.183     christos 1225:                            rn_refines((void *)ifa->ifa_netmask,
                   1226:                            (void *)ifa_maybe->ifa_netmask))
1.15      mycroft  1227:                                ifa_maybe = ifa;
                   1228:                }
1.53      thorpej  1229:        }
1.185     dyoung   1230:        return ifa_maybe;
1.26      mrg      1231: }
1.53      thorpej  1232:
1.26      mrg      1233: /*
                   1234:  * Find the interface of the addresss.
                   1235:  */
                   1236: struct ifaddr *
1.163     thorpej  1237: ifa_ifwithladdr(const struct sockaddr *addr)
1.26      mrg      1238: {
                   1239:        struct ifaddr *ia;
                   1240:
1.53      thorpej  1241:        if ((ia = ifa_ifwithaddr(addr)) || (ia = ifa_ifwithdstaddr(addr)) ||
                   1242:            (ia = ifa_ifwithnet(addr)))
1.185     dyoung   1243:                return ia;
                   1244:        return NULL;
1.1       cgd      1245: }
                   1246:
                   1247: /*
                   1248:  * Find an interface using a specific address family
                   1249:  */
                   1250: struct ifaddr *
1.163     thorpej  1251: ifa_ifwithaf(int af)
1.1       cgd      1252: {
1.61      augustss 1253:        struct ifnet *ifp;
                   1254:        struct ifaddr *ifa;
1.1       cgd      1255:
1.185     dyoung   1256:        IFNET_FOREACH(ifp) {
1.53      thorpej  1257:                if (ifp->if_output == if_nulloutput)
                   1258:                        continue;
1.204     dyoung   1259:                IFADDR_FOREACH(ifa, ifp) {
1.21      mycroft  1260:                        if (ifa->ifa_addr->sa_family == af)
1.178     dyoung   1261:                                return ifa;
1.53      thorpej  1262:                }
                   1263:        }
1.178     dyoung   1264:        return NULL;
1.1       cgd      1265: }
                   1266:
                   1267: /*
                   1268:  * Find an interface address specific to an interface best matching
                   1269:  * a given address.
                   1270:  */
                   1271: struct ifaddr *
1.163     thorpej  1272: ifaof_ifpforaddr(const struct sockaddr *addr, struct ifnet *ifp)
1.1       cgd      1273: {
1.61      augustss 1274:        struct ifaddr *ifa;
1.140     matt     1275:        const char *cp, *cp2, *cp3;
                   1276:        const char *cplim;
1.1       cgd      1277:        struct ifaddr *ifa_maybe = 0;
                   1278:        u_int af = addr->sa_family;
                   1279:
1.53      thorpej  1280:        if (ifp->if_output == if_nulloutput)
1.185     dyoung   1281:                return NULL;
1.53      thorpej  1282:
1.1       cgd      1283:        if (af >= AF_MAX)
1.185     dyoung   1284:                return NULL;
1.53      thorpej  1285:
1.204     dyoung   1286:        IFADDR_FOREACH(ifa, ifp) {
1.1       cgd      1287:                if (ifa->ifa_addr->sa_family != af)
                   1288:                        continue;
                   1289:                ifa_maybe = ifa;
1.185     dyoung   1290:                if (ifa->ifa_netmask == NULL) {
1.1       cgd      1291:                        if (equal(addr, ifa->ifa_addr) ||
1.53      thorpej  1292:                            (ifa->ifa_dstaddr &&
                   1293:                             equal(addr, ifa->ifa_dstaddr)))
1.185     dyoung   1294:                                return ifa;
1.1       cgd      1295:                        continue;
                   1296:                }
                   1297:                cp = addr->sa_data;
                   1298:                cp2 = ifa->ifa_addr->sa_data;
                   1299:                cp3 = ifa->ifa_netmask->sa_data;
                   1300:                cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
1.53      thorpej  1301:                for (; cp3 < cplim; cp3++) {
1.1       cgd      1302:                        if ((*cp++ ^ *cp2++) & *cp3)
                   1303:                                break;
1.53      thorpej  1304:                }
1.1       cgd      1305:                if (cp3 == cplim)
1.185     dyoung   1306:                        return ifa;
1.1       cgd      1307:        }
1.185     dyoung   1308:        return ifa_maybe;
1.1       cgd      1309: }
1.9       mycroft  1310:
1.1       cgd      1311: /*
                   1312:  * Default action when installing a route with a Link Level gateway.
                   1313:  * Lookup an appropriate real ifa to point to.
                   1314:  * This should be moved to /sys/net/link.c eventually.
                   1315:  */
1.15      mycroft  1316: void
1.228     dyoung   1317: link_rtrequest(int cmd, struct rtentry *rt, const struct rt_addrinfo *info)
1.1       cgd      1318: {
1.61      augustss 1319:        struct ifaddr *ifa;
1.194     dyoung   1320:        const struct sockaddr *dst;
1.15      mycroft  1321:        struct ifnet *ifp;
1.1       cgd      1322:
1.225     dyoung   1323:        if (cmd != RTM_ADD || (ifa = rt->rt_ifa) == NULL ||
                   1324:            (ifp = ifa->ifa_ifp) == NULL || (dst = rt_getkey(rt)) == NULL)
1.1       cgd      1325:                return;
1.24      christos 1326:        if ((ifa = ifaof_ifpforaddr(dst, ifp)) != NULL) {
1.176     dyoung   1327:                rt_replace_ifa(rt, ifa);
1.1       cgd      1328:                if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)
1.82      itojun   1329:                        ifa->ifa_rtrequest(cmd, rt, info);
1.1       cgd      1330:        }
                   1331: }
                   1332:
                   1333: /*
1.159     dyoung   1334:  * Handle a change in the interface link state.
1.264     roy      1335:  * XXX: We should listen to the routing socket in-kernel rather
                   1336:  * than calling in6_if_link_* functions directly from here.
1.159     dyoung   1337:  */
                   1338: void
                   1339: if_link_state_change(struct ifnet *ifp, int link_state)
                   1340: {
1.268     martin   1341:        int s;
1.269     mrg      1342: #if defined(DEBUG) || defined(INET6)
1.268     martin   1343:        int old_link_state;
                   1344: #endif
1.263     roy      1345:
1.264     roy      1346:        s = splnet();
                   1347:        if (ifp->if_link_state == link_state) {
                   1348:                splx(s);
1.185     dyoung   1349:                return;
1.264     roy      1350:        }
1.263     roy      1351:
1.269     mrg      1352: #if defined(DEBUG) || defined(INET6)
1.263     roy      1353:        old_link_state = ifp->if_link_state;
1.268     martin   1354: #endif
1.185     dyoung   1355:        ifp->if_link_state = link_state;
1.263     roy      1356: #ifdef DEBUG
                   1357:        log(LOG_DEBUG, "%s: link state %s (was %s)\n", ifp->if_xname,
                   1358:                link_state == LINK_STATE_UP ? "UP" :
                   1359:                link_state == LINK_STATE_DOWN ? "DOWN" :
                   1360:                "UNKNOWN",
1.264     roy      1361:                 old_link_state == LINK_STATE_UP ? "UP" :
1.263     roy      1362:                old_link_state == LINK_STATE_DOWN ? "DOWN" :
                   1363:                "UNKNOWN");
                   1364: #endif
                   1365:
                   1366: #ifdef INET6
                   1367:        /*
                   1368:         * When going from UNKNOWN to UP, we need to mark existing
                   1369:         * IPv6 addresses as tentative and restart DAD as we may have
                   1370:         * erroneously not found a duplicate.
                   1371:         *
                   1372:         * This needs to happen before rt_ifmsg to avoid a race where
                   1373:         * listeners would have an address and expect it to work right
                   1374:         * away.
                   1375:         */
1.270     pooka    1376:        if (in6_present && link_state == LINK_STATE_UP &&
1.263     roy      1377:            old_link_state == LINK_STATE_UNKNOWN)
1.264     roy      1378:                in6_if_link_down(ifp);
1.263     roy      1379: #endif
                   1380:
1.159     dyoung   1381:        /* Notify that the link state has changed. */
1.185     dyoung   1382:        rt_ifmsg(ifp);
1.263     roy      1383:
1.166     liamjfoy 1384: #if NCARP > 0
1.185     dyoung   1385:        if (ifp->if_carp)
                   1386:                carp_carpdev_state(ifp);
1.166     liamjfoy 1387: #endif
1.263     roy      1388:
                   1389: #ifdef INET6
1.270     pooka    1390:        if (in6_present) {
                   1391:                if (link_state == LINK_STATE_DOWN)
                   1392:                        in6_if_link_down(ifp);
                   1393:                else if (link_state == LINK_STATE_UP)
                   1394:                        in6_if_link_up(ifp);
                   1395:        }
1.263     roy      1396: #endif
1.264     roy      1397:
                   1398:        splx(s);
1.159     dyoung   1399: }
                   1400:
                   1401: /*
1.1       cgd      1402:  * Mark an interface down and notify protocols of
                   1403:  * the transition.
1.23      mycroft  1404:  * NOTE: must be called at splsoftnet or equivalent.
1.1       cgd      1405:  */
1.15      mycroft  1406: void
1.163     thorpej  1407: if_down(struct ifnet *ifp)
1.1       cgd      1408: {
1.61      augustss 1409:        struct ifaddr *ifa;
1.1       cgd      1410:
                   1411:        ifp->if_flags &= ~IFF_UP;
1.232     christos 1412:        nanotime(&ifp->if_lastchange);
1.204     dyoung   1413:        IFADDR_FOREACH(ifa, ifp)
1.1       cgd      1414:                pfctlinput(PRC_IFDOWN, ifa->ifa_addr);
1.78      thorpej  1415:        IFQ_PURGE(&ifp->if_snd);
1.166     liamjfoy 1416: #if NCARP > 0
                   1417:        if (ifp->if_carp)
                   1418:                carp_carpdev_state(ifp);
                   1419: #endif
1.15      mycroft  1420:        rt_ifmsg(ifp);
1.263     roy      1421: #ifdef INET6
1.270     pooka    1422:        if (in6_present)
                   1423:                in6_if_down(ifp);
1.263     roy      1424: #endif
1.15      mycroft  1425: }
                   1426:
                   1427: /*
                   1428:  * Mark an interface up and notify protocols of
                   1429:  * the transition.
1.23      mycroft  1430:  * NOTE: must be called at splsoftnet or equivalent.
1.15      mycroft  1431:  */
                   1432: void
1.163     thorpej  1433: if_up(struct ifnet *ifp)
1.15      mycroft  1434: {
1.24      christos 1435: #ifdef notyet
1.61      augustss 1436:        struct ifaddr *ifa;
1.24      christos 1437: #endif
1.15      mycroft  1438:
                   1439:        ifp->if_flags |= IFF_UP;
1.232     christos 1440:        nanotime(&ifp->if_lastchange);
1.15      mycroft  1441: #ifdef notyet
                   1442:        /* this has no effect on IP, and will kill all ISO connections XXX */
1.204     dyoung   1443:        IFADDR_FOREACH(ifa, ifp)
1.15      mycroft  1444:                pfctlinput(PRC_IFUP, ifa->ifa_addr);
                   1445: #endif
1.166     liamjfoy 1446: #if NCARP > 0
                   1447:        if (ifp->if_carp)
                   1448:                carp_carpdev_state(ifp);
                   1449: #endif
1.15      mycroft  1450:        rt_ifmsg(ifp);
1.49      itojun   1451: #ifdef INET6
1.270     pooka    1452:        if (in6_present)
                   1453:                in6_if_up(ifp);
1.49      itojun   1454: #endif
1.1       cgd      1455: }
                   1456:
                   1457: /*
                   1458:  * Handle interface watchdog timer routines.  Called
                   1459:  * from softclock, we decrement timers (if set) and
                   1460:  * call the appropriate interface routine on expiration.
                   1461:  */
1.4       andrew   1462: void
1.177     christos 1463: if_slowtimo(void *arg)
1.1       cgd      1464: {
1.61      augustss 1465:        struct ifnet *ifp;
1.88      thorpej  1466:        int s = splnet();
1.1       cgd      1467:
1.185     dyoung   1468:        IFNET_FOREACH(ifp) {
1.1       cgd      1469:                if (ifp->if_timer == 0 || --ifp->if_timer)
                   1470:                        continue;
1.185     dyoung   1471:                if (ifp->if_watchdog != NULL)
1.34      thorpej  1472:                        (*ifp->if_watchdog)(ifp);
1.1       cgd      1473:        }
                   1474:        splx(s);
1.185     dyoung   1475:        callout_reset(&if_slowtimo_ch, hz / IFNET_SLOWHZ, if_slowtimo, NULL);
1.65      thorpej  1476: }
                   1477:
                   1478: /*
                   1479:  * Set/clear promiscuous mode on interface ifp based on the truth value
                   1480:  * of pswitch.  The calls are reference counted so that only the first
                   1481:  * "on" request actually has an effect, as does the final "off" request.
                   1482:  * Results are undefined if the "off" and "on" requests are not matched.
                   1483:  */
                   1484: int
1.163     thorpej  1485: ifpromisc(struct ifnet *ifp, int pswitch)
1.65      thorpej  1486: {
                   1487:        int pcount, ret;
1.259     dyoung   1488:        short nflags;
1.65      thorpej  1489:
                   1490:        pcount = ifp->if_pcount;
                   1491:        if (pswitch) {
                   1492:                /*
1.71      thorpej  1493:                 * Allow the device to be "placed" into promiscuous
                   1494:                 * mode even if it is not configured up.  It will
1.242     mbalmer  1495:                 * consult IFF_PROMISC when it is brought up.
1.65      thorpej  1496:                 */
1.68      pk       1497:                if (ifp->if_pcount++ != 0)
1.185     dyoung   1498:                        return 0;
1.252     dyoung   1499:                nflags = ifp->if_flags | IFF_PROMISC;
1.65      thorpej  1500:        } else {
                   1501:                if (--ifp->if_pcount > 0)
1.185     dyoung   1502:                        return 0;
1.252     dyoung   1503:                nflags = ifp->if_flags & ~IFF_PROMISC;
1.65      thorpej  1504:        }
1.252     dyoung   1505:        ret = if_flags_set(ifp, nflags);
1.65      thorpej  1506:        /* Restore interface state if not successful. */
                   1507:        if (ret != 0) {
                   1508:                ifp->if_pcount = pcount;
                   1509:        }
1.185     dyoung   1510:        return ret;
1.1       cgd      1511: }
                   1512:
                   1513: /*
                   1514:  * Map interface name to
                   1515:  * interface structure pointer.
                   1516:  */
                   1517: struct ifnet *
1.163     thorpej  1518: ifunit(const char *name)
1.1       cgd      1519: {
1.61      augustss 1520:        struct ifnet *ifp;
1.105     matt     1521:        const char *cp = name;
                   1522:        u_int unit = 0;
                   1523:        u_int i;
                   1524:
                   1525:        /*
                   1526:         * If the entire name is a number, treat it as an ifindex.
                   1527:         */
                   1528:        for (i = 0; i < IFNAMSIZ && *cp >= '0' && *cp <= '9'; i++, cp++) {
                   1529:                unit = unit * 10 + (*cp - '0');
                   1530:        }
                   1531:
                   1532:        /*
                   1533:         * If the number took all of the name, then it's a valid ifindex.
                   1534:         */
                   1535:        if (i == IFNAMSIZ || (cp != name && *cp == '\0')) {
1.137     itojun   1536:                if (unit >= if_indexlim)
1.185     dyoung   1537:                        return NULL;
1.105     matt     1538:                ifp = ifindex2ifnet[unit];
                   1539:                if (ifp == NULL || ifp->if_output == if_nulloutput)
1.185     dyoung   1540:                        return NULL;
                   1541:                return ifp;
1.105     matt     1542:        }
1.34      thorpej  1543:
1.185     dyoung   1544:        IFNET_FOREACH(ifp) {
1.53      thorpej  1545:                if (ifp->if_output == if_nulloutput)
                   1546:                        continue;
                   1547:                if (strcmp(ifp->if_xname, name) == 0)
1.185     dyoung   1548:                        return ifp;
1.53      thorpej  1549:        }
1.185     dyoung   1550:        return NULL;
1.1       cgd      1551: }
1.49      itojun   1552:
1.250     rmind    1553: ifnet_t *
                   1554: if_byindex(u_int idx)
                   1555: {
                   1556:        return (idx < if_indexlim) ? ifindex2ifnet[idx] : NULL;
                   1557: }
                   1558:
1.211     dyoung   1559: /* common */
1.215     dyoung   1560: int
                   1561: ifioctl_common(struct ifnet *ifp, u_long cmd, void *data)
1.211     dyoung   1562: {
1.224     dyoung   1563:        int s;
1.215     dyoung   1564:        struct ifreq *ifr;
                   1565:        struct ifcapreq *ifcr;
                   1566:        struct ifdatareq *ifdr;
1.211     dyoung   1567:
                   1568:        switch (cmd) {
                   1569:        case SIOCSIFCAP:
1.215     dyoung   1570:                ifcr = data;
1.211     dyoung   1571:                if ((ifcr->ifcr_capenable & ~ifp->if_capabilities) != 0)
                   1572:                        return EINVAL;
                   1573:
1.213     dyoung   1574:                if (ifcr->ifcr_capenable == ifp->if_capenable)
                   1575:                        return 0;
1.211     dyoung   1576:
1.213     dyoung   1577:                ifp->if_capenable = ifcr->ifcr_capenable;
1.211     dyoung   1578:
1.213     dyoung   1579:                /* Pre-compute the checksum flags mask. */
                   1580:                ifp->if_csum_flags_tx = 0;
                   1581:                ifp->if_csum_flags_rx = 0;
                   1582:                if (ifp->if_capenable & IFCAP_CSUM_IPv4_Tx) {
                   1583:                        ifp->if_csum_flags_tx |= M_CSUM_IPv4;
                   1584:                }
                   1585:                if (ifp->if_capenable & IFCAP_CSUM_IPv4_Rx) {
                   1586:                        ifp->if_csum_flags_rx |= M_CSUM_IPv4;
                   1587:                }
1.211     dyoung   1588:
1.213     dyoung   1589:                if (ifp->if_capenable & IFCAP_CSUM_TCPv4_Tx) {
                   1590:                        ifp->if_csum_flags_tx |= M_CSUM_TCPv4;
                   1591:                }
                   1592:                if (ifp->if_capenable & IFCAP_CSUM_TCPv4_Rx) {
                   1593:                        ifp->if_csum_flags_rx |= M_CSUM_TCPv4;
                   1594:                }
1.211     dyoung   1595:
1.213     dyoung   1596:                if (ifp->if_capenable & IFCAP_CSUM_UDPv4_Tx) {
                   1597:                        ifp->if_csum_flags_tx |= M_CSUM_UDPv4;
                   1598:                }
                   1599:                if (ifp->if_capenable & IFCAP_CSUM_UDPv4_Rx) {
                   1600:                        ifp->if_csum_flags_rx |= M_CSUM_UDPv4;
                   1601:                }
1.211     dyoung   1602:
1.213     dyoung   1603:                if (ifp->if_capenable & IFCAP_CSUM_TCPv6_Tx) {
                   1604:                        ifp->if_csum_flags_tx |= M_CSUM_TCPv6;
                   1605:                }
                   1606:                if (ifp->if_capenable & IFCAP_CSUM_TCPv6_Rx) {
                   1607:                        ifp->if_csum_flags_rx |= M_CSUM_TCPv6;
                   1608:                }
1.211     dyoung   1609:
1.213     dyoung   1610:                if (ifp->if_capenable & IFCAP_CSUM_UDPv6_Tx) {
                   1611:                        ifp->if_csum_flags_tx |= M_CSUM_UDPv6;
1.211     dyoung   1612:                }
1.213     dyoung   1613:                if (ifp->if_capenable & IFCAP_CSUM_UDPv6_Rx) {
                   1614:                        ifp->if_csum_flags_rx |= M_CSUM_UDPv6;
                   1615:                }
1.215     dyoung   1616:                if (ifp->if_flags & IFF_UP)
                   1617:                        return ENETRESET;
                   1618:                return 0;
1.211     dyoung   1619:        case SIOCSIFFLAGS:
1.215     dyoung   1620:                ifr = data;
1.211     dyoung   1621:                if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) {
                   1622:                        s = splnet();
                   1623:                        if_down(ifp);
                   1624:                        splx(s);
                   1625:                }
                   1626:                if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) {
                   1627:                        s = splnet();
                   1628:                        if_up(ifp);
                   1629:                        splx(s);
                   1630:                }
                   1631:                ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
                   1632:                        (ifr->ifr_flags &~ IFF_CANTCHANGE);
                   1633:                break;
                   1634:        case SIOCGIFFLAGS:
1.215     dyoung   1635:                ifr = data;
1.211     dyoung   1636:                ifr->ifr_flags = ifp->if_flags;
                   1637:                break;
                   1638:
                   1639:        case SIOCGIFMETRIC:
1.215     dyoung   1640:                ifr = data;
1.211     dyoung   1641:                ifr->ifr_metric = ifp->if_metric;
                   1642:                break;
                   1643:
                   1644:        case SIOCGIFMTU:
1.215     dyoung   1645:                ifr = data;
1.211     dyoung   1646:                ifr->ifr_mtu = ifp->if_mtu;
                   1647:                break;
                   1648:
                   1649:        case SIOCGIFDLT:
1.215     dyoung   1650:                ifr = data;
1.211     dyoung   1651:                ifr->ifr_dlt = ifp->if_dlt;
                   1652:                break;
                   1653:
                   1654:        case SIOCGIFCAP:
1.215     dyoung   1655:                ifcr = data;
1.211     dyoung   1656:                ifcr->ifcr_capabilities = ifp->if_capabilities;
                   1657:                ifcr->ifcr_capenable = ifp->if_capenable;
                   1658:                break;
                   1659:
                   1660:        case SIOCSIFMETRIC:
1.215     dyoung   1661:                ifr = data;
1.211     dyoung   1662:                ifp->if_metric = ifr->ifr_metric;
                   1663:                break;
                   1664:
                   1665:        case SIOCGIFDATA:
1.215     dyoung   1666:                ifdr = data;
1.211     dyoung   1667:                ifdr->ifdr_data = ifp->if_data;
                   1668:                break;
                   1669:
1.266     christos 1670:        case SIOCGIFINDEX:
                   1671:                ifr = data;
                   1672:                ifr->ifr_index = ifp->if_index;
                   1673:                break;
                   1674:
1.211     dyoung   1675:        case SIOCZIFDATA:
1.215     dyoung   1676:                ifdr = data;
1.211     dyoung   1677:                ifdr->ifdr_data = ifp->if_data;
                   1678:                /*
                   1679:                 * Assumes that the volatile counters that can be
                   1680:                 * zero'ed are at the end of if_data.
                   1681:                 */
                   1682:                memset(&ifp->if_data.ifi_ipackets, 0, sizeof(ifp->if_data) -
                   1683:                    offsetof(struct if_data, ifi_ipackets));
1.261     msaitoh  1684:                /*
                   1685:                 * The memset() clears to the bottm of if_data. In the area,
                   1686:                 * if_lastchange is included. Please be careful if new entry
                   1687:                 * will be added into if_data or rewite this.
                   1688:                 *
                   1689:                 * And also, update if_lastchnage.
                   1690:                 */
                   1691:                getnanotime(&ifp->if_lastchange);
1.211     dyoung   1692:                break;
1.215     dyoung   1693:        case SIOCSIFMTU:
                   1694:                ifr = data;
                   1695:                if (ifp->if_mtu == ifr->ifr_mtu)
                   1696:                        break;
                   1697:                ifp->if_mtu = ifr->ifr_mtu;
                   1698:                /*
                   1699:                 * If the link MTU changed, do network layer specific procedure.
                   1700:                 */
                   1701: #ifdef INET6
1.271     pooka    1702:                if (in6_present)
                   1703:                        nd6_setmtu(ifp);
1.215     dyoung   1704: #endif
                   1705:                return ENETRESET;
1.211     dyoung   1706:        default:
1.223     dyoung   1707:                return ENOTTY;
1.211     dyoung   1708:        }
                   1709:        return 0;
                   1710: }
                   1711:
1.235     dyoung   1712: int
                   1713: ifaddrpref_ioctl(struct socket *so, u_long cmd, void *data, struct ifnet *ifp,
                   1714:     lwp_t *l)
                   1715: {
                   1716:        struct if_addrprefreq *ifap = (struct if_addrprefreq *)data;
                   1717:        struct ifaddr *ifa;
                   1718:        const struct sockaddr *any, *sa;
                   1719:        union {
                   1720:                struct sockaddr sa;
                   1721:                struct sockaddr_storage ss;
1.236     jakllsch 1722:        } u, v;
1.235     dyoung   1723:
                   1724:        switch (cmd) {
                   1725:        case SIOCSIFADDRPREF:
                   1726:                if (kauth_authorize_network(l->l_cred, KAUTH_NETWORK_INTERFACE,
                   1727:                    KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd,
                   1728:                    NULL) != 0)
                   1729:                        return EPERM;
                   1730:        case SIOCGIFADDRPREF:
                   1731:                break;
                   1732:        default:
                   1733:                return EOPNOTSUPP;
                   1734:        }
                   1735:
                   1736:        /* sanity checks */
                   1737:        if (data == NULL || ifp == NULL) {
                   1738:                panic("invalid argument to %s", __func__);
                   1739:                /*NOTREACHED*/
                   1740:        }
                   1741:
                   1742:        /* address must be specified on ADD and DELETE */
                   1743:        sa = sstocsa(&ifap->ifap_addr);
                   1744:        if (sa->sa_family != sofamily(so))
                   1745:                return EINVAL;
                   1746:        if ((any = sockaddr_any(sa)) == NULL || sa->sa_len != any->sa_len)
                   1747:                return EINVAL;
                   1748:
1.236     jakllsch 1749:        sockaddr_externalize(&v.sa, sizeof(v.ss), sa);
                   1750:
1.235     dyoung   1751:        IFADDR_FOREACH(ifa, ifp) {
                   1752:                if (ifa->ifa_addr->sa_family != sa->sa_family)
                   1753:                        continue;
                   1754:                sockaddr_externalize(&u.sa, sizeof(u.ss), ifa->ifa_addr);
1.236     jakllsch 1755:                if (sockaddr_cmp(&u.sa, &v.sa) == 0)
1.235     dyoung   1756:                        break;
                   1757:        }
                   1758:        if (ifa == NULL)
                   1759:                return EADDRNOTAVAIL;
                   1760:
                   1761:        switch (cmd) {
                   1762:        case SIOCSIFADDRPREF:
                   1763:                ifa->ifa_preference = ifap->ifap_preference;
                   1764:                return 0;
                   1765:        case SIOCGIFADDRPREF:
                   1766:                /* fill in the if_laddrreq structure */
                   1767:                (void)sockaddr_copy(sstosa(&ifap->ifap_addr),
                   1768:                    sizeof(ifap->ifap_addr), ifa->ifa_addr);
                   1769:                ifap->ifap_preference = ifa->ifa_preference;
                   1770:                return 0;
                   1771:        default:
                   1772:                return EOPNOTSUPP;
                   1773:        }
                   1774: }
                   1775:
1.253     dyoung   1776: static void
1.254     dyoung   1777: ifnet_lock_enter(struct ifnet_lock *il)
1.253     dyoung   1778: {
1.254     dyoung   1779:        uint64_t *nenter;
                   1780:
1.255     dyoung   1781:        /* Before trying to acquire the mutex, increase the count of threads
                   1782:         * who have entered or who wait to enter the critical section.
                   1783:         * Avoid one costly locked memory transaction by keeping a count for
                   1784:         * each CPU.
                   1785:         */
1.254     dyoung   1786:        nenter = percpu_getref(il->il_nenter);
1.253     dyoung   1787:        (*nenter)++;
1.254     dyoung   1788:        percpu_putref(il->il_nenter);
                   1789:        mutex_enter(&il->il_lock);
1.253     dyoung   1790: }
                   1791:
                   1792: static void
1.254     dyoung   1793: ifnet_lock_exit(struct ifnet_lock *il)
1.253     dyoung   1794: {
1.255     dyoung   1795:        /* Increase the count of threads who have exited the critical
                   1796:         * section.  Increase while we still hold the lock.
                   1797:         */
1.254     dyoung   1798:        il->il_nexit++;
                   1799:        mutex_exit(&il->il_lock);
1.253     dyoung   1800: }
                   1801:
1.1       cgd      1802: /*
                   1803:  * Interface ioctls.
                   1804:  */
1.273     pooka    1805: static int
                   1806: doifioctl(struct socket *so, u_long cmd, void *data, struct lwp *l)
1.1       cgd      1807: {
1.61      augustss 1808:        struct ifnet *ifp;
                   1809:        struct ifreq *ifr;
1.217     martin   1810:        int error = 0;
1.191     christos 1811: #if defined(COMPAT_OSOCK) || defined(COMPAT_OIFREQ)
                   1812:        u_long ocmd = cmd;
                   1813: #endif
1.49      itojun   1814:        short oif_flags;
1.186     christos 1815: #ifdef COMPAT_OIFREQ
                   1816:        struct ifreq ifrb;
1.187     xtraeme  1817:        struct oifreq *oifr = NULL;
1.186     christos 1818: #endif
1.1       cgd      1819:
                   1820:        switch (cmd) {
1.186     christos 1821: #ifdef COMPAT_OIFREQ
                   1822:        case OSIOCGIFCONF:
                   1823:        case OOSIOCGIFCONF:
                   1824:                return compat_ifconf(cmd, data);
                   1825: #endif
1.232     christos 1826: #ifdef COMPAT_OIFDATA
                   1827:        case OSIOCGIFDATA:
                   1828:        case OSIOCZIFDATA:
                   1829:                return compat_ifdatareq(l, cmd, data);
                   1830: #endif
1.1       cgd      1831:        case SIOCGIFCONF:
1.185     dyoung   1832:                return ifconf(cmd, data);
1.231     dyoung   1833:        case SIOCINITIFADDR:
                   1834:                return EPERM;
1.1       cgd      1835:        }
1.191     christos 1836:
1.186     christos 1837: #ifdef COMPAT_OIFREQ
1.196     skd      1838:        cmd = compat_cvtcmd(cmd);
1.186     christos 1839:        if (cmd != ocmd) {
                   1840:                oifr = data;
                   1841:                data = ifr = &ifrb;
                   1842:                ifreqo2n(oifr, ifr);
                   1843:        } else
                   1844: #endif
                   1845:                ifr = data;
1.63      thorpej  1846:
1.174     elad     1847:        ifp = ifunit(ifr->ifr_name);
                   1848:
1.63      thorpej  1849:        switch (cmd) {
                   1850:        case SIOCIFCREATE:
                   1851:        case SIOCIFDESTROY:
1.185     dyoung   1852:                if (l != NULL) {
1.174     elad     1853:                        error = kauth_authorize_network(l->l_cred,
                   1854:                            KAUTH_NETWORK_INTERFACE,
                   1855:                            KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp,
                   1856:                            (void *)cmd, NULL);
1.185     dyoung   1857:                        if (error != 0)
1.151     yamt     1858:                                return error;
                   1859:                }
1.185     dyoung   1860:                return (cmd == SIOCIFCREATE) ?
1.64      thorpej  1861:                        if_clone_create(ifr->ifr_name) :
1.185     dyoung   1862:                        if_clone_destroy(ifr->ifr_name);
1.67      thorpej  1863:
                   1864:        case SIOCIFGCLONERS:
1.185     dyoung   1865:                return if_clone_list((struct if_clonereq *)data);
1.63      thorpej  1866:        }
                   1867:
1.185     dyoung   1868:        if (ifp == NULL)
                   1869:                return ENXIO;
1.151     yamt     1870:
                   1871:        switch (cmd) {
1.233     christos 1872:        case SIOCALIFADDR:
                   1873:        case SIOCDLIFADDR:
                   1874:        case SIOCSIFADDRPREF:
1.151     yamt     1875:        case SIOCSIFFLAGS:
                   1876:        case SIOCSIFCAP:
                   1877:        case SIOCSIFMETRIC:
                   1878:        case SIOCZIFDATA:
                   1879:        case SIOCSIFMTU:
                   1880:        case SIOCSIFPHYADDR:
                   1881:        case SIOCDIFPHYADDR:
                   1882: #ifdef INET6
                   1883:        case SIOCSIFPHYADDR_IN6:
                   1884: #endif
                   1885:        case SIOCSLIFPHYADDR:
                   1886:        case SIOCADDMULTI:
                   1887:        case SIOCDELMULTI:
                   1888:        case SIOCSIFMEDIA:
1.154     perry    1889:        case SIOCSDRVSPEC:
1.196     skd      1890:        case SIOCG80211:
                   1891:        case SIOCS80211:
1.151     yamt     1892:        case SIOCS80211NWID:
                   1893:        case SIOCS80211NWKEY:
                   1894:        case SIOCS80211POWER:
                   1895:        case SIOCS80211BSSID:
                   1896:        case SIOCS80211CHANNEL:
1.249     pooka    1897:        case SIOCSLINKSTR:
1.185     dyoung   1898:                if (l != NULL) {
1.174     elad     1899:                        error = kauth_authorize_network(l->l_cred,
                   1900:                            KAUTH_NETWORK_INTERFACE,
                   1901:                            KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp,
                   1902:                            (void *)cmd, NULL);
1.185     dyoung   1903:                        if (error != 0)
1.151     yamt     1904:                                return error;
                   1905:                }
                   1906:        }
                   1907:
1.49      itojun   1908:        oif_flags = ifp->if_flags;
1.1       cgd      1909:
1.254     dyoung   1910:        ifnet_lock_enter(ifp->if_ioctl_lock);
1.231     dyoung   1911:        error = (*ifp->if_ioctl)(ifp, cmd, data);
                   1912:        if (error != ENOTTY)
                   1913:                ;
                   1914:        else if (so->so_proto == NULL)
1.252     dyoung   1915:                error = EOPNOTSUPP;
1.231     dyoung   1916:        else {
1.161     christos 1917: #ifdef COMPAT_OSOCK
1.186     christos 1918:                error = compat_ifioctl(so, ocmd, cmd, data, l);
1.161     christos 1919: #else
1.275     rmind    1920:                error = (*so->so_proto->pr_usrreqs->pr_generic)(so,
                   1921:                    PRU_CONTROL, (struct mbuf *)cmd, (struct mbuf *)data,
1.220     martin   1922:                    (struct mbuf *)ifp, l);
1.1       cgd      1923: #endif
1.49      itojun   1924:        }
1.1       cgd      1925:
1.49      itojun   1926:        if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0) {
                   1927: #ifdef INET6
1.270     pooka    1928:                if (in6_present && (ifp->if_flags & IFF_UP) != 0) {
1.217     martin   1929:                        int s = splnet();
1.49      itojun   1930:                        in6_if_up(ifp);
                   1931:                        splx(s);
                   1932:                }
1.1       cgd      1933: #endif
                   1934:        }
1.186     christos 1935: #ifdef COMPAT_OIFREQ
                   1936:        if (cmd != ocmd)
1.246     christos 1937:                ifreqn2o(oifr, ifr);
1.186     christos 1938: #endif
1.49      itojun   1939:
1.254     dyoung   1940:        ifnet_lock_exit(ifp->if_ioctl_lock);
1.185     dyoung   1941:        return error;
1.1       cgd      1942: }
                   1943:
1.255     dyoung   1944: /* This callback adds to the sum in `arg' the number of
                   1945:  * threads on `ci' who have entered or who wait to enter the
                   1946:  * critical section.
                   1947:  */
1.252     dyoung   1948: static void
1.254     dyoung   1949: ifnet_lock_sum(void *p, void *arg, struct cpu_info *ci)
1.252     dyoung   1950: {
                   1951:        uint64_t *sum = arg, *nenter = p;
                   1952:
                   1953:        *sum += *nenter;
                   1954: }
                   1955:
1.255     dyoung   1956: /* Return the number of threads who have entered or who wait
                   1957:  * to enter the critical section on all CPUs.
                   1958:  */
1.252     dyoung   1959: static uint64_t
1.254     dyoung   1960: ifnet_lock_entrances(struct ifnet_lock *il)
1.252     dyoung   1961: {
                   1962:        uint64_t sum = 0;
                   1963:
1.254     dyoung   1964:        percpu_foreach(il->il_nenter, ifnet_lock_sum, &sum);
1.252     dyoung   1965:
                   1966:        return sum;
                   1967: }
                   1968:
                   1969: static int
                   1970: ifioctl_attach(struct ifnet *ifp)
                   1971: {
1.254     dyoung   1972:        struct ifnet_lock *il;
                   1973:
1.255     dyoung   1974:        /* If the driver has not supplied its own if_ioctl, then
                   1975:         * supply the default.
                   1976:         */
1.252     dyoung   1977:        if (ifp->if_ioctl == NULL)
                   1978:                ifp->if_ioctl = ifioctl_common;
                   1979:
1.255     dyoung   1980:        /* Create an ifnet_lock for synchronizing ifioctls. */
1.254     dyoung   1981:        if ((il = kmem_zalloc(sizeof(*il), KM_SLEEP)) == NULL)
1.252     dyoung   1982:                return ENOMEM;
                   1983:
1.254     dyoung   1984:        il->il_nenter = percpu_alloc(sizeof(uint64_t));
                   1985:        if (il->il_nenter == NULL) {
                   1986:                kmem_free(il, sizeof(*il));
                   1987:                return ENOMEM;
                   1988:        }
                   1989:
                   1990:        mutex_init(&il->il_lock, MUTEX_DEFAULT, IPL_NONE);
                   1991:        cv_init(&il->il_emptied, ifp->if_xname);
                   1992:
                   1993:        ifp->if_ioctl_lock = il;
1.252     dyoung   1994:
                   1995:        return 0;
                   1996: }
                   1997:
1.255     dyoung   1998: /*
                   1999:  * This must not be called until after `ifp' has been withdrawn from the
                   2000:  * ifnet tables so that ifioctl() cannot get a handle on it by calling
                   2001:  * ifunit().
                   2002:  */
1.252     dyoung   2003: static void
                   2004: ifioctl_detach(struct ifnet *ifp)
                   2005: {
1.254     dyoung   2006:        struct ifnet_lock *il;
                   2007:
                   2008:        il = ifp->if_ioctl_lock;
                   2009:        mutex_enter(&il->il_lock);
1.255     dyoung   2010:        /* Install if_nullioctl to make sure that any thread that
                   2011:         * subsequently enters the critical section will quit it
                   2012:         * immediately and signal the condition variable that we
                   2013:         * wait on, below.
                   2014:         */
1.252     dyoung   2015:        ifp->if_ioctl = if_nullioctl;
1.255     dyoung   2016:        /* Sleep while threads are still in the critical section or
                   2017:         * wait to enter it.
                   2018:         */
1.254     dyoung   2019:        while (ifnet_lock_entrances(il) != il->il_nexit)
                   2020:                cv_wait(&il->il_emptied, &il->il_lock);
1.255     dyoung   2021:        /* At this point, we are the only thread still in the critical
                   2022:         * section, and no new thread can get a handle on the ifioctl
                   2023:         * lock, so it is safe to free its memory.
                   2024:         */
1.254     dyoung   2025:        mutex_exit(&il->il_lock);
                   2026:        ifp->if_ioctl_lock = NULL;
1.255     dyoung   2027:        percpu_free(il->il_nenter, sizeof(uint64_t));
                   2028:        il->il_nenter = NULL;
1.258     jakllsch 2029:        cv_destroy(&il->il_emptied);
1.257     dyoung   2030:        mutex_destroy(&il->il_lock);
1.254     dyoung   2031:        kmem_free(il, sizeof(*il));
1.252     dyoung   2032: }
                   2033:
1.1       cgd      2034: /*
                   2035:  * Return interface configuration
                   2036:  * of system.  List may be used
                   2037:  * in later ioctl's (above) to get
                   2038:  * other information.
1.200     gdt      2039:  *
                   2040:  * Each record is a struct ifreq.  Before the addition of
                   2041:  * sockaddr_storage, the API rule was that sockaddr flavors that did
                   2042:  * not fit would extend beyond the struct ifreq, with the next struct
                   2043:  * ifreq starting sa_len beyond the struct sockaddr.  Because the
                   2044:  * union in struct ifreq includes struct sockaddr_storage, every kind
                   2045:  * of sockaddr must fit.  Thus, there are no longer any overlength
                   2046:  * records.
                   2047:  *
                   2048:  * Records are added to the user buffer if they fit, and ifc_len is
                   2049:  * adjusted to the length that was written.  Thus, the user is only
                   2050:  * assured of getting the complete list if ifc_len on return is at
                   2051:  * least sizeof(struct ifreq) less than it was on entry.
                   2052:  *
                   2053:  * If the user buffer pointer is NULL, this routine copies no data and
                   2054:  * returns the amount of space that would be needed.
                   2055:  *
                   2056:  * Invariants:
                   2057:  * ifrp points to the next part of the user's buffer to be used.  If
                   2058:  * ifrp != NULL, space holds the number of bytes remaining that we may
                   2059:  * write at ifrp.  Otherwise, space holds the number of bytes that
                   2060:  * would have been written had there been adequate space.
1.1       cgd      2061:  */
                   2062: /*ARGSUSED*/
1.15      mycroft  2063: int
1.183     christos 2064: ifconf(u_long cmd, void *data)
1.1       cgd      2065: {
1.61      augustss 2066:        struct ifconf *ifc = (struct ifconf *)data;
                   2067:        struct ifnet *ifp;
                   2068:        struct ifaddr *ifa;
1.1       cgd      2069:        struct ifreq ifr, *ifrp;
1.190     enami    2070:        int space, error = 0;
1.200     gdt      2071:        const int sz = (int)sizeof(struct ifreq);
1.1       cgd      2072:
1.190     enami    2073:        if ((ifrp = ifc->ifc_req) == NULL)
1.127     christos 2074:                space = 0;
1.190     enami    2075:        else
                   2076:                space = ifc->ifc_len;
1.153     matt     2077:        IFNET_FOREACH(ifp) {
1.175     christos 2078:                (void)strncpy(ifr.ifr_name, ifp->if_xname,
1.173     christos 2079:                    sizeof(ifr.ifr_name));
1.175     christos 2080:                if (ifr.ifr_name[sizeof(ifr.ifr_name) - 1] != '\0')
                   2081:                        return ENAMETOOLONG;
1.205     dyoung   2082:                if (IFADDR_EMPTY(ifp)) {
1.200     gdt      2083:                        /* Interface with no addresses - send zero sockaddr. */
1.127     christos 2084:                        memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
1.218     dyoung   2085:                        if (ifrp == NULL) {
                   2086:                                space += sz;
                   2087:                                continue;
                   2088:                        }
                   2089:                        if (space >= sz) {
                   2090:                                error = copyout(&ifr, ifrp, sz);
                   2091:                                if (error != 0)
                   2092:                                        return error;
                   2093:                                ifrp++;
                   2094:                                space -= sz;
1.70      mellon   2095:                        }
1.127     christos 2096:                }
                   2097:
1.204     dyoung   2098:                IFADDR_FOREACH(ifa, ifp) {
1.61      augustss 2099:                        struct sockaddr *sa = ifa->ifa_addr;
1.200     gdt      2100:                        /* all sockaddrs must fit in sockaddr_storage */
                   2101:                        KASSERT(sa->sa_len <= sizeof(ifr.ifr_ifru));
                   2102:
1.218     dyoung   2103:                        if (ifrp == NULL) {
                   2104:                                space += sz;
                   2105:                                continue;
                   2106:                        }
                   2107:                        memcpy(&ifr.ifr_space, sa, sa->sa_len);
                   2108:                        if (space >= sz) {
                   2109:                                error = copyout(&ifr, ifrp, sz);
                   2110:                                if (error != 0)
                   2111:                                        return (error);
                   2112:                                ifrp++; space -= sz;
1.1       cgd      2113:                        }
                   2114:                }
                   2115:        }
1.218     dyoung   2116:        if (ifrp != NULL) {
1.200     gdt      2117:                KASSERT(0 <= space && space <= ifc->ifc_len);
1.127     christos 2118:                ifc->ifc_len -= space;
1.218     dyoung   2119:        } else {
1.200     gdt      2120:                KASSERT(space >= 0);
                   2121:                ifc->ifc_len = space;
                   2122:        }
1.190     enami    2123:        return (0);
1.1       cgd      2124: }
1.133     jonathan 2125:
1.198     dyoung   2126: int
1.247     christos 2127: ifreq_setaddr(u_long cmd, struct ifreq *ifr, const struct sockaddr *sa)
1.198     dyoung   2128: {
                   2129:        uint8_t len;
1.247     christos 2130: #ifdef COMPAT_OIFREQ
                   2131:        struct ifreq ifrb;
                   2132:        struct oifreq *oifr = NULL;
                   2133:        u_long ocmd = cmd;
                   2134:        cmd = compat_cvtcmd(cmd);
                   2135:        if (cmd != ocmd) {
                   2136:                oifr = (struct oifreq *)(void *)ifr;
                   2137:                ifr = &ifrb;
                   2138:                ifreqo2n(oifr, ifr);
                   2139:                len = sizeof(oifr->ifr_addr);
                   2140:        } else
                   2141: #endif
                   2142:                len = sizeof(ifr->ifr_ifru.ifru_space);
1.198     dyoung   2143:
                   2144:        if (len < sa->sa_len)
                   2145:                return EFBIG;
1.247     christos 2146:
1.241     joerg    2147:        memset(&ifr->ifr_addr, 0, len);
1.202     dyoung   2148:        sockaddr_copy(&ifr->ifr_addr, len, sa);
1.247     christos 2149:
                   2150: #ifdef COMPAT_OIFREQ
                   2151:        if (cmd != ocmd)
                   2152:                ifreqn2o(oifr, ifr);
                   2153: #endif
1.198     dyoung   2154:        return 0;
                   2155: }
                   2156:
1.155     christos 2157: /*
                   2158:  * Queue message on interface, and start output if interface
                   2159:  * not yet active.
                   2160:  */
                   2161: int
                   2162: ifq_enqueue(struct ifnet *ifp, struct mbuf *m
                   2163:     ALTQ_COMMA ALTQ_DECL(struct altq_pktattr *pktattr))
                   2164: {
                   2165:        int len = m->m_pkthdr.len;
                   2166:        int mflags = m->m_flags;
                   2167:        int s = splnet();
                   2168:        int error;
                   2169:
1.156     christos 2170:        IFQ_ENQUEUE(&ifp->if_snd, m, pktattr, error);
1.185     dyoung   2171:        if (error != 0)
                   2172:                goto out;
1.155     christos 2173:        ifp->if_obytes += len;
                   2174:        if (mflags & M_MCAST)
                   2175:                ifp->if_omcasts++;
                   2176:        if ((ifp->if_flags & IFF_OACTIVE) == 0)
                   2177:                (*ifp->if_start)(ifp);
1.185     dyoung   2178: out:
1.155     christos 2179:        splx(s);
                   2180:        return error;
                   2181: }
                   2182:
                   2183: /*
                   2184:  * Queue message on interface, possibly using a second fast queue
                   2185:  */
                   2186: int
                   2187: ifq_enqueue2(struct ifnet *ifp, struct ifqueue *ifq, struct mbuf *m
                   2188:     ALTQ_COMMA ALTQ_DECL(struct altq_pktattr *pktattr))
                   2189: {
                   2190:        int error = 0;
                   2191:
                   2192:        if (ifq != NULL
                   2193: #ifdef ALTQ
                   2194:            && ALTQ_IS_ENABLED(&ifp->if_snd) == 0
                   2195: #endif
                   2196:            ) {
                   2197:                if (IF_QFULL(ifq)) {
                   2198:                        IF_DROP(&ifp->if_snd);
                   2199:                        m_freem(m);
                   2200:                        if (error == 0)
                   2201:                                error = ENOBUFS;
1.185     dyoung   2202:                } else
1.155     christos 2203:                        IF_ENQUEUE(ifq, m);
                   2204:        } else
1.156     christos 2205:                IFQ_ENQUEUE(&ifp->if_snd, m, pktattr, error);
1.155     christos 2206:        if (error != 0) {
                   2207:                ++ifp->if_oerrors;
                   2208:                return error;
                   2209:        }
                   2210:        return 0;
                   2211: }
                   2212:
1.252     dyoung   2213: int
                   2214: if_addr_init(ifnet_t *ifp, struct ifaddr *ifa, const bool src)
                   2215: {
                   2216:        int rc;
                   2217:
                   2218:        if (ifp->if_initaddr != NULL)
                   2219:                rc = (*ifp->if_initaddr)(ifp, ifa, src);
                   2220:        else if (src ||
                   2221:                 (rc = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, ifa)) == ENOTTY)
                   2222:                rc = (*ifp->if_ioctl)(ifp, SIOCINITIFADDR, ifa);
                   2223:
                   2224:        return rc;
                   2225: }
                   2226:
                   2227: int
                   2228: if_flags_set(ifnet_t *ifp, const short flags)
                   2229: {
                   2230:        int rc;
                   2231:
                   2232:        if (ifp->if_setflags != NULL)
                   2233:                rc = (*ifp->if_setflags)(ifp, flags);
                   2234:        else {
1.259     dyoung   2235:                short cantflags, chgdflags;
1.256     dyoung   2236:                struct ifreq ifr;
                   2237:
1.259     dyoung   2238:                chgdflags = ifp->if_flags ^ flags;
                   2239:                cantflags = chgdflags & IFF_CANTCHANGE;
1.256     dyoung   2240:
                   2241:                if (cantflags != 0)
                   2242:                        ifp->if_flags ^= cantflags;
                   2243:
1.259     dyoung   2244:                 /* Traditionally, we do not call if_ioctl after
                   2245:                  * setting/clearing only IFF_PROMISC if the interface
                   2246:                  * isn't IFF_UP.  Uphold that tradition.
                   2247:                 */
                   2248:                if (chgdflags == IFF_PROMISC && (ifp->if_flags & IFF_UP) == 0)
                   2249:                        return 0;
                   2250:
                   2251:                memset(&ifr, 0, sizeof(ifr));
                   2252:
1.256     dyoung   2253:                ifr.ifr_flags = flags & ~IFF_CANTCHANGE;
1.252     dyoung   2254:                rc = (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, &ifr);
1.256     dyoung   2255:
                   2256:                if (rc != 0 && cantflags != 0)
                   2257:                        ifp->if_flags ^= cantflags;
1.252     dyoung   2258:        }
                   2259:
                   2260:        return rc;
                   2261: }
                   2262:
                   2263: int
                   2264: if_mcast_op(ifnet_t *ifp, const unsigned long cmd, const struct sockaddr *sa)
                   2265: {
                   2266:        int rc;
                   2267:        struct ifreq ifr;
                   2268:
                   2269:        if (ifp->if_mcastop != NULL)
                   2270:                rc = (*ifp->if_mcastop)(ifp, cmd, sa);
                   2271:        else {
                   2272:                ifreq_setaddr(cmd, &ifr, sa);
                   2273:                rc = (*ifp->if_ioctl)(ifp, cmd, &ifr);
                   2274:        }
                   2275:
                   2276:        return rc;
                   2277: }
1.155     christos 2278:
1.234     dyoung   2279: static void
                   2280: sysctl_sndq_setup(struct sysctllog **clog, const char *ifname,
                   2281:     struct ifaltq *ifq)
                   2282: {
                   2283:        const struct sysctlnode *cnode, *rnode;
                   2284:
                   2285:        if (sysctl_createv(clog, 0, NULL, &rnode,
                   2286:                       CTLFLAG_PERMANENT,
                   2287:                       CTLTYPE_NODE, "interfaces",
                   2288:                       SYSCTL_DESCR("Per-interface controls"),
                   2289:                       NULL, 0, NULL, 0,
1.272     pooka    2290:                       CTL_NET, CTL_CREATE, CTL_EOL) != 0)
1.234     dyoung   2291:                goto bad;
                   2292:
                   2293:        if (sysctl_createv(clog, 0, &rnode, &rnode,
                   2294:                       CTLFLAG_PERMANENT,
                   2295:                       CTLTYPE_NODE, ifname,
                   2296:                       SYSCTL_DESCR("Interface controls"),
                   2297:                       NULL, 0, NULL, 0,
                   2298:                       CTL_CREATE, CTL_EOL) != 0)
                   2299:                goto bad;
                   2300:
                   2301:        if (sysctl_createv(clog, 0, &rnode, &rnode,
                   2302:                       CTLFLAG_PERMANENT,
                   2303:                       CTLTYPE_NODE, "sndq",
                   2304:                       SYSCTL_DESCR("Interface output queue controls"),
                   2305:                       NULL, 0, NULL, 0,
                   2306:                       CTL_CREATE, CTL_EOL) != 0)
                   2307:                goto bad;
                   2308:
                   2309:        if (sysctl_createv(clog, 0, &rnode, &cnode,
                   2310:                       CTLFLAG_PERMANENT,
                   2311:                       CTLTYPE_INT, "len",
                   2312:                       SYSCTL_DESCR("Current output queue length"),
                   2313:                       NULL, 0, &ifq->ifq_len, 0,
                   2314:                       CTL_CREATE, CTL_EOL) != 0)
                   2315:                goto bad;
                   2316:
                   2317:        if (sysctl_createv(clog, 0, &rnode, &cnode,
                   2318:                       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
                   2319:                       CTLTYPE_INT, "maxlen",
                   2320:                       SYSCTL_DESCR("Maximum allowed output queue length"),
                   2321:                       NULL, 0, &ifq->ifq_maxlen, 0,
                   2322:                       CTL_CREATE, CTL_EOL) != 0)
                   2323:                goto bad;
                   2324:
                   2325:        if (sysctl_createv(clog, 0, &rnode, &cnode,
                   2326:                       CTLFLAG_PERMANENT,
                   2327:                       CTLTYPE_INT, "drops",
                   2328:                       SYSCTL_DESCR("Packets dropped due to full output queue"),
                   2329:                       NULL, 0, &ifq->ifq_drops, 0,
                   2330:                       CTL_CREATE, CTL_EOL) != 0)
                   2331:                goto bad;
                   2332:
                   2333:        return;
                   2334: bad:
                   2335:        printf("%s: could not attach sysctl nodes\n", ifname);
                   2336:        return;
                   2337: }
                   2338:
1.138     drochner 2339: #if defined(INET) || defined(INET6)
1.276     rmind    2340:
                   2341: static int
                   2342: sysctl_pktq_count(SYSCTLFN_ARGS, pktqueue_t *pq, u_int count_id)
                   2343: {
                   2344:        int count = pktq_get_count(pq, count_id);
                   2345:        struct sysctlnode node = *rnode;
                   2346:        node.sysctl_data = &count;
                   2347:        return sysctl_lookup(SYSCTLFN_CALL(&node));
                   2348: }
                   2349:
                   2350: #define        SYSCTL_NET_PKTQ(q, cn, c)                                       \
                   2351:        static int                                                      \
                   2352:        sysctl_net_##q##_##cn(SYSCTLFN_ARGS)                            \
                   2353:        {                                                               \
                   2354:                return sysctl_pktq_count(SYSCTLFN_CALL(rnode), q, c);   \
                   2355:        }
                   2356:
                   2357: #if defined(INET)
                   2358: SYSCTL_NET_PKTQ(ip_pktq, maxlen, PKTQ_MAXLEN)
                   2359: SYSCTL_NET_PKTQ(ip_pktq, items, PKTQ_NITEMS)
                   2360: SYSCTL_NET_PKTQ(ip_pktq, drops, PKTQ_DROPS)
                   2361: #endif
                   2362: #if defined(INET6)
                   2363: SYSCTL_NET_PKTQ(ip6_pktq, maxlen, PKTQ_MAXLEN)
                   2364: SYSCTL_NET_PKTQ(ip6_pktq, items, PKTQ_NITEMS)
                   2365: SYSCTL_NET_PKTQ(ip6_pktq, drops, PKTQ_DROPS)
                   2366: #endif
                   2367:
1.136     atatat   2368: static void
1.276     rmind    2369: sysctl_net_pktq_setup(struct sysctllog **clog, int pf)
1.136     atatat   2370: {
1.276     rmind    2371:        sysctlfn len_func = NULL, maxlen_func = NULL, drops_func = NULL;
                   2372:        const char *pfname = NULL, *ipname = NULL;
                   2373:        int ipn = 0, qid = 0;
                   2374:
                   2375:        switch (pf) {
                   2376: #if defined(INET)
                   2377:        case PF_INET:
                   2378:                len_func = sysctl_net_ip_pktq_items;
                   2379:                maxlen_func = sysctl_net_ip_pktq_maxlen;
                   2380:                drops_func = sysctl_net_ip_pktq_drops;
                   2381:                pfname = "inet", ipn = IPPROTO_IP;
                   2382:                ipname = "ip", qid = IPCTL_IFQ;
                   2383:                break;
                   2384: #endif
                   2385: #if defined(INET6)
                   2386:        case PF_INET6:
                   2387:                len_func = sysctl_net_ip6_pktq_items;
                   2388:                maxlen_func = sysctl_net_ip6_pktq_maxlen;
                   2389:                drops_func = sysctl_net_ip6_pktq_drops;
                   2390:                pfname = "inet6", ipn = IPPROTO_IPV6;
                   2391:                ipname = "ip6", qid = IPV6CTL_IFQ;
                   2392:                break;
                   2393: #endif
                   2394:        default:
                   2395:                KASSERT(false);
                   2396:        }
1.136     atatat   2397:
1.139     atatat   2398:        sysctl_createv(clog, 0, NULL, NULL,
                   2399:                       CTLFLAG_PERMANENT,
1.136     atatat   2400:                       CTLTYPE_NODE, pfname, NULL,
                   2401:                       NULL, 0, NULL, 0,
                   2402:                       CTL_NET, pf, CTL_EOL);
1.139     atatat   2403:        sysctl_createv(clog, 0, NULL, NULL,
                   2404:                       CTLFLAG_PERMANENT,
1.136     atatat   2405:                       CTLTYPE_NODE, ipname, NULL,
                   2406:                       NULL, 0, NULL, 0,
                   2407:                       CTL_NET, pf, ipn, CTL_EOL);
1.139     atatat   2408:        sysctl_createv(clog, 0, NULL, NULL,
                   2409:                       CTLFLAG_PERMANENT,
1.142     atatat   2410:                       CTLTYPE_NODE, "ifq",
                   2411:                       SYSCTL_DESCR("Protocol input queue controls"),
1.139     atatat   2412:                       NULL, 0, NULL, 0,
                   2413:                       CTL_NET, pf, ipn, qid, CTL_EOL);
1.136     atatat   2414:
1.139     atatat   2415:        sysctl_createv(clog, 0, NULL, NULL,
                   2416:                       CTLFLAG_PERMANENT,
1.142     atatat   2417:                       CTLTYPE_INT, "len",
                   2418:                       SYSCTL_DESCR("Current input queue length"),
1.276     rmind    2419:                       len_func, 0, NULL, 0,
1.136     atatat   2420:                       CTL_NET, pf, ipn, qid, IFQCTL_LEN, CTL_EOL);
1.139     atatat   2421:        sysctl_createv(clog, 0, NULL, NULL,
                   2422:                       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
1.142     atatat   2423:                       CTLTYPE_INT, "maxlen",
                   2424:                       SYSCTL_DESCR("Maximum allowed input queue length"),
1.276     rmind    2425:                       maxlen_func, 0, NULL, 0,
1.136     atatat   2426:                       CTL_NET, pf, ipn, qid, IFQCTL_MAXLEN, CTL_EOL);
1.139     atatat   2427:        sysctl_createv(clog, 0, NULL, NULL,
                   2428:                       CTLFLAG_PERMANENT,
1.142     atatat   2429:                       CTLTYPE_INT, "drops",
                   2430:                       SYSCTL_DESCR("Packets dropped due to full input queue"),
1.276     rmind    2431:                       drops_func, 0, NULL, 0,
1.136     atatat   2432:                       CTL_NET, pf, ipn, qid, IFQCTL_DROPS, CTL_EOL);
                   2433: }
1.138     drochner 2434: #endif /* INET || INET6 */

CVSweb <webmaster@jp.NetBSD.org>