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/netipx/ipx_usrreq.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) 1995, Mike Mitchell
    3  * Copyright (c) 1984, 1985, 1986, 1987, 1993
    4  *      The Regents of the University of California.  All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. All advertising materials mentioning features or use of this software
   15  *    must display the following acknowledgement:
   16  *      This product includes software developed by the University of
   17  *      California, Berkeley and its contributors.
   18  * 4. Neither the name of the University nor the names of its contributors
   19  *    may be used to endorse or promote products derived from this software
   20  *    without specific prior written permission.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   32  * SUCH DAMAGE.
   33  *
   34  *      @(#)ipx_usrreq.c
   35  */
   36 
   37 #include <sys/cdefs.h>
   38 __FBSDID("$FreeBSD: releng/5.2/sys/netipx/ipx_usrreq.c 122875 2003-11-18 00:39:07Z rwatson $");
   39 
   40 #include "opt_ipx.h"
   41 
   42 #include <sys/param.h>
   43 #include <sys/kernel.h>
   44 #include <sys/lock.h>
   45 #include <sys/mbuf.h>
   46 #include <sys/protosw.h>
   47 #include <sys/signalvar.h>
   48 #include <sys/socket.h>
   49 #include <sys/socketvar.h>
   50 #include <sys/sx.h>
   51 #include <sys/sysctl.h>
   52 #include <sys/systm.h>
   53 
   54 #include <net/if.h>
   55 #include <net/route.h>
   56 
   57 #include <netinet/in.h>
   58 
   59 #include <netipx/ipx.h>
   60 #include <netipx/ipx_if.h>
   61 #include <netipx/ipx_ip.h>
   62 #include <netipx/ipx_pcb.h>
   63 #include <netipx/ipx_var.h>
   64 
   65 /*
   66  * IPX protocol implementation.
   67  */
   68 
   69 static int ipxsendspace = IPXSNDQ;
   70 SYSCTL_INT(_net_ipx_ipx, OID_AUTO, ipxsendspace, CTLFLAG_RW,
   71             &ipxsendspace, 0, "");
   72 static int ipxrecvspace = IPXRCVQ;
   73 SYSCTL_INT(_net_ipx_ipx, OID_AUTO, ipxrecvspace, CTLFLAG_RW,
   74             &ipxrecvspace, 0, "");
   75 
   76 static  int ipx_usr_abort(struct socket *so);
   77 static  int ipx_attach(struct socket *so, int proto, struct thread *td);
   78 static  int ipx_bind(struct socket *so, struct sockaddr *nam, struct thread *td);
   79 static  int ipx_connect(struct socket *so, struct sockaddr *nam,
   80                         struct thread *td);
   81 static  int ipx_detach(struct socket *so);
   82 static  int ipx_disconnect(struct socket *so);
   83 static  int ipx_send(struct socket *so, int flags, struct mbuf *m,
   84                      struct sockaddr *addr, struct mbuf *control, 
   85                      struct thread *td);
   86 static  int ipx_shutdown(struct socket *so);
   87 static  int ripx_attach(struct socket *so, int proto, struct thread *td);
   88 static  int ipx_output(struct ipxpcb *ipxp, struct mbuf *m0);
   89 
   90 struct  pr_usrreqs ipx_usrreqs = {
   91         ipx_usr_abort, pru_accept_notsupp, ipx_attach, ipx_bind,
   92         ipx_connect, pru_connect2_notsupp, ipx_control, ipx_detach,
   93         ipx_disconnect, pru_listen_notsupp, ipx_peeraddr, pru_rcvd_notsupp,
   94         pru_rcvoob_notsupp, ipx_send, pru_sense_null, ipx_shutdown,
   95         ipx_sockaddr, sosend, soreceive, sopoll, pru_sosetlabel_null
   96 };
   97 
   98 struct  pr_usrreqs ripx_usrreqs = {
   99         ipx_usr_abort, pru_accept_notsupp, ripx_attach, ipx_bind,
  100         ipx_connect, pru_connect2_notsupp, ipx_control, ipx_detach,
  101         ipx_disconnect, pru_listen_notsupp, ipx_peeraddr, pru_rcvd_notsupp,
  102         pru_rcvoob_notsupp, ipx_send, pru_sense_null, ipx_shutdown,
  103         ipx_sockaddr, sosend, soreceive, sopoll, pru_sosetlabel_null
  104 };
  105 
  106 /*
  107  *  This may also be called for raw listeners.
  108  */
  109 void
  110 ipx_input(m, ipxp)
  111         struct mbuf *m;
  112         register struct ipxpcb *ipxp;
  113 {
  114         register struct ipx *ipx = mtod(m, struct ipx *);
  115         struct ifnet *ifp = m->m_pkthdr.rcvif;
  116         struct sockaddr_ipx ipx_ipx;
  117 
  118         if (ipxp == NULL)
  119                 panic("No ipxpcb");
  120         /*
  121          * Construct sockaddr format source address.
  122          * Stuff source address and datagram in user buffer.
  123          */
  124         ipx_ipx.sipx_len = sizeof(ipx_ipx);
  125         ipx_ipx.sipx_family = AF_IPX;
  126         ipx_ipx.sipx_addr = ipx->ipx_sna;
  127         ipx_ipx.sipx_zero[0] = '\0';
  128         ipx_ipx.sipx_zero[1] = '\0';
  129         if (ipx_neteqnn(ipx->ipx_sna.x_net, ipx_zeronet) && ifp != NULL) {
  130                 register struct ifaddr *ifa;
  131 
  132                 for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa != NULL; 
  133                      ifa = TAILQ_NEXT(ifa, ifa_link)) {
  134                         if (ifa->ifa_addr->sa_family == AF_IPX) {
  135                                 ipx_ipx.sipx_addr.x_net =
  136                                         IA_SIPX(ifa)->sipx_addr.x_net;
  137                                 break;
  138                         }
  139                 }
  140         }
  141         ipxp->ipxp_rpt = ipx->ipx_pt;
  142         if (!(ipxp->ipxp_flags & IPXP_RAWIN) ) {
  143                 m->m_len -= sizeof(struct ipx);
  144                 m->m_pkthdr.len -= sizeof(struct ipx);
  145                 m->m_data += sizeof(struct ipx);
  146         }
  147         if (sbappendaddr(&ipxp->ipxp_socket->so_rcv, (struct sockaddr *)&ipx_ipx,
  148             m, (struct mbuf *)NULL) == 0)
  149                 goto bad;
  150         sorwakeup(ipxp->ipxp_socket);
  151         return;
  152 bad:
  153         m_freem(m);
  154 }
  155 
  156 void
  157 ipx_abort(ipxp)
  158         struct ipxpcb *ipxp;
  159 {
  160         struct socket *so = ipxp->ipxp_socket;
  161 
  162         ipx_pcbdisconnect(ipxp);
  163         soisdisconnected(so);
  164 }
  165 
  166 /*
  167  * Drop connection, reporting
  168  * the specified error.
  169  */
  170 void
  171 ipx_drop(ipxp, errno)
  172         register struct ipxpcb *ipxp;
  173         int errno;
  174 {
  175         struct socket *so = ipxp->ipxp_socket;
  176 
  177         /*
  178          * someday, in the IPX world
  179          * we will generate error protocol packets
  180          * announcing that the socket has gone away.
  181          *
  182          * XXX Probably never. IPX does not have error packets.
  183          */
  184         /*if (TCPS_HAVERCVDSYN(tp->t_state)) {
  185                 tp->t_state = TCPS_CLOSED;
  186                 tcp_output(tp);
  187         }*/
  188         so->so_error = errno;
  189         ipx_pcbdisconnect(ipxp);
  190         soisdisconnected(so);
  191 }
  192 
  193 static int
  194 ipx_output(ipxp, m0)
  195         struct ipxpcb *ipxp;
  196         struct mbuf *m0;
  197 {
  198         register struct ipx *ipx;
  199         register struct socket *so;
  200         register int len = 0;
  201         register struct route *ro;
  202         struct mbuf *m;
  203         struct mbuf *mprev = NULL;
  204 
  205         /*
  206          * Calculate data length.
  207          */
  208         for (m = m0; m != NULL; m = m->m_next) {
  209                 mprev = m;
  210                 len += m->m_len;
  211         }
  212         /*
  213          * Make sure packet is actually of even length.
  214          */
  215         
  216         if (len & 1) {
  217                 m = mprev;
  218                 if ((m->m_flags & M_EXT) == 0 &&
  219                         (m->m_len + m->m_data < &m->m_dat[MLEN])) {
  220                         mtod(m, char*)[m->m_len++] = 0;
  221                 } else {
  222                         struct mbuf *m1 = m_get(M_DONTWAIT, MT_DATA);
  223 
  224                         if (m1 == NULL) {
  225                                 m_freem(m0);
  226                                 return (ENOBUFS);
  227                         }
  228                         m1->m_len = 1;
  229                         * mtod(m1, char *) = 0;
  230                         m->m_next = m1;
  231                 }
  232                 m0->m_pkthdr.len++;
  233         }
  234 
  235         /*
  236          * Fill in mbuf with extended IPX header
  237          * and addresses and length put into network format.
  238          */
  239         m = m0;
  240         if (ipxp->ipxp_flags & IPXP_RAWOUT) {
  241                 ipx = mtod(m, struct ipx *);
  242         } else {
  243                 M_PREPEND(m, sizeof(struct ipx), M_DONTWAIT);
  244                 if (m == NULL)
  245                         return (ENOBUFS);
  246                 ipx = mtod(m, struct ipx *);
  247                 ipx->ipx_tc = 0;
  248                 ipx->ipx_pt = ipxp->ipxp_dpt;
  249                 ipx->ipx_sna = ipxp->ipxp_laddr;
  250                 ipx->ipx_dna = ipxp->ipxp_faddr;
  251                 len += sizeof(struct ipx);
  252         }
  253 
  254         ipx->ipx_len = htons((u_short)len);
  255 
  256         if (ipxp->ipxp_flags & IPXP_CHECKSUM) {
  257                 ipx->ipx_sum = ipx_cksum(m, len);
  258         } else
  259                 ipx->ipx_sum = 0xffff;
  260 
  261         /*
  262          * Output datagram.
  263          */
  264         so = ipxp->ipxp_socket;
  265         if (so->so_options & SO_DONTROUTE)
  266                 return (ipx_outputfl(m, (struct route *)NULL,
  267                     (so->so_options & SO_BROADCAST) | IPX_ROUTETOIF));
  268         /*
  269          * Use cached route for previous datagram if
  270          * possible.  If the previous net was the same
  271          * and the interface was a broadcast medium, or
  272          * if the previous destination was identical,
  273          * then we are ok.
  274          *
  275          * NB: We don't handle broadcasts because that
  276          *     would require 3 subroutine calls.
  277          */
  278         ro = &ipxp->ipxp_route;
  279 #ifdef ancient_history
  280         /*
  281          * I think that this will all be handled in ipx_pcbconnect!
  282          */
  283         if (ro->ro_rt != NULL) {
  284                 if(ipx_neteq(ipxp->ipxp_lastdst, ipx->ipx_dna)) {
  285                         /*
  286                          * This assumes we have no GH type routes
  287                          */
  288                         if (ro->ro_rt->rt_flags & RTF_HOST) {
  289                                 if (!ipx_hosteq(ipxp->ipxp_lastdst, ipx->ipx_dna))
  290                                         goto re_route;
  291 
  292                         }
  293                         if ((ro->ro_rt->rt_flags & RTF_GATEWAY) == 0) {
  294                                 register struct ipx_addr *dst =
  295                                                 &satoipx_addr(ro->ro_dst);
  296                                 dst->x_host = ipx->ipx_dna.x_host;
  297                         }
  298                         /* 
  299                          * Otherwise, we go through the same gateway
  300                          * and dst is already set up.
  301                          */
  302                 } else {
  303                 re_route:
  304                         RTFREE(ro->ro_rt);
  305                         ro->ro_rt = NULL;
  306                 }
  307         }
  308         ipxp->ipxp_lastdst = ipx->ipx_dna;
  309 #endif /* ancient_history */
  310         return (ipx_outputfl(m, ro, so->so_options & SO_BROADCAST));
  311 }
  312 
  313 int
  314 ipx_ctloutput(so, sopt)
  315         struct socket *so;
  316         struct sockopt *sopt;
  317 {
  318         struct ipxpcb *ipxp = sotoipxpcb(so);
  319         int mask, error, optval;
  320         short soptval;
  321         struct ipx ioptval;
  322 
  323         error = 0;
  324         if (ipxp == NULL)
  325                 return (EINVAL);
  326 
  327         switch (sopt->sopt_dir) {
  328         case SOPT_GET:
  329                 switch (sopt->sopt_name) {
  330                 case SO_ALL_PACKETS:
  331                         mask = IPXP_ALL_PACKETS;
  332                         goto get_flags;
  333 
  334                 case SO_HEADERS_ON_INPUT:
  335                         mask = IPXP_RAWIN;
  336                         goto get_flags;
  337 
  338                 case SO_IPX_CHECKSUM:
  339                         mask = IPXP_CHECKSUM;
  340                         goto get_flags;
  341                         
  342                 case SO_HEADERS_ON_OUTPUT:
  343                         mask = IPXP_RAWOUT;
  344                 get_flags:
  345                         soptval = ipxp->ipxp_flags & mask;
  346                         error = sooptcopyout(sopt, &soptval, sizeof soptval);
  347                         break;
  348 
  349                 case SO_DEFAULT_HEADERS:
  350                         ioptval.ipx_len = 0;
  351                         ioptval.ipx_sum = 0;
  352                         ioptval.ipx_tc = 0;
  353                         ioptval.ipx_pt = ipxp->ipxp_dpt;
  354                         ioptval.ipx_dna = ipxp->ipxp_faddr;
  355                         ioptval.ipx_sna = ipxp->ipxp_laddr;
  356                         error = sooptcopyout(sopt, &soptval, sizeof soptval);
  357                         break;
  358 
  359                 case SO_SEQNO:
  360                         error = sooptcopyout(sopt, &ipx_pexseq, 
  361                                              sizeof ipx_pexseq);
  362                         ipx_pexseq++;
  363                         break;
  364 
  365                 default:
  366                         error = EINVAL;
  367                 }
  368                 break;
  369 
  370         case SOPT_SET:
  371                 switch (sopt->sopt_name) {
  372                 case SO_ALL_PACKETS:
  373                         mask = IPXP_ALL_PACKETS;
  374                         goto set_head;
  375 
  376                 case SO_HEADERS_ON_INPUT:
  377                         mask = IPXP_RAWIN;
  378                         goto set_head;
  379 
  380                 case SO_IPX_CHECKSUM:
  381                         mask = IPXP_CHECKSUM;
  382 
  383                 case SO_HEADERS_ON_OUTPUT:
  384                         mask = IPXP_RAWOUT;
  385                 set_head:
  386                         error = sooptcopyin(sopt, &optval, sizeof optval,
  387                                             sizeof optval);
  388                         if (error)
  389                                 break;
  390                         if (optval)
  391                                 ipxp->ipxp_flags |= mask;
  392                         else
  393                                 ipxp->ipxp_flags &= ~mask;
  394                         break;
  395 
  396                 case SO_DEFAULT_HEADERS:
  397                         error = sooptcopyin(sopt, &ioptval, sizeof ioptval,
  398                                             sizeof ioptval);
  399                         if (error)
  400                                 break;
  401                         ipxp->ipxp_dpt = ioptval.ipx_pt;
  402                         break;
  403 #ifdef IPXIP
  404                 case SO_IPXIP_ROUTE:
  405                         error = ipxip_route(so, sopt);
  406                         break;
  407 #endif /* IPXIP */
  408                 default:
  409                         error = EINVAL;
  410                 }
  411                 break;
  412         }
  413         return (error);
  414 }
  415 
  416 static int
  417 ipx_usr_abort(so)
  418         struct socket *so;
  419 {
  420         int s;
  421         struct ipxpcb *ipxp = sotoipxpcb(so);
  422 
  423         s = splnet();
  424         ipx_pcbdetach(ipxp);
  425         splx(s);
  426         sotryfree(so);
  427         soisdisconnected(so);
  428         return (0);
  429 }
  430 
  431 static int
  432 ipx_attach(so, proto, td)
  433         struct socket *so;
  434         int proto;
  435         struct thread *td;
  436 {
  437         int error;
  438         int s;
  439         struct ipxpcb *ipxp = sotoipxpcb(so);
  440 
  441         if (ipxp != NULL)
  442                 return (EINVAL);
  443         s = splnet();
  444         error = ipx_pcballoc(so, &ipxpcb, td);
  445         splx(s);
  446         if (error == 0)
  447                 error = soreserve(so, ipxsendspace, ipxrecvspace);
  448         return (error);
  449 }
  450 
  451 static int
  452 ipx_bind(so, nam, td)
  453         struct socket *so;
  454         struct sockaddr *nam;
  455         struct thread *td;
  456 {
  457         struct ipxpcb *ipxp = sotoipxpcb(so);
  458 
  459         return (ipx_pcbbind(ipxp, nam, td));
  460 }
  461 
  462 static int
  463 ipx_connect(so, nam, td)
  464         struct socket *so;
  465         struct sockaddr *nam;
  466         struct thread *td;
  467 {
  468         int error;
  469         int s;
  470         struct ipxpcb *ipxp = sotoipxpcb(so);
  471 
  472         if (!ipx_nullhost(ipxp->ipxp_faddr))
  473                 return (EISCONN);
  474         s = splnet();
  475         error = ipx_pcbconnect(ipxp, nam, td);
  476         splx(s);
  477         if (error == 0)
  478                 soisconnected(so);
  479         return (error);
  480 }
  481 
  482 static int
  483 ipx_detach(so)
  484         struct socket *so;
  485 {
  486         int s;
  487         struct ipxpcb *ipxp = sotoipxpcb(so);
  488 
  489         if (ipxp == NULL)
  490                 return (ENOTCONN);
  491         s = splnet();
  492         ipx_pcbdetach(ipxp);
  493         splx(s);
  494         return (0);
  495 }
  496 
  497 static int
  498 ipx_disconnect(so)
  499         struct socket *so;
  500 {
  501         int s;
  502         struct ipxpcb *ipxp = sotoipxpcb(so);
  503 
  504         if (ipx_nullhost(ipxp->ipxp_faddr))
  505                 return (ENOTCONN);
  506         s = splnet();
  507         ipx_pcbdisconnect(ipxp);
  508         splx(s);
  509         soisdisconnected(so);
  510         return (0);
  511 }
  512 
  513 int
  514 ipx_peeraddr(so, nam)
  515         struct socket *so;
  516         struct sockaddr **nam;
  517 {
  518         struct ipxpcb *ipxp = sotoipxpcb(so);
  519 
  520         ipx_setpeeraddr(ipxp, nam); /* XXX what if alloc fails? */
  521         return (0);
  522 }
  523 
  524 static int
  525 ipx_send(so, flags, m, nam, control, td)
  526         struct socket *so;
  527         int flags;
  528         struct mbuf *m;
  529         struct sockaddr *nam;
  530         struct mbuf *control;
  531         struct thread *td;
  532 {
  533         int error;
  534         struct ipxpcb *ipxp = sotoipxpcb(so);
  535         struct ipx_addr laddr;
  536         int s = 0;
  537 
  538         if (nam != NULL) {
  539                 laddr = ipxp->ipxp_laddr;
  540                 if (!ipx_nullhost(ipxp->ipxp_faddr)) {
  541                         error = EISCONN;
  542                         goto send_release;
  543                 }
  544                 /*
  545                  * Must block input while temporarily connected.
  546                  */
  547                 s = splnet();
  548                 error = ipx_pcbconnect(ipxp, nam, td);
  549                 if (error) {
  550                         splx(s);
  551                         goto send_release;
  552                 }
  553         } else {
  554                 if (ipx_nullhost(ipxp->ipxp_faddr)) {
  555                         error = ENOTCONN;
  556                         goto send_release;
  557                 }
  558         }
  559         error = ipx_output(ipxp, m);
  560         m = NULL;
  561         if (nam != NULL) {
  562                 ipx_pcbdisconnect(ipxp);
  563                 splx(s);
  564                 ipxp->ipxp_laddr = laddr;
  565         }
  566 
  567 send_release:
  568         if (m != NULL)
  569                 m_freem(m);
  570         return (error);
  571 }
  572 
  573 static int
  574 ipx_shutdown(so)
  575         struct socket *so;
  576 {
  577         socantsendmore(so);
  578         return (0);
  579 }
  580 
  581 int
  582 ipx_sockaddr(so, nam)
  583         struct socket *so;
  584         struct sockaddr **nam;
  585 {
  586         struct ipxpcb *ipxp = sotoipxpcb(so);
  587 
  588         ipx_setsockaddr(ipxp, nam); /* XXX what if alloc fails? */
  589         return (0);
  590 }
  591 
  592 static int
  593 ripx_attach(so, proto, td)
  594         struct socket *so;
  595         int proto;
  596         struct thread *td;
  597 {
  598         int error = 0;
  599         int s;
  600         struct ipxpcb *ipxp = sotoipxpcb(so);
  601 
  602         if (td != NULL && (error = suser(td)) != 0)
  603                 return (error);
  604         s = splnet();
  605         error = ipx_pcballoc(so, &ipxrawpcb, td);
  606         splx(s);
  607         if (error)
  608                 return (error);
  609         error = soreserve(so, ipxsendspace, ipxrecvspace);
  610         if (error)
  611                 return (error);
  612         ipxp = sotoipxpcb(so);
  613         ipxp->ipxp_faddr.x_host = ipx_broadhost;
  614         ipxp->ipxp_flags = IPXP_RAWIN | IPXP_RAWOUT;
  615         return (error);
  616 }

Cache object: b649388afa73774e2409d734b5d78096


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