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/if_loop.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, 1986, 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  *      @(#)if_loop.c   8.1 (Berkeley) 6/10/93
   58  * $FreeBSD: src/sys/net/if_loop.c,v 1.47.2.5 2001/07/03 11:01:41 ume Exp $
   59  */
   60 
   61 /*
   62  * Loopback interface driver for protocol testing and timing.
   63  */
   64 #include "loop.h"
   65 #if NLOOP > 0
   66 
   67 #include <sys/param.h>
   68 #include <sys/systm.h>
   69 #include <sys/kernel.h>
   70 #include <sys/mbuf.h>
   71 #include <sys/socket.h>
   72 #include <sys/sockio.h>
   73 
   74 #include <net/if.h>
   75 #include <net/if_types.h>
   76 #include <net/netisr.h>
   77 #include <net/route.h>
   78 #include <net/bpf.h>
   79 #include <sys/malloc.h>
   80 
   81 #if     INET
   82 #include <netinet/in.h>
   83 #include <netinet/in_var.h>
   84 #endif
   85 
   86 #if IPX
   87 #include <netipx/ipx.h>
   88 #include <netipx/ipx_if.h>
   89 #endif
   90 
   91 #if INET6
   92 #ifndef INET
   93 #include <netinet/in.h>
   94 #endif
   95 #include <netinet6/in6_var.h>
   96 #include <netinet/ip6.h>
   97 #endif
   98 
   99 #include <net/dlil.h>
  100 
  101 #if NETAT
  102 extern struct ifqueue atalkintrq;
  103 #endif
  104 
  105 #include "bpfilter.h"
  106 #if NBPFILTER > 0
  107 #include <net/bpfdesc.h>
  108 #endif
  109 
  110 #define NLOOP_ATTACHMENTS (NLOOP * 12)
  111 
  112 struct lo_statics_str {
  113         int     bpf_mode;
  114         int     (*bpf_callback)(struct ifnet *, struct mbuf *);
  115 };
  116 
  117 static struct if_proto *lo_array[NLOOP_ATTACHMENTS];
  118 static struct lo_statics_str lo_statics[NLOOP];
  119 static lo_count = 0;
  120 
  121 
  122 #ifdef TINY_LOMTU
  123 #define LOMTU   (1024+512)
  124 #else
  125 #define LOMTU   16384
  126 #endif
  127 
  128 struct  ifnet loif[NLOOP];
  129 
  130 void lo_reg_if_mods();
  131 
  132 
  133 
  134 
  135 int lo_demux(ifp, m, frame_header, proto)
  136     struct ifnet *ifp;
  137     struct mbuf  *m;
  138     char         *frame_header;
  139     struct if_proto **proto;
  140 {
  141     int i;
  142     struct if_proto **proto_ptr;
  143 
  144     proto_ptr = mtod(m, struct if_proto **);
  145     *proto = *proto_ptr;
  146     m_adj(m, sizeof(u_long));
  147     return 0;
  148 }
  149 
  150 
  151 int lo_framer(ifp, m, dest, dest_linkaddr, frame_type)
  152     struct ifnet    *ifp;
  153     struct mbuf     **m;
  154     struct sockaddr *dest;
  155     char            *dest_linkaddr;
  156     char            *frame_type;
  157 
  158 {
  159     char  *to_ptr;
  160 
  161         M_PREPEND(*m, (4 * sizeof(u_long)), M_WAITOK);
  162         to_ptr = mtod(*m, char *);
  163         bcopy(dest_linkaddr, to_ptr, (4 * sizeof(u_long)));
  164         return 0;
  165 }
  166 
  167 static
  168 int  lo_add_if(struct ifnet *ifp)
  169 {
  170     ifp->if_demux  = lo_demux;
  171     ifp->if_framer = lo_framer;
  172     ifp->if_event  = 0;
  173     return 0;
  174 }
  175 
  176 static
  177 int  lo_del_if(struct ifnet *ifp)
  178 {
  179     return 0;
  180 }
  181 
  182 
  183 
  184 
  185 static
  186 int  lo_add_proto(struct ddesc_head_str *desc_head, struct if_proto *proto, u_long dl_tag)
  187 {
  188     int i;
  189 
  190     for (i=0; i < lo_count; i++)
  191         if (lo_array[i] == 0) {
  192             lo_array[lo_count] = proto;
  193             return 0;
  194         }
  195 
  196     if ((i == lo_count) && (lo_count == NLOOP_ATTACHMENTS))
  197        panic("lo_add_proto -- Too many attachments\n");
  198 
  199     lo_array[lo_count++] = proto;
  200     return 0;
  201 }
  202 
  203 
  204 static
  205 int  lo_del_proto(struct if_proto *proto, u_long dl_tag)
  206 {
  207     int i;
  208 
  209     for (i=0; i < lo_count; i++)
  210         if (lo_array[i] == proto) {
  211             lo_array[i] = 0;
  212             return 0;
  213         }
  214 
  215     return ENOENT;
  216 }
  217 
  218 static int
  219 lo_output(ifp, m)
  220         struct ifnet *ifp;
  221         register struct mbuf *m;
  222 {       u_int  *prepend_ptr;
  223         u_int  af;
  224         u_long saved_header[3];
  225 
  226         if ((m->m_flags & M_PKTHDR) == 0)
  227                 panic("lo_output: no HDR");
  228 
  229         /*
  230          * Don't overwrite the rcvif field if it is in use.
  231          *  This is used to match multicast packets, sent looping
  232          *  back, with the appropriate group record on input.
  233          */
  234         if (m->m_pkthdr.rcvif == NULL)
  235                 m->m_pkthdr.rcvif = ifp;
  236         prepend_ptr = mtod(m, u_int *);
  237         af = *prepend_ptr;
  238         m_adj(m, sizeof(u_int));
  239 
  240 
  241 #if NBPFILTER > 0
  242         if (lo_statics[ifp->if_unit].bpf_mode != BPF_TAP_DISABLE) {
  243                 struct mbuf m0, *n;
  244 
  245                 bcopy(mtod(m, caddr_t), &saved_header[0], (3 * sizeof(u_long)));
  246                 m_adj(m, (3 * sizeof(u_long)));
  247 
  248                 n = m;
  249                 if (ifp->if_bpf->bif_dlt == DLT_NULL) {
  250                         /*
  251                          * We need to prepend the address family as
  252                          * a four byte field.  Cons up a dummy header
  253                          * to pacify bpf.  This is safe because bpf
  254                          * will only read from the mbuf (i.e., it won't
  255                          * try to free it or keep a pointer a to it).
  256                          */
  257                         m0.m_next = m;
  258                         m0.m_len = 4;
  259                         m0.m_data = (char *)&af;
  260                         n = &m0;
  261                 }
  262 
  263                 (*lo_statics[ifp->if_unit].bpf_callback)(ifp, n);
  264 
  265                 M_PREPEND(m, (3 * sizeof(u_long)), M_WAITOK);
  266                 bcopy(&saved_header[0], mtod(m, caddr_t), (3 * sizeof(u_long)));
  267 
  268         }
  269 #endif
  270 
  271         ifp->if_ibytes += m->m_pkthdr.len;
  272         ifp->if_obytes += m->m_pkthdr.len;
  273 
  274         ifp->if_opackets++;
  275         ifp->if_ipackets++;
  276 
  277         m->m_pkthdr.header = mtod(m, char *);
  278         m->m_pkthdr.csum_data = 0xffff; /* loopback checksums are always OK */
  279         m->m_pkthdr.csum_flags = CSUM_DATA_VALID | CSUM_PSEUDO_HDR | 
  280                                                          CSUM_IP_CHECKED | CSUM_IP_VALID;
  281         return dlil_input(ifp, m, m);
  282 }
  283 
  284 
  285 /*
  286  * This is a common pre-output route used by INET, AT, etc. This could
  287  * (should?) be split into separate pre-output routines for each protocol.
  288  */
  289 
  290 static int
  291 lo_pre_output(ifp, m, dst, route, frame_type, dst_addr, dl_tag)
  292         struct ifnet *ifp;
  293         register struct mbuf **m;
  294         struct sockaddr *dst;
  295         void                 *route;
  296         char                 *frame_type;
  297         char                 *dst_addr;
  298         u_long               dl_tag;
  299 
  300 {
  301         int s, isr;
  302         register struct ifqueue *ifq = 0;
  303         u_long *prepend_ptr;
  304         register struct rtentry *rt = (struct rtentry *) route;
  305 
  306         prepend_ptr = (u_long *) dst_addr;
  307         if (((*m)->m_flags & M_PKTHDR) == 0)
  308                 panic("looutput no HDR");
  309 
  310         if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
  311             if (rt->rt_flags & RTF_BLACKHOLE) {
  312                 m_freem(*m);
  313                 return EJUSTRETURN;
  314             }
  315             else
  316                 return ((rt->rt_flags & RTF_HOST) ? EHOSTUNREACH : ENETUNREACH);
  317         }
  318 
  319         switch (dst->sa_family) {
  320 #if INET
  321         case AF_INET:
  322             ifq = &ipintrq;
  323             isr = NETISR_IP;
  324             break;
  325 #endif
  326 #if INET6
  327         case AF_INET6:
  328             (*m)->m_flags |= M_LOOP;
  329             ifq = &ip6intrq;
  330             isr = NETISR_IPV6;
  331             break;
  332 #endif
  333 #if IPX
  334         case AF_IPX:
  335             ifq = &ipxintrq;
  336             isr = NETISR_IPX;
  337             break;
  338 #endif
  339 #if NS
  340         case AF_NS:
  341             ifq = &nsintrq;
  342             isr = NETISR_NS;
  343             break;
  344 #endif
  345 #if ISO
  346         case AF_ISO:
  347             ifq = &clnlintrq;
  348             isr = NETISR_ISO;
  349             break;
  350 #endif
  351 #if NETAT
  352         case AF_APPLETALK:
  353             ifq = &atalkintrq;
  354             isr = NETISR_APPLETALK;
  355             break;
  356 #endif /* NETAT */
  357         default:
  358             return (EAFNOSUPPORT);
  359         }
  360 
  361         *prepend_ptr++ = dst->sa_family;        /* For lo_output(BPF) */
  362         *prepend_ptr++ = dlttoproto(dl_tag);    /* For lo_demux */
  363         *prepend_ptr++ = (u_long) ifq;          /* For lo_input */
  364         *prepend_ptr   = isr;                   /* For lo_input */
  365 
  366         return 0;
  367 }
  368 
  369 
  370 
  371 
  372 /*
  373  *  lo_input - This should work for all attached protocols that use the
  374  *             ifq/schednetisr input mechanism.
  375  */
  376 
  377 
  378 int
  379 lo_input(m, fh, ifp, dl_tag, sync_ok)
  380         register struct mbuf *m;
  381         char         *fh;
  382         struct ifnet *ifp;
  383         u_long       dl_tag;
  384         int sync_ok;
  385 
  386 {
  387         u_long *prepend_ptr;
  388         int s, isr;
  389         register struct ifqueue *ifq = 0;
  390 
  391         prepend_ptr = mtod(m, u_long *);
  392         ifq = (struct ifqueue *) *prepend_ptr++;
  393         isr = *prepend_ptr;
  394         m_adj(m, (2 * sizeof(u_long)));
  395 
  396         s = splimp();
  397         if (IF_QFULL(ifq)) {
  398                 IF_DROP(ifq);
  399                 m_freem(m);
  400                 splx(s);
  401                 return (EJUSTRETURN);
  402         }
  403 
  404         IF_ENQUEUE(ifq, m);
  405         schednetisr(isr);
  406         splx(s);
  407         return (0);
  408 }
  409 
  410 
  411 
  412 
  413 /* ARGSUSED */
  414 static void
  415 lortrequest(cmd, rt, sa)
  416         int cmd;
  417         struct rtentry *rt;
  418         struct sockaddr *sa;
  419 {
  420         if (rt) {
  421                 rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu; /* for ISO */
  422                 /*
  423                  * For optimal performance, the send and receive buffers
  424                  * should be at least twice the MTU plus a little more for
  425                  * overhead.
  426                  */
  427                 rt->rt_rmx.rmx_recvpipe = 
  428                         rt->rt_rmx.rmx_sendpipe = 3 * LOMTU;
  429         }
  430 }
  431 
  432 /*
  433  * Process an ioctl request.
  434  */
  435 /* ARGSUSED */
  436 static int
  437 loioctl(dl_tag, ifp, cmd, data)
  438         u_long   dl_tag;
  439         register struct ifnet *ifp;
  440         u_long cmd;
  441         void   *data;
  442 {
  443         register struct ifaddr *ifa;
  444         register struct ifreq *ifr = (struct ifreq *)data;
  445         register int error = 0;
  446 
  447         switch (cmd) {
  448 
  449         case SIOCSIFADDR:
  450                 ifp->if_flags |= IFF_UP | IFF_RUNNING;
  451                 ifa = (struct ifaddr *)data;
  452                 ifa->ifa_rtrequest = lortrequest;
  453                 /*
  454                  * Everything else is done at a higher level.
  455                  */
  456                 break;
  457 
  458         case SIOCADDMULTI:
  459         case SIOCDELMULTI:
  460                 if (ifr == 0) {
  461                         error = EAFNOSUPPORT;           /* XXX */
  462                         break;
  463                 }
  464                 switch (ifr->ifr_addr.sa_family) {
  465 
  466 #if INET
  467                 case AF_INET:
  468                         break;
  469 #endif
  470 #if INET6
  471                 case AF_INET6:
  472                         break;
  473 #endif
  474 
  475                 default:
  476                         error = EAFNOSUPPORT;
  477                         break;
  478                 }
  479                 break;
  480 
  481         case SIOCSIFMTU:
  482                 ifp->if_mtu = ifr->ifr_mtu;
  483                 break;
  484 
  485         case SIOCSIFFLAGS:
  486                 break;
  487 
  488         default:
  489                 error = EOPNOTSUPP;
  490         }
  491         return (error);
  492 }
  493 #endif /* NLOOP > 0 */
  494 
  495 
  496 int lo_shutdown()
  497 {
  498     return 0;
  499 }
  500 
  501 int  lo_attach_inet(struct ifnet *ifp, u_long *dl_tag)
  502 {
  503     struct dlil_proto_reg_str   reg;
  504     struct dlil_demux_desc      desc;
  505     short native=0;
  506     int   stat =0 ;
  507     int i;
  508 
  509     for (i=0; i < lo_count; i++) {
  510         if ((lo_array[i]) && (lo_array[i]->ifp == ifp)) {
  511             if (lo_array[i]->protocol_family == PF_INET) {
  512                 *dl_tag = lo_array[i]->dl_tag;
  513                 return (0);
  514             }
  515         }
  516     }
  517 
  518     TAILQ_INIT(&reg.demux_desc_head);
  519     desc.type = DLIL_DESC_RAW;
  520     desc.variants.bitmask.proto_id_length = 0;
  521     desc.variants.bitmask.proto_id = 0;
  522     desc.variants.bitmask.proto_id_mask = 0;
  523     desc.native_type = (char *) &native;
  524     TAILQ_INSERT_TAIL(&reg.demux_desc_head, &desc, next);
  525     reg.interface_family = ifp->if_family;
  526     reg.unit_number      = ifp->if_unit;
  527     reg.input            = lo_input;
  528     reg.pre_output       = lo_pre_output;
  529     reg.event            = 0;
  530     reg.offer            = 0;
  531     reg.ioctl            = loioctl;
  532     reg.default_proto    = 0;
  533     reg.protocol_family  = PF_INET;
  534 
  535     stat = dlil_attach_protocol(&reg, dl_tag);
  536 
  537     if (stat)
  538         printf("lo_attach_inet: dlil_attach_protocol returned=%d\n", stat);
  539     
  540     return stat;
  541 }
  542 
  543 int  lo_attach_inet6(struct ifnet *ifp, u_long *dl_tag)
  544 {
  545     struct dlil_proto_reg_str   reg;
  546     struct dlil_demux_desc      desc;
  547     short native=0;
  548     int   stat;
  549     int i;
  550 
  551     for (i=0; i < lo_count; i++) {
  552         if ((lo_array[i]) && (lo_array[i]->ifp == ifp)) {
  553             if (lo_array[i]->protocol_family == PF_INET6) {
  554                 *dl_tag = lo_array[i]->dl_tag;
  555                 return (0);
  556             }
  557         }
  558     }
  559 
  560     TAILQ_INIT(&reg.demux_desc_head);
  561     desc.type = DLIL_DESC_RAW;
  562     desc.variants.bitmask.proto_id_length = 0;
  563     desc.variants.bitmask.proto_id = 0;
  564     desc.variants.bitmask.proto_id_mask = 0;
  565     desc.native_type = (char *) &native;
  566     TAILQ_INSERT_TAIL(&reg.demux_desc_head, &desc, next);
  567     reg.interface_family = ifp->if_family;
  568     reg.unit_number      = ifp->if_unit;
  569     reg.input            = lo_input;
  570     reg.pre_output       = lo_pre_output;
  571     reg.event            = 0;
  572     reg.offer            = 0;
  573     reg.ioctl            = loioctl;
  574     reg.default_proto    = 0;
  575     reg.protocol_family  = PF_INET6;
  576 
  577     stat = dlil_attach_protocol(&reg, dl_tag);
  578 
  579     if (stat)
  580         printf("lo_attach_inet6: dlil_attach_protocol returned=%d\n", stat);
  581     
  582     return stat;
  583 }
  584 
  585 void lo_reg_if_mods()
  586 {
  587      struct dlil_ifmod_reg_str  lo_ifmod;
  588      struct dlil_protomod_reg_str lo_protoreg;
  589      int error;
  590 
  591      bzero(&lo_ifmod, sizeof(lo_ifmod));
  592      lo_ifmod.add_if = lo_add_if;
  593      lo_ifmod.del_if = lo_del_if;
  594      lo_ifmod.add_proto = lo_add_proto;
  595      lo_ifmod.del_proto = lo_del_proto;
  596      lo_ifmod.ifmod_ioctl = 0;
  597      lo_ifmod.shutdown    = lo_shutdown;
  598 
  599         if (dlil_reg_if_modules(APPLE_IF_FAM_LOOPBACK, &lo_ifmod))
  600                 panic("Couldn't register lo modules\n");
  601 
  602         /* Register protocol registration functions */
  603 
  604         bzero(&lo_protoreg, sizeof(lo_protoreg));
  605         lo_protoreg.attach_proto = lo_attach_inet;
  606         lo_protoreg.detach_proto = NULL; /* no detach function for loopback */
  607         
  608         if ( error = dlil_reg_proto_module(PF_INET, APPLE_IF_FAM_LOOPBACK, &lo_protoreg) != 0)
  609                 printf("dlil_reg_proto_module failed for AF_INET error=%d\n", error);
  610 
  611         lo_protoreg.attach_proto = lo_attach_inet6;
  612         lo_protoreg.detach_proto = NULL;
  613         
  614         if ( error = dlil_reg_proto_module(PF_INET6, APPLE_IF_FAM_LOOPBACK, &lo_protoreg) != 0)
  615                 printf("dlil_reg_proto_module failed for AF_INET6 error=%d\n", error);
  616 
  617 }
  618 
  619 int lo_set_bpf_tap(struct ifnet *ifp, int mode, int (*bpf_callback)(struct ifnet *, struct mbuf *))
  620 {
  621 
  622   /*
  623    * NEED MUTEX HERE XXX
  624    */
  625         if (mode == BPF_TAP_DISABLE) {
  626                 lo_statics[ifp->if_unit].bpf_mode = mode;
  627                 lo_statics[ifp->if_unit].bpf_callback = bpf_callback;
  628         }
  629         else {
  630                 lo_statics[ifp->if_unit].bpf_callback = bpf_callback;
  631                 lo_statics[ifp->if_unit].bpf_mode = mode;               
  632         }
  633 
  634         return 0;
  635 }
  636 
  637 
  638 /* ARGSUSED */
  639 void
  640 loopattach(dummy)
  641         void *dummy;
  642 {
  643         register struct ifnet *ifp;
  644         register int i = 0;
  645 
  646         thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
  647         lo_reg_if_mods();
  648 
  649         for (ifp = loif; i < NLOOP; ifp++) {
  650                 lo_statics[i].bpf_callback = 0;
  651                 lo_statics[i].bpf_mode      = BPF_TAP_DISABLE;
  652                 ifp->if_name = "lo";
  653                 ifp->if_family = APPLE_IF_FAM_LOOPBACK;
  654                 ifp->if_unit = i++;
  655                 ifp->if_mtu = LOMTU;
  656                 ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
  657                 ifp->if_ioctl = loioctl;
  658                 ifp->if_set_bpf_tap = lo_set_bpf_tap;
  659                 ifp->if_output = lo_output;
  660                 ifp->if_type = IFT_LOOP;
  661                 ifp->if_hwassist = 0; /* HW cksum on send side breaks Classic loopback */
  662                 dlil_if_attach(ifp);
  663 #if NBPFILTER > 0
  664                 bpfattach(ifp, DLT_NULL, sizeof(u_int));
  665 #endif
  666         }
  667         thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
  668 }

Cache object: 8f2abff672b20de9da5d77eabe0eacca


[ 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.