[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

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