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/netatalk/ddp_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 /*      $NetBSD: ddp_usrreq.c,v 1.76 2022/09/03 01:48:22 thorpej Exp $   */
    2 
    3 /*
    4  * Copyright (c) 1990,1991 Regents of The University of Michigan.
    5  * All Rights Reserved.
    6  *
    7  * Permission to use, copy, modify, and distribute this software and
    8  * its documentation for any purpose and without fee is hereby granted,
    9  * provided that the above copyright notice appears in all copies and
   10  * that both that copyright notice and this permission notice appear
   11  * in supporting documentation, and that the name of The University
   12  * of Michigan not be used in advertising or publicity pertaining to
   13  * distribution of the software without specific, written prior
   14  * permission. This software is supplied as is without expressed or
   15  * implied warranties of any kind.
   16  *
   17  * This product includes software developed by the University of
   18  * California, Berkeley and its contributors.
   19  *
   20  *      Research Systems Unix Group
   21  *      The University of Michigan
   22  *      c/o Wesley Craig
   23  *      535 W. William Street
   24  *      Ann Arbor, Michigan
   25  *      +1-313-764-2278
   26  *      netatalk@umich.edu
   27  */
   28 
   29 #include <sys/cdefs.h>
   30 __KERNEL_RCSID(0, "$NetBSD: ddp_usrreq.c,v 1.76 2022/09/03 01:48:22 thorpej Exp $");
   31 
   32 #include "opt_mbuftrace.h"
   33 #include "opt_atalk.h"
   34 
   35 #include <sys/param.h>
   36 #include <sys/errno.h>
   37 #include <sys/systm.h>
   38 #include <sys/mbuf.h>
   39 #include <sys/ioctl.h>
   40 #include <sys/queue.h>
   41 #include <sys/socket.h>
   42 #include <sys/socketvar.h>
   43 #include <sys/protosw.h>
   44 #include <sys/kauth.h>
   45 #include <sys/kmem.h>
   46 #include <sys/sysctl.h>
   47 #include <net/if.h>
   48 #include <net/route.h>
   49 #include <net/if_ether.h>
   50 #include <net/net_stats.h>
   51 #include <netinet/in.h>
   52 
   53 #include <netatalk/at.h>
   54 #include <netatalk/at_var.h>
   55 #include <netatalk/ddp_var.h>
   56 #include <netatalk/ddp_private.h>
   57 #include <netatalk/aarp.h>
   58 #include <netatalk/at_extern.h>
   59 
   60 static void at_pcbdisconnect(struct ddpcb *);
   61 static void at_sockaddr(struct ddpcb *, struct sockaddr_at *);
   62 static int at_pcbsetaddr(struct ddpcb *, struct sockaddr_at *);
   63 static int at_pcbconnect(struct ddpcb *, struct sockaddr_at *);
   64 static void ddp_detach(struct socket *);
   65 
   66 pktqueue_t *            at_pktq1                __read_mostly;
   67 pktqueue_t *            at_pktq2                __read_mostly;
   68 
   69 struct ddpcb   *ddp_ports[ATPORT_LAST];
   70 struct ddpcb   *ddpcb = NULL;
   71 percpu_t *ddpstat_percpu;
   72 struct at_ifaddrhead at_ifaddr;         /* Here as inited in this file */
   73 u_long ddp_sendspace = DDP_MAXSZ;       /* Max ddp size + 1 (ddp_type) */
   74 u_long ddp_recvspace = 25 * (587 + sizeof(struct sockaddr_at));
   75 
   76 #ifdef MBUFTRACE
   77 struct mowner atalk_rx_mowner = MOWNER_INIT("atalk", "rx");
   78 struct mowner atalk_tx_mowner = MOWNER_INIT("atalk", "tx");
   79 #endif
   80 
   81 static void
   82 at_sockaddr(struct ddpcb *ddp, struct sockaddr_at *addr)
   83 {
   84 
   85         *addr = ddp->ddp_lsat;
   86 }
   87 
   88 static int
   89 at_pcbsetaddr(struct ddpcb *ddp, struct sockaddr_at *sat)
   90 {
   91         struct sockaddr_at lsat;
   92         struct at_ifaddr *aa;
   93         struct ddpcb   *ddpp;
   94 
   95         if (ddp->ddp_lsat.sat_port != ATADDR_ANYPORT) { /* shouldn't be bound */
   96                 return (EINVAL);
   97         }
   98         if (NULL != sat) {      /* validate passed address */
   99 
  100                 if (sat->sat_family != AF_APPLETALK)
  101                         return (EAFNOSUPPORT);
  102                 if (sat->sat_len != sizeof(*sat))
  103                         return EINVAL;
  104 
  105                 if (sat->sat_addr.s_node != ATADDR_ANYNODE ||
  106                     sat->sat_addr.s_net != ATADDR_ANYNET) {
  107                         TAILQ_FOREACH(aa, &at_ifaddr, aa_list) {
  108                                 if ((sat->sat_addr.s_net ==
  109                                     AA_SAT(aa)->sat_addr.s_net) &&
  110                                     (sat->sat_addr.s_node ==
  111                                     AA_SAT(aa)->sat_addr.s_node))
  112                                         break;
  113                         }
  114                         if (!aa)
  115                                 return (EADDRNOTAVAIL);
  116                 }
  117                 if (sat->sat_port != ATADDR_ANYPORT) {
  118                         int error;
  119 
  120                         if (sat->sat_port < ATPORT_FIRST ||
  121                             sat->sat_port >= ATPORT_LAST)
  122                                 return (EINVAL);
  123 
  124                         if (sat->sat_port < ATPORT_RESERVED &&
  125                             (error = kauth_authorize_network(
  126                             kauth_cred_get(),
  127                             KAUTH_NETWORK_BIND, KAUTH_REQ_NETWORK_BIND_PRIVPORT,
  128                             ddpcb->ddp_socket, sat, NULL)) != 0)
  129                                 return (error);
  130                 }
  131         } else {
  132                 memset((void *) & lsat, 0, sizeof(struct sockaddr_at));
  133                 lsat.sat_len = sizeof(struct sockaddr_at);
  134                 lsat.sat_addr.s_node = ATADDR_ANYNODE;
  135                 lsat.sat_addr.s_net = ATADDR_ANYNET;
  136                 lsat.sat_family = AF_APPLETALK;
  137                 sat = &lsat;
  138         }
  139 
  140         if (sat->sat_addr.s_node == ATADDR_ANYNODE &&
  141             sat->sat_addr.s_net == ATADDR_ANYNET) {
  142                 if (TAILQ_EMPTY(&at_ifaddr))
  143                         return EADDRNOTAVAIL;
  144                 sat->sat_addr = AA_SAT(TAILQ_FIRST(&at_ifaddr))->sat_addr;
  145         }
  146         ddp->ddp_lsat = *sat;
  147 
  148         /*
  149          * Choose port.
  150          */
  151         if (sat->sat_port == ATADDR_ANYPORT) {
  152                 for (sat->sat_port = ATPORT_RESERVED;
  153                      sat->sat_port < ATPORT_LAST; sat->sat_port++) {
  154                         if (ddp_ports[sat->sat_port - 1] == 0)
  155                                 break;
  156                 }
  157                 if (sat->sat_port == ATPORT_LAST) {
  158                         return (EADDRNOTAVAIL);
  159                 }
  160                 ddp->ddp_lsat.sat_port = sat->sat_port;
  161                 ddp_ports[sat->sat_port - 1] = ddp;
  162         } else {
  163                 for (ddpp = ddp_ports[sat->sat_port - 1]; ddpp;
  164                      ddpp = ddpp->ddp_pnext) {
  165                         if (ddpp->ddp_lsat.sat_addr.s_net ==
  166                             sat->sat_addr.s_net &&
  167                             ddpp->ddp_lsat.sat_addr.s_node ==
  168                             sat->sat_addr.s_node)
  169                                 break;
  170                 }
  171                 if (ddpp != NULL)
  172                         return (EADDRINUSE);
  173 
  174                 ddp->ddp_pnext = ddp_ports[sat->sat_port - 1];
  175                 ddp_ports[sat->sat_port - 1] = ddp;
  176                 if (ddp->ddp_pnext)
  177                         ddp->ddp_pnext->ddp_pprev = ddp;
  178         }
  179 
  180         return 0;
  181 }
  182 
  183 static int
  184 at_pcbconnect(struct ddpcb *ddp, struct sockaddr_at *sat)
  185 {
  186         struct rtentry *rt;
  187         const struct sockaddr_at *cdst;
  188         struct route *ro;
  189         struct at_ifaddr *aa;
  190         struct ifnet   *ifp;
  191         u_short         hintnet = 0, net;
  192 
  193         if (sat->sat_family != AF_APPLETALK)
  194                 return EAFNOSUPPORT;
  195         if (sat->sat_len != sizeof(*sat))
  196                 return EINVAL;
  197 
  198         /*
  199          * Under phase 2, network 0 means "the network".  We take "the
  200          * network" to mean the network the control block is bound to.
  201          * If the control block is not bound, there is an error.
  202          */
  203         if (sat->sat_addr.s_net == ATADDR_ANYNET
  204             && sat->sat_addr.s_node != ATADDR_ANYNODE) {
  205                 if (ddp->ddp_lsat.sat_port == ATADDR_ANYPORT) {
  206                         return EADDRNOTAVAIL;
  207                 }
  208                 hintnet = ddp->ddp_lsat.sat_addr.s_net;
  209         }
  210         ro = &ddp->ddp_route;
  211         /*
  212          * If we've got an old route for this pcb, check that it is valid.
  213          * If we've changed our address, we may have an old "good looking"
  214          * route here.  Attempt to detect it.
  215          */
  216         if ((rt = rtcache_validate(ro)) != NULL ||
  217             (rt = rtcache_update(ro, 1)) != NULL) {
  218                 if (hintnet) {
  219                         net = hintnet;
  220                 } else {
  221                         net = sat->sat_addr.s_net;
  222                 }
  223                 if ((ifp = rt->rt_ifp) != NULL) {
  224                         TAILQ_FOREACH(aa, &at_ifaddr, aa_list) {
  225                                 if (aa->aa_ifp == ifp &&
  226                                     ntohs(net) >= ntohs(aa->aa_firstnet) &&
  227                                     ntohs(net) <= ntohs(aa->aa_lastnet)) {
  228                                         break;
  229                                 }
  230                         }
  231                 } else
  232                         aa = NULL;
  233                 cdst = satocsat(rtcache_getdst(ro));
  234                 if (aa == NULL || (cdst->sat_addr.s_net !=
  235                     (hintnet ? hintnet : sat->sat_addr.s_net) ||
  236                     cdst->sat_addr.s_node != sat->sat_addr.s_node)) {
  237                         rtcache_unref(rt, ro);
  238                         rtcache_free(ro);
  239                         rt = NULL;
  240                 }
  241         }
  242         /*
  243          * If we've got no route for this interface, try to find one.
  244          */
  245         if (rt == NULL) {
  246                 union {
  247                         struct sockaddr         dst;
  248                         struct sockaddr_at      dsta;
  249                 } u;
  250 
  251                 sockaddr_at_init(&u.dsta, &sat->sat_addr, 0);
  252                 if (hintnet)
  253                         u.dsta.sat_addr.s_net = hintnet;
  254                 rt = rtcache_lookup(ro, &u.dst);
  255         }
  256         /*
  257          * Make sure any route that we have has a valid interface.
  258          */
  259         if (rt != NULL && (ifp = rt->rt_ifp) != NULL) {
  260                 TAILQ_FOREACH(aa, &at_ifaddr, aa_list) {
  261                         if (aa->aa_ifp == ifp)
  262                                 break;
  263                 }
  264         } else
  265                 aa = NULL;
  266         rtcache_unref(rt, ro);
  267         if (aa == NULL)
  268                 return ENETUNREACH;
  269         ddp->ddp_fsat = *sat;
  270         if (ddp->ddp_lsat.sat_port == ATADDR_ANYPORT)
  271                 return at_pcbsetaddr(ddp, NULL);
  272         return 0;
  273 }
  274 
  275 static void
  276 at_pcbdisconnect(struct ddpcb *ddp)
  277 {
  278         ddp->ddp_fsat.sat_addr.s_net = ATADDR_ANYNET;
  279         ddp->ddp_fsat.sat_addr.s_node = ATADDR_ANYNODE;
  280         ddp->ddp_fsat.sat_port = ATADDR_ANYPORT;
  281 }
  282 
  283 static int
  284 ddp_attach(struct socket *so, int proto)
  285 {
  286         struct ddpcb *ddp;
  287         int error;
  288 
  289         KASSERT(sotoddpcb(so) == NULL);
  290         sosetlock(so);
  291 #ifdef MBUFTRACE
  292         so->so_rcv.sb_mowner = &atalk_rx_mowner;
  293         so->so_snd.sb_mowner = &atalk_tx_mowner;
  294 #endif
  295         error = soreserve(so, ddp_sendspace, ddp_recvspace);
  296         if (error) {
  297                 return error;
  298         }
  299 
  300         ddp = kmem_zalloc(sizeof(*ddp), KM_SLEEP);
  301         ddp->ddp_lsat.sat_port = ATADDR_ANYPORT;
  302 
  303         ddp->ddp_next = ddpcb;
  304         ddp->ddp_prev = NULL;
  305         ddp->ddp_pprev = NULL;
  306         ddp->ddp_pnext = NULL;
  307         if (ddpcb) {
  308                 ddpcb->ddp_prev = ddp;
  309         }
  310         ddpcb = ddp;
  311 
  312         ddp->ddp_socket = so;
  313         so->so_pcb = ddp;
  314         return 0;
  315 }
  316 
  317 static void
  318 ddp_detach(struct socket *so)
  319 {
  320         struct ddpcb *ddp = sotoddpcb(so);
  321 
  322         soisdisconnected(so);
  323         so->so_pcb = NULL;
  324         /* sofree drops the lock */
  325         sofree(so);
  326         mutex_enter(softnet_lock);
  327 
  328         /* remove ddp from ddp_ports list */
  329         if (ddp->ddp_lsat.sat_port != ATADDR_ANYPORT &&
  330             ddp_ports[ddp->ddp_lsat.sat_port - 1] != NULL) {
  331                 if (ddp->ddp_pprev != NULL) {
  332                         ddp->ddp_pprev->ddp_pnext = ddp->ddp_pnext;
  333                 } else {
  334                         ddp_ports[ddp->ddp_lsat.sat_port - 1] = ddp->ddp_pnext;
  335                 }
  336                 if (ddp->ddp_pnext != NULL) {
  337                         ddp->ddp_pnext->ddp_pprev = ddp->ddp_pprev;
  338                 }
  339         }
  340         rtcache_free(&ddp->ddp_route);
  341         if (ddp->ddp_prev) {
  342                 ddp->ddp_prev->ddp_next = ddp->ddp_next;
  343         } else {
  344                 ddpcb = ddp->ddp_next;
  345         }
  346         if (ddp->ddp_next) {
  347                 ddp->ddp_next->ddp_prev = ddp->ddp_prev;
  348         }
  349         kmem_free(ddp, sizeof(*ddp));
  350 }
  351 
  352 static int
  353 ddp_accept(struct socket *so, struct sockaddr *nam)
  354 {
  355         KASSERT(solocked(so));
  356 
  357         return EOPNOTSUPP;
  358 }
  359 
  360 static int
  361 ddp_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
  362 {
  363         KASSERT(solocked(so));
  364         KASSERT(sotoddpcb(so) != NULL);
  365 
  366         return at_pcbsetaddr(sotoddpcb(so), (struct sockaddr_at *)nam);
  367 }
  368 
  369 static int
  370 ddp_listen(struct socket *so, struct lwp *l)
  371 {
  372         KASSERT(solocked(so));
  373 
  374         return EOPNOTSUPP;
  375 }
  376 
  377 static int
  378 ddp_connect(struct socket *so, struct sockaddr *nam, struct lwp *l)
  379 {
  380         struct ddpcb *ddp = sotoddpcb(so);
  381         int error = 0;
  382 
  383         KASSERT(solocked(so));
  384         KASSERT(ddp != NULL);
  385         KASSERT(nam != NULL);
  386 
  387         if (ddp->ddp_fsat.sat_port != ATADDR_ANYPORT)
  388                 return EISCONN;
  389         error = at_pcbconnect(ddp, (struct sockaddr_at *)nam);
  390         if (error == 0)
  391                 soisconnected(so);
  392 
  393         return error;
  394 }
  395 
  396 static int
  397 ddp_connect2(struct socket *so, struct socket *so2)
  398 {
  399         KASSERT(solocked(so));
  400 
  401         return EOPNOTSUPP;
  402 }
  403 
  404 static int
  405 ddp_disconnect(struct socket *so)
  406 {
  407         struct ddpcb *ddp = sotoddpcb(so);
  408 
  409         KASSERT(solocked(so));
  410         KASSERT(ddp != NULL);
  411 
  412         if (ddp->ddp_fsat.sat_addr.s_node == ATADDR_ANYNODE)
  413                 return ENOTCONN;
  414 
  415         at_pcbdisconnect(ddp);
  416         soisdisconnected(so);
  417         return 0;
  418 }
  419 
  420 static int
  421 ddp_shutdown(struct socket *so)
  422 {
  423         KASSERT(solocked(so));
  424 
  425         socantsendmore(so);
  426         return 0;
  427 }
  428 
  429 static int
  430 ddp_abort(struct socket *so)
  431 {
  432         KASSERT(solocked(so));
  433 
  434         soisdisconnected(so);
  435         ddp_detach(so);
  436         return 0;
  437 }
  438 
  439 static int
  440 ddp_ioctl(struct socket *so, u_long cmd, void *addr, struct ifnet *ifp)
  441 {
  442         return at_control(cmd, addr, ifp);
  443 }
  444 
  445 static int
  446 ddp_stat(struct socket *so, struct stat *ub)
  447 {
  448         KASSERT(solocked(so));
  449 
  450         /* stat: don't bother with a blocksize. */
  451         return 0;
  452 }
  453 
  454 static int
  455 ddp_peeraddr(struct socket *so, struct sockaddr *nam)
  456 {
  457         KASSERT(solocked(so));
  458 
  459         return EOPNOTSUPP;
  460 }
  461 
  462 static int
  463 ddp_sockaddr(struct socket *so, struct sockaddr *nam)
  464 {
  465         KASSERT(solocked(so));
  466         KASSERT(sotoddpcb(so) != NULL);
  467         KASSERT(nam != NULL);
  468 
  469         at_sockaddr(sotoddpcb(so), (struct sockaddr_at *)nam);
  470         return 0;
  471 }
  472 
  473 static int
  474 ddp_rcvd(struct socket *so, int flags, struct lwp *l)
  475 {
  476         KASSERT(solocked(so));
  477 
  478         return EOPNOTSUPP;
  479 }
  480 
  481 static int
  482 ddp_recvoob(struct socket *so, struct mbuf *m, int flags)
  483 {
  484         KASSERT(solocked(so));
  485 
  486         return EOPNOTSUPP;
  487 }
  488 
  489 static int
  490 ddp_send(struct socket *so, struct mbuf *m, struct sockaddr *nam,
  491     struct mbuf *control, struct lwp *l)
  492 {
  493         struct ddpcb *ddp = sotoddpcb(so);
  494         int error = 0;
  495         int s = 0; /* XXX gcc 4.8 warns on sgimips */
  496 
  497         KASSERT(solocked(so));
  498         KASSERT(ddp != NULL);
  499 
  500         if (nam) {
  501                 if (ddp->ddp_fsat.sat_port != ATADDR_ANYPORT)
  502                         return EISCONN;
  503                 s = splnet();
  504                 error = at_pcbconnect(ddp, (struct sockaddr_at *)nam);
  505                 if (error) {
  506                         splx(s);
  507                         return error;
  508                 }
  509         } else {
  510                 if (ddp->ddp_fsat.sat_port == ATADDR_ANYPORT)
  511                         return ENOTCONN;
  512         }
  513 
  514         error = ddp_output(m, ddp);
  515         m = NULL;
  516         if (nam) {
  517                 at_pcbdisconnect(ddp);
  518                 splx(s);
  519         }
  520 
  521         return error;
  522 }
  523 
  524 static int
  525 ddp_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
  526 {
  527         KASSERT(solocked(so));
  528 
  529         m_freem(m);
  530         m_freem(control);
  531 
  532         return EOPNOTSUPP;
  533 }
  534 
  535 static int
  536 ddp_purgeif(struct socket *so, struct ifnet *ifp)
  537 {
  538 
  539         mutex_enter(softnet_lock);
  540         at_purgeif(ifp);
  541         mutex_exit(softnet_lock);
  542 
  543         return 0;
  544 }
  545 
  546 /*
  547  * For the moment, this just find the pcb with the correct local address.
  548  * In the future, this will actually do some real searching, so we can use
  549  * the sender's address to do de-multiplexing on a single port to many
  550  * sockets (pcbs).
  551  */
  552 struct ddpcb   *
  553 ddp_search(
  554     struct sockaddr_at *from,
  555     struct sockaddr_at *to,
  556     struct at_ifaddr *aa)
  557 {
  558         struct ddpcb   *ddp;
  559 
  560         /*
  561          * Check for bad ports.
  562          */
  563         if (to->sat_port < ATPORT_FIRST || to->sat_port >= ATPORT_LAST)
  564                 return NULL;
  565 
  566         /*
  567          * Make sure the local address matches the sent address.  What about
  568          * the interface?
  569          */
  570         for (ddp = ddp_ports[to->sat_port - 1]; ddp; ddp = ddp->ddp_pnext) {
  571                 /* XXX should we handle 0.YY? */
  572 
  573                 /* XXXX.YY to socket on destination interface */
  574                 if (to->sat_addr.s_net == ddp->ddp_lsat.sat_addr.s_net &&
  575                     to->sat_addr.s_node == ddp->ddp_lsat.sat_addr.s_node) {
  576                         break;
  577                 }
  578                 /* 0.255 to socket on receiving interface */
  579                 if (to->sat_addr.s_node == ATADDR_BCAST &&
  580                     (to->sat_addr.s_net == 0 ||
  581                     to->sat_addr.s_net == ddp->ddp_lsat.sat_addr.s_net) &&
  582                 ddp->ddp_lsat.sat_addr.s_net == AA_SAT(aa)->sat_addr.s_net) {
  583                         break;
  584                 }
  585                 /* XXXX.0 to socket on destination interface */
  586                 if (to->sat_addr.s_net == aa->aa_firstnet &&
  587                     to->sat_addr.s_node == 0 &&
  588                     ntohs(ddp->ddp_lsat.sat_addr.s_net) >=
  589                     ntohs(aa->aa_firstnet) &&
  590                     ntohs(ddp->ddp_lsat.sat_addr.s_net) <=
  591                     ntohs(aa->aa_lastnet)) {
  592                         break;
  593                 }
  594         }
  595         return (ddp);
  596 }
  597 
  598 /*
  599  * Initialize all the ddp & appletalk stuff
  600  */
  601 void
  602 ddp_init(void)
  603 {
  604 
  605         ddpstat_percpu = percpu_alloc(sizeof(uint64_t) * DDP_NSTATS);
  606 
  607         TAILQ_INIT(&at_ifaddr);
  608 
  609         at_pktq1 = pktq_create(IFQ_MAXLEN, atintr1, NULL);
  610         KASSERT(at_pktq1 != NULL);
  611 
  612         at_pktq2 = pktq_create(IFQ_MAXLEN, atintr2, NULL);
  613         KASSERT(at_pktq2 != NULL);
  614 
  615         MOWNER_ATTACH(&atalk_tx_mowner);
  616         MOWNER_ATTACH(&atalk_rx_mowner);
  617         MOWNER_ATTACH(&aarp_mowner);
  618 }
  619 
  620 PR_WRAP_USRREQS(ddp)
  621 #define ddp_attach      ddp_attach_wrapper
  622 #define ddp_detach      ddp_detach_wrapper
  623 #define ddp_accept      ddp_accept_wrapper
  624 #define ddp_bind        ddp_bind_wrapper
  625 #define ddp_listen      ddp_listen_wrapper
  626 #define ddp_connect     ddp_connect_wrapper
  627 #define ddp_connect2    ddp_connect2_wrapper
  628 #define ddp_disconnect  ddp_disconnect_wrapper
  629 #define ddp_shutdown    ddp_shutdown_wrapper
  630 #define ddp_abort       ddp_abort_wrapper
  631 #define ddp_ioctl       ddp_ioctl_wrapper
  632 #define ddp_stat        ddp_stat_wrapper
  633 #define ddp_peeraddr    ddp_peeraddr_wrapper
  634 #define ddp_sockaddr    ddp_sockaddr_wrapper
  635 #define ddp_rcvd        ddp_rcvd_wrapper
  636 #define ddp_recvoob     ddp_recvoob_wrapper
  637 #define ddp_send        ddp_send_wrapper
  638 #define ddp_sendoob     ddp_sendoob_wrapper
  639 #define ddp_purgeif     ddp_purgeif_wrapper
  640 
  641 const struct pr_usrreqs ddp_usrreqs = {
  642         .pr_attach      = ddp_attach,
  643         .pr_detach      = ddp_detach,
  644         .pr_accept      = ddp_accept,
  645         .pr_bind        = ddp_bind,
  646         .pr_listen      = ddp_listen,
  647         .pr_connect     = ddp_connect,
  648         .pr_connect2    = ddp_connect2,
  649         .pr_disconnect  = ddp_disconnect,
  650         .pr_shutdown    = ddp_shutdown,
  651         .pr_abort       = ddp_abort,
  652         .pr_ioctl       = ddp_ioctl,
  653         .pr_stat        = ddp_stat,
  654         .pr_peeraddr    = ddp_peeraddr,
  655         .pr_sockaddr    = ddp_sockaddr,
  656         .pr_rcvd        = ddp_rcvd,
  657         .pr_recvoob     = ddp_recvoob,
  658         .pr_send        = ddp_send,
  659         .pr_sendoob     = ddp_sendoob,
  660         .pr_purgeif     = ddp_purgeif,
  661 };
  662 
  663 static int
  664 sysctl_net_atalk_ddp_stats(SYSCTLFN_ARGS)
  665 {
  666 
  667         return (NETSTAT_SYSCTL(ddpstat_percpu, DDP_NSTATS));
  668 }
  669 
  670 /*
  671  * Sysctl for DDP variables.
  672  */
  673 SYSCTL_SETUP(sysctl_net_atalk_ddp_setup, "sysctl net.atalk.ddp subtree setup")
  674 {
  675 
  676         sysctl_createv(clog, 0, NULL, NULL,
  677                        CTLFLAG_PERMANENT,
  678                        CTLTYPE_NODE, "atalk", NULL,
  679                        NULL, 0, NULL, 0,
  680                        CTL_NET, PF_APPLETALK, CTL_EOL);
  681         sysctl_createv(clog, 0, NULL, NULL,
  682                        CTLFLAG_PERMANENT,
  683                        CTLTYPE_NODE, "ddp",
  684                        SYSCTL_DESCR("DDP related settings"),
  685                        NULL, 0, NULL, 0,
  686                        CTL_NET, PF_APPLETALK, ATPROTO_DDP, CTL_EOL);
  687         
  688         sysctl_createv(clog, 0, NULL, NULL,
  689                        CTLFLAG_PERMANENT,
  690                        CTLTYPE_STRUCT, "stats",
  691                        SYSCTL_DESCR("DDP statistics"),
  692                        sysctl_net_atalk_ddp_stats, 0, NULL, 0,
  693                        CTL_NET, PF_APPLETALK, ATPROTO_DDP, CTL_CREATE,
  694                        CTL_EOL);
  695 }

Cache object: 56a631dd569032708fb736f99f641dfc


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