[BACK]Return to if_ethersubr.c CVS log [TXT][DIR] Up to [local] / sys / net

Annotation of sys/net/if_ethersubr.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: if_ethersubr.c,v 1.110 2007/06/06 10:04:36 henning Exp $      */
                      2: /*     $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $        */
                      3:
                      4: /*
                      5:  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. Neither the name of the project nor the names of its contributors
                     17:  *    may be used to endorse or promote products derived from this software
                     18:  *    without specific prior written permission.
                     19:  *
                     20:  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
                     21:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     22:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     23:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
                     24:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     25:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     26:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     27:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     28:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     29:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     30:  * SUCH DAMAGE.
                     31:  */
                     32:
                     33: /*
                     34:  * Copyright (c) 1982, 1989, 1993
                     35:  *     The Regents of the University of California.  All rights reserved.
                     36:  *
                     37:  * Redistribution and use in source and binary forms, with or without
                     38:  * modification, are permitted provided that the following conditions
                     39:  * are met:
                     40:  * 1. Redistributions of source code must retain the above copyright
                     41:  *    notice, this list of conditions and the following disclaimer.
                     42:  * 2. Redistributions in binary form must reproduce the above copyright
                     43:  *    notice, this list of conditions and the following disclaimer in the
                     44:  *    documentation and/or other materials provided with the distribution.
                     45:  * 3. Neither the name of the University nor the names of its contributors
                     46:  *    may be used to endorse or promote products derived from this software
                     47:  *    without specific prior written permission.
                     48:  *
                     49:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     50:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     51:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     52:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     53:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     54:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     55:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     56:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     57:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     58:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     59:  * SUCH DAMAGE.
                     60:  *
                     61:  *     @(#)if_ethersubr.c      8.1 (Berkeley) 6/10/93
                     62:  */
                     63:
                     64: /*
                     65: %%% portions-copyright-nrl-95
                     66: Portions of this software are Copyright 1995-1998 by Randall Atkinson,
                     67: Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
                     68: Reserved. All rights under this copyright have been assigned to the US
                     69: Naval Research Laboratory (NRL). The NRL Copyright Notice and License
                     70: Agreement Version 1.1 (January 17, 1995) applies to these portions of the
                     71: software.
                     72: You should have received a copy of the license with this software. If you
                     73: didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
                     74: */
                     75:
                     76: #include "bpfilter.h"
                     77:
                     78: #include <sys/param.h>
                     79: #include <sys/systm.h>
                     80: #include <sys/kernel.h>
                     81: #include <sys/malloc.h>
                     82: #include <sys/mbuf.h>
                     83: #include <sys/protosw.h>
                     84: #include <sys/socket.h>
                     85: #include <sys/ioctl.h>
                     86: #include <sys/errno.h>
                     87: #include <sys/syslog.h>
                     88: #include <sys/timeout.h>
                     89:
                     90: #include <machine/cpu.h>
                     91:
                     92: #include <net/if.h>
                     93: #include <net/netisr.h>
                     94: #include <net/route.h>
                     95: #include <net/if_llc.h>
                     96: #include <net/if_dl.h>
                     97: #include <net/if_media.h>
                     98: #include <net/if_types.h>
                     99:
                    100: #include <netinet/in.h>
                    101: #ifdef INET
                    102: #include <netinet/in_var.h>
                    103: #endif
                    104: #include <netinet/if_ether.h>
                    105: #include <netinet/ip_ipsp.h>
                    106:
                    107: #if NBPFILTER > 0
                    108: #include <net/bpf.h>
                    109: #endif
                    110:
                    111: #include "bridge.h"
                    112: #if NBRIDGE > 0
                    113: #include <net/if_bridge.h>
                    114: #endif
                    115:
                    116: #include "vlan.h"
                    117: #if NVLAN > 0
                    118: #include <net/if_vlan_var.h>
                    119: #endif /* NVLAN > 0 */
                    120:
                    121: #include "carp.h"
                    122: #if NCARP > 0
                    123: #include <netinet/ip_carp.h>
                    124: #endif
                    125:
                    126: #include "pppoe.h"
                    127: #if NPPPOE > 0
                    128: #include <net/if_pppoe.h>
                    129: #endif
                    130:
                    131: #include "trunk.h"
                    132: #if NTRUNK > 0
                    133: #include <net/if_trunk.h>
                    134: #endif
                    135:
                    136: #ifdef INET6
                    137: #ifndef INET
                    138: #include <netinet/in.h>
                    139: #endif
                    140: #include <netinet6/in6_var.h>
                    141: #include <netinet6/nd6.h>
                    142: #endif
                    143:
                    144: #ifdef NETATALK
                    145: #include <netatalk/at.h>
                    146: #include <netatalk/at_var.h>
                    147: #include <netatalk/at_extern.h>
                    148:
                    149: extern u_char  at_org_code[ 3 ];
                    150: extern u_char  aarp_org_code[ 3 ];
                    151: #endif /* NETATALK */
                    152:
                    153: u_char etherbroadcastaddr[ETHER_ADDR_LEN] =
                    154:     { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
                    155: #define senderr(e) { error = (e); goto bad;}
                    156:
                    157:
                    158: int
                    159: ether_ioctl(ifp, arp, cmd, data)
                    160:        struct ifnet *ifp;
                    161:        struct arpcom *arp;
                    162:        u_long cmd;
                    163:        caddr_t data;
                    164: {
                    165:        struct ifaddr *ifa = (struct ifaddr *)data;
                    166:        int     error = 0;
                    167:
                    168:        switch (cmd) {
                    169:
                    170:        case SIOCSIFADDR:
                    171:                switch (ifa->ifa_addr->sa_family) {
                    172: #ifdef NETATALK
                    173:                case AF_APPLETALK:
                    174:                        /* Nothing to do. */
                    175:                        break;
                    176: #endif /* NETATALK */
                    177:                }
                    178:                break;
                    179:        default:
                    180:                break;
                    181:        }
                    182:
                    183:        return error;
                    184: }
                    185:
                    186: /*
                    187:  * Ethernet output routine.
                    188:  * Encapsulate a packet of type family for the local net.
                    189:  * Assumes that ifp is actually pointer to arpcom structure.
                    190:  */
                    191: int
                    192: ether_output(ifp0, m0, dst, rt0)
                    193:        struct ifnet *ifp0;
                    194:        struct mbuf *m0;
                    195:        struct sockaddr *dst;
                    196:        struct rtentry *rt0;
                    197: {
                    198:        u_int16_t etype;
                    199:        int s, len, error = 0, hdrcmplt = 0;
                    200:        u_char edst[ETHER_ADDR_LEN], esrc[ETHER_ADDR_LEN];
                    201:        struct mbuf *m = m0;
                    202:        struct rtentry *rt;
                    203:        struct mbuf *mcopy = (struct mbuf *)0;
                    204:        struct ether_header *eh;
                    205:        struct arpcom *ac = (struct arpcom *)ifp0;
                    206:        short mflags;
                    207:        struct ifnet *ifp = ifp0;
                    208:
                    209: #if NTRUNK > 0
                    210:        if (ifp->if_type == IFT_IEEE8023ADLAG)
                    211:                senderr(EBUSY);
                    212: #endif
                    213:
                    214: #if NCARP > 0
                    215:        if (ifp->if_type == IFT_CARP) {
                    216:                struct ifaddr *ifa;
                    217:
                    218:                /* loop back if this is going to the carp interface */
                    219:                if (dst != NULL && LINK_STATE_IS_UP(ifp0->if_link_state) &&
                    220:                    (ifa = ifa_ifwithaddr(dst)) != NULL &&
                    221:                    ifa->ifa_ifp == ifp0)
                    222:                        return (looutput(ifp0, m, dst, rt0));
                    223:
                    224:                ifp = ifp->if_carpdev;
                    225:                ac = (struct arpcom *)ifp;
                    226:
                    227:                if ((ifp0->if_flags & (IFF_UP|IFF_RUNNING)) !=
                    228:                    (IFF_UP|IFF_RUNNING))
                    229:                        senderr(ENETDOWN);
                    230:        }
                    231: #endif /* NCARP > 0 */
                    232:
                    233:        if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
                    234:                senderr(ENETDOWN);
                    235:        if ((rt = rt0) != NULL) {
                    236:                if ((rt->rt_flags & RTF_UP) == 0) {
                    237:                        if ((rt0 = rt = rtalloc1(dst, 1, 0)) != NULL)
                    238:                                rt->rt_refcnt--;
                    239:                        else
                    240:                                senderr(EHOSTUNREACH);
                    241:                }
                    242:                if (rt->rt_flags & RTF_GATEWAY) {
                    243:                        if (rt->rt_gwroute == 0)
                    244:                                goto lookup;
                    245:                        if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
                    246:                                rtfree(rt); rt = rt0;
                    247:                        lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1, 0);
                    248:                                if ((rt = rt->rt_gwroute) == 0)
                    249:                                        senderr(EHOSTUNREACH);
                    250:                        }
                    251:                }
                    252:                if (rt->rt_flags & RTF_REJECT)
                    253:                        if (rt->rt_rmx.rmx_expire == 0 ||
                    254:                            time_second < rt->rt_rmx.rmx_expire)
                    255:                                senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
                    256:        }
                    257:
                    258:        switch (dst->sa_family) {
                    259:
                    260: #ifdef INET
                    261:        case AF_INET:
                    262:                if (!arpresolve(ac, rt, m, dst, edst))
                    263:                        return (0);     /* if not yet resolved */
                    264:                /* If broadcasting on a simplex interface, loopback a copy */
                    265:                if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
                    266:                    !m->m_pkthdr.pf.routed)
                    267:                        mcopy = m_copy(m, 0, (int)M_COPYALL);
                    268:                etype = htons(ETHERTYPE_IP);
                    269:                break;
                    270: #endif
                    271: #ifdef INET6
                    272:        case AF_INET6:
                    273:                if (!nd6_storelladdr(ifp, rt, m, dst, (u_char *)edst))
                    274:                        return (0); /* it must be impossible, but... */
                    275:                etype = htons(ETHERTYPE_IPV6);
                    276:                break;
                    277: #endif
                    278: #ifdef NETATALK
                    279:        case AF_APPLETALK: {
                    280:                struct at_ifaddr *aa;
                    281:
                    282:                if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst)) {
                    283: #ifdef NETATALKDEBUG
                    284:                        extern char *prsockaddr(struct sockaddr *);
                    285:                        printf("aarpresolv: failed for %s\n", prsockaddr(dst));
                    286: #endif /* NETATALKDEBUG */
                    287:                        return (0);
                    288:                }
                    289:
                    290:                /*
                    291:                 * ifaddr is the first thing in at_ifaddr
                    292:                 */
                    293:                aa = (struct at_ifaddr *)at_ifawithnet(
                    294:                        (struct sockaddr_at *)dst,
                    295:                        TAILQ_FIRST(&ifp->if_addrlist));
                    296:                if (aa == 0)
                    297:                        goto bad;
                    298:
                    299:                /*
                    300:                 * In the phase 2 case, we need to prepend an mbuf for the llc
                    301:                 * header. Since we must preserve the value of m, which is
                    302:                 * passed to us by value, we m_copy() the first mbuf,
                    303:                 * and use it for our llc header.
                    304:                 */
                    305:                if (aa->aa_flags & AFA_PHASE2) {
                    306:                        struct llc llc;
                    307:
                    308:                        M_PREPEND(m, AT_LLC_SIZE, M_DONTWAIT);
                    309:                        if (m == NULL)
                    310:                                return (0);
                    311:                        /*
                    312:                         * FreeBSD doesn't count the LLC len in
                    313:                         * ifp->obytes, so they increment a length
                    314:                         * field here. We don't do this.
                    315:                         */
                    316:                        llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP;
                    317:                        llc.llc_control = LLC_UI;
                    318:                        bcopy(at_org_code, llc.llc_snap.org_code,
                    319:                                sizeof(at_org_code));
                    320:                        llc.llc_snap.ether_type = htons( ETHERTYPE_AT );
                    321:                        bcopy(&llc, mtod(m, caddr_t), AT_LLC_SIZE);
                    322:                        etype = htons(m->m_pkthdr.len);
                    323:                } else {
                    324:                        etype = htons(ETHERTYPE_AT);
                    325:                }
                    326:                } break;
                    327: #endif /* NETATALK */
                    328:        case pseudo_AF_HDRCMPLT:
                    329:                hdrcmplt = 1;
                    330:                eh = (struct ether_header *)dst->sa_data;
                    331:                bcopy((caddr_t)eh->ether_shost, (caddr_t)esrc, sizeof(esrc));
                    332:                /* FALLTHROUGH */
                    333:
                    334:        case AF_UNSPEC:
                    335:                eh = (struct ether_header *)dst->sa_data;
                    336:                bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof(edst));
                    337:                /* AF_UNSPEC doesn't swap the byte order of the ether_type. */
                    338:                etype = eh->ether_type;
                    339:                break;
                    340:
                    341:        default:
                    342:                printf("%s: can't handle af%d\n", ifp->if_xname,
                    343:                        dst->sa_family);
                    344:                senderr(EAFNOSUPPORT);
                    345:        }
                    346:
                    347:        /* XXX Should we feed-back an unencrypted IPsec packet ? */
                    348:        if (mcopy)
                    349:                (void) looutput(ifp, mcopy, dst, rt);
                    350:
                    351:        /*
                    352:         * Add local net header.  If no space in first mbuf,
                    353:         * allocate another.
                    354:         */
                    355:        M_PREPEND(m, ETHER_HDR_LEN, M_DONTWAIT);
                    356:        if (m == 0)
                    357:                senderr(ENOBUFS);
                    358:        eh = mtod(m, struct ether_header *);
                    359:        bcopy((caddr_t)&etype,(caddr_t)&eh->ether_type,
                    360:                sizeof(eh->ether_type));
                    361:        bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof(edst));
                    362:        if (hdrcmplt)
                    363:                bcopy((caddr_t)esrc, (caddr_t)eh->ether_shost,
                    364:                    sizeof(eh->ether_shost));
                    365:        else
                    366:                bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost,
                    367:                    sizeof(eh->ether_shost));
                    368:
                    369: #if NCARP > 0
                    370:        if (ifp0 != ifp && ifp0->if_type == IFT_CARP &&
                    371:            !(ifp0->if_flags & IFF_LINK1)) {
                    372:                bcopy((caddr_t)((struct arpcom *)ifp0)->ac_enaddr,
                    373:                    (caddr_t)eh->ether_shost, sizeof(eh->ether_shost));
                    374:        }
                    375: #endif
                    376:
                    377: #if NBRIDGE > 0
                    378:        /*
                    379:         * Interfaces that are bridge members need special handling
                    380:         * for output.
                    381:         */
                    382:        if (ifp->if_bridge) {
                    383:                struct m_tag *mtag;
                    384:
                    385:                /*
                    386:                 * Check if this packet has already been sent out through
                    387:                 * this bridge, in which case we simply send it out
                    388:                 * without further bridge processing.
                    389:                 */
                    390:                for (mtag = m_tag_find(m, PACKET_TAG_BRIDGE, NULL); mtag;
                    391:                    mtag = m_tag_find(m, PACKET_TAG_BRIDGE, mtag)) {
                    392: #ifdef DEBUG
                    393:                        /* Check that the information is there */
                    394:                        if (mtag->m_tag_len != sizeof(caddr_t)) {
                    395:                                error = EINVAL;
                    396:                                goto bad;
                    397:                        }
                    398: #endif
                    399:                        if (!bcmp(&ifp->if_bridge, mtag + 1, sizeof(caddr_t)))
                    400:                                break;
                    401:                }
                    402:                if (mtag == NULL) {
                    403:                        /* Attach a tag so we can detect loops */
                    404:                        mtag = m_tag_get(PACKET_TAG_BRIDGE, sizeof(caddr_t),
                    405:                            M_NOWAIT);
                    406:                        if (mtag == NULL) {
                    407:                                error = ENOBUFS;
                    408:                                goto bad;
                    409:                        }
                    410:                        bcopy(&ifp->if_bridge, mtag + 1, sizeof(caddr_t));
                    411:                        m_tag_prepend(m, mtag);
                    412:                        error = bridge_output(ifp, m, NULL, NULL);
                    413:                        return (error);
                    414:                }
                    415:        }
                    416: #endif
                    417:
                    418:        mflags = m->m_flags;
                    419:        len = m->m_pkthdr.len;
                    420:        s = splnet();
                    421:        /*
                    422:         * Queue message on interface, and start output if interface
                    423:         * not yet active.
                    424:         */
                    425:        IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
                    426:        if (error) {
                    427:                /* mbuf is already freed */
                    428:                splx(s);
                    429:                return (error);
                    430:        }
                    431:        ifp->if_obytes += len + ETHER_HDR_LEN;
                    432: #if NCARP > 0
                    433:        if (ifp != ifp0)
                    434:                ifp0->if_obytes += len + ETHER_HDR_LEN;
                    435: #endif /* NCARP > 0 */
                    436:        if (mflags & M_MCAST)
                    437:                ifp->if_omcasts++;
                    438:        if ((ifp->if_flags & IFF_OACTIVE) == 0)
                    439:                (*ifp->if_start)(ifp);
                    440:        splx(s);
                    441:        return (error);
                    442:
                    443: bad:
                    444:        if (m)
                    445:                m_freem(m);
                    446:        return (error);
                    447: }
                    448:
                    449: /*
                    450:  * Process a received Ethernet packet;
                    451:  * the packet is in the mbuf chain m without
                    452:  * the ether header, which is provided separately.
                    453:  */
                    454: void
                    455: ether_input(ifp, eh, m)
                    456:        struct ifnet *ifp;
                    457:        struct ether_header *eh;
                    458:        struct mbuf *m;
                    459: {
                    460:        struct ifqueue *inq;
                    461:        u_int16_t etype;
                    462:        int s, llcfound = 0;
                    463:        struct llc *l;
                    464:        struct arpcom *ac;
                    465: #if NTRUNK > 0
                    466:        int i = 0;
                    467: #endif
                    468: #if NPPPOE > 0
                    469:        struct ether_header *eh_tmp;
                    470: #endif
                    471:
                    472:        if (eh == NULL) {
                    473:                eh = mtod(m, struct ether_header *);
                    474:                m_adj(m, ETHER_HDR_LEN);
                    475:        }
                    476:
                    477: #if NTRUNK > 0
                    478:        /* Handle input from a trunk port */
                    479:        while (ifp->if_type == IFT_IEEE8023ADLAG) {
                    480:                if (++i > TRUNK_MAX_STACKING ||
                    481:                    trunk_input(ifp, eh, m) != 0) {
                    482:                        if (m)
                    483:                                m_freem(m);
                    484:                        return;
                    485:                }
                    486:
                    487:                /* Has been set to the trunk interface */
                    488:                ifp = m->m_pkthdr.rcvif;
                    489:        }
                    490: #endif
                    491:
                    492:        if ((ifp->if_flags & IFF_UP) == 0) {
                    493:                m_freem(m);
                    494:                return;
                    495:        }
                    496:        if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
                    497:                if ((ifp->if_flags & IFF_SIMPLEX) == 0) {
                    498:                        struct ifaddr *ifa;
                    499:                        struct sockaddr_dl *sdl = NULL;
                    500:
                    501:                        TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
                    502:                                if ((sdl =
                    503:                                    (struct sockaddr_dl *)ifa->ifa_addr) &&
                    504:                                    sdl->sdl_family == AF_LINK)
                    505:                                        break;
                    506:                        }
                    507:                        /*
                    508:                         * If this is not a simplex interface, drop the packet
                    509:                         * if it came from us.
                    510:                         */
                    511:                        if (sdl && bcmp(LLADDR(sdl), eh->ether_shost,
                    512:                            ETHER_ADDR_LEN) == 0) {
                    513:                                m_freem(m);
                    514:                                return;
                    515:                        }
                    516:                }
                    517:
                    518:                if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
                    519:                    sizeof(etherbroadcastaddr)) == 0)
                    520:                        m->m_flags |= M_BCAST;
                    521:                else
                    522:                        m->m_flags |= M_MCAST;
                    523:                ifp->if_imcasts++;
                    524:        }
                    525:
                    526:        ifp->if_ibytes += m->m_pkthdr.len + sizeof(*eh);
                    527:
                    528:        etype = ntohs(eh->ether_type);
                    529:
                    530: #if NVLAN > 0
                    531:        if (etype == ETHERTYPE_VLAN && (vlan_input(eh, m) == 0))
                    532:                return;
                    533: #endif
                    534:
                    535: #if NBRIDGE > 0
                    536:        /*
                    537:         * Tap the packet off here for a bridge, if configured and
                    538:         * active for this interface.  bridge_input returns
                    539:         * NULL if it has consumed the packet, otherwise, it
                    540:         * gets processed as normal.
                    541:         */
                    542:        if (ifp->if_bridge) {
                    543:                if (m->m_flags & M_PROTO1)
                    544:                        m->m_flags &= ~M_PROTO1;
                    545:                else {
                    546:                        m = bridge_input(ifp, eh, m);
                    547:                        if (m == NULL)
                    548:                                return;
                    549:                        /* The bridge has determined it's for us. */
                    550:                        ifp = m->m_pkthdr.rcvif;
                    551:                }
                    552:        }
                    553: #endif
                    554:
                    555: #if NVLAN > 0
                    556:        if (etype == ETHERTYPE_VLAN) {
                    557:                /* The bridge did not want the vlan frame either, drop it. */
                    558:                ifp->if_noproto++;
                    559:                m_freem(m);
                    560:                return;
                    561:        }
                    562: #endif /* NVLAN > 0 */
                    563:
                    564: #if NCARP > 0
                    565:        if (ifp->if_carp) {
                    566:                if (ifp->if_type != IFT_CARP &&
                    567:                    (carp_input(m, (u_int8_t *)&eh->ether_shost,
                    568:                    (u_int8_t *)&eh->ether_dhost, eh->ether_type) == 0))
                    569:                        return;
                    570:                /* Always clear multicast flags if received on a carp address */
                    571:                else if (ifp->if_type == IFT_CARP &&
                    572:                    ifp->if_flags & IFF_LINK2 &&
                    573:                    m->m_flags & (M_BCAST|M_MCAST) &&
                    574:                    !bcmp(((struct arpcom *)ifp)->ac_enaddr,
                    575:                    (caddr_t)eh->ether_dhost, ETHER_ADDR_LEN))
                    576:                        m->m_flags &= ~(M_BCAST|M_MCAST);
                    577:        }
                    578: #endif /* NCARP > 0 */
                    579:
                    580:        ac = (struct arpcom *)ifp;
                    581:
                    582:        /*
                    583:         * If packet has been filtered by the bpf listener, drop it now
                    584:         */
                    585:        if (m->m_flags & M_FILDROP) {
                    586:                m_free(m);
                    587:                return;
                    588:        }
                    589:
                    590:        /*
                    591:         * If packet is unicast and we're in promiscuous mode, make sure it
                    592:         * is for us.  Drop otherwise.
                    593:         */
                    594:        if ((m->m_flags & (M_BCAST|M_MCAST)) == 0 &&
                    595:            (ifp->if_flags & IFF_PROMISC)) {
                    596:                if (bcmp(ac->ac_enaddr, (caddr_t)eh->ether_dhost,
                    597:                    ETHER_ADDR_LEN)) {
                    598:                        m_freem(m);
                    599:                        return;
                    600:                }
                    601:        }
                    602:
                    603: decapsulate:
                    604:
                    605:        switch (etype) {
                    606: #ifdef INET
                    607:        case ETHERTYPE_IP:
                    608:                schednetisr(NETISR_IP);
                    609:                inq = &ipintrq;
                    610:                break;
                    611:
                    612:        case ETHERTYPE_ARP:
                    613:                if (ifp->if_flags & IFF_NOARP)
                    614:                        goto dropanyway;
                    615:                schednetisr(NETISR_ARP);
                    616:                inq = &arpintrq;
                    617:                break;
                    618:
                    619:        case ETHERTYPE_REVARP:
                    620:                if (ifp->if_flags & IFF_NOARP)
                    621:                        goto dropanyway;
                    622:                revarpinput(m); /* XXX queue? */
                    623:                return;
                    624:
                    625: #endif
                    626: #ifdef INET6
                    627:        /*
                    628:         * Schedule IPv6 software interrupt for incoming IPv6 packet.
                    629:         */
                    630:        case ETHERTYPE_IPV6:
                    631:                schednetisr(NETISR_IPV6);
                    632:                inq = &ip6intrq;
                    633:                break;
                    634: #endif /* INET6 */
                    635: #ifdef NETATALK
                    636:        case ETHERTYPE_AT:
                    637:                schednetisr(NETISR_ATALK);
                    638:                inq = &atintrq1;
                    639:                break;
                    640:        case ETHERTYPE_AARP:
                    641:                /* probably this should be done with a NETISR as well */
                    642:                /* XXX queue this */
                    643:                aarpinput((struct arpcom *)ifp, m);
                    644:                return;
                    645: #endif
                    646: #if NPPPOE > 0
                    647:        case ETHERTYPE_PPPOEDISC:
                    648:        case ETHERTYPE_PPPOE:
                    649:                /* XXX we dont have this flag */
                    650:                /*
                    651:                if (m->m_flags & M_PROMISC) {
                    652:                        m_freem(m);
                    653:                        return;
                    654:                }
                    655:                */
                    656: #ifndef PPPOE_SERVER
                    657:                if (m->m_flags & (M_MCAST | M_BCAST)) {
                    658:                        m_freem(m);
                    659:                        return;
                    660:                }
                    661: #endif
                    662:                M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
                    663:                if (m == NULL)
                    664:                        return;
                    665:
                    666:                eh_tmp = mtod(m, struct ether_header *);
                    667:                bcopy(eh, eh_tmp, sizeof(struct ether_header));
                    668:
                    669:                if (etype == ETHERTYPE_PPPOEDISC)
                    670:                        inq = &ppoediscinq;
                    671:                else
                    672:                        inq = &ppoeinq;
                    673:
                    674:                schednetisr(NETISR_PPPOE);
                    675:                break;
                    676: #endif /* NPPPOE > 0 */
                    677:        default:
                    678:                if (llcfound || etype > ETHERMTU)
                    679:                        goto dropanyway;
                    680:                llcfound = 1;
                    681:                l = mtod(m, struct llc *);
                    682:                switch (l->llc_dsap) {
                    683:                case LLC_SNAP_LSAP:
                    684: #ifdef NETATALK
                    685:                        /*
                    686:                         * Some protocols (like Appletalk) need special
                    687:                         * handling depending on if they are type II
                    688:                         * or SNAP encapsulated. Everything else
                    689:                         * gets handled by stripping off the SNAP header
                    690:                         * and going back up to decapsulate.
                    691:                         */
                    692:                        if (l->llc_control == LLC_UI &&
                    693:                            l->llc_ssap == LLC_SNAP_LSAP &&
                    694:                            Bcmp(&(l->llc_snap.org_code)[0],
                    695:                            at_org_code, sizeof(at_org_code)) == 0 &&
                    696:                            ntohs(l->llc_snap.ether_type) == ETHERTYPE_AT) {
                    697:                                inq = &atintrq2;
                    698:                                m_adj(m, AT_LLC_SIZE);
                    699:                                schednetisr(NETISR_ATALK);
                    700:                                break;
                    701:                        }
                    702:
                    703:                        if (l->llc_control == LLC_UI &&
                    704:                            l->llc_ssap == LLC_SNAP_LSAP &&
                    705:                            Bcmp(&(l->llc_snap.org_code)[0],
                    706:                            aarp_org_code, sizeof(aarp_org_code)) == 0 &&
                    707:                            ntohs(l->llc_snap.ether_type) == ETHERTYPE_AARP) {
                    708:                                m_adj(m, AT_LLC_SIZE);
                    709:                                /* XXX Really this should use netisr too */
                    710:                                aarpinput((struct arpcom *)ifp, m);
                    711:                                return;
                    712:                        }
                    713: #endif /* NETATALK */
                    714:                        if (l->llc_control == LLC_UI &&
                    715:                            l->llc_dsap == LLC_SNAP_LSAP &&
                    716:                            l->llc_ssap == LLC_SNAP_LSAP) {
                    717:                                /* SNAP */
                    718:                                if (m->m_pkthdr.len > etype)
                    719:                                        m_adj(m, etype - m->m_pkthdr.len);
                    720:                                m->m_data += 6;         /* XXX */
                    721:                                m->m_len -= 6;          /* XXX */
                    722:                                m->m_pkthdr.len -= 6;   /* XXX */
                    723:                                M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
                    724:                                if (m == 0)
                    725:                                        return;
                    726:                                *mtod(m, struct ether_header *) = *eh;
                    727:                                goto decapsulate;
                    728:                        }
                    729:                        goto dropanyway;
                    730:                dropanyway:
                    731:                default:
                    732:                        m_freem(m);
                    733:                        return;
                    734:                }
                    735:        }
                    736:
                    737:        s = splnet();
                    738:        IF_INPUT_ENQUEUE(inq, m);
                    739:        splx(s);
                    740: }
                    741:
                    742: /*
                    743:  * Convert Ethernet address to printable (loggable) representation.
                    744:  */
                    745: static char digits[] = "0123456789abcdef";
                    746: char *
                    747: ether_sprintf(ap)
                    748:        u_char *ap;
                    749: {
                    750:        int i;
                    751:        static char etherbuf[ETHER_ADDR_LEN * 3];
                    752:        char *cp = etherbuf;
                    753:
                    754:        for (i = 0; i < ETHER_ADDR_LEN; i++) {
                    755:                *cp++ = digits[*ap >> 4];
                    756:                *cp++ = digits[*ap++ & 0xf];
                    757:                *cp++ = ':';
                    758:        }
                    759:        *--cp = 0;
                    760:        return (etherbuf);
                    761: }
                    762:
                    763: /*
                    764:  * Perform common duties while attaching to interface list
                    765:  */
                    766: void
                    767: ether_ifattach(ifp)
                    768:        struct ifnet *ifp;
                    769: {
                    770:
                    771:        /*
                    772:         * Any interface which provides a MAC address which is obviously
                    773:         * invalid gets whacked, so that users will notice.
                    774:         */
                    775:        if (ETHER_IS_MULTICAST(((struct arpcom *)ifp)->ac_enaddr)) {
                    776:                ((struct arpcom *)ifp)->ac_enaddr[0] = 0x00;
                    777:                ((struct arpcom *)ifp)->ac_enaddr[1] = 0xfe;
                    778:                ((struct arpcom *)ifp)->ac_enaddr[2] = 0xe1;
                    779:                ((struct arpcom *)ifp)->ac_enaddr[3] = 0xba;
                    780:                ((struct arpcom *)ifp)->ac_enaddr[4] = 0xd0;
                    781:                /*
                    782:                 * XXX use of random() by anything except the scheduler is
                    783:                 * normally invalid, but this is boot time, so pre-scheduler,
                    784:                 * and the random subsystem is not alive yet
                    785:                 */
                    786:                ((struct arpcom *)ifp)->ac_enaddr[5] = (u_char)random() & 0xff;
                    787:        }
                    788:
                    789:        ifp->if_type = IFT_ETHER;
                    790:        ifp->if_addrlen = ETHER_ADDR_LEN;
                    791:        ifp->if_hdrlen = ETHER_HDR_LEN;
                    792:        ifp->if_mtu = ETHERMTU;
                    793:        ifp->if_output = ether_output;
                    794:
                    795:        if (ifp->if_hardmtu == 0)
                    796:                ifp->if_hardmtu = ETHERMTU;
                    797:
                    798:        if_alloc_sadl(ifp);
                    799:        bcopy((caddr_t)((struct arpcom *)ifp)->ac_enaddr,
                    800:            LLADDR(ifp->if_sadl), ifp->if_addrlen);
                    801:        LIST_INIT(&((struct arpcom *)ifp)->ac_multiaddrs);
                    802: #if NBPFILTER > 0
                    803:        bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, ETHER_HDR_LEN);
                    804: #endif
                    805: }
                    806:
                    807: void
                    808: ether_ifdetach(ifp)
                    809:        struct ifnet *ifp;
                    810: {
                    811:        struct arpcom *ac = (struct arpcom *)ifp;
                    812:        struct ether_multi *enm;
                    813:
                    814:        for (enm = LIST_FIRST(&ac->ac_multiaddrs);
                    815:            enm != LIST_END(&ac->ac_multiaddrs);
                    816:            enm = LIST_FIRST(&ac->ac_multiaddrs)) {
                    817:                LIST_REMOVE(enm, enm_list);
                    818:                free(enm, M_IFMADDR);
                    819:        }
                    820:
                    821: #if 0
                    822:        /* moved to if_detach() */
                    823:        if_free_sadl(ifp);
                    824: #endif
                    825: }
                    826:
                    827: #if 0
                    828: /*
                    829:  * This is for reference.  We have table-driven versions of the
                    830:  * crc32 generators, which are faster than the double-loop.
                    831:  */
                    832: u_int32_t
                    833: ether_crc32_le(const u_int8_t *buf, size_t len)
                    834: {
                    835:        u_int32_t c, crc, carry;
                    836:        size_t i, j;
                    837:
                    838:        crc = 0xffffffffU;      /* initial value */
                    839:
                    840:        for (i = 0; i < len; i++) {
                    841:                c = buf[i];
                    842:                for (j = 0; j < 8; j++) {
                    843:                        carry = ((crc & 0x01) ? 1 : 0) ^ (c & 0x01);
                    844:                        crc >>= 1;
                    845:                        c >>= 1;
                    846:                        if (carry)
                    847:                                crc = (crc ^ ETHER_CRC_POLY_LE);
                    848:                }
                    849:        }
                    850:
                    851:        return (crc);
                    852: }
                    853:
                    854: u_int32_t
                    855: ether_crc32_be(const u_int8_t *buf, size_t len)
                    856: {
                    857:        u_int32_t c, crc, carry;
                    858:        size_t i, j;
                    859:
                    860:        crc = 0xffffffffU;      /* initial value */
                    861:
                    862:        for (i = 0; i < len; i++) {
                    863:                c = buf[i];
                    864:                for (j = 0; j < 8; j++) {
                    865:                        carry = ((crc & 0x80000000U) ? 1 : 0) ^ (c & 0x01);
                    866:                        crc <<= 1;
                    867:                        c >>= 1;
                    868:                        if (carry)
                    869:                                crc = (crc ^ ETHER_CRC_POLY_BE) | carry;
                    870:                }
                    871:        }
                    872:
                    873:        return (crc);
                    874: }
                    875: #else
                    876: u_int32_t
                    877: ether_crc32_le(const u_int8_t *buf, size_t len)
                    878: {
                    879:        static const u_int32_t crctab[] = {
                    880:                0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
                    881:                0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
                    882:                0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
                    883:                0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
                    884:        };
                    885:        size_t i;
                    886:        u_int32_t crc;
                    887:
                    888:        crc = 0xffffffffU;      /* initial value */
                    889:
                    890:        for (i = 0; i < len; i++) {
                    891:                crc ^= buf[i];
                    892:                crc = (crc >> 4) ^ crctab[crc & 0xf];
                    893:                crc = (crc >> 4) ^ crctab[crc & 0xf];
                    894:        }
                    895:
                    896:        return (crc);
                    897: }
                    898:
                    899: u_int32_t
                    900: ether_crc32_be(const u_int8_t *buf, size_t len)
                    901: {
                    902:        static const u_int8_t rev[] = {
                    903:                0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
                    904:                0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf
                    905:        };
                    906:        static const u_int32_t crctab[] = {
                    907:                0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
                    908:                0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
                    909:                0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
                    910:                0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd
                    911:        };
                    912:        size_t i;
                    913:        u_int32_t crc;
                    914:        u_int8_t data;
                    915:
                    916:        crc = 0xffffffffU;      /* initial value */
                    917:        for (i = 0; i < len; i++) {
                    918:                data = buf[i];
                    919:                crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data & 0xf]];
                    920:                crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data >> 4]];
                    921:        }
                    922:
                    923:        return (crc);
                    924: }
                    925: #endif
                    926:
                    927: #ifdef INET
                    928: u_char ether_ipmulticast_min[ETHER_ADDR_LEN] =
                    929:     { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
                    930: u_char ether_ipmulticast_max[ETHER_ADDR_LEN] =
                    931:     { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
                    932: #endif
                    933:
                    934: #ifdef INET6
                    935: u_char ether_ip6multicast_min[ETHER_ADDR_LEN] =
                    936:     { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 };
                    937: u_char ether_ip6multicast_max[ETHER_ADDR_LEN] =
                    938:     { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff };
                    939: #endif
                    940:
                    941: /*
                    942:  * Convert a sockaddr into an Ethernet address or range of Ethernet
                    943:  * addresses.
                    944:  */
                    945: int
                    946: ether_multiaddr(struct sockaddr *sa, u_int8_t addrlo[ETHER_ADDR_LEN],
                    947:     u_int8_t addrhi[ETHER_ADDR_LEN])
                    948: {
                    949: #ifdef INET
                    950:        struct sockaddr_in *sin;
                    951: #endif /* INET */
                    952: #ifdef INET6
                    953:        struct sockaddr_in6 *sin6;
                    954: #endif /* INET6 */
                    955:
                    956:        switch (sa->sa_family) {
                    957:
                    958:        case AF_UNSPEC:
                    959:                bcopy(sa->sa_data, addrlo, ETHER_ADDR_LEN);
                    960:                bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
                    961:                break;
                    962:
                    963: #ifdef INET
                    964:        case AF_INET:
                    965:                sin = satosin(sa);
                    966:                if (sin->sin_addr.s_addr == INADDR_ANY) {
                    967:                        /*
                    968:                         * An IP address of INADDR_ANY means listen to
                    969:                         * or stop listening to all of the Ethernet
                    970:                         * multicast addresses used for IP.
                    971:                         * (This is for the sake of IP multicast routers.)
                    972:                         */
                    973:                        bcopy(ether_ipmulticast_min, addrlo, ETHER_ADDR_LEN);
                    974:                        bcopy(ether_ipmulticast_max, addrhi, ETHER_ADDR_LEN);
                    975:                } else {
                    976:                        ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
                    977:                        bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
                    978:                }
                    979:                break;
                    980: #endif
                    981: #ifdef INET6
                    982:        case AF_INET6:
                    983:                sin6 = satosin6(sa);
                    984:                if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
                    985:                        /*
                    986:                         * An IP6 address of 0 means listen to or stop
                    987:                         * listening to all of the Ethernet multicast
                    988:                         * address used for IP6.
                    989:                         *
                    990:                         * (This might not be healthy, given IPv6's reliance on
                    991:                         * multicast for things like neighbor discovery.
                    992:                         * Perhaps initializing all-nodes, solicited nodes, and
                    993:                         * possibly all-routers for this interface afterwards
                    994:                         * is not a bad idea.)
                    995:                         */
                    996:
                    997:                        bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN);
                    998:                        bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN);
                    999:                } else {
                   1000:                        ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
                   1001:                        bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
                   1002:                }
                   1003:                break;
                   1004: #endif
                   1005:
                   1006:        default:
                   1007:                return (EAFNOSUPPORT);
                   1008:        }
                   1009:        return (0);
                   1010: }
                   1011:
                   1012: /*
                   1013:  * Add an Ethernet multicast address or range of addresses to the list for a
                   1014:  * given interface.
                   1015:  */
                   1016: int
                   1017: ether_addmulti(ifr, ac)
                   1018:        struct ifreq *ifr;
                   1019:        struct arpcom *ac;
                   1020: {
                   1021:        struct ether_multi *enm;
                   1022:        u_char addrlo[ETHER_ADDR_LEN];
                   1023:        u_char addrhi[ETHER_ADDR_LEN];
                   1024:        int s = splnet(), error;
                   1025:
                   1026:        error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
                   1027:        if (error != 0) {
                   1028:                splx(s);
                   1029:                return (error);
                   1030:        }
                   1031:
                   1032:        /*
                   1033:         * Verify that we have valid Ethernet multicast addresses.
                   1034:         */
                   1035:        if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) {
                   1036:                splx(s);
                   1037:                return (EINVAL);
                   1038:        }
                   1039:        /*
                   1040:         * See if the address range is already in the list.
                   1041:         */
                   1042:        ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
                   1043:        if (enm != NULL) {
                   1044:                /*
                   1045:                 * Found it; just increment the reference count.
                   1046:                 */
                   1047:                ++enm->enm_refcount;
                   1048:                splx(s);
                   1049:                return (0);
                   1050:        }
                   1051:        /*
                   1052:         * New address or range; malloc a new multicast record
                   1053:         * and link it into the interface's multicast list.
                   1054:         */
                   1055:        enm = (struct ether_multi *)malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT);
                   1056:        if (enm == NULL) {
                   1057:                splx(s);
                   1058:                return (ENOBUFS);
                   1059:        }
                   1060:        bcopy(addrlo, enm->enm_addrlo, ETHER_ADDR_LEN);
                   1061:        bcopy(addrhi, enm->enm_addrhi, ETHER_ADDR_LEN);
                   1062:        enm->enm_ac = ac;
                   1063:        enm->enm_refcount = 1;
                   1064:        LIST_INSERT_HEAD(&ac->ac_multiaddrs, enm, enm_list);
                   1065:        ac->ac_multicnt++;
                   1066:        if (bcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0)
                   1067:                ac->ac_multirangecnt++;
                   1068:        splx(s);
                   1069:        /*
                   1070:         * Return ENETRESET to inform the driver that the list has changed
                   1071:         * and its reception filter should be adjusted accordingly.
                   1072:         */
                   1073:        return (ENETRESET);
                   1074: }
                   1075:
                   1076: /*
                   1077:  * Delete a multicast address record.
                   1078:  */
                   1079: int
                   1080: ether_delmulti(ifr, ac)
                   1081:        struct ifreq *ifr;
                   1082:        struct arpcom *ac;
                   1083: {
                   1084:        struct ether_multi *enm;
                   1085:        u_char addrlo[ETHER_ADDR_LEN];
                   1086:        u_char addrhi[ETHER_ADDR_LEN];
                   1087:        int s = splnet(), error;
                   1088:
                   1089:        error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
                   1090:        if (error != 0) {
                   1091:                splx(s);
                   1092:                return (error);
                   1093:        }
                   1094:
                   1095:        /*
                   1096:         * Look up the address in our list.
                   1097:         */
                   1098:        ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
                   1099:        if (enm == NULL) {
                   1100:                splx(s);
                   1101:                return (ENXIO);
                   1102:        }
                   1103:        if (--enm->enm_refcount != 0) {
                   1104:                /*
                   1105:                 * Still some claims to this record.
                   1106:                 */
                   1107:                splx(s);
                   1108:                return (0);
                   1109:        }
                   1110:        /*
                   1111:         * No remaining claims to this record; unlink and free it.
                   1112:         */
                   1113:        LIST_REMOVE(enm, enm_list);
                   1114:        free(enm, M_IFMADDR);
                   1115:        ac->ac_multicnt--;
                   1116:        if (bcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0)
                   1117:                ac->ac_multirangecnt--;
                   1118:        splx(s);
                   1119:        /*
                   1120:         * Return ENETRESET to inform the driver that the list has changed
                   1121:         * and its reception filter should be adjusted accordingly.
                   1122:         */
                   1123:        return (ENETRESET);
                   1124: }

CVSweb