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/contrib/ngatm/netnatm/api/cc_port.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) 2003-2004
    3  *      Hartmut Brandt
    4  *      All rights reserved.
    5  *
    6  * Copyright (c) 2001-2002
    7  *      Fraunhofer Institute for Open Communication Systems (FhG Fokus).
    8  *      All rights reserved.
    9  *
   10  * Author: Harti Brandt <harti@freebsd.org>
   11  *
   12  * Redistribution of this software and documentation and use in source and
   13  * binary forms, with or without modification, are permitted provided that
   14  * the following conditions are met:
   15  *
   16  * 1. Redistributions of source code or documentation must retain the above
   17  *    copyright notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  *
   22  * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE AUTHOR
   23  * AND ITS CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
   24  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   25  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
   26  * THE AUTHOR OR ITS CONTRIBUTORS  BE LIABLE FOR ANY DIRECT, INDIRECT,
   27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   28  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
   29  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   30  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   31  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
   32  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   33  *
   34  * $Begemot: libunimsg/netnatm/api/cc_port.c,v 1.1 2004/07/08 08:21:53 brandt Exp $
   35  *
   36  * ATM API as defined per af-saa-0108
   37  *
   38  * Port-global stuff (ILMI and Co.)
   39  */
   40 #include <netnatm/unimsg.h>
   41 #include <netnatm/msg/unistruct.h>
   42 #include <netnatm/api/unisap.h>
   43 #include <netnatm/sig/unidef.h>
   44 #include <netnatm/api/atmapi.h>
   45 #include <netnatm/api/ccatm.h>
   46 #include <netnatm/api/ccpriv.h>
   47 
   48 /*
   49  * Find a port with a given number
   50  */
   51 static struct ccport *
   52 find_port(struct ccdata *cc, u_int portno)
   53 {
   54         struct ccport *port;
   55 
   56         TAILQ_FOREACH(port, &cc->port_list, node_link)
   57                 if (port->param.port == portno)
   58                         return (port);
   59         return (NULL);
   60 }
   61 
   62 /*
   63  * Create a new port structure, initialize it and link it to the node.
   64  * Returns 0 on success, an errno otherwise.
   65  */
   66 struct ccport *
   67 cc_port_create(struct ccdata *cc, void *uarg, u_int portno)
   68 {
   69         struct ccport *port, *p1;
   70 
   71         if (portno == 0 || portno > 0xffffffff)
   72                 return (NULL);
   73 
   74         TAILQ_FOREACH(port, &cc->port_list, node_link)
   75                 if (port->param.port == portno)
   76                         return (NULL);
   77 
   78         port = CCZALLOC(sizeof(*port));
   79         if (port == NULL)
   80                 return (NULL);
   81 
   82         port->uarg = uarg;
   83         port->cc = cc;
   84         port->admin = CCPORT_STOPPED;
   85         LIST_INIT(&port->conn_list);
   86         TAILQ_INIT(&port->addr_list);
   87         port->param.port = portno;
   88         port->param.pcr = 350053;
   89         port->param.max_vpi_bits = 0;
   90         port->param.max_vci_bits = 8;
   91         port->param.max_svpc_vpi = 0;
   92         port->param.max_svcc_vpi = 0;
   93         port->param.min_svcc_vci = 32;
   94         port->param.num_addrs = 0;
   95         TAILQ_INIT(&port->cookies);
   96 
   97         TAILQ_FOREACH(p1, &cc->port_list, node_link)
   98                 if (p1->param.port > portno) {
   99                         TAILQ_INSERT_BEFORE(p1, port, node_link);
  100                         break;
  101                 }
  102         if (p1 == NULL)
  103                 TAILQ_INSERT_TAIL(&cc->port_list, port, node_link);
  104 
  105         return (port);
  106 }
  107 
  108 /*
  109  * Destroy a port. This closes all connections and aborts all the users of
  110  * these connections.
  111  * This should be called only after work has returned so that no signals
  112  * are pending.
  113  */
  114 void
  115 cc_port_destroy(struct ccport *port, int shutdown)
  116 {
  117         struct ccaddr *addr;
  118         struct ccreq *r;
  119 
  120         TAILQ_REMOVE(&port->cc->port_list, port, node_link);
  121 
  122         while ((r = TAILQ_FIRST(&port->cookies)) != NULL) {
  123                 TAILQ_REMOVE(&port->cookies, r, link);
  124                 CCFREE(r);
  125         }
  126 
  127         /*
  128          * Abort all connections.
  129          */
  130         while (!LIST_EMPTY(&port->conn_list))
  131                 cc_conn_abort(LIST_FIRST(&port->conn_list), shutdown);
  132 
  133         /*
  134          * Free addresses.
  135          */
  136         while ((addr = TAILQ_FIRST(&port->addr_list)) != NULL) {
  137                 TAILQ_REMOVE(&port->addr_list, addr, port_link);
  138                 CCFREE(addr);
  139         }
  140 
  141         CCFREE(port);
  142 }
  143 
  144 /*
  145  * Management is given up on this node. Remove all addresses from the port.
  146  */
  147 void
  148 cc_unmanage(struct ccdata *cc)
  149 {
  150         struct ccport *port;
  151         struct ccaddr *addr;
  152 
  153         TAILQ_FOREACH(port, &cc->port_list, node_link) {
  154                 while ((addr = TAILQ_FIRST(&port->addr_list)) != NULL) {
  155                         TAILQ_REMOVE(&port->addr_list, addr, port_link);
  156                         CCFREE(addr);
  157                 }
  158         }
  159 }
  160 
  161 /*
  162  * Compare two addresses
  163  */
  164 static __inline int
  165 addr_eq(const struct uni_addr *a1, const struct uni_addr *a2)
  166 {
  167         return (a1->type == a2->type && a1->plan == a2->plan &&
  168             a1->len == a2->len && memcmp(a1->addr, a2->addr, a1->len) == 0);
  169 }
  170 
  171 
  172 /*
  173  * retrieve addresses
  174  */
  175 int
  176 cc_get_addrs(struct ccdata *cc, u_int portno,
  177     struct uni_addr **pa, u_int **ports, u_int *count)
  178 {
  179         struct ccport *port = NULL;
  180         struct ccaddr *addr;
  181         struct uni_addr *buf, *ptr;
  182         u_int *pports;
  183 
  184         /*
  185          * If a port number is specified and the port does not exist,
  186          * return an error.
  187          */
  188         if (portno != 0)
  189                 if ((port = find_port(cc, portno)) == NULL)
  190                         return (ENOENT);
  191 
  192         /*
  193          * Count the addresses
  194          */
  195         *count = 0;
  196         if (portno != 0) {
  197                 TAILQ_FOREACH(addr, &port->addr_list, port_link)
  198                         (*count)++;
  199         } else {
  200                 TAILQ_FOREACH(port, &cc->port_list, node_link)
  201                         TAILQ_FOREACH(addr, &port->addr_list, port_link)
  202                                 (*count)++;
  203         }
  204 
  205         buf = CCMALLOC(*count * sizeof(struct uni_addr));
  206         if (buf == NULL)
  207                 return (ENOMEM);
  208         ptr = buf;
  209 
  210         *ports = CCMALLOC(*count * sizeof(u_int));
  211         if (*ports == NULL) {
  212                 CCFREE(buf);
  213                 return (ENOMEM);
  214         }
  215         pports = *ports;
  216 
  217         if (portno != 0) {
  218                 TAILQ_FOREACH(addr, &port->addr_list, port_link) {
  219                         *ptr++ = addr->addr;
  220                         *pports++ = portno;
  221                 }
  222         } else {
  223                 TAILQ_FOREACH(port, &cc->port_list, node_link)
  224                         TAILQ_FOREACH(addr, &port->addr_list, port_link) {
  225                                 *ptr++ = addr->addr;
  226                                 *pports++ = port->param.port;
  227                         }
  228         }
  229 
  230         *pa = buf;
  231         return (0);
  232 }
  233 
  234 /*
  235  * return port number
  236  */
  237 u_int
  238 cc_port_no(struct ccport *port)
  239 {
  240         return (port->param.port);
  241 }
  242 
  243 /*
  244  * Address unregisterd.
  245  */
  246 int
  247 cc_addr_unregister(struct ccdata *cc, u_int portno, const struct uni_addr *arg)
  248 {
  249         struct ccport *port;
  250         struct ccaddr *a;
  251 
  252         if ((port = find_port(cc, portno)) == NULL)
  253                 return (ENOENT);
  254 
  255         /* Find the address */
  256         TAILQ_FOREACH(a, &port->addr_list, port_link)
  257                 if (addr_eq(arg, &a->addr)) {
  258                         TAILQ_REMOVE(&port->addr_list, a, port_link);
  259                         CCFREE(a);
  260                         return (0);
  261                 }
  262 
  263         return (ENOENT);
  264 }
  265 
  266 /*
  267  * Address registerd.
  268  */
  269 int
  270 cc_addr_register(struct ccdata *cc, u_int portno, const struct uni_addr *arg)
  271 {
  272         struct ccport *port, *p1;
  273         struct ccaddr *a;
  274 
  275         if ((port = find_port(cc, portno)) == NULL)
  276                 return (ENOENT);
  277 
  278         /* maybe we know it already? */
  279         TAILQ_FOREACH(p1, &port->cc->port_list, node_link)
  280                 TAILQ_FOREACH(a, &p1->addr_list, port_link)
  281                         if (addr_eq(arg, &a->addr))
  282                                 return (EISCONN);
  283 
  284         a = CCZALLOC(sizeof(*a));
  285         if (a == NULL)
  286                 return (ENOMEM);
  287         a->addr = *arg;
  288 
  289         TAILQ_INSERT_TAIL(&port->addr_list, a, port_link);
  290 
  291         return (0);
  292 }
  293 
  294 /*
  295  * Set/get port parameters.
  296  */
  297 int
  298 cc_port_get_param(struct ccdata *cc, u_int portno,
  299     struct atm_port_info *param)
  300 {
  301         struct ccport *port;
  302 
  303         if ((port = find_port(cc, portno)) == NULL)
  304                 return (ENOENT);
  305 
  306         *param = port->param;
  307         return (0);
  308 }
  309 
  310 /* XXX maybe allow only in stopped. */
  311 int
  312 cc_port_set_param(struct ccdata *cc, const struct atm_port_info *param)
  313 {
  314         struct ccport *port;
  315         struct ccaddr *addr;
  316 
  317         if ((port = find_port(cc, param->port)) == NULL)
  318                 return (ENOENT);
  319 
  320         port->param = *param;
  321 
  322         port->param.num_addrs = 0;
  323         TAILQ_FOREACH(addr, &port->addr_list, port_link)
  324                 port->param.num_addrs++;
  325 
  326         return (0);
  327 }
  328 
  329 /*
  330  * get port list
  331  */
  332 int
  333 cc_port_getlist(struct ccdata *cc, u_int *cnt, u_int **ports)
  334 {
  335         struct ccport *p;
  336         u_int n;
  337 
  338         n = 0;
  339         TAILQ_FOREACH(p, &cc->port_list, node_link)
  340                 n++;
  341 
  342         *ports = CCMALLOC(n * sizeof(u_int));
  343         if (*ports == NULL)
  344                 return (ENOMEM);
  345 
  346         n = 0;
  347         TAILQ_FOREACH(p, &cc->port_list, node_link)
  348                 (*ports)[n++] = p->param.port;
  349         *cnt = n;
  350 
  351         return (0);
  352 }
  353 
  354 /*
  355  * START and STOP signalling
  356  */
  357 int
  358 cc_port_start(struct ccdata *cc, u_int portno)
  359 {
  360         struct ccport *port;
  361 
  362         if ((port = find_port(cc, portno)) == NULL)
  363                 return (ENOENT);
  364         if (port->admin != CCPORT_STOPPED)
  365                 return (EISCONN);
  366 
  367         cc->funcs->send_uni_glob(port, port->uarg,
  368             UNIAPI_LINK_ESTABLISH_request, 0, NULL);
  369         port->admin = CCPORT_RUNNING;
  370 
  371         return (0);
  372 }
  373 
  374 int
  375 cc_port_stop(struct ccdata *cc, u_int portno)
  376 {
  377         struct ccport *port;
  378 
  379         if ((port = find_port(cc, portno)) == NULL)
  380                 return (ENOENT);
  381         if (port->admin != CCPORT_RUNNING)
  382                 return (ENOTCONN);
  383 
  384         port->admin = CCPORT_STOPPED;
  385 
  386         /*
  387          * Abort all connections.
  388          */
  389         while (!LIST_EMPTY(&port->conn_list))
  390                 cc_conn_destroy(LIST_FIRST(&port->conn_list));
  391 
  392         return (0);
  393 }
  394 
  395 /*
  396  * is port running?
  397  */
  398 int
  399 cc_port_isrunning(struct ccdata *cc, u_int portno, int *state)
  400 {
  401         struct ccport *port;
  402 
  403         if ((port = find_port(cc, portno)) == NULL)
  404                 return (ENOENT);
  405         if (port->admin == CCPORT_RUNNING)
  406                 *state = 1;
  407         else
  408                 *state = 0;
  409         return (0);
  410 }
  411 
  412 /*
  413  * Clear address and prefix information from the named port.
  414  */
  415 int
  416 cc_port_clear(struct ccdata *cc, u_int portno)
  417 {
  418         struct ccaddr *addr;
  419         struct ccport *port;
  420 
  421         if ((port = find_port(cc, portno)) == NULL)
  422                 return (ENOENT);
  423 
  424         while ((addr = TAILQ_FIRST(&port->addr_list)) != NULL) {
  425                 TAILQ_REMOVE(&port->addr_list, addr, port_link);
  426                 CCFREE(addr);
  427         }
  428         return (0);
  429 }
  430 
  431 /*
  432  * retrieve info on local ports
  433  */
  434 struct atm_port_list *
  435 cc_get_local_port_info(struct ccdata *cc, u_int portno, size_t *lenp)
  436 {
  437         struct atm_port_list *list;
  438         struct atm_port_info *pp;
  439         struct uni_addr *aa;
  440         struct ccaddr *addr;
  441         struct ccport *port;
  442         u_int nports, naddrs;
  443 
  444         /*
  445          * Count ports and addresses.
  446          */
  447         nports = 0;
  448         naddrs = 0;
  449         TAILQ_FOREACH(port, &cc->port_list, node_link) {
  450                 if (portno == 0 || port->param.port == portno) {
  451                         nports++;
  452                         TAILQ_FOREACH(addr, &port->addr_list, port_link)
  453                                 naddrs++;
  454                 }
  455         }
  456 
  457         /*
  458          * Size and allocate message
  459          */
  460         *lenp = sizeof(*list) + nports * sizeof(*pp) + naddrs * sizeof(*aa);
  461 
  462         list = CCZALLOC(*lenp);
  463         if (list == NULL)
  464                 return (NULL);
  465 
  466         /*
  467          * Fill the message.
  468          */
  469         list->num_ports = nports;
  470         list->num_addrs = naddrs;
  471 
  472         pp = (void *)((u_char *)list + sizeof(*list));
  473         aa = (void *)((u_char *)list + sizeof(*list) + nports * sizeof(*pp));
  474 
  475         TAILQ_FOREACH(port, &cc->port_list, node_link) {
  476                 if (portno == 0 || port->param.port == portno) {
  477                         *pp = port->param;
  478                         pp->num_addrs = 0;
  479                         TAILQ_FOREACH(addr, &port->addr_list, port_link) {
  480                                 *aa++ = addr->addr;
  481                                 pp->num_addrs++;
  482                         }
  483                         pp++;
  484                 }
  485         }
  486 
  487         return (list);
  488 }
  489 
  490 static struct ccreq *
  491 find_cookie(struct ccport *port, u_int cookie)
  492 {
  493         struct ccreq *r;
  494 
  495         TAILQ_FOREACH(r, &port->cookies, link)
  496                 if (r->cookie == cookie)
  497                         return (r);
  498         return (NULL);
  499 }
  500 
  501 /*
  502  * input a response from the UNI layer to CC
  503  */
  504 int
  505 cc_uni_response(struct ccport *port, u_int cookie, u_int reason, u_int state)
  506 {
  507         struct ccconn *conn;
  508         struct ccreq *req;
  509 
  510         if (cookie == 0)
  511                 return (EINVAL);
  512 
  513         if (port->admin != CCPORT_RUNNING)
  514                 return (ENOTCONN);
  515 
  516         if ((req = find_cookie(port, cookie)) == NULL) {
  517                 cc_port_log(port, "UNI response for unknown cookie %u", cookie);
  518                 return (EINVAL);
  519         }
  520         conn = req->conn;
  521 
  522         TAILQ_REMOVE(&port->cookies, req, link);
  523         CCFREE(req);
  524 
  525         if (reason == UNIAPI_OK)
  526                 return (cc_conn_resp(conn, CONN_SIG_OK,
  527                     cookie, reason, state));
  528         else
  529                 return (cc_conn_resp(conn, CONN_SIG_ERROR,
  530                     cookie, reason, state));
  531 }
  532 
  533 static struct ccconn *
  534 find_cref(const struct ccport *port, const struct uni_cref *cref)
  535 {
  536         struct ccconn *conn;
  537 
  538         LIST_FOREACH(conn, &port->conn_list, port_link)
  539                 if (conn->cref.cref == cref->cref &&
  540                     conn->cref.flag == cref->flag)
  541                         return (conn);
  542         return (NULL);
  543 }
  544 
  545 /*
  546  * Signal from UNI on this port
  547  */
  548 int
  549 cc_uni_signal(struct ccport *port, u_int cookie, u_int sig, struct uni_msg *msg)
  550 {
  551         int error = 0;
  552         size_t len, ilen = 0;
  553         struct uni_cref *cref;
  554         struct ccconn *conn;
  555 
  556         if (port->admin != CCPORT_RUNNING) {
  557                 error = ENOTCONN;
  558                 goto out;
  559         }
  560         len = (msg != NULL) ? uni_msg_len(msg) : 0;
  561 
  562         switch ((enum uni_sig)sig) {
  563 
  564           case UNIAPI_ERROR:
  565                 /* handled above */
  566                 cc_port_log(port, "bad UNIAPI_ERROR cookie=%u", cookie);
  567                 error = EINVAL;
  568                 break;
  569 
  570           case UNIAPI_CALL_CREATED:
  571                 ilen = sizeof(struct uniapi_call_created);
  572                 if (len != ilen)
  573                         goto bad_len;
  574 
  575                 if (cookie != 0) {
  576                         /* outgoing call */
  577                         struct ccreq *req;
  578 
  579                         if ((req = find_cookie(port, cookie)) == NULL) {
  580                                 cc_port_log(port, "bad cookie %u in CREATE",
  581                                     cookie);
  582                                 error = EINVAL;
  583                                 goto out;
  584                         }
  585                         conn = req->conn;
  586 
  587                 } else {
  588                         if ((conn = cc_conn_create(port->cc)) == NULL) {
  589                                 error = ENOMEM;
  590                                 goto out;
  591                         }
  592                         cc_conn_ins_port(conn, port);
  593                 }
  594 
  595                 cc_conn_sig_msg_nodef(conn, CONN_SIG_CREATED, msg);
  596                 msg = NULL;
  597                 goto out;
  598 
  599           case UNIAPI_CALL_DESTROYED:
  600                 ilen = sizeof(struct uniapi_call_destroyed);
  601                 if (len != ilen)
  602                         goto bad_len;
  603 
  604                 cref = &uni_msg_rptr(msg, struct uniapi_call_destroyed *)->cref;
  605                 if ((conn = find_cref(port, cref)) == NULL)
  606                         goto unk_call;
  607 
  608                 error = cc_conn_sig(conn, CONN_SIG_DESTROYED, NULL);
  609                 goto out;
  610 
  611           case UNIAPI_LINK_ESTABLISH_confirm:
  612                 goto out;
  613 
  614           case UNIAPI_LINK_RELEASE_confirm:
  615                 /* Ups. If we administratively up, restart the link */
  616                 if (port->admin == CCPORT_RUNNING)
  617                         port->cc->funcs->send_uni_glob(port, port->uarg,
  618                             UNIAPI_LINK_ESTABLISH_request, 0, NULL);
  619                 goto out;
  620 
  621           case UNIAPI_PARTY_CREATED:
  622                 ilen = sizeof(struct uniapi_party_created);
  623                 if (len != ilen)
  624                         goto bad_len;
  625 
  626                 cref = &uni_msg_rptr(msg, struct uniapi_party_created *)->cref;
  627 
  628                 if ((conn = find_cref(port, cref)) == NULL)
  629                         goto unk_call;
  630 
  631                 error = cc_conn_sig_msg_nodef(conn,
  632                      CONN_SIG_PARTY_CREATED, msg);
  633                 msg = NULL;
  634                 goto out;
  635 
  636           case UNIAPI_PARTY_DESTROYED:
  637                 ilen = sizeof(struct uniapi_party_destroyed);
  638                 if (len != ilen)
  639                         goto bad_len;
  640 
  641                 cref = &uni_msg_rptr(msg,
  642                     struct uniapi_party_destroyed *)->cref;
  643 
  644                 if ((conn = find_cref(port, cref)) == NULL)
  645                         goto unk_call;
  646 
  647                 error = cc_conn_sig_msg(conn, CONN_SIG_PARTY_DESTROYED, msg);
  648                 msg = NULL;
  649                 goto out;
  650 
  651           case UNIAPI_DROP_PARTY_ACK_indication:        /* UNI -> API */
  652                 ilen = sizeof(struct uniapi_drop_party_ack_indication);
  653                 if (len != ilen)
  654                         goto bad_len;
  655 
  656                 cref = &uni_msg_rptr(msg,
  657                     struct uniapi_drop_party_ack_indication *)->drop.hdr.cref;
  658 
  659                 if ((conn = find_cref(port, cref)) == NULL)
  660                         goto unk_call;
  661 
  662                 error = cc_conn_sig_msg(conn, CONN_SIG_DROP_PARTY_ACK_IND, msg);
  663                 msg = NULL;
  664                 goto out;
  665 
  666           case UNIAPI_RESET_indication:                 /* UNI -> API */
  667             {
  668                 /*
  669                  * XXX - do the right thing
  670                  */
  671                 struct uniapi_reset_indication *ind = uni_msg_rptr(msg,
  672                     struct uniapi_reset_indication *);
  673                 struct uniapi_reset_response *resp;
  674                 struct uni_msg *u;
  675                 
  676                 /*
  677                  * Construct message to UNI.
  678                  */
  679                 if ((u = uni_msg_alloc(sizeof(*resp))) == NULL)
  680                         return (ENOMEM);
  681 
  682                 resp = uni_msg_wptr(u, struct uniapi_reset_response *);
  683                 memset(resp, 0, sizeof(*resp));
  684                 u->b_wptr += sizeof(*resp);
  685 
  686                 resp->restart = ind->restart;
  687                 resp->connid = ind->connid;
  688 
  689                 port->cc->funcs->send_uni_glob(port, port->uarg,
  690                     UNIAPI_RESET_response, 0, u);
  691 
  692                 goto out;
  693             }
  694 
  695           case UNIAPI_RELEASE_indication:               /* UNI -> API */
  696                 ilen = sizeof(struct uniapi_release_indication);
  697                 if (len != ilen)
  698                         goto bad_len;
  699 
  700                 cref = &uni_msg_rptr(msg, struct uniapi_release_indication *)
  701                     ->release.hdr.cref;
  702 
  703                 if ((conn = find_cref(port, cref)) == NULL)
  704                         goto unk_call;
  705 
  706                 error = cc_conn_sig_msg(conn, CONN_SIG_REL_IND, msg);
  707                 msg = NULL;
  708                 goto out;
  709 
  710           case UNIAPI_RELEASE_confirm:                  /* UNI -> API */
  711                 ilen = sizeof(struct uniapi_release_confirm);
  712                 if (len != ilen)
  713                         goto bad_len;
  714 
  715                 cref = &uni_msg_rptr(msg, struct uniapi_release_confirm *)
  716                     ->release.hdr.cref;
  717 
  718                 if ((conn = find_cref(port, cref)) == NULL)
  719                         goto unk_call;
  720 
  721                 error = cc_conn_sig_msg(conn, CONN_SIG_REL_CONF, msg);
  722                 msg = NULL;
  723                 goto out;
  724 
  725           case UNIAPI_SETUP_confirm:                    /* UNI -> API */
  726                 ilen = sizeof(struct uniapi_setup_confirm);
  727                 if (len != ilen)
  728                         goto bad_len;
  729 
  730                 cref = &uni_msg_rptr(msg, struct uniapi_setup_confirm *)
  731                     ->connect.hdr.cref;
  732 
  733                 if ((conn = find_cref(port, cref)) == NULL)
  734                         goto unk_call;
  735 
  736                 error = cc_conn_sig_msg(conn, CONN_SIG_SETUP_CONFIRM, msg);
  737                 msg = NULL;
  738                 goto out;
  739 
  740 
  741           case UNIAPI_ALERTING_indication:              /* UNI -> API */
  742                 ilen = sizeof(struct uniapi_alerting_indication);
  743                 if (len != ilen)
  744                         goto bad_len;
  745 
  746                 cref = &uni_msg_rptr(msg, struct uniapi_alerting_indication *)
  747                     ->alerting.hdr.cref;
  748 
  749                 if ((conn = find_cref(port, cref)) == NULL)
  750                         goto unk_call;
  751 
  752                 error = cc_conn_sig_msg(conn, CONN_SIG_ALERTING_IND, msg);
  753                 msg = NULL;
  754                 goto out;
  755 
  756 
  757           case UNIAPI_PROCEEDING_indication:            /* UNI -> API */
  758                 ilen = sizeof(struct uniapi_proceeding_indication);
  759                 if (len != ilen)
  760                         goto bad_len;
  761 
  762                 cref = &uni_msg_rptr(msg, struct uniapi_proceeding_indication *)
  763                     ->call_proc.hdr.cref;
  764 
  765                 if ((conn = find_cref(port, cref)) == NULL)
  766                         goto unk_call;
  767 
  768                 error = cc_conn_sig_msg(conn, CONN_SIG_PROC_IND, msg);
  769                 msg = NULL;
  770                 goto out;
  771 
  772 
  773           case UNIAPI_SETUP_indication:                 /* UNI -> API */
  774                 ilen = sizeof(struct uniapi_setup_indication);
  775                 if (len != ilen)
  776                         goto bad_len;
  777 
  778                 cref = &uni_msg_rptr(msg, struct uniapi_setup_indication *)
  779                     ->setup.hdr.cref;
  780 
  781                 if ((conn = find_cref(port, cref)) == NULL)
  782                         goto unk_call;
  783 
  784                 error = cc_conn_sig_msg(conn, CONN_SIG_SETUP_IND, msg);
  785                 msg = NULL;
  786                 goto out;
  787 
  788           case UNIAPI_SETUP_COMPLETE_indication:        /* UNI -> API */
  789                 ilen = sizeof(struct uniapi_setup_complete_indication);
  790                 if (len != ilen)
  791                         goto bad_len;
  792 
  793                 cref = &uni_msg_rptr(msg,
  794                     struct uniapi_setup_complete_indication *)
  795                     ->connect_ack.hdr.cref;
  796 
  797                 if ((conn = find_cref(port, cref)) == NULL)
  798                         goto unk_call;
  799 
  800                 error = cc_conn_sig_msg(conn, CONN_SIG_SETUP_COMPL, msg);
  801                 msg = NULL;
  802                 goto out;
  803 
  804           case UNIAPI_PARTY_ALERTING_indication:        /* UNI -> API */
  805                 ilen = sizeof(struct uniapi_party_alerting_indication);
  806                 if (len != ilen)
  807                         goto bad_len;
  808 
  809                 cref = &uni_msg_rptr(msg,
  810                     struct uniapi_party_alerting_indication *)->alert.hdr.cref;
  811 
  812                 if ((conn = find_cref(port, cref)) == NULL)
  813                         goto unk_call;
  814 
  815                 error = cc_conn_sig_msg(conn, CONN_SIG_PARTY_ALERTING_IND, msg);
  816                 msg = NULL;
  817                 goto out;
  818 
  819           case UNIAPI_ADD_PARTY_ACK_indication:         /* UNI -> API */
  820                 ilen = sizeof(struct uniapi_add_party_ack_indication);
  821                 if (len != ilen)
  822                         goto bad_len;
  823 
  824                 cref = &uni_msg_rptr(msg,
  825                     struct uniapi_add_party_ack_indication *)->ack.hdr.cref;
  826 
  827                 if ((conn = find_cref(port, cref)) == NULL)
  828                         goto unk_call;
  829 
  830                 error = cc_conn_sig_msg(conn, CONN_SIG_PARTY_ADD_ACK_IND, msg);
  831                 msg = NULL;
  832                 goto out;
  833 
  834           case UNIAPI_ADD_PARTY_REJ_indication:         /* UNI -> API */
  835                 ilen = sizeof(struct uniapi_add_party_rej_indication);
  836                 if (len != ilen)
  837                         goto bad_len;
  838 
  839                 cref = &uni_msg_rptr(msg,
  840                     struct uniapi_add_party_rej_indication *)->rej.hdr.cref;
  841 
  842                 if ((conn = find_cref(port, cref)) == NULL)
  843                         goto unk_call;
  844 
  845                 error = cc_conn_sig_msg(conn, CONN_SIG_PARTY_ADD_REJ_IND, msg);
  846                 msg = NULL;
  847                 goto out;
  848 
  849           case UNIAPI_DROP_PARTY_indication:            /* UNI -> API */
  850                 ilen = sizeof(struct uniapi_drop_party_indication);
  851                 if (len != ilen)
  852                         goto bad_len;
  853 
  854                 cref = &uni_msg_rptr(msg, struct uniapi_drop_party_indication *)
  855                     ->drop.hdr.cref;
  856 
  857                 if ((conn = find_cref(port, cref)) == NULL)
  858                         goto unk_call;
  859 
  860                 error = cc_conn_sig_msg(conn, CONN_SIG_DROP_PARTY_IND, msg);
  861                 msg = NULL;
  862                 goto out;
  863 
  864           case UNIAPI_RESET_confirm:                    /* UNI -> API */
  865           case UNIAPI_RESET_ERROR_indication:           /* UNI -> API */
  866           case UNIAPI_RESET_STATUS_indication:          /* UNI -> API */
  867                 /* XXX */
  868                 goto out;
  869 
  870           case UNIAPI_NOTIFY_indication:                /* UNI -> API */
  871           case UNIAPI_STATUS_indication:                /* UNI -> API */
  872                 break;
  873 
  874           case UNIAPI_ADD_PARTY_indication:             /* UNI -> API */
  875                 /* not supported by the API */
  876                 break;
  877 
  878         /*
  879          * All these are illegal in this direction
  880          */
  881           case UNIAPI_LINK_ESTABLISH_request:           /* API -> UNI */
  882           case UNIAPI_LINK_RELEASE_request:             /* API -> UNI */
  883           case UNIAPI_RESET_request:                    /* API -> UNI */
  884           case UNIAPI_RESET_response:                   /* API -> UNI */
  885           case UNIAPI_RESET_ERROR_response:             /* API -> UNI */
  886           case UNIAPI_SETUP_request:                    /* API -> UNI */
  887           case UNIAPI_SETUP_response:                   /* API -> UNI */
  888           case UNIAPI_ALERTING_request:                 /* API -> UNI */
  889           case UNIAPI_PROCEEDING_request:               /* API -> UNI */
  890           case UNIAPI_RELEASE_request:                  /* API -> UNI */
  891           case UNIAPI_RELEASE_response:                 /* API -> UNI */
  892           case UNIAPI_NOTIFY_request:                   /* API -> UNI */
  893           case UNIAPI_STATUS_ENQUIRY_request:           /* API -> UNI */
  894           case UNIAPI_ADD_PARTY_request:                /* API -> UNI */
  895           case UNIAPI_PARTY_ALERTING_request:           /* API -> UNI */
  896           case UNIAPI_ADD_PARTY_ACK_request:            /* API -> UNI */
  897           case UNIAPI_ADD_PARTY_REJ_request:            /* API -> UNI */
  898           case UNIAPI_DROP_PARTY_request:               /* API -> UNI */
  899           case UNIAPI_DROP_PARTY_ACK_request:           /* API -> UNI */
  900           case UNIAPI_ABORT_CALL_request:               /* API -> UNI */
  901           case UNIAPI_SETUP_COMPLETE_request:           /* API -> UNI */
  902           case UNIAPI_MAXSIG:
  903                 break;
  904         }
  905         cc_port_log(port, "bad signal %u", sig);
  906         error = EINVAL;
  907         goto out;
  908 
  909   bad_len:
  910         cc_port_log(port, "signal %u bad length: %zu, need %zu", len, ilen);
  911         error = EINVAL;
  912         goto out;
  913 
  914   unk_call:
  915         cc_port_log(port, "unknown call %u/%u", cref->cref, cref->flag);
  916         error = EINVAL;
  917 
  918   out:
  919         if (msg != NULL)
  920                 uni_msg_destroy(msg);
  921         return (error);
  922 }
  923 

Cache object: a3dca657135e2a7a7298dc512b342229


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