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/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) 1982, 1986, 1993
    3  *      The Regents of the University of California.  All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 3. All advertising materials mentioning features or use of this software
   14  *    must display the following acknowledgement:
   15  *      This product includes software developed by the University of
   16  *      California, Berkeley and its contributors.
   17  * 4. Neither the name of the University nor the names of its contributors
   18  *    may be used to endorse or promote products derived from this software
   19  *    without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   31  * SUCH DAMAGE.
   32  *
   33  *      @(#)if_loop.c   8.1 (Berkeley) 6/10/93
   34  * $FreeBSD: src/sys/net/if_loop.c,v 1.22.2.2 1999/09/05 08:17:39 peter Exp $
   35  */
   36 
   37 /*
   38  * Loopback interface driver for protocol testing and timing.
   39  */
   40 #include "loop.h"
   41 #if NLOOP > 0
   42 
   43 #include <sys/param.h>
   44 #include <sys/systm.h>
   45 #include <sys/kernel.h>
   46 #include <sys/mbuf.h>
   47 #include <sys/socket.h>
   48 #include <sys/errno.h>
   49 #include <sys/ioctl.h>
   50 #include <sys/time.h>
   51 
   52 #include <net/if.h>
   53 #include <net/if_types.h>
   54 #include <net/netisr.h>
   55 #include <net/route.h>
   56 #include <net/bpf.h>
   57 
   58 #ifdef  INET
   59 #include <netinet/in.h>
   60 #include <netinet/in_systm.h>
   61 #include <netinet/in_var.h>
   62 #include <netinet/ip.h>
   63 #endif
   64 
   65 #ifdef IPX
   66 #include <netipx/ipx.h>
   67 #include <netipx/ipx_if.h>
   68 #endif
   69 
   70 #ifdef NS
   71 #include <netns/ns.h>
   72 #include <netns/ns_if.h>
   73 #endif
   74 
   75 #ifdef ISO
   76 #include <netiso/iso.h>
   77 #include <netiso/iso_var.h>
   78 #endif
   79 
   80 #ifdef NETATALK
   81 #include <netinet/if_ether.h>
   82 #include <netatalk/at.h>
   83 #include <netatalk/at_var.h>
   84 #endif NETATALK
   85 
   86 #include "bpfilter.h"
   87 
   88 static int loioctl __P((struct ifnet *, int, caddr_t));
   89 static void lortrequest __P((int, struct rtentry *, struct sockaddr *));
   90 
   91 static void loopattach __P((void *));
   92 PSEUDO_SET(loopattach, if_loop);
   93 
   94 #ifdef TINY_LOMTU
   95 #define LOMTU   (1024+512)
   96 #else
   97 #define LOMTU   16384
   98 #endif
   99 
  100 struct  ifnet loif[NLOOP];
  101 
  102 /* ARGSUSED */
  103 static void
  104 loopattach(dummy)
  105         void *dummy;
  106 {
  107         register struct ifnet *ifp;
  108         register int i = 0;
  109 
  110         for (ifp = loif; i < NLOOP; ifp++) {
  111             ifp->if_name = "lo";
  112             ifp->if_next = NULL;
  113             ifp->if_unit = i++;
  114             ifp->if_mtu = LOMTU;
  115             ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
  116             ifp->if_ioctl = loioctl;
  117             ifp->if_output = looutput;
  118             ifp->if_type = IFT_LOOP;
  119             ifp->if_hdrlen = 0;
  120             ifp->if_addrlen = 0;
  121             if_attach(ifp);
  122 #if NBPFILTER > 0
  123             bpfattach(ifp, DLT_NULL, sizeof(u_int));
  124 #endif
  125         }
  126 }
  127 
  128 int
  129 looutput(ifp, m, dst, rt)
  130         struct ifnet *ifp;
  131         register struct mbuf *m;
  132         struct sockaddr *dst;
  133         register struct rtentry *rt;
  134 {
  135         int s, isr;
  136         register struct ifqueue *ifq = 0;
  137 
  138         if ((m->m_flags & M_PKTHDR) == 0)
  139                 panic("looutput no HDR");
  140 #if NBPFILTER > 0
  141         /* BPF write needs to be handled specially */
  142         if (dst->sa_family == AF_UNSPEC) {
  143                 dst->sa_family = *(mtod(m, int *));
  144                 m->m_len -= sizeof(int);
  145                 m->m_pkthdr.len -= sizeof(int);
  146                 m->m_data += sizeof(int);
  147         }
  148 
  149         if (ifp->if_bpf) {
  150                 /*
  151                  * We need to prepend the address family as
  152                  * a four byte field.  Cons up a dummy header
  153                  * to pacify bpf.  This is safe because bpf
  154                  * will only read from the mbuf (i.e., it won't
  155                  * try to free it or keep a pointer a to it).
  156                  */
  157                 struct mbuf m0;
  158                 u_int af = dst->sa_family;
  159 
  160                 m0.m_next = m;
  161                 m0.m_len = 4;
  162                 m0.m_data = (char *)&af;
  163 
  164                 bpf_mtap(ifp, &m0);
  165         }
  166 #endif
  167         m->m_pkthdr.rcvif = ifp;
  168 
  169         if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
  170                 m_freem(m);
  171                 return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
  172                         rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
  173         }
  174         ifp->if_opackets++;
  175         ifp->if_obytes += m->m_pkthdr.len;
  176         switch (dst->sa_family) {
  177 
  178 #ifdef INET
  179         case AF_INET:
  180                 ifq = &ipintrq;
  181                 isr = NETISR_IP;
  182                 break;
  183 #endif
  184 #ifdef IPX
  185         case AF_IPX:
  186                 ifq = &ipxintrq;
  187                 isr = NETISR_IPX;
  188                 break;
  189 #endif
  190 #ifdef NS
  191         case AF_NS:
  192                 ifq = &nsintrq;
  193                 isr = NETISR_NS;
  194                 break;
  195 #endif
  196 #ifdef ISO
  197         case AF_ISO:
  198                 ifq = &clnlintrq;
  199                 isr = NETISR_ISO;
  200                 break;
  201 #endif
  202 #ifdef NETATALK
  203         case AF_APPLETALK:
  204                 ifq = &atintrq2;
  205                 isr = NETISR_ATALK;
  206                 break;
  207 #endif NETATALK
  208         default:
  209                 printf("lo%d: can't handle af%d\n", ifp->if_unit,
  210                         dst->sa_family);
  211                 m_freem(m);
  212                 return (EAFNOSUPPORT);
  213         }
  214         s = splimp();
  215         if (IF_QFULL(ifq)) {
  216                 IF_DROP(ifq);
  217                 m_freem(m);
  218                 splx(s);
  219                 return (ENOBUFS);
  220         }
  221         IF_ENQUEUE(ifq, m);
  222         schednetisr(isr);
  223         ifp->if_ipackets++;
  224         ifp->if_ibytes += m->m_pkthdr.len;
  225         splx(s);
  226         return (0);
  227 }
  228 
  229 /* ARGSUSED */
  230 static void
  231 lortrequest(cmd, rt, sa)
  232         int cmd;
  233         struct rtentry *rt;
  234         struct sockaddr *sa;
  235 {
  236         if (rt) {
  237                 rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu; /* for ISO */
  238                 /*
  239                  * For optimal performance, the send and receive buffers
  240                  * should be at least twice the MTU plus a little more for
  241                  * overhead.
  242                  */
  243                 rt->rt_rmx.rmx_recvpipe = 
  244                         rt->rt_rmx.rmx_sendpipe = 3 * LOMTU;
  245         }
  246 }
  247 
  248 /*
  249  * Process an ioctl request.
  250  */
  251 /* ARGSUSED */
  252 static int
  253 loioctl(ifp, cmd, data)
  254         register struct ifnet *ifp;
  255         int cmd;
  256         caddr_t data;
  257 {
  258         register struct ifaddr *ifa;
  259         register struct ifreq *ifr = (struct ifreq *)data;
  260         register int error = 0;
  261 
  262         switch (cmd) {
  263 
  264         case SIOCSIFADDR:
  265                 ifp->if_flags |= IFF_UP | IFF_RUNNING;
  266                 ifa = (struct ifaddr *)data;
  267                 ifa->ifa_rtrequest = lortrequest;
  268                 /*
  269                  * Everything else is done at a higher level.
  270                  */
  271                 break;
  272 
  273         case SIOCADDMULTI:
  274         case SIOCDELMULTI:
  275                 if (ifr == 0) {
  276                         error = EAFNOSUPPORT;           /* XXX */
  277                         break;
  278                 }
  279                 switch (ifr->ifr_addr.sa_family) {
  280 
  281 #ifdef INET
  282                 case AF_INET:
  283                         break;
  284 #endif
  285 
  286                 default:
  287                         error = EAFNOSUPPORT;
  288                         break;
  289                 }
  290                 break;
  291 
  292         case SIOCSIFMTU:
  293                 ifp->if_mtu = ifr->ifr_mtu;
  294                 break;
  295 
  296         case SIOCSIFFLAGS:
  297                 break;
  298 
  299         default:
  300                 error = EINVAL;
  301         }
  302         return (error);
  303 }
  304 #endif /* NLOOP > 0 */

Cache object: f46c2e1a4ee1f5896aaac6f939e01c4c


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