LCOV - code coverage report
Current view: top level - net - if_loop.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 77 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: if_loop.c,v 1.88 2018/09/09 10:11:41 henning Exp $    */
       2             : /*      $NetBSD: if_loop.c,v 1.15 1996/05/07 02:40:33 thorpej Exp $     */
       3             : 
       4             : /*
       5             :  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
       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. Neither the name of the project nor the names of its contributors
      17             :  *    may be used to endorse or promote products derived from this software
      18             :  *    without specific prior written permission.
      19             :  *
      20             :  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
      21             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      22             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      23             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
      24             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      25             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      26             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      27             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      28             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      29             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      30             :  * SUCH DAMAGE.
      31             :  */
      32             : 
      33             : /*
      34             :  * Copyright (c) 1982, 1986, 1993
      35             :  *      The Regents of the University of California.  All rights reserved.
      36             :  *
      37             :  * Redistribution and use in source and binary forms, with or without
      38             :  * modification, are permitted provided that the following conditions
      39             :  * are met:
      40             :  * 1. Redistributions of source code must retain the above copyright
      41             :  *    notice, this list of conditions and the following disclaimer.
      42             :  * 2. Redistributions in binary form must reproduce the above copyright
      43             :  *    notice, this list of conditions and the following disclaimer in the
      44             :  *    documentation and/or other materials provided with the distribution.
      45             :  * 3. Neither the name of the University nor the names of its contributors
      46             :  *    may be used to endorse or promote products derived from this software
      47             :  *    without specific prior written permission.
      48             :  *
      49             :  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      50             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      51             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      52             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      53             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      54             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      55             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      56             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      57             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      58             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      59             :  * SUCH DAMAGE.
      60             :  *
      61             :  *      @(#)if_loop.c   8.1 (Berkeley) 6/10/93
      62             :  */
      63             : 
      64             : /*
      65             :  *      @(#)COPYRIGHT   1.1 (NRL) 17 January 1995
      66             :  *
      67             :  * NRL grants permission for redistribution and use in source and binary
      68             :  * forms, with or without modification, of the software and documentation
      69             :  * created at NRL provided that the following conditions are met:
      70             :  *
      71             :  * 1. Redistributions of source code must retain the above copyright
      72             :  *    notice, this list of conditions and the following disclaimer.
      73             :  * 2. Redistributions in binary form must reproduce the above copyright
      74             :  *    notice, this list of conditions and the following disclaimer in the
      75             :  *    documentation and/or other materials provided with the distribution.
      76             :  * 3. All advertising materials mentioning features or use of this software
      77             :  *    must display the following acknowledgements:
      78             :  *      This product includes software developed by the University of
      79             :  *      California, Berkeley and its contributors.
      80             :  *      This product includes software developed at the Information
      81             :  *      Technology Division, US Naval Research Laboratory.
      82             :  * 4. Neither the name of the NRL nor the names of its contributors
      83             :  *    may be used to endorse or promote products derived from this software
      84             :  *    without specific prior written permission.
      85             :  *
      86             :  * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS
      87             :  * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
      88             :  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
      89             :  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL NRL OR
      90             :  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
      91             :  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
      92             :  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
      93             :  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
      94             :  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
      95             :  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
      96             :  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      97             :  *
      98             :  * The views and conclusions contained in the software and documentation
      99             :  * are those of the authors and should not be interpreted as representing
     100             :  * official policies, either expressed or implied, of the US Naval
     101             :  * Research Laboratory (NRL).
     102             :  */
     103             : 
     104             : /*
     105             :  * Loopback interface driver for protocol testing and timing.
     106             :  */
     107             : 
     108             : #include "bpfilter.h"
     109             : 
     110             : #include <sys/param.h>
     111             : #include <sys/systm.h>
     112             : #include <sys/kernel.h>
     113             : #include <sys/mbuf.h>
     114             : #include <sys/socket.h>
     115             : #include <sys/errno.h>
     116             : #include <sys/ioctl.h>
     117             : #include <sys/time.h>
     118             : 
     119             : 
     120             : #include <net/if.h>
     121             : #include <net/if_var.h>
     122             : #include <net/if_types.h>
     123             : #include <net/netisr.h>
     124             : #include <net/rtable.h>
     125             : #include <net/route.h>
     126             : 
     127             : #include <netinet/in.h>
     128             : 
     129             : #ifdef INET6
     130             : #include <netinet/ip6.h>
     131             : #endif
     132             : 
     133             : #ifdef MPLS
     134             : #include <netmpls/mpls.h>
     135             : #endif
     136             : 
     137             : #if NBPFILTER > 0
     138             : #include <net/bpf.h>
     139             : #endif
     140             : 
     141             : #define LOMTU   32768
     142             : 
     143             : int     loioctl(struct ifnet *, u_long, caddr_t);
     144             : void    loopattach(int);
     145             : void    lortrequest(struct ifnet *, int, struct rtentry *);
     146             : int     loinput(struct ifnet *, struct mbuf *, void *);
     147             : int     looutput(struct ifnet *,
     148             :             struct mbuf *, struct sockaddr *, struct rtentry *);
     149             : 
     150             : int     loop_clone_create(struct if_clone *, int);
     151             : int     loop_clone_destroy(struct ifnet *);
     152             : 
     153             : struct if_clone loop_cloner =
     154             :     IF_CLONE_INITIALIZER("lo", loop_clone_create, loop_clone_destroy);
     155             : 
     156             : void
     157           0 : loopattach(int n)
     158             : {
     159           0 :         if (loop_clone_create(&loop_cloner, 0))
     160           0 :                 panic("unable to create lo0");
     161             : 
     162           0 :         if_clone_attach(&loop_cloner);
     163           0 : }
     164             : 
     165             : int
     166           0 : loop_clone_create(struct if_clone *ifc, int unit)
     167             : {
     168             :         struct ifnet *ifp;
     169             : 
     170           0 :         ifp = malloc(sizeof(*ifp), M_DEVBUF, M_WAITOK|M_ZERO);
     171           0 :         snprintf(ifp->if_xname, sizeof ifp->if_xname, "lo%d", unit);
     172           0 :         ifp->if_softc = NULL;
     173           0 :         ifp->if_mtu = LOMTU;
     174           0 :         ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
     175           0 :         ifp->if_xflags = IFXF_CLONED;
     176           0 :         ifp->if_rtrequest = lortrequest;
     177           0 :         ifp->if_ioctl = loioctl;
     178           0 :         ifp->if_output = looutput;
     179           0 :         ifp->if_type = IFT_LOOP;
     180           0 :         ifp->if_hdrlen = sizeof(u_int32_t);
     181           0 :         if (unit == 0) {
     182           0 :                 if_attachhead(ifp);
     183           0 :                 if_addgroup(ifp, ifc->ifc_name);
     184           0 :                 rtable_l2set(0, 0, ifp->if_index);
     185           0 :         } else
     186           0 :                 if_attach(ifp);
     187           0 :         if_alloc_sadl(ifp);
     188             : #if NBPFILTER > 0
     189           0 :         bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(u_int32_t));
     190             : #endif
     191           0 :         if_ih_insert(ifp, loinput, NULL);
     192           0 :         return (0);
     193             : }
     194             : 
     195             : int
     196           0 : loop_clone_destroy(struct ifnet *ifp)
     197             : {
     198             :         struct ifnet    *p;
     199             : 
     200           0 :         if (ifp->if_index == rtable_loindex(ifp->if_rdomain)) {
     201             :                 /* rdomain 0 always needs a loopback */
     202           0 :                 if (ifp->if_rdomain == 0)
     203           0 :                         return (EPERM);
     204             : 
     205             :                 /* if there is any other interface in this rdomain, deny */
     206           0 :                 NET_LOCK();
     207           0 :                 TAILQ_FOREACH(p, &ifnet, if_list) {
     208           0 :                         if (p->if_rdomain != ifp->if_rdomain)
     209             :                                 continue;
     210           0 :                         if (p->if_index == ifp->if_index)
     211             :                                 continue;
     212           0 :                         NET_UNLOCK();
     213           0 :                         return (EBUSY);
     214             :                 }
     215           0 :                 NET_UNLOCK();
     216             : 
     217           0 :                 rtable_l2set(ifp->if_rdomain, 0, 0);
     218           0 :         }
     219             : 
     220           0 :         if_ih_remove(ifp, loinput, NULL);
     221           0 :         if_detach(ifp);
     222             : 
     223           0 :         free(ifp, M_DEVBUF, sizeof(*ifp));
     224           0 :         return (0);
     225           0 : }
     226             : 
     227             : int
     228           0 : loinput(struct ifnet *ifp, struct mbuf *m, void *cookie)
     229             : {
     230             :         int error;
     231             : 
     232           0 :         if ((m->m_flags & M_PKTHDR) == 0)
     233           0 :                 panic("%s: no header mbuf", __func__);
     234             : 
     235           0 :         error = if_input_local(ifp, m, m->m_pkthdr.ph_family);
     236           0 :         if (error)
     237           0 :                 ifp->if_ierrors++;
     238             : 
     239           0 :         return (1);
     240             : }
     241             : 
     242             : int
     243           0 : looutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
     244             :     struct rtentry *rt)
     245             : {
     246           0 :         if ((m->m_flags & M_PKTHDR) == 0)
     247           0 :                 panic("%s: no header mbuf", __func__);
     248             : 
     249           0 :         if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
     250           0 :                 m_freem(m);
     251           0 :                 return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
     252           0 :                         rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
     253             :         }
     254             : 
     255             :         /* Use the quick path only once to avoid stack overflow. */
     256           0 :         if ((m->m_flags & M_LOOP) == 0)
     257           0 :                 return (if_input_local(ifp, m, dst->sa_family));
     258             : 
     259           0 :         return (if_output_local(ifp, m, dst->sa_family));
     260           0 : }
     261             : 
     262             : void
     263           0 : lortrequest(struct ifnet *ifp, int cmd, struct rtentry *rt)
     264             : {
     265           0 :         if (rt && rt->rt_mtu == 0)
     266           0 :                 rt->rt_mtu = LOMTU;
     267           0 : }
     268             : 
     269             : /*
     270             :  * Process an ioctl request.
     271             :  */
     272             : int
     273           0 : loioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
     274             : {
     275             :         struct ifreq *ifr;
     276             :         int error = 0;
     277             : 
     278           0 :         switch (cmd) {
     279             :         case SIOCSIFFLAGS:
     280             :                 break;
     281             : 
     282             :         case SIOCSIFADDR:
     283           0 :                 ifp->if_flags |= IFF_RUNNING;
     284           0 :                 if_up(ifp);             /* send up RTM_IFINFO */
     285             :                 /*
     286             :                  * Everything else is done at a higher level.
     287             :                  */
     288           0 :                 break;
     289             : 
     290             :         case SIOCADDMULTI:
     291             :         case SIOCDELMULTI:
     292             :                 break;
     293             : 
     294             :         case SIOCSIFMTU:
     295           0 :                 ifr = (struct ifreq *)data;
     296           0 :                 ifp->if_mtu = ifr->ifr_mtu;
     297           0 :                 break;
     298             : 
     299             :         default:
     300             :                 error = ENOTTY;
     301           0 :         }
     302           0 :         return (error);
     303             : }

Generated by: LCOV version 1.13