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/altq/altq_afmap.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 /*      $NetBSD: altq_afmap.c,v 1.6 2003/11/09 22:11:12 christos Exp $  */
    2 /*      $KAME: altq_afmap.c,v 1.7 2000/12/14 08:12:45 thorpej Exp $     */
    3 
    4 /*
    5  * Copyright (C) 1997-2000
    6  *      Sony Computer Science Laboratories Inc.  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  *
   17  * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED.  IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE
   21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  */
   29 
   30 /*
   31  * experimental:
   32  * mapping an ip flow to atm vpi/vci.
   33  * this module is not related to queueing at all, but uses the altq
   34  * flowinfo mechanism.  it's just put in the altq framework since
   35  * it is easy to add devices to altq.
   36  */
   37 
   38 #include <sys/cdefs.h>
   39 __KERNEL_RCSID(0, "$NetBSD: altq_afmap.c,v 1.6 2003/11/09 22:11:12 christos Exp $");
   40 
   41 #if defined(__FreeBSD__) || defined(__NetBSD__)
   42 #include "opt_altq.h"
   43 #if (__FreeBSD__ != 2)
   44 #include "opt_inet.h"
   45 #ifdef __FreeBSD__
   46 #include "opt_inet6.h"
   47 #endif
   48 #endif
   49 #endif /* __FreeBSD__ || __NetBSD__ */
   50 #ifdef ALTQ_AFMAP
   51 
   52 #include <sys/param.h>
   53 #include <sys/malloc.h>
   54 #include <sys/mbuf.h>
   55 #include <sys/uio.h>
   56 #include <sys/socket.h>
   57 #include <sys/systm.h>
   58 #include <sys/proc.h>
   59 #include <sys/errno.h>
   60 #include <sys/time.h>
   61 #include <sys/kernel.h>
   62 
   63 #include <net/if.h>
   64 #include <net/if_types.h>
   65 #include <netinet/in.h>
   66 
   67 #include <altq/altq.h>
   68 #include <altq/altq_conf.h>
   69 #include <altq/altq_afmap.h>
   70 
   71 LIST_HEAD(, afm_head) afhead_chain;
   72 
   73 static struct afm *afm_match4 __P((struct afm_head *, struct flowinfo_in *));
   74 #ifdef INET6
   75 static struct afm *afm_match6 __P((struct afm_head *, struct flowinfo_in6 *));
   76 #endif
   77 
   78 /*
   79  * rules to block interrupts: afm_match can be called from a net
   80  * level interrupt so that other routines handling the lists should
   81  * be called in splnet().
   82  */
   83 int
   84 afm_alloc(ifp)
   85         struct ifnet *ifp;
   86 {
   87         struct afm_head *head;
   88     
   89         MALLOC(head, struct afm_head *, sizeof(struct afm_head),
   90                M_DEVBUF, M_WAITOK);
   91         if (head == NULL)
   92                 panic("afm_alloc: malloc failed!");
   93         (void)memset(head, 0, sizeof(struct afm_head));
   94 
   95         /* initialize per interface afmap list */
   96         LIST_INIT(&head->afh_head);
   97 
   98         head->afh_ifp = ifp;
   99     
  100         /* add this afm_head to the chain */
  101         LIST_INSERT_HEAD(&afhead_chain, head, afh_chain);
  102     
  103         return (0);
  104 }
  105 
  106 int
  107 afm_dealloc(ifp)
  108         struct ifnet *ifp;
  109 {
  110         struct afm_head *head;
  111 
  112         for (head = afhead_chain.lh_first; head != NULL;
  113              head = head->afh_chain.le_next)
  114                 if (head->afh_ifp == ifp)
  115                         break;
  116         if (head == NULL)
  117                 return (-1);
  118 
  119         afm_removeall(ifp);
  120 
  121         LIST_REMOVE(head, afh_chain);
  122 
  123         FREE(head, M_DEVBUF);
  124         return 0;
  125 }
  126 
  127 struct afm *
  128 afm_top(ifp)
  129         struct ifnet *ifp;
  130 {
  131         struct afm_head *head;
  132 
  133         for (head = afhead_chain.lh_first; head != NULL;
  134              head = head->afh_chain.le_next)
  135                 if (head->afh_ifp == ifp)
  136                         break;
  137         if (head == NULL)
  138                 return NULL;
  139     
  140         return (head->afh_head.lh_first);
  141 }
  142 
  143 int afm_add(ifp, flowmap)
  144         struct ifnet *ifp;
  145         struct atm_flowmap *flowmap;
  146 {
  147         struct afm_head *head;
  148         struct afm *afm;
  149 
  150         for (head = afhead_chain.lh_first; head != NULL;
  151              head = head->afh_chain.le_next)
  152                 if (head->afh_ifp == ifp)
  153                         break;
  154         if (head == NULL)
  155                 return (-1);
  156 
  157         if (flowmap->af_flowinfo.fi_family == AF_INET) {
  158                 if (flowmap->af_flowinfo.fi_len != sizeof(struct flowinfo_in))
  159                         return (EINVAL);
  160 #ifdef INET6
  161         } else if (flowmap->af_flowinfo.fi_family == AF_INET6) {
  162                 if (flowmap->af_flowinfo.fi_len != sizeof(struct flowinfo_in6))
  163                         return (EINVAL);
  164 #endif
  165         } else
  166                 return (EINVAL);
  167 
  168         MALLOC(afm, struct afm *, sizeof(struct afm),
  169                M_DEVBUF, M_WAITOK);
  170         if (afm == NULL)
  171                 return (ENOMEM);
  172         (void)memset(afm, 0, sizeof(struct afm));
  173 
  174         afm->afm_vci = flowmap->af_vci;
  175         afm->afm_vpi = flowmap->af_vpi;
  176         (void)memcpy(&afm->afm_flowinfo, &flowmap->af_flowinfo,
  177               flowmap->af_flowinfo.fi_len);
  178 
  179         LIST_INSERT_HEAD(&head->afh_head, afm, afm_list);
  180         return 0;
  181 }
  182 
  183 int 
  184 afm_remove(afm)
  185         struct afm *afm;
  186 {
  187         LIST_REMOVE(afm, afm_list);
  188         FREE(afm, M_DEVBUF);
  189         return (0);
  190 }
  191 
  192 int 
  193 afm_removeall(ifp)
  194         struct ifnet *ifp;
  195 {
  196         struct afm_head *head;
  197         struct afm *afm;
  198 
  199         for (head = afhead_chain.lh_first; head != NULL;
  200              head = head->afh_chain.le_next)
  201                 if (head->afh_ifp == ifp)
  202                         break;
  203         if (head == NULL)
  204                 return (-1);
  205 
  206         while ((afm = head->afh_head.lh_first) != NULL)
  207                 afm_remove(afm);
  208         return (0);
  209 }
  210 
  211 struct afm *
  212 afm_lookup(ifp, vpi, vci)
  213         struct ifnet *ifp;
  214         int vpi, vci;
  215 {
  216         struct afm_head *head;
  217         struct afm *afm;
  218 
  219         for (head = afhead_chain.lh_first; head != NULL;
  220              head = head->afh_chain.le_next)
  221                 if (head->afh_ifp == ifp)
  222                         break;
  223         if (head == NULL)
  224                 return NULL;
  225 
  226         for (afm = head->afh_head.lh_first; afm != NULL;
  227              afm = afm->afm_list.le_next)
  228                 if (afm->afm_vpi == vpi && afm->afm_vci == vci)
  229                         break;
  230         return afm;
  231 }
  232 
  233 static struct afm *
  234 afm_match4(head, fp)
  235         struct afm_head *head;
  236         struct flowinfo_in *fp;
  237 {
  238         struct afm *afm;
  239 
  240         for (afm = head->afh_head.lh_first; afm != NULL;
  241              afm = afm->afm_list.le_next) {
  242                 if (afm->afm_flowinfo4.fi_dst.s_addr != 0 &&
  243                     afm->afm_flowinfo4.fi_dst.s_addr != fp->fi_dst.s_addr)
  244                         continue;
  245                 if (afm->afm_flowinfo4.fi_dport != 0 &&
  246                     afm->afm_flowinfo4.fi_dport != fp->fi_dport)
  247                         continue;
  248                 if (afm->afm_flowinfo4.fi_src.s_addr != 0 &&
  249                     afm->afm_flowinfo4.fi_src.s_addr != fp->fi_src.s_addr)
  250                         continue;
  251                 if (afm->afm_flowinfo4.fi_sport != 0 &&
  252                     afm->afm_flowinfo4.fi_sport != fp->fi_sport)
  253                         continue;
  254                 if (afm->afm_flowinfo4.fi_proto != 0 &&
  255                     afm->afm_flowinfo4.fi_proto != fp->fi_proto)
  256                         continue;
  257                 /* match found! */
  258                 return (afm);
  259         }
  260         return NULL;
  261 }
  262 
  263 #ifdef INET6
  264 static struct afm *
  265 afm_match6(head, fp)
  266         struct afm_head *head;
  267         struct flowinfo_in6 *fp;
  268 {
  269         struct afm *afm;
  270 
  271         for (afm = head->afh_head.lh_first; afm != NULL;
  272              afm = afm->afm_list.le_next) {
  273                 if (afm->afm_flowinfo6.fi6_flowlabel != 0 &&
  274                     afm->afm_flowinfo6.fi6_flowlabel != fp->fi6_flowlabel)
  275                         continue;
  276 #ifdef notyet
  277                 if (!IN6_IS_ADDR_UNSPECIFIED(&afm->afm_flowinfo6.fi6_dst) &&
  278                     !IN6_ARE_ADDR_EQUAL(&afm->afm_flowinfo6.fi6_dst,
  279                                         &fp->fi6_dst))
  280                         continue;
  281                 if (afm->afm_flowinfo6.fi6_dport != 0 &&
  282                     afm->afm_flowinfo6.fi6_dport != fp->fi6_dport)
  283                         continue;
  284 #endif
  285                 if (!IN6_IS_ADDR_UNSPECIFIED(&afm->afm_flowinfo6.fi6_src) &&
  286                     !IN6_ARE_ADDR_EQUAL(&afm->afm_flowinfo6.fi6_src,
  287                                         &fp->fi6_src))
  288                         continue;
  289 #ifdef notyet
  290                 if (afm->afm_flowinfo6.fi6_sport != 0 &&
  291                     afm->afm_flowinfo6.fi6_sport != fp->fi6_sport)
  292                         continue;
  293 #endif
  294                 if (afm->afm_flowinfo6.fi6_proto != 0 &&
  295                     afm->afm_flowinfo6.fi6_proto != fp->fi6_proto)
  296                         continue;
  297                 /* match found! */
  298                 return (afm);
  299         }
  300         return NULL;
  301 }
  302 #endif
  303 
  304 /* should be called in splnet() */
  305 struct afm *
  306 afm_match(ifp, flow)
  307         struct ifnet *ifp;
  308         struct flowinfo *flow;
  309 {
  310         struct afm_head *head;
  311 
  312         for (head = afhead_chain.lh_first; head != NULL;
  313              head = head->afh_chain.le_next)
  314                 if (head->afh_ifp == ifp)
  315                         break;
  316         if (head == NULL)
  317                 return NULL;
  318 
  319         switch (flow->fi_family) {
  320         case AF_INET:
  321                 return (afm_match4(head, (struct flowinfo_in *)flow));
  322 
  323 #ifdef INET6
  324         case AF_INET6:
  325                 return (afm_match6(head, (struct flowinfo_in6 *)flow));
  326 #endif
  327 
  328         default:
  329                 return NULL;
  330         }
  331 }
  332 
  333 /*
  334  * afm device interface
  335  */
  336 altqdev_decl(afm);
  337 
  338 int
  339 afmopen(dev, flag, fmt, p)
  340         dev_t dev;
  341         int flag, fmt;
  342         struct proc *p;
  343 {
  344         return 0;
  345 }
  346 
  347 int
  348 afmclose(dev, flag, fmt, p)
  349         dev_t dev;
  350         int flag, fmt;
  351         struct proc *p;
  352 {
  353         int err, error = 0;
  354         struct atm_flowmap fmap;
  355         struct afm_head *head;
  356 
  357         for (head = afhead_chain.lh_first; head != NULL;
  358              head = head->afh_chain.le_next) {
  359 
  360                 /* call interface to clean up maps */
  361 #if defined(__NetBSD__) || defined(__OpenBSD__)
  362                 sprintf(fmap.af_ifname, "%s", head->afh_ifp->if_xname);
  363 #else
  364                 sprintf(fmap.af_ifname, "%s%d",
  365                         head->afh_ifp->if_name, head->afh_ifp->if_unit);
  366 #endif
  367                 err = afmioctl(dev, AFM_CLEANFMAP, (caddr_t)&fmap, flag, p);
  368                 if (err && error == 0)
  369                         error = err;
  370         }
  371 
  372         return error;
  373 }
  374 
  375 int
  376 afmioctl(dev, cmd, addr, flag, p)
  377         dev_t dev;
  378         ioctlcmd_t cmd;
  379         caddr_t addr;
  380         int flag;
  381         struct proc *p;
  382 {
  383         int     error = 0;
  384         struct atm_flowmap *flowmap;
  385         struct ifnet *ifp;
  386 
  387         /* check cmd for superuser only */
  388         switch (cmd) {
  389         case AFM_GETFMAP:
  390                 break;
  391         default:
  392 #if (__FreeBSD_version > 400000)
  393                 error = suser(p);
  394 #else
  395                 error = suser(p->p_ucred, &p->p_acflag);
  396 #endif
  397                 if (error)
  398                         return (error);
  399                 break;
  400         }
  401 
  402         /* lookup interface */
  403         flowmap = (struct atm_flowmap *)addr;
  404         flowmap->af_ifname[IFNAMSIZ-1] = '\0';    
  405         ifp = ifunit(flowmap->af_ifname);
  406         if (ifp == NULL || ifp->if_ioctl == NULL ||
  407             (ifp->if_flags & IFF_RUNNING) == 0)
  408                 error = ENXIO;
  409         else
  410                 error = ifp->if_ioctl(ifp, cmd, addr);
  411 
  412         return error;
  413 }
  414 
  415 #endif /* ALTQ_AFMAP */

Cache object: 3443412cba88102177b2c5ed1910f3cf


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