The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/bsd/net/ether_inet6_pr_module.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
    3  *
    4  * @APPLE_LICENSE_HEADER_START@
    5  * 
    6  * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
    7  * 
    8  * This file contains Original Code and/or Modifications of Original Code
    9  * as defined in and that are subject to the Apple Public Source License
   10  * Version 2.0 (the 'License'). You may not use this file except in
   11  * compliance with the License. Please obtain a copy of the License at
   12  * http://www.opensource.apple.com/apsl/ and read it before using this
   13  * file.
   14  * 
   15  * The Original Code and all software distributed under the License are
   16  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
   17  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   18  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   19  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
   20  * Please see the License for the specific language governing rights and
   21  * limitations under the License.
   22  * 
   23  * @APPLE_LICENSE_HEADER_END@
   24  */
   25 /*
   26  * Copyright (c) 1982, 1989, 1993
   27  *      The Regents of the University of California.  All rights reserved.
   28  *
   29  * Redistribution and use in source and binary forms, with or without
   30  * modification, are permitted provided that the following conditions
   31  * are met:
   32  * 1. Redistributions of source code must retain the above copyright
   33  *    notice, this list of conditions and the following disclaimer.
   34  * 2. Redistributions in binary form must reproduce the above copyright
   35  *    notice, this list of conditions and the following disclaimer in the
   36  *    documentation and/or other materials provided with the distribution.
   37  * 3. All advertising materials mentioning features or use of this software
   38  *    must display the following acknowledgement:
   39  *      This product includes software developed by the University of
   40  *      California, Berkeley and its contributors.
   41  * 4. Neither the name of the University nor the names of its contributors
   42  *    may be used to endorse or promote products derived from this software
   43  *    without specific prior written permission.
   44  *
   45  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   46  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   47  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   48  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   49  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   50  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   51  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   52  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   53  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   54  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   55  * SUCH DAMAGE.
   56  *
   57  */
   58 
   59 
   60 
   61 #include <sys/param.h>
   62 #include <sys/systm.h>
   63 #include <sys/kernel.h>
   64 #include <sys/malloc.h>
   65 #include <sys/mbuf.h>
   66 #include <sys/socket.h>
   67 #include <sys/sockio.h>
   68 #include <sys/sysctl.h>
   69 
   70 #include <net/if.h>
   71 #include <net/netisr.h>
   72 #include <net/route.h>
   73 #include <net/if_llc.h>
   74 #include <net/if_dl.h>
   75 #include <net/if_types.h>
   76 #include <net/ndrv.h>
   77 
   78 #include <netinet/in.h>
   79 #include <netinet/in_var.h>
   80 #include <netinet/if_ether.h>
   81 #include <netinet/in_systm.h>
   82 #include <netinet/ip.h>
   83 
   84 #if INET6
   85 #include <netinet6/nd6.h>
   86 #include <netinet6/in6_ifattach.h>
   87 #endif
   88 
   89 
   90 
   91 #include <sys/socketvar.h>
   92 
   93 #include <net/dlil.h>
   94 
   95 
   96 #if LLC && CCITT
   97 extern struct ifqueue pkintrq;
   98 #endif
   99 
  100 
  101 #if BRIDGE
  102 #include <net/bridge.h>
  103 #endif
  104 
  105 /* #include "vlan.h" */
  106 #if NVLAN > 0
  107 #include <net/if_vlan_var.h>
  108 #endif /* NVLAN > 0 */
  109 
  110 static u_long lo_dlt = 0;
  111 static ivedonethis = 0;
  112 static u_char   etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  113 
  114 #define IFP2AC(IFP) ((struct arpcom *)IFP)
  115 
  116 
  117 
  118 
  119 /*
  120  * Process a received Ethernet packet;
  121  * the packet is in the mbuf chain m without
  122  * the ether header, which is provided separately.
  123  */
  124 int
  125 inet6_ether_input(m, frame_header, ifp, dl_tag, sync_ok)
  126     struct mbuf  *m;
  127     char         *frame_header;
  128     struct ifnet *ifp;
  129     u_long           dl_tag;
  130     int          sync_ok;
  131 
  132 {
  133     register struct ether_header *eh = (struct ether_header *) frame_header;
  134     register struct ifqueue *inq=0;
  135     u_short ether_type;
  136     int s;
  137     u_int16_t ptype = -1;
  138     unsigned char buf[18];
  139 
  140 
  141 
  142     if ((ifp->if_flags & IFF_UP) == 0) {
  143          m_freem(m);
  144          return EJUSTRETURN;
  145     }
  146 
  147     ifp->if_lastchange = time;
  148 
  149     if (eh->ether_dhost[0] & 1) {
  150         if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
  151                  sizeof(etherbroadcastaddr)) == 0)
  152             m->m_flags |= M_BCAST;
  153         else
  154             m->m_flags |= M_MCAST;
  155     }
  156     if (m->m_flags & (M_BCAST|M_MCAST))
  157         ifp->if_imcasts++;
  158 
  159     ether_type = ntohs(eh->ether_type);
  160 
  161 
  162     switch (ether_type) {
  163 
  164     case ETHERTYPE_IPV6:
  165         schednetisr(NETISR_IPV6);
  166         inq = &ip6intrq;
  167         break;
  168 
  169     default: {
  170         return ENOENT;
  171         }
  172     }
  173 
  174     if (inq == 0)
  175         return ENOENT;
  176 
  177         s = splimp();
  178         if (IF_QFULL(inq)) {
  179                 IF_DROP(inq);
  180                 m_freem(m);
  181                 splx(s);
  182                 return EJUSTRETURN;
  183         } else
  184                 IF_ENQUEUE(inq, m);
  185         splx(s);
  186 
  187 
  188     return 0;
  189 }
  190 
  191 
  192 
  193 
  194 int
  195 inet6_ether_pre_output(ifp, m0, dst_netaddr, route, type, edst, dl_tag )
  196     struct ifnet    *ifp;
  197     struct mbuf     **m0;
  198     struct sockaddr *dst_netaddr;
  199     caddr_t         route;
  200     char            *type;
  201     char            *edst;
  202     u_long          dl_tag;
  203 {
  204     struct rtentry  *rt0 = (struct rtentry *) route;
  205     int s;
  206     register struct mbuf *m = *m0;
  207     register struct rtentry *rt;
  208     register struct ether_header *eh;
  209     int hlen;   /* link layer header lenght */
  210     struct arpcom *ac = IFP2AC(ifp);
  211 
  212 
  213 
  214     if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) 
  215         return ENETDOWN;
  216 
  217     rt = rt0;
  218     if (rt) {
  219         if ((rt->rt_flags & RTF_UP) == 0) {
  220             rt0 = rt = rtalloc1(dst_netaddr, 1, 0UL);
  221             if (rt0)
  222                 rtunref(rt);
  223             else
  224                 return EHOSTUNREACH;
  225         }
  226 
  227         if (rt->rt_flags & RTF_GATEWAY) {
  228             if (rt->rt_gwroute == 0)
  229                 goto lookup;
  230             if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
  231                 rtfree(rt); rt = rt0;
  232             lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1,
  233                                               0UL);
  234                 if ((rt = rt->rt_gwroute) == 0)
  235                     return (EHOSTUNREACH);
  236             }
  237         }
  238 
  239         
  240         if (rt->rt_flags & RTF_REJECT)
  241             if (rt->rt_rmx.rmx_expire == 0 ||
  242                 time_second < rt->rt_rmx.rmx_expire)
  243                 return (rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
  244     }
  245 
  246     hlen = ETHER_HDR_LEN;
  247 
  248     /*
  249      * Tell ether_frameout it's ok to loop packet unless negated below.
  250      */
  251     m->m_flags |= M_LOOP;
  252 
  253     switch (dst_netaddr->sa_family) {
  254 
  255 
  256     case AF_INET6:
  257         if (!nd6_storelladdr(&ac->ac_if, rt, m, dst_netaddr, (u_char *)edst)) {
  258              /* this must be impossible, so we bark */
  259              printf("nd6_storelladdr failed\n");
  260              return(EADDRNOTAVAIL); /* dlil_output will free the mbuf */
  261                 }
  262        *(u_short *)type = htons(ETHERTYPE_IPV6);
  263        break;
  264 
  265     default:
  266         printf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit,
  267                dst_netaddr->sa_family);
  268 
  269         /* dlil_output will free the mbuf */
  270         return EAFNOSUPPORT;
  271     }
  272 
  273     return (0);
  274 }
  275 
  276 
  277 int
  278 ether_inet6_prmod_ioctl(dl_tag, ifp, command, data)
  279     u_long       dl_tag;
  280     struct ifnet *ifp;
  281     int          command;
  282     caddr_t      data;
  283 {
  284     struct ifaddr *ifa = (struct ifaddr *) data;
  285     struct ifreq *ifr = (struct ifreq *) data;
  286     struct rslvmulti_req *rsreq = (struct rslvmulti_req *) data;
  287     int error = 0;
  288     boolean_t funnel_state;
  289     struct arpcom *ac = (struct arpcom *) ifp;
  290     struct sockaddr_dl *sdl;
  291     struct sockaddr_in *sin;
  292     struct sockaddr_in6 *sin6;
  293 
  294     u_char *e_addr;
  295 
  296 
  297     switch (command) {
  298     case SIOCRSLVMULTI: {
  299         switch(rsreq->sa->sa_family) {
  300 
  301         case AF_INET6:
  302                 sin6 = (struct sockaddr_in6 *)rsreq->sa;
  303                 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
  304                         /*
  305                          * An IP6 address of 0 means listen to all
  306                          * of the Ethernet multicast address used for IP6.
  307                          * (This is used for multicast routers.)
  308                          */
  309                         ifp->if_flags |= IFF_ALLMULTI;
  310                         *rsreq->llsa = 0;
  311                         return 0;
  312                 }
  313                 MALLOC(sdl, struct sockaddr_dl *, sizeof *sdl, M_IFMADDR,
  314                        M_WAITOK);
  315                 sdl->sdl_len = sizeof *sdl;
  316                 sdl->sdl_family = AF_LINK;
  317                 sdl->sdl_index = ifp->if_index;
  318                 sdl->sdl_type = IFT_ETHER;
  319                 sdl->sdl_nlen = 0;
  320                 sdl->sdl_alen = ETHER_ADDR_LEN;
  321                 sdl->sdl_slen = 0;
  322                 e_addr = LLADDR(sdl);
  323                 ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, e_addr);
  324 #ifndef __APPLE__
  325                 printf("ether_resolvemulti AF_INET6 Adding %x:%x:%x:%x:%x:%x\n",
  326                                 e_addr[0], e_addr[1], e_addr[2], e_addr[3], e_addr[4], e_addr[5]);
  327 #endif
  328                 *rsreq->llsa = (struct sockaddr *)sdl;
  329                 return 0;
  330 
  331         default:
  332                 /* 
  333                  * Well, the text isn't quite right, but it's the name
  334                  * that counts...
  335                  */
  336                 return EAFNOSUPPORT;
  337         }
  338 
  339     }
  340     case SIOCSIFADDR:
  341          if ((ifp->if_flags & IFF_RUNNING) == 0) {
  342               ifp->if_flags |= IFF_UP;
  343               dlil_ioctl(0, ifp, SIOCSIFFLAGS, (caddr_t) 0);
  344          }
  345 
  346         break;
  347 
  348     case SIOCGIFADDR:
  349     {
  350         struct sockaddr *sa;
  351 
  352         sa = (struct sockaddr *) & ifr->ifr_data;
  353         bcopy(IFP2AC(ifp)->ac_enaddr,
  354               (caddr_t) sa->sa_data, ETHER_ADDR_LEN);
  355     }
  356     break;
  357 
  358     case SIOCSIFMTU:
  359         /*
  360          * IOKit IONetworkFamily will set the right MTU according to the driver
  361          */
  362 
  363          return (0);
  364 
  365     default:
  366          return EOPNOTSUPP;
  367     }
  368 
  369     return (error);
  370 }
  371 
  372 
  373 
  374 
  375 
  376 int  ether_attach_inet6(struct ifnet *ifp, u_long *dl_tag)
  377 {
  378     struct dlil_proto_reg_str   reg;
  379     struct dlil_demux_desc      desc;
  380     u_short en_6native=ETHERTYPE_IPV6;
  381     int   stat;
  382     int i;
  383 
  384 
  385     stat = dlil_find_dltag(ifp->if_family, ifp->if_unit, PF_INET6, dl_tag);
  386     if (stat == 0)
  387          return stat;
  388 
  389     TAILQ_INIT(&reg.demux_desc_head);
  390     desc.type = DLIL_DESC_RAW;
  391     desc.variants.bitmask.proto_id_length = 0;
  392     desc.variants.bitmask.proto_id = 0;
  393     desc.variants.bitmask.proto_id_mask = 0;
  394     desc.native_type = (char *) &en_6native;
  395     TAILQ_INSERT_TAIL(&reg.demux_desc_head, &desc, next);
  396     reg.interface_family = ifp->if_family;
  397     reg.unit_number      = ifp->if_unit;
  398     reg.input            = inet6_ether_input;
  399     reg.pre_output       = inet6_ether_pre_output;
  400     reg.event            = 0;
  401     reg.offer            = 0;
  402     reg.ioctl            = ether_inet6_prmod_ioctl;
  403     reg.default_proto    = 0;
  404     reg.protocol_family  = PF_INET6;
  405 
  406     stat = dlil_attach_protocol(&reg, dl_tag);
  407     if (stat) {
  408         printf("WARNING: ether_attach_inet6 can't attach ip to interface\n");
  409     }
  410 
  411     return stat;
  412 }
  413 
  414 int  ether_detach_inet6(struct ifnet *ifp, u_long dl_tag)
  415 {
  416     int         stat;
  417 
  418     stat = dlil_find_dltag(ifp->if_family, ifp->if_unit, PF_INET6, &dl_tag);
  419     if (stat == 0) {
  420         stat = dlil_detach_protocol(dl_tag);
  421         if (stat) {
  422             printf("WARNING: ether_detach_inet6 can't detach ip6 from interface\n");
  423         }
  424     }
  425     return stat;
  426 }
  427 

Cache object: 3546ffb782d20020c34f2606856da894


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.