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

Annotation of sys/net/if_atmsubr.c, Revision 1.1

1.1     ! nbrk        1: /*      $OpenBSD: if_atmsubr.c,v 1.26 2006/03/04 22:40:15 brad Exp $       */
        !             2:
        !             3: /*
        !             4:  *
        !             5:  * Copyright (c) 1996 Charles D. Cranor and Washington University.
        !             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. All advertising materials mentioning features or use of this software
        !            17:  *    must display the following acknowledgement:
        !            18:  *      This product includes software developed by Charles D. Cranor and
        !            19:  *     Washington University.
        !            20:  * 4. The name of the author may not be used to endorse or promote products
        !            21:  *    derived from this software without specific prior written permission.
        !            22:  *
        !            23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            25:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            26:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            27:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            28:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            29:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            30:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            31:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            32:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            33:  */
        !            34:
        !            35: /*
        !            36:  *     @(#)COPYRIGHT   1.1 (NRL) January 1995
        !            37:  *
        !            38:  * NRL grants permission for redistribution and use in source and binary
        !            39:  * forms, with or without modification, of the software and documentation
        !            40:  * created at NRL provided that the following conditions are met:
        !            41:  *
        !            42:  * 1. Redistributions of source code must retain the above copyright
        !            43:  *    notice, this list of conditions and the following disclaimer.
        !            44:  * 2. Redistributions in binary form must reproduce the above copyright
        !            45:  *    notice, this list of conditions and the following disclaimer in the
        !            46:  *    documentation and/or other materials provided with the distribution.
        !            47:  * 3. All advertising materials mentioning features or use of this software
        !            48:  *    must display the following acknowledgements:
        !            49:  *     This product includes software developed by the University of
        !            50:  *     California, Berkeley and its contributors.
        !            51:  *     This product includes software developed at the Information
        !            52:  *     Technology Division, US Naval Research Laboratory.
        !            53:  * 4. Neither the name of the NRL nor the names of its contributors
        !            54:  *    may be used to endorse or promote products derived from this software
        !            55:  *    without specific prior written permission.
        !            56:  *
        !            57:  * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS
        !            58:  * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
        !            59:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
        !            60:  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL NRL OR
        !            61:  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
        !            62:  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
        !            63:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
        !            64:  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
        !            65:  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
        !            66:  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
        !            67:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            68:  *
        !            69:  * The views and conclusions contained in the software and documentation
        !            70:  * are those of the authors and should not be interpreted as representing
        !            71:  * official policies, either expressed or implied, of the US Naval
        !            72:  * Research Laboratory (NRL).
        !            73:  */
        !            74:
        !            75: /*
        !            76:  * if_atmsubr.c
        !            77:  */
        !            78:
        !            79: #include <sys/param.h>
        !            80: #include <sys/systm.h>
        !            81: #include <sys/kernel.h>
        !            82: #include <sys/malloc.h>
        !            83: #include <sys/mbuf.h>
        !            84: #include <sys/protosw.h>
        !            85: #include <sys/socket.h>
        !            86: #include <sys/ioctl.h>
        !            87: #include <sys/errno.h>
        !            88: #include <sys/syslog.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_dl.h>
        !            96: #include <net/if_types.h>
        !            97: #include <net/if_atm.h>
        !            98:
        !            99: #include <netinet/in.h>
        !           100: #include <netinet/if_atm.h>
        !           101: #include <netinet/if_ether.h> /* XXX: for ETHERTYPE_* */
        !           102: #if defined(INET) || defined(INET6)
        !           103: #include <netinet/in_var.h>
        !           104: #endif
        !           105: #ifdef NATM
        !           106: #include <netnatm/natm.h>
        !           107: #endif
        !           108:
        !           109: #ifdef INET6
        !           110: #include <netinet6/in6_var.h>
        !           111: #endif /* INET6 */
        !           112:
        !           113: #define senderr(e) { error = (e); goto bad;}
        !           114:
        !           115: /*
        !           116:  * atm_output: ATM output routine
        !           117:  *   inputs:
        !           118:  *     "ifp" = ATM interface to output to
        !           119:  *     "m0" = the packet to output
        !           120:  *     "dst" = the sockaddr to send to (either IP addr, or raw VPI/VCI)
        !           121:  *     "rt0" = the route to use
        !           122:  *   returns: error code   [0 == ok]
        !           123:  *
        !           124:  *   note: special semantic: if (dst == NULL) then we assume "m" already
        !           125:  *             has an atm_pseudohdr on it and just send it directly.
        !           126:  *             [for native mode ATM output]   if dst is null, then
        !           127:  *             rt0 must also be NULL.
        !           128:  */
        !           129:
        !           130: int
        !           131: atm_output(ifp, m0, dst, rt0)
        !           132:        struct ifnet *ifp;
        !           133:        struct mbuf *m0;
        !           134:        struct sockaddr *dst;
        !           135:        struct rtentry *rt0;
        !           136: {
        !           137:        u_int16_t etype = 0;                    /* if using LLC/SNAP */
        !           138:        int s, error = 0, sz, len;
        !           139:        struct atm_pseudohdr atmdst, *ad;
        !           140:        struct mbuf *m = m0;
        !           141:        struct rtentry *rt;
        !           142:        struct atmllc *atmllc;
        !           143:        u_int32_t atm_flags;
        !           144:
        !           145:        if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
        !           146:                senderr(ENETDOWN);
        !           147:
        !           148:        /*
        !           149:         * check route
        !           150:         */
        !           151:        if ((rt = rt0) != NULL) {
        !           152:
        !           153:                if ((rt->rt_flags & RTF_UP) == 0) { /* route went down! */
        !           154:                        if ((rt0 = rt = RTALLOC1(dst, 0)) != NULL)
        !           155:                                rt->rt_refcnt--;
        !           156:                        else
        !           157:                                senderr(EHOSTUNREACH);
        !           158:                }
        !           159:
        !           160:                if (rt->rt_flags & RTF_GATEWAY) {
        !           161:                        if (rt->rt_gwroute == 0)
        !           162:                                goto lookup;
        !           163:                        if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
        !           164:                                rtfree(rt); rt = rt0;
        !           165:                        lookup: rt->rt_gwroute = RTALLOC1(rt->rt_gateway, 0);
        !           166:                                if ((rt = rt->rt_gwroute) == 0)
        !           167:                                        senderr(EHOSTUNREACH);
        !           168:                        }
        !           169:                }
        !           170:
        !           171:                /* XXX: put RTF_REJECT code here if doing ATMARP */
        !           172:
        !           173:        }
        !           174:
        !           175:        /*
        !           176:         * check for non-native ATM traffic   (dst != NULL)
        !           177:         */
        !           178:        if (dst) {
        !           179:                switch (dst->sa_family) {
        !           180: #ifdef INET
        !           181:                case AF_INET:
        !           182: #endif
        !           183: #ifdef INET6
        !           184:                case AF_INET6:
        !           185: #endif
        !           186: #if defined(INET) || defined(INET6)
        !           187:                        if (dst->sa_family == AF_INET)
        !           188:                                etype = ETHERTYPE_IP;
        !           189:                        else
        !           190:                                etype = ETHERTYPE_IPV6;
        !           191:                        if (!atmresolve(rt, m, dst, &atmdst)) {
        !           192:                                m = NULL;
        !           193:                                /* XXX: atmresolve already free'd it */
        !           194:                                senderr(EHOSTUNREACH);
        !           195:                                /* XXX: put ATMARP stuff here */
        !           196:                                /* XXX: watch who frees m on failure */
        !           197:                        }
        !           198:                        break;
        !           199: #endif
        !           200:
        !           201:                default:
        !           202: #if defined(__NetBSD__) || defined(__OpenBSD__)
        !           203:                        printf("%s: can't handle af%d\n", ifp->if_xname,
        !           204:                               dst->sa_family);
        !           205: #elif defined(__FreeBSD__) || defined(__bsdi__)
        !           206:                        printf("%s%d: can't handle af%d\n", ifp->if_name,
        !           207:                               ifp->if_unit, dst->sa_family);
        !           208: #endif
        !           209:                        senderr(EAFNOSUPPORT);
        !           210:                }
        !           211:
        !           212:                /*
        !           213:                 * must add atm_pseudohdr to data
        !           214:                 */
        !           215:                sz = sizeof(atmdst);
        !           216:                atm_flags = ATM_PH_FLAGS(&atmdst);
        !           217:                if (atm_flags & ATM_PH_LLCSNAP) sz += 8; /* sizeof snap == 8 */
        !           218:                M_PREPEND(m, sz, M_DONTWAIT);
        !           219:                if (m == 0)
        !           220:                        senderr(ENOBUFS);
        !           221:                ad = mtod(m, struct atm_pseudohdr *);
        !           222:                *ad = atmdst;
        !           223:                if (atm_flags & ATM_PH_LLCSNAP) {
        !           224:                        atmllc = (struct atmllc *)(ad + 1);
        !           225:                        bcopy(ATMLLC_HDR, atmllc->llchdr,
        !           226:                                                sizeof(atmllc->llchdr));
        !           227:                        ATM_LLC_SETTYPE(atmllc, etype);
        !           228:                }
        !           229:        }
        !           230:
        !           231:        /*
        !           232:         * Queue message on interface, and start output if interface
        !           233:         * not yet active.
        !           234:         */
        !           235:        len = m->m_pkthdr.len;
        !           236:        s = splnet();
        !           237:        IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
        !           238:        if (error) {
        !           239:                splx(s);
        !           240:                return (error);
        !           241:        }
        !           242:        ifp->if_obytes += len;
        !           243:        if ((ifp->if_flags & IFF_OACTIVE) == 0)
        !           244:                (*ifp->if_start)(ifp);
        !           245:        splx(s);
        !           246:        return (error);
        !           247:
        !           248: bad:
        !           249:        if (m)
        !           250:                m_freem(m);
        !           251:        return (error);
        !           252: }
        !           253:
        !           254: /*
        !           255:  * Process a received ATM packet;
        !           256:  * the packet is in the mbuf chain m.
        !           257:  */
        !           258: void
        !           259: atm_input(ifp, ah, m, rxhand)
        !           260:        struct ifnet *ifp;
        !           261:        struct atm_pseudohdr *ah;
        !           262:        struct mbuf *m;
        !           263:        void *rxhand;
        !           264: {
        !           265:        struct ifqueue *inq;
        !           266:        u_int16_t etype = ETHERTYPE_IP; /* default */
        !           267:        int s;
        !           268:
        !           269:        if ((ifp->if_flags & IFF_UP) == 0) {
        !           270:                m_freem(m);
        !           271:                return;
        !           272:        }
        !           273:        ifp->if_ibytes += m->m_pkthdr.len;
        !           274:
        !           275:        if (rxhand) {
        !           276: #ifdef NATM
        !           277:          struct natmpcb *npcb = rxhand;
        !           278:          s = splnet();                 /* in case 2 atm cards @ diff lvls */
        !           279:          npcb->npcb_inq++;                     /* count # in queue */
        !           280:          splx(s);
        !           281:          schednetisr(NETISR_NATM);
        !           282:          inq = &natmintrq;
        !           283:          m->m_pkthdr.rcvif = rxhand; /* XXX: overload */
        !           284: #else
        !           285:          printf("atm_input: NATM detected but not configured in kernel\n");
        !           286:          m_freem(m);
        !           287:          return;
        !           288: #endif
        !           289:        } else {
        !           290:          /*
        !           291:           * handle LLC/SNAP header, if present
        !           292:           */
        !           293:          if (ATM_PH_FLAGS(ah) & ATM_PH_LLCSNAP) {
        !           294:            struct atmllc *alc;
        !           295:            if (m->m_len < sizeof(*alc) &&
        !           296:                (m = m_pullup(m, sizeof(*alc))) == NULL)
        !           297:                  return; /* failed */
        !           298:            alc = mtod(m, struct atmllc *);
        !           299:            if (bcmp(alc, ATMLLC_HDR, 6)) {
        !           300: #if defined(__NetBSD__) || defined(__OpenBSD__)
        !           301:              printf("%s: recv'd invalid LLC/SNAP frame [vp=%d,vc=%d]\n",
        !           302:                  ifp->if_xname, ATM_PH_VPI(ah), ATM_PH_VCI(ah));
        !           303: #elif defined(__FreeBSD__) || defined(__bsdi__)
        !           304:              printf("%s%d: recv'd invalid LLC/SNAP frame [vp=%d,vc=%d]\n",
        !           305:                  ifp->if_name, ifp->if_unit, ATM_PH_VPI(ah), ATM_PH_VCI(ah));
        !           306: #endif
        !           307:              m_freem(m);
        !           308:               return;
        !           309:            }
        !           310:            etype = ATM_LLC_TYPE(alc);
        !           311:            m_adj(m, sizeof(*alc));
        !           312:          }
        !           313:
        !           314:          switch (etype) {
        !           315: #ifdef INET
        !           316:          case ETHERTYPE_IP:
        !           317:                  schednetisr(NETISR_IP);
        !           318:                  inq = &ipintrq;
        !           319:                  break;
        !           320: #endif /* INET */
        !           321: #ifdef INET6
        !           322:          case ETHERTYPE_IPV6:
        !           323:                  schednetisr(NETISR_IPV6);
        !           324:                  inq = &ip6intrq;
        !           325:                  break;
        !           326: #endif
        !           327:          default:
        !           328:              m_freem(m);
        !           329:              return;
        !           330:          }
        !           331:        }
        !           332:
        !           333:        s = splnet();
        !           334:        IF_INPUT_ENQUEUE(inq, m);
        !           335:        splx(s);
        !           336: }
        !           337:
        !           338: /*
        !           339:  * Perform common duties while attaching to interface list
        !           340:  */
        !           341: void
        !           342: atm_ifattach(ifp)
        !           343:        struct ifnet *ifp;
        !           344: {
        !           345:
        !           346:        ifp->if_type = IFT_ATM;
        !           347:        ifp->if_addrlen = 0;
        !           348:        ifp->if_hdrlen = 0;
        !           349:        ifp->if_mtu = ATMMTU;
        !           350:        ifp->if_output = atm_output;
        !           351:
        !           352:        if_alloc_sadl(ifp);
        !           353: #ifdef notyet /* if using ATMARP, store hardware address using the next line */
        !           354:        bcopy(ifp->hw_addr, LLADDR(ifp->if_sadl), ifp->if_addrlen);
        !           355: #endif
        !           356: }

CVSweb