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_faith.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 /*      $KAME: if_faith.c,v 1.23 2001/12/17 13:55:29 sumikawa Exp $     */
    2 
    3 /*-
    4  * Copyright (c) 1982, 1986, 1993
    5  *      The Regents of the University of California.  All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 4. Neither the name of the University nor the names of its contributors
   16  *    may be used to endorse or promote products derived from this software
   17  *    without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  *
   31  * $FreeBSD$
   32  */
   33 /*
   34  * derived from
   35  *      @(#)if_loop.c   8.1 (Berkeley) 6/10/93
   36  * Id: if_loop.c,v 1.22 1996/06/19 16:24:10 wollman Exp
   37  */
   38 
   39 /*
   40  * Loopback interface driver for protocol testing and timing.
   41  */
   42 #include "opt_inet.h"
   43 #include "opt_inet6.h"
   44 
   45 #include <sys/param.h>
   46 #include <sys/systm.h>
   47 #include <sys/kernel.h>
   48 #include <sys/mbuf.h>
   49 #include <sys/module.h>
   50 #include <sys/socket.h>
   51 #include <sys/errno.h>
   52 #include <sys/sockio.h>
   53 #include <sys/time.h>
   54 #include <sys/queue.h>
   55 #include <sys/types.h>
   56 #include <sys/malloc.h>
   57 
   58 #include <net/if.h>
   59 #include <net/if_clone.h>
   60 #include <net/if_types.h>
   61 #include <net/netisr.h>
   62 #include <net/route.h>
   63 #include <net/bpf.h>
   64 
   65 #ifdef  INET
   66 #include <netinet/in.h>
   67 #include <netinet/in_systm.h>
   68 #include <netinet/in_var.h>
   69 #include <netinet/ip.h>
   70 #endif
   71 
   72 #ifdef INET6
   73 #ifndef INET
   74 #include <netinet/in.h>
   75 #endif
   76 #include <netinet6/in6_var.h>
   77 #include <netinet/ip6.h>
   78 #include <netinet6/ip6_var.h>
   79 #endif
   80 
   81 #define FAITHNAME       "faith"
   82 
   83 struct faith_softc {
   84         struct ifnet *sc_ifp;
   85 };
   86 
   87 static int faithioctl(struct ifnet *, u_long, caddr_t);
   88 int faithoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
   89         struct rtentry *);
   90 static void faithrtrequest(int, struct rtentry *, struct rt_addrinfo *);
   91 #ifdef INET6
   92 static int faithprefix(struct in6_addr *);
   93 #endif
   94 
   95 static int faithmodevent(module_t, int, void *);
   96 
   97 static MALLOC_DEFINE(M_FAITH, FAITHNAME, "Firewall Assisted Tunnel Interface");
   98 
   99 static int      faith_clone_create(struct if_clone *, int, caddr_t);
  100 static void     faith_clone_destroy(struct ifnet *);
  101 
  102 IFC_SIMPLE_DECLARE(faith, 0);
  103 
  104 #define FAITHMTU        1500
  105 
  106 static int
  107 faithmodevent(mod, type, data)
  108         module_t mod;
  109         int type;
  110         void *data;
  111 {
  112 
  113         switch (type) {
  114         case MOD_LOAD:
  115                 if_clone_attach(&faith_cloner);
  116 
  117 #ifdef INET6
  118                 faithprefix_p = faithprefix;
  119 #endif
  120 
  121                 break;
  122         case MOD_UNLOAD:
  123 #ifdef INET6
  124                 faithprefix_p = NULL;
  125 #endif
  126 
  127                 if_clone_detach(&faith_cloner);
  128                 break;
  129         default:
  130                 return EOPNOTSUPP;
  131         }
  132         return 0;
  133 }
  134 
  135 static moduledata_t faith_mod = {
  136         "if_faith",
  137         faithmodevent,
  138         0
  139 };
  140 
  141 DECLARE_MODULE(if_faith, faith_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
  142 MODULE_VERSION(if_faith, 1);
  143 
  144 static int
  145 faith_clone_create(ifc, unit, params)
  146         struct if_clone *ifc;
  147         int unit;
  148         caddr_t params;
  149 {
  150         struct ifnet *ifp;
  151         struct faith_softc *sc;
  152 
  153         sc = malloc(sizeof(struct faith_softc), M_FAITH, M_WAITOK | M_ZERO);
  154         ifp = sc->sc_ifp = if_alloc(IFT_FAITH);
  155         if (ifp == NULL) {
  156                 free(sc, M_FAITH);
  157                 return (ENOSPC);
  158         }
  159 
  160         ifp->if_softc = sc;
  161         if_initname(sc->sc_ifp, ifc->ifc_name, unit);
  162 
  163         ifp->if_mtu = FAITHMTU;
  164         /* Change to BROADCAST experimentaly to announce its prefix. */
  165         ifp->if_flags = /* IFF_LOOPBACK */ IFF_BROADCAST | IFF_MULTICAST;
  166         ifp->if_ioctl = faithioctl;
  167         ifp->if_output = faithoutput;
  168         ifp->if_hdrlen = 0;
  169         ifp->if_addrlen = 0;
  170         ifp->if_snd.ifq_maxlen = ifqmaxlen;
  171         if_attach(ifp);
  172         bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
  173         return (0);
  174 }
  175 
  176 static void
  177 faith_clone_destroy(ifp)
  178         struct ifnet *ifp;
  179 {
  180         struct faith_softc *sc = ifp->if_softc;
  181 
  182         bpfdetach(ifp);
  183         if_detach(ifp);
  184         if_free(ifp);
  185         free(sc, M_FAITH);
  186 }
  187 
  188 int
  189 faithoutput(ifp, m, dst, rt)
  190         struct ifnet *ifp;
  191         struct mbuf *m;
  192         struct sockaddr *dst;
  193         struct rtentry *rt;
  194 {
  195         int isr;
  196         u_int32_t af;
  197 
  198         M_ASSERTPKTHDR(m);
  199 
  200         /* BPF writes need to be handled specially. */
  201         if (dst->sa_family == AF_UNSPEC) {
  202                 bcopy(dst->sa_data, &af, sizeof(af));
  203                 dst->sa_family = af;
  204         }
  205 
  206         if (bpf_peers_present(ifp->if_bpf)) {
  207                 af = dst->sa_family;
  208                 bpf_mtap2(ifp->if_bpf, &af, sizeof(af), m);
  209         }
  210 
  211         if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
  212                 m_freem(m);
  213                 return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
  214                         rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
  215         }
  216         ifp->if_opackets++;
  217         ifp->if_obytes += m->m_pkthdr.len;
  218         switch (dst->sa_family) {
  219 #ifdef INET
  220         case AF_INET:
  221                 isr = NETISR_IP;
  222                 break;
  223 #endif
  224 #ifdef INET6
  225         case AF_INET6:
  226                 isr = NETISR_IPV6;
  227                 break;
  228 #endif
  229         default:
  230                 m_freem(m);
  231                 return EAFNOSUPPORT;
  232         }
  233 
  234         /* XXX do we need more sanity checks? */
  235 
  236         m->m_pkthdr.rcvif = ifp;
  237         ifp->if_ipackets++;
  238         ifp->if_ibytes += m->m_pkthdr.len;
  239         netisr_dispatch(isr, m);
  240         return (0);
  241 }
  242 
  243 /* ARGSUSED */
  244 static void
  245 faithrtrequest(cmd, rt, info)
  246         int cmd;
  247         struct rtentry *rt;
  248         struct rt_addrinfo *info;
  249 {
  250         RT_LOCK_ASSERT(rt);
  251         rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu;
  252 }
  253 
  254 /*
  255  * Process an ioctl request.
  256  */
  257 /* ARGSUSED */
  258 static int
  259 faithioctl(ifp, cmd, data)
  260         struct ifnet *ifp;
  261         u_long cmd;
  262         caddr_t data;
  263 {
  264         struct ifaddr *ifa;
  265         struct ifreq *ifr = (struct ifreq *)data;
  266         int error = 0;
  267 
  268         switch (cmd) {
  269 
  270         case SIOCSIFADDR:
  271                 ifp->if_flags |= IFF_UP;
  272                 ifp->if_drv_flags |= IFF_DRV_RUNNING;
  273                 ifa = (struct ifaddr *)data;
  274                 ifa->ifa_rtrequest = faithrtrequest;
  275                 /*
  276                  * Everything else is done at a higher level.
  277                  */
  278                 break;
  279 
  280         case SIOCADDMULTI:
  281         case SIOCDELMULTI:
  282                 if (ifr == 0) {
  283                         error = EAFNOSUPPORT;           /* XXX */
  284                         break;
  285                 }
  286                 switch (ifr->ifr_addr.sa_family) {
  287 #ifdef INET
  288                 case AF_INET:
  289                         break;
  290 #endif
  291 #ifdef INET6
  292                 case AF_INET6:
  293                         break;
  294 #endif
  295 
  296                 default:
  297                         error = EAFNOSUPPORT;
  298                         break;
  299                 }
  300                 break;
  301 
  302 #ifdef SIOCSIFMTU
  303         case SIOCSIFMTU:
  304                 ifp->if_mtu = ifr->ifr_mtu;
  305                 break;
  306 #endif
  307 
  308         case SIOCSIFFLAGS:
  309                 break;
  310 
  311         default:
  312                 error = EINVAL;
  313         }
  314         return (error);
  315 }
  316 
  317 #ifdef INET6
  318 /*
  319  * XXX could be slow
  320  * XXX could be layer violation to call sys/net from sys/netinet6
  321  */
  322 static int
  323 faithprefix(in6)
  324         struct in6_addr *in6;
  325 {
  326         struct rtentry *rt;
  327         struct sockaddr_in6 sin6;
  328         int ret;
  329 
  330         if (ip6_keepfaith == 0)
  331                 return 0;
  332 
  333         bzero(&sin6, sizeof(sin6));
  334         sin6.sin6_family = AF_INET6;
  335         sin6.sin6_len = sizeof(struct sockaddr_in6);
  336         sin6.sin6_addr = *in6;
  337         rt = rtalloc1((struct sockaddr *)&sin6, 0, 0UL);
  338         if (rt && rt->rt_ifp && rt->rt_ifp->if_type == IFT_FAITH &&
  339             (rt->rt_ifp->if_flags & IFF_UP) != 0)
  340                 ret = 1;
  341         else
  342                 ret = 0;
  343         if (rt)
  344                 RTFREE_LOCKED(rt);
  345         return ret;
  346 }
  347 #endif

Cache object: cc18effe1190573d8ebffbd5994ed4cb


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