1139823Simp/*- 2133578Sharti * Copyright (c) 2001-2002 3133578Sharti * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4133578Sharti * All rights reserved. 5133578Sharti * Copyright (c) 2003-2004 6133578Sharti * Hartmut Brandt 7133578Sharti * All rights reserved. 8133578Sharti * 9133578Sharti * Author: Harti Brandt <harti@freebsd.org> 10133578Sharti * 11133578Sharti * Redistribution of this software and documentation and use in source and 12133578Sharti * binary forms, with or without modification, are permitted provided that 13133578Sharti * the following conditions are met: 14133578Sharti * 15133578Sharti * 1. Redistributions of source code or documentation must retain the above 16133578Sharti * copyright notice, this list of conditions and the following disclaimer. 17133578Sharti * 2. Redistributions in binary form must reproduce the above copyright 18133578Sharti * notice, this list of conditions and the following disclaimer in the 19133578Sharti * documentation and/or other materials provided with the distribution. 20133578Sharti * 21133578Sharti * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE AUTHOR 22133578Sharti * AND ITS CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 23133578Sharti * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 24133578Sharti * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 25133578Sharti * THE AUTHOR OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26133578Sharti * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27133578Sharti * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 28133578Sharti * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29133578Sharti * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30133578Sharti * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 31133578Sharti * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32133578Sharti * 33133578Sharti * $FreeBSD$ 34133578Sharti * 35133578Sharti * ATM call control and API 36133578Sharti */ 37133578Sharti 38133578Sharti#include <sys/cdefs.h> 39133578Sharti__FBSDID("$FreeBSD$"); 40133578Sharti 41133578Sharti#include <sys/param.h> 42133578Sharti#include <sys/systm.h> 43133578Sharti#include <sys/kernel.h> 44133578Sharti#include <sys/malloc.h> 45133578Sharti#include <sys/mbuf.h> 46133578Sharti#include <sys/errno.h> 47133578Sharti#include <sys/socket.h> 48133578Sharti#include <sys/socketvar.h> 49133578Sharti#include <sys/sbuf.h> 50133578Sharti#include <machine/stdarg.h> 51133578Sharti 52133578Sharti#include <netgraph/ng_message.h> 53133578Sharti#include <netgraph/netgraph.h> 54133578Sharti#include <netgraph/ng_parse.h> 55133578Sharti#include <netnatm/unimsg.h> 56133578Sharti#include <netnatm/msg/unistruct.h> 57133578Sharti#include <netnatm/api/unisap.h> 58133578Sharti#include <netnatm/sig/unidef.h> 59133578Sharti#include <netgraph/atm/ngatmbase.h> 60133578Sharti#include <netgraph/atm/ng_uni.h> 61133578Sharti#include <netnatm/api/atmapi.h> 62133578Sharti#include <netgraph/atm/ng_ccatm.h> 63133578Sharti#include <netnatm/api/ccatm.h> 64133578Sharti 65133578ShartiMODULE_DEPEND(ng_ccatm, ngatmbase, 1, 1, 1); 66133578Sharti 67133578ShartiMALLOC_DEFINE(M_NG_CCATM, "ng_ccatm", "netgraph uni api node"); 68133578Sharti 69133578Sharti/* 70133578Sharti * Command structure parsing 71133578Sharti */ 72133578Sharti 73133578Sharti/* ESI */ 74133578Shartistatic const struct ng_parse_fixedarray_info ng_ccatm_esi_type_info = 75133578Sharti NGM_CCATM_ESI_INFO; 76133578Shartistatic const struct ng_parse_type ng_ccatm_esi_type = { 77133578Sharti &ng_parse_fixedarray_type, 78133578Sharti &ng_ccatm_esi_type_info 79133578Sharti}; 80133578Sharti 81133578Sharti/* PORT PARAMETERS */ 82133578Shartistatic const struct ng_parse_struct_field ng_ccatm_atm_port_type_info[] = 83133578Sharti NGM_CCATM_ATM_PORT_INFO; 84133578Shartistatic const struct ng_parse_type ng_ccatm_atm_port_type = { 85133578Sharti &ng_parse_struct_type, 86133578Sharti ng_ccatm_atm_port_type_info 87133578Sharti}; 88133578Sharti 89133578Sharti/* PORT structure */ 90133578Shartistatic const struct ng_parse_struct_field ng_ccatm_port_type_info[] = 91133578Sharti NGM_CCATM_PORT_INFO; 92133578Shartistatic const struct ng_parse_type ng_ccatm_port_type = { 93133578Sharti &ng_parse_struct_type, 94133578Sharti ng_ccatm_port_type_info 95133578Sharti}; 96133578Sharti 97133578Sharti/* the ADDRESS array itself */ 98133578Shartistatic const struct ng_parse_fixedarray_info ng_ccatm_addr_array_type_info = 99133578Sharti NGM_CCATM_ADDR_ARRAY_INFO; 100133578Shartistatic const struct ng_parse_type ng_ccatm_addr_array_type = { 101133578Sharti &ng_parse_fixedarray_type, 102133578Sharti &ng_ccatm_addr_array_type_info 103133578Sharti}; 104133578Sharti 105133578Sharti/* one ADDRESS */ 106133578Shartistatic const struct ng_parse_struct_field ng_ccatm_uni_addr_type_info[] = 107133578Sharti NGM_CCATM_UNI_ADDR_INFO; 108133578Shartistatic const struct ng_parse_type ng_ccatm_uni_addr_type = { 109133578Sharti &ng_parse_struct_type, 110133578Sharti ng_ccatm_uni_addr_type_info 111133578Sharti}; 112133578Sharti 113133578Sharti/* ADDRESS request */ 114133578Shartistatic const struct ng_parse_struct_field ng_ccatm_addr_req_type_info[] = 115133578Sharti NGM_CCATM_ADDR_REQ_INFO; 116133578Shartistatic const struct ng_parse_type ng_ccatm_addr_req_type = { 117133578Sharti &ng_parse_struct_type, 118133578Sharti ng_ccatm_addr_req_type_info 119133578Sharti}; 120133578Sharti 121133578Sharti/* ADDRESS var-array */ 122133578Shartistatic int 123133578Sharting_ccatm_addr_req_array_getlen(const struct ng_parse_type *type, 124133578Sharti const u_char *start, const u_char *buf) 125133578Sharti{ 126133578Sharti const struct ngm_ccatm_get_addresses *p; 127133578Sharti 128133578Sharti p = (const struct ngm_ccatm_get_addresses *) 129133578Sharti (buf - offsetof(struct ngm_ccatm_get_addresses, addr)); 130133578Sharti return (p->count); 131133578Sharti} 132133578Shartistatic const struct ng_parse_array_info ng_ccatm_addr_req_array_type_info = 133133578Sharti NGM_CCATM_ADDR_REQ_ARRAY_INFO; 134133578Shartistatic const struct ng_parse_type ng_ccatm_addr_req_array_type = { 135133578Sharti &ng_parse_array_type, 136133578Sharti &ng_ccatm_addr_req_array_type_info 137133578Sharti}; 138133578Sharti 139133578Sharti/* Outer get_ADDRESSes structure */ 140133578Shartistatic const struct ng_parse_struct_field ng_ccatm_get_addresses_type_info[] = 141133578Sharti NGM_CCATM_GET_ADDRESSES_INFO; 142133578Shartistatic const struct ng_parse_type ng_ccatm_get_addresses_type = { 143133578Sharti &ng_parse_struct_type, 144133578Sharti ng_ccatm_get_addresses_type_info 145133578Sharti}; 146133578Sharti 147133578Sharti/* Port array */ 148133578Shartistatic int 149133578Sharting_ccatm_port_array_getlen(const struct ng_parse_type *type, 150133578Sharti const u_char *start, const u_char *buf) 151133578Sharti{ 152133578Sharti const struct ngm_ccatm_portlist *p; 153133578Sharti 154133578Sharti p = (const struct ngm_ccatm_portlist *) 155133578Sharti (buf - offsetof(struct ngm_ccatm_portlist, ports)); 156133578Sharti return (p->nports); 157133578Sharti} 158133578Shartistatic const struct ng_parse_array_info ng_ccatm_port_array_type_info = 159133578Sharti NGM_CCATM_PORT_ARRAY_INFO; 160133578Shartistatic const struct ng_parse_type ng_ccatm_port_array_type = { 161133578Sharti &ng_parse_array_type, 162133578Sharti &ng_ccatm_port_array_type_info 163133578Sharti}; 164133578Sharti 165133578Sharti/* Portlist structure */ 166133578Shartistatic const struct ng_parse_struct_field ng_ccatm_portlist_type_info[] = 167133578Sharti NGM_CCATM_PORTLIST_INFO; 168133578Shartistatic const struct ng_parse_type ng_ccatm_portlist_type = { 169133578Sharti &ng_parse_struct_type, 170133578Sharti ng_ccatm_portlist_type_info 171133578Sharti}; 172133578Sharti 173133578Sharti/* 174133578Sharti * Command list 175133578Sharti */ 176133578Shartistatic const struct ng_cmdlist ng_ccatm_cmdlist[] = { 177133578Sharti { 178133578Sharti NGM_CCATM_COOKIE, 179133578Sharti NGM_CCATM_DUMP, 180133578Sharti "dump", 181133578Sharti NULL, 182133578Sharti NULL 183133578Sharti }, 184133578Sharti { 185133578Sharti NGM_CCATM_COOKIE, 186133578Sharti NGM_CCATM_STOP, 187133578Sharti "stop", 188133578Sharti &ng_ccatm_port_type, 189133578Sharti NULL 190133578Sharti }, 191133578Sharti { 192133578Sharti NGM_CCATM_COOKIE, 193133578Sharti NGM_CCATM_START, 194133578Sharti "start", 195133578Sharti &ng_ccatm_port_type, 196133578Sharti NULL 197133578Sharti }, 198133578Sharti { 199133578Sharti NGM_CCATM_COOKIE, 200133578Sharti NGM_CCATM_GETSTATE, 201133578Sharti "getstate", 202133578Sharti &ng_ccatm_port_type, 203133578Sharti &ng_parse_uint32_type 204133578Sharti }, 205133578Sharti { 206133578Sharti NGM_CCATM_COOKIE, 207133578Sharti NGM_CCATM_GET_ADDRESSES, 208133578Sharti "get_addresses", 209133578Sharti &ng_ccatm_port_type, 210133578Sharti &ng_ccatm_get_addresses_type 211133578Sharti }, 212133578Sharti { 213133578Sharti NGM_CCATM_COOKIE, 214133578Sharti NGM_CCATM_CLEAR, 215133578Sharti "clear", 216133578Sharti &ng_ccatm_port_type, 217133578Sharti NULL 218133578Sharti }, 219133578Sharti { 220133578Sharti NGM_CCATM_COOKIE, 221133578Sharti NGM_CCATM_ADDRESS_REGISTERED, 222133578Sharti "address_reg", 223133578Sharti &ng_ccatm_addr_req_type, 224133578Sharti NULL 225133578Sharti }, 226133578Sharti { 227133578Sharti NGM_CCATM_COOKIE, 228133578Sharti NGM_CCATM_ADDRESS_UNREGISTERED, 229133578Sharti "address_unreg", 230133578Sharti &ng_ccatm_addr_req_type, 231133578Sharti NULL 232133578Sharti }, 233133578Sharti { 234133578Sharti NGM_CCATM_COOKIE, 235133578Sharti NGM_CCATM_SET_PORT_PARAM, 236133578Sharti "set_port_param", 237133578Sharti &ng_ccatm_atm_port_type, 238133578Sharti NULL 239133578Sharti }, 240133578Sharti { 241133578Sharti NGM_CCATM_COOKIE, 242133578Sharti NGM_CCATM_GET_PORT_PARAM, 243133578Sharti "get_port_param", 244133578Sharti &ng_ccatm_port_type, 245133578Sharti &ng_ccatm_atm_port_type, 246133578Sharti }, 247133578Sharti { 248133578Sharti NGM_CCATM_COOKIE, 249133578Sharti NGM_CCATM_GET_PORTLIST, 250133578Sharti "get_portlist", 251133578Sharti NULL, 252133578Sharti &ng_ccatm_portlist_type, 253133578Sharti }, 254133578Sharti { 255133578Sharti NGM_CCATM_COOKIE, 256133578Sharti NGM_CCATM_SETLOG, 257133578Sharti "setlog", 258133578Sharti &ng_parse_hint32_type, 259133578Sharti &ng_parse_hint32_type, 260133578Sharti }, 261133578Sharti { 262133578Sharti NGM_CCATM_COOKIE, 263133578Sharti NGM_CCATM_RESET, 264133578Sharti "reset", 265133578Sharti NULL, 266133578Sharti NULL, 267133578Sharti }, 268133578Sharti { 0 } 269133578Sharti}; 270133578Sharti 271133578Sharti/* 272133578Sharti * Module data 273133578Sharti */ 274133578Shartistatic ng_constructor_t ng_ccatm_constructor; 275133578Shartistatic ng_rcvmsg_t ng_ccatm_rcvmsg; 276133578Shartistatic ng_shutdown_t ng_ccatm_shutdown; 277133578Shartistatic ng_newhook_t ng_ccatm_newhook; 278133578Shartistatic ng_rcvdata_t ng_ccatm_rcvdata; 279133578Shartistatic ng_disconnect_t ng_ccatm_disconnect; 280133578Shartistatic int ng_ccatm_mod_event(module_t, int, void *); 281133578Sharti 282133578Shartistatic struct ng_type ng_ccatm_typestruct = { 283133578Sharti .version = NG_ABI_VERSION, 284133578Sharti .name = NG_CCATM_NODE_TYPE, 285133578Sharti .mod_event = ng_ccatm_mod_event, 286133578Sharti .constructor = ng_ccatm_constructor, /* Node constructor */ 287133578Sharti .rcvmsg = ng_ccatm_rcvmsg, /* Control messages */ 288133578Sharti .shutdown = ng_ccatm_shutdown, /* Node destructor */ 289133578Sharti .newhook = ng_ccatm_newhook, /* Arrival of new hook */ 290133578Sharti .rcvdata = ng_ccatm_rcvdata, /* receive data */ 291133578Sharti .disconnect = ng_ccatm_disconnect, /* disconnect a hook */ 292133578Sharti .cmdlist = ng_ccatm_cmdlist, 293133578Sharti}; 294133578ShartiNETGRAPH_INIT(ccatm, &ng_ccatm_typestruct); 295133578Sharti 296133578Shartistatic ng_rcvdata_t ng_ccatm_rcvuni; 297133578Shartistatic ng_rcvdata_t ng_ccatm_rcvdump; 298133578Shartistatic ng_rcvdata_t ng_ccatm_rcvmanage; 299133578Sharti 300133578Sharti/* 301133578Sharti * Private node data. 302133578Sharti */ 303133578Shartistruct ccnode { 304133578Sharti node_p node; /* the owning node */ 305133578Sharti hook_p dump; /* dump hook */ 306133578Sharti hook_p manage; /* hook to ILMI */ 307133578Sharti 308133578Sharti struct ccdata *data; 309133578Sharti struct mbuf *dump_first; 310133578Sharti struct mbuf *dump_last; /* first and last mbuf when dumping */ 311133578Sharti 312133578Sharti u_int hook_cnt; /* count user and port hooks */ 313133578Sharti}; 314133578Sharti 315133578Sharti/* 316133578Sharti * Private UNI hook data 317133578Sharti */ 318133578Shartistruct cchook { 319133578Sharti int is_uni; /* true if uni hook, user otherwise */ 320133578Sharti struct ccnode *node; /* the owning node */ 321133578Sharti hook_p hook; 322133578Sharti void *inst; /* port or user */ 323133578Sharti}; 324133578Sharti 325133578Shartistatic void ng_ccatm_send_user(struct ccuser *, void *, u_int, void *, size_t); 326133578Shartistatic void ng_ccatm_respond_user(struct ccuser *, void *, int, u_int, 327133578Sharti void *, size_t); 328133578Shartistatic void ng_ccatm_send_uni(struct ccconn *, void *, u_int, u_int, 329133578Sharti struct uni_msg *); 330133578Shartistatic void ng_ccatm_send_uni_glob(struct ccport *, void *, u_int, u_int, 331133578Sharti struct uni_msg *); 332133578Shartistatic void ng_ccatm_log(const char *, ...) __printflike(1, 2); 333133578Sharti 334133578Shartistatic const struct cc_funcs cc_funcs = { 335133578Sharti .send_user = ng_ccatm_send_user, 336133578Sharti .respond_user = ng_ccatm_respond_user, 337133578Sharti .send_uni = ng_ccatm_send_uni, 338133578Sharti .send_uni_glob = ng_ccatm_send_uni_glob, 339133578Sharti .log = ng_ccatm_log, 340133578Sharti}; 341133578Sharti 342133578Sharti/************************************************************ 343133578Sharti * 344133578Sharti * Create a new node 345133578Sharti */ 346133578Shartistatic int 347133578Sharting_ccatm_constructor(node_p node) 348133578Sharti{ 349133578Sharti struct ccnode *priv; 350133578Sharti 351220768Sglebius priv = malloc(sizeof(*priv), M_NG_CCATM, M_WAITOK | M_ZERO); 352133578Sharti 353133578Sharti priv->node = node; 354133578Sharti priv->data = cc_create(&cc_funcs); 355133578Sharti if (priv->data == NULL) { 356133578Sharti free(priv, M_NG_CCATM); 357133578Sharti return (ENOMEM); 358133578Sharti } 359133578Sharti 360133578Sharti NG_NODE_SET_PRIVATE(node, priv); 361133578Sharti 362133578Sharti return (0); 363133578Sharti} 364133578Sharti 365133578Sharti/* 366133578Sharti * Destroy a node. The user list is empty here, because all hooks are 367133578Sharti * previously disconnected. The connection lists may not be empty, because 368133578Sharti * connections may be waiting for responses from the stack. This also means, 369133578Sharti * that no orphaned connections will be made by the port_destroy routine. 370133578Sharti */ 371133578Shartistatic int 372133578Sharting_ccatm_shutdown(node_p node) 373133578Sharti{ 374133578Sharti struct ccnode *priv = NG_NODE_PRIVATE(node); 375133578Sharti 376133578Sharti cc_destroy(priv->data); 377133578Sharti 378133578Sharti free(priv, M_NG_CCATM); 379133578Sharti NG_NODE_SET_PRIVATE(node, NULL); 380133578Sharti 381133578Sharti NG_NODE_UNREF(node); 382133578Sharti 383133578Sharti return (0); 384133578Sharti} 385133578Sharti 386133578Sharti/* 387133578Sharti * Retrieve the registered addresses for one port or all ports. 388133578Sharti * Returns an error code or 0 on success. 389133578Sharti */ 390133578Shartistatic int 391133578Sharting_ccatm_get_addresses(node_p node, uint32_t portno, struct ng_mesg *msg, 392133578Sharti struct ng_mesg **resp) 393133578Sharti{ 394133578Sharti struct ccnode *priv = NG_NODE_PRIVATE(node); 395133578Sharti struct uni_addr *addrs; 396133578Sharti u_int *ports; 397133578Sharti struct ngm_ccatm_get_addresses *list; 398133578Sharti u_int count, i; 399133578Sharti size_t len; 400133578Sharti int err; 401133578Sharti 402133578Sharti err = cc_get_addrs(priv->data, portno, &addrs, &ports, &count); 403133578Sharti if (err != 0) 404133578Sharti return (err); 405133578Sharti 406133578Sharti len = sizeof(*list) + count * sizeof(list->addr[0]); 407133578Sharti NG_MKRESPONSE(*resp, msg, len, M_NOWAIT); 408133578Sharti if (*resp == NULL) { 409133578Sharti free(addrs, M_NG_CCATM); 410133578Sharti free(ports, M_NG_CCATM); 411133578Sharti return (ENOMEM); 412133578Sharti } 413133578Sharti list = (struct ngm_ccatm_get_addresses *)(*resp)->data; 414133578Sharti 415133578Sharti list->count = count; 416133578Sharti for (i = 0; i < count; i++) { 417133578Sharti list->addr[i].port = ports[i]; 418133578Sharti list->addr[i].addr = addrs[i]; 419133578Sharti } 420133578Sharti 421133578Sharti free(addrs, M_NG_CCATM); 422133578Sharti free(ports, M_NG_CCATM); 423133578Sharti 424133578Sharti return (0); 425133578Sharti} 426133578Sharti 427133578Sharti/* 428133578Sharti * Dumper function. Pack the data into an mbuf chain. 429133578Sharti */ 430133578Shartistatic int 431133578Shartisend_dump(struct ccdata *data, void *uarg, const char *buf) 432133578Sharti{ 433133578Sharti struct mbuf *m; 434133578Sharti struct ccnode *priv = uarg; 435133578Sharti 436133578Sharti if (priv->dump == NULL) { 437243882Sglebius m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 438133578Sharti if (m == NULL) 439133578Sharti return (ENOBUFS); 440133578Sharti priv->dump_first = priv->dump_last = m; 441133578Sharti m->m_pkthdr.len = 0; 442133578Sharti } else { 443243882Sglebius m = m_getcl(M_NOWAIT, MT_DATA, 0); 444133578Sharti if (m == 0) { 445133578Sharti m_freem(priv->dump_first); 446133578Sharti return (ENOBUFS); 447133578Sharti } 448133578Sharti priv->dump_last->m_next = m; 449133578Sharti priv->dump_last = m; 450133578Sharti } 451133578Sharti 452133578Sharti strcpy(m->m_data, buf); 453133578Sharti priv->dump_first->m_pkthdr.len += (m->m_len = strlen(buf)); 454133578Sharti 455133578Sharti return (0); 456133578Sharti} 457133578Sharti 458133578Sharti/* 459133578Sharti * Dump current status to dump hook 460133578Sharti */ 461133578Shartistatic int 462133578Sharting_ccatm_dump(node_p node) 463133578Sharti{ 464133578Sharti struct ccnode *priv = NG_NODE_PRIVATE(node); 465133578Sharti struct mbuf *m; 466133578Sharti int error; 467133578Sharti 468133578Sharti priv->dump_first = priv->dump_last = NULL; 469133578Sharti error = cc_dump(priv->data, MCLBYTES, send_dump, priv); 470133578Sharti if (error != 0) 471133578Sharti return (error); 472133578Sharti 473133578Sharti if ((m = priv->dump_first) != NULL) { 474133578Sharti priv->dump_first = priv->dump_last = NULL; 475133578Sharti NG_SEND_DATA_ONLY(error, priv->dump, m); 476133578Sharti return (error); 477133578Sharti } 478133578Sharti return (0); 479133578Sharti} 480133578Sharti 481133578Sharti/* 482133578Sharti * Control message 483133578Sharti */ 484133578Shartistatic int 485133578Sharting_ccatm_rcvmsg(node_p node, item_p item, hook_p lasthook) 486133578Sharti{ 487133578Sharti struct ng_mesg *resp = NULL; 488133578Sharti struct ng_mesg *msg; 489133578Sharti struct ccnode *priv = NG_NODE_PRIVATE(node); 490133578Sharti int error = 0; 491133578Sharti 492133578Sharti NGI_GET_MSG(item, msg); 493133578Sharti 494133578Sharti switch (msg->header.typecookie) { 495133578Sharti 496133578Sharti case NGM_CCATM_COOKIE: 497133578Sharti switch (msg->header.cmd) { 498133578Sharti 499133578Sharti case NGM_CCATM_DUMP: 500133578Sharti if (priv->dump) 501133578Sharti error = ng_ccatm_dump(node); 502133578Sharti else 503133578Sharti error = ENOTCONN; 504133578Sharti break; 505133578Sharti 506133578Sharti case NGM_CCATM_STOP: 507133578Sharti { 508133578Sharti struct ngm_ccatm_port *arg; 509133578Sharti 510133578Sharti if (msg->header.arglen != sizeof(*arg)) { 511133578Sharti error = EINVAL; 512133578Sharti break; 513133578Sharti } 514133578Sharti arg = (struct ngm_ccatm_port *)msg->data; 515133578Sharti error = cc_port_stop(priv->data, arg->port); 516133578Sharti break; 517133578Sharti } 518133578Sharti 519133578Sharti case NGM_CCATM_START: 520133578Sharti { 521133578Sharti struct ngm_ccatm_port *arg; 522133578Sharti 523133578Sharti if (msg->header.arglen != sizeof(*arg)) { 524133578Sharti error = EINVAL; 525133578Sharti break; 526133578Sharti } 527133578Sharti arg = (struct ngm_ccatm_port *)msg->data; 528133578Sharti error = cc_port_start(priv->data, arg->port); 529133578Sharti break; 530133578Sharti } 531133578Sharti 532133578Sharti case NGM_CCATM_GETSTATE: 533133578Sharti { 534133578Sharti struct ngm_ccatm_port *arg; 535133578Sharti int state; 536133578Sharti 537133578Sharti if (msg->header.arglen != sizeof(*arg)) { 538133578Sharti error = EINVAL; 539133578Sharti break; 540133578Sharti } 541133578Sharti arg = (struct ngm_ccatm_port *)msg->data; 542133578Sharti error = cc_port_isrunning(priv->data, arg->port, 543133578Sharti &state); 544133578Sharti if (error == 0) { 545133578Sharti NG_MKRESPONSE(resp, msg, sizeof(uint32_t), 546133578Sharti M_NOWAIT); 547133578Sharti if (resp == NULL) { 548133578Sharti error = ENOMEM; 549133578Sharti break; 550133578Sharti } 551133578Sharti *(uint32_t *)resp->data = state; 552133578Sharti } 553133578Sharti break; 554133578Sharti } 555133578Sharti 556133578Sharti case NGM_CCATM_GET_ADDRESSES: 557133578Sharti { 558133578Sharti struct ngm_ccatm_port *arg; 559133578Sharti 560133578Sharti if (msg->header.arglen != sizeof(*arg)) { 561133578Sharti error = EINVAL; 562133578Sharti break; 563133578Sharti } 564133578Sharti arg = (struct ngm_ccatm_port *)msg->data; 565133578Sharti error = ng_ccatm_get_addresses(node, arg->port, msg, 566133578Sharti &resp); 567133578Sharti break; 568133578Sharti } 569133578Sharti 570133578Sharti case NGM_CCATM_CLEAR: 571133578Sharti { 572133578Sharti struct ngm_ccatm_port *arg; 573133578Sharti 574133578Sharti if (msg->header.arglen != sizeof(*arg)) { 575133578Sharti error = EINVAL; 576133578Sharti break; 577133578Sharti } 578133578Sharti arg = (struct ngm_ccatm_port *)msg->data; 579133578Sharti error = cc_port_clear(priv->data, arg->port); 580133578Sharti break; 581133578Sharti } 582133578Sharti 583133578Sharti case NGM_CCATM_ADDRESS_REGISTERED: 584133578Sharti { 585133578Sharti struct ngm_ccatm_addr_req *arg; 586133578Sharti 587133578Sharti if (msg->header.arglen != sizeof(*arg)) { 588133578Sharti error = EINVAL; 589133578Sharti break; 590133578Sharti } 591133578Sharti arg = (struct ngm_ccatm_addr_req *)msg->data; 592133578Sharti error = cc_addr_register(priv->data, arg->port, 593133578Sharti &arg->addr); 594133578Sharti break; 595133578Sharti } 596133578Sharti 597133578Sharti case NGM_CCATM_ADDRESS_UNREGISTERED: 598133578Sharti { 599133578Sharti struct ngm_ccatm_addr_req *arg; 600133578Sharti 601133578Sharti if (msg->header.arglen != sizeof(*arg)) { 602133578Sharti error = EINVAL; 603133578Sharti break; 604133578Sharti } 605133578Sharti arg = (struct ngm_ccatm_addr_req *)msg->data; 606133578Sharti error = cc_addr_unregister(priv->data, arg->port, 607133578Sharti &arg->addr); 608133578Sharti break; 609133578Sharti } 610133578Sharti 611133578Sharti case NGM_CCATM_GET_PORT_PARAM: 612133578Sharti { 613133578Sharti struct ngm_ccatm_port *arg; 614133578Sharti 615133578Sharti if (msg->header.arglen != sizeof(*arg)) { 616133578Sharti error = EINVAL; 617133578Sharti break; 618133578Sharti } 619133578Sharti arg = (struct ngm_ccatm_port *)msg->data; 620133578Sharti NG_MKRESPONSE(resp, msg, sizeof(struct atm_port_info), 621133578Sharti M_NOWAIT); 622133578Sharti if (resp == NULL) { 623133578Sharti error = ENOMEM; 624133578Sharti break; 625133578Sharti } 626133578Sharti error = cc_port_get_param(priv->data, arg->port, 627133578Sharti (struct atm_port_info *)resp->data); 628133578Sharti if (error != 0) { 629133578Sharti free(resp, M_NETGRAPH_MSG); 630133578Sharti resp = NULL; 631133578Sharti } 632133578Sharti break; 633133578Sharti } 634133578Sharti 635133578Sharti case NGM_CCATM_SET_PORT_PARAM: 636133578Sharti { 637133578Sharti struct atm_port_info *arg; 638133578Sharti 639133578Sharti if (msg->header.arglen != sizeof(*arg)) { 640133578Sharti error = EINVAL; 641133578Sharti break; 642133578Sharti } 643133578Sharti arg = (struct atm_port_info *)msg->data; 644133578Sharti error = cc_port_set_param(priv->data, arg); 645133578Sharti break; 646133578Sharti } 647133578Sharti 648133578Sharti case NGM_CCATM_GET_PORTLIST: 649133578Sharti { 650133578Sharti struct ngm_ccatm_portlist *arg; 651133578Sharti u_int n, *ports; 652133578Sharti 653133578Sharti if (msg->header.arglen != 0) { 654133578Sharti error = EINVAL; 655133578Sharti break; 656133578Sharti } 657133578Sharti error = cc_port_getlist(priv->data, &n, &ports); 658133578Sharti if (error != 0) 659133578Sharti break; 660133578Sharti 661133578Sharti NG_MKRESPONSE(resp, msg, sizeof(*arg) + 662133578Sharti n * sizeof(arg->ports[0]), M_NOWAIT); 663133578Sharti if (resp == NULL) { 664133578Sharti free(ports, M_NG_CCATM); 665133578Sharti error = ENOMEM; 666133578Sharti break; 667133578Sharti } 668133578Sharti arg = (struct ngm_ccatm_portlist *)resp->data; 669133578Sharti 670133578Sharti arg->nports = 0; 671133578Sharti for (arg->nports = 0; arg->nports < n; arg->nports++) 672133578Sharti arg->ports[arg->nports] = ports[arg->nports]; 673133578Sharti free(ports, M_NG_CCATM); 674133578Sharti break; 675133578Sharti } 676133578Sharti 677133578Sharti case NGM_CCATM_SETLOG: 678133578Sharti { 679133578Sharti uint32_t log_level; 680133578Sharti 681133578Sharti log_level = cc_get_log(priv->data); 682133578Sharti if (msg->header.arglen != 0) { 683133578Sharti if (msg->header.arglen != sizeof(log_level)) { 684133578Sharti error = EINVAL; 685133578Sharti break; 686133578Sharti } 687133578Sharti cc_set_log(priv->data, *(uint32_t *)msg->data); 688133578Sharti } 689133578Sharti 690133578Sharti NG_MKRESPONSE(resp, msg, sizeof(uint32_t), M_NOWAIT); 691133578Sharti if (resp == NULL) { 692133578Sharti error = ENOMEM; 693133578Sharti if (msg->header.arglen != 0) 694133578Sharti cc_set_log(priv->data, log_level); 695133578Sharti break; 696133578Sharti } 697133578Sharti *(uint32_t *)resp->data = log_level; 698133578Sharti break; 699133578Sharti } 700133578Sharti 701133578Sharti case NGM_CCATM_RESET: 702133578Sharti if (msg->header.arglen != 0) { 703133578Sharti error = EINVAL; 704133578Sharti break; 705133578Sharti } 706133578Sharti 707133578Sharti if (priv->hook_cnt != 0) { 708133578Sharti error = EBUSY; 709133578Sharti break; 710133578Sharti } 711133578Sharti cc_reset(priv->data); 712133578Sharti break; 713133578Sharti 714133578Sharti case NGM_CCATM_GET_EXSTAT: 715133578Sharti { 716133578Sharti struct atm_exstatus s; 717133578Sharti struct atm_exstatus_ep *eps; 718133578Sharti struct atm_exstatus_port *ports; 719133578Sharti struct atm_exstatus_conn *conns; 720133578Sharti struct atm_exstatus_party *parties; 721133578Sharti size_t offs; 722133578Sharti 723133578Sharti if (msg->header.arglen != 0) { 724133578Sharti error = EINVAL; 725133578Sharti break; 726133578Sharti } 727133578Sharti error = cc_get_extended_status(priv->data, 728133578Sharti &s, &eps, &ports, &conns, &parties); 729133578Sharti if (error != 0) 730133578Sharti break; 731133578Sharti 732133578Sharti offs = sizeof(s) + s.neps * sizeof(*eps) + 733133578Sharti s.nports * sizeof(*ports) + 734133578Sharti s.nconns * sizeof(*conns) + 735133578Sharti s.nparties * sizeof(*parties); 736133578Sharti 737133578Sharti NG_MKRESPONSE(resp, msg, offs, M_NOWAIT); 738133578Sharti if (resp == NULL) { 739133578Sharti error = ENOMEM; 740133578Sharti break; 741133578Sharti } 742133578Sharti 743133578Sharti memcpy(resp->data, &s, sizeof(s)); 744133578Sharti offs = sizeof(s); 745133578Sharti 746133578Sharti memcpy(resp->data + offs, eps, 747133578Sharti sizeof(*eps) * s.neps); 748133578Sharti offs += sizeof(*eps) * s.neps; 749133578Sharti 750133578Sharti memcpy(resp->data + offs, ports, 751133578Sharti sizeof(*ports) * s.nports); 752133578Sharti offs += sizeof(*ports) * s.nports; 753133578Sharti 754133578Sharti memcpy(resp->data + offs, conns, 755133578Sharti sizeof(*conns) * s.nconns); 756133578Sharti offs += sizeof(*conns) * s.nconns; 757133578Sharti 758133578Sharti memcpy(resp->data + offs, parties, 759133578Sharti sizeof(*parties) * s.nparties); 760133578Sharti offs += sizeof(*parties) * s.nparties; 761133578Sharti 762133578Sharti free(eps, M_NG_CCATM); 763133578Sharti free(ports, M_NG_CCATM); 764133578Sharti free(conns, M_NG_CCATM); 765133578Sharti free(parties, M_NG_CCATM); 766133578Sharti break; 767133578Sharti } 768133578Sharti 769133578Sharti default: 770133578Sharti error = EINVAL; 771133578Sharti break; 772133578Sharti 773133578Sharti } 774133578Sharti break; 775133578Sharti 776133578Sharti default: 777133578Sharti error = EINVAL; 778133578Sharti break; 779133578Sharti 780133578Sharti } 781133578Sharti 782133578Sharti NG_RESPOND_MSG(error, node, item, resp); 783133578Sharti NG_FREE_MSG(msg); 784133578Sharti return (error); 785133578Sharti} 786133578Sharti 787133578Sharti/************************************************************ 788133578Sharti * 789133578Sharti * New hook arrival 790133578Sharti */ 791133578Shartistatic int 792133578Sharting_ccatm_newhook(node_p node, hook_p hook, const char *name) 793133578Sharti{ 794133578Sharti struct ccnode *priv = NG_NODE_PRIVATE(node); 795133578Sharti struct ccport *port; 796133578Sharti struct ccuser *user; 797133578Sharti struct cchook *hd; 798133578Sharti u_long lport; 799133578Sharti char *end; 800133578Sharti 801133578Sharti if (strncmp(name, "uni", 3) == 0) { 802133578Sharti /* 803133578Sharti * This is a UNI hook. Should be a new port. 804133578Sharti */ 805133578Sharti if (name[3] == '\0') 806133578Sharti return (EINVAL); 807133578Sharti lport = strtoul(name + 3, &end, 10); 808133578Sharti if (*end != '\0' || lport == 0 || lport > 0xffffffff) 809133578Sharti return (EINVAL); 810133578Sharti 811133578Sharti hd = malloc(sizeof(*hd), M_NG_CCATM, M_NOWAIT); 812133578Sharti if (hd == NULL) 813133578Sharti return (ENOMEM); 814133578Sharti hd->is_uni = 1; 815133578Sharti hd->node = priv; 816133578Sharti hd->hook = hook; 817133578Sharti 818133578Sharti port = cc_port_create(priv->data, hd, (u_int)lport); 819133578Sharti if (port == NULL) { 820133578Sharti free(hd, M_NG_CCATM); 821133578Sharti return (ENOMEM); 822133578Sharti } 823133578Sharti hd->inst = port; 824133578Sharti 825133578Sharti NG_HOOK_SET_PRIVATE(hook, hd); 826133578Sharti NG_HOOK_SET_RCVDATA(hook, ng_ccatm_rcvuni); 827133578Sharti NG_HOOK_FORCE_QUEUE(hook); 828133578Sharti 829133578Sharti priv->hook_cnt++; 830133578Sharti 831133578Sharti return (0); 832133578Sharti } 833133578Sharti 834133578Sharti if (strcmp(name, "dump") == 0) { 835133578Sharti priv->dump = hook; 836133578Sharti NG_HOOK_SET_RCVDATA(hook, ng_ccatm_rcvdump); 837133578Sharti return (0); 838133578Sharti } 839133578Sharti 840133578Sharti if (strcmp(name, "manage") == 0) { 841133578Sharti priv->manage = hook; 842133578Sharti NG_HOOK_SET_RCVDATA(hook, ng_ccatm_rcvmanage); 843133578Sharti return (0); 844133578Sharti } 845133578Sharti 846133578Sharti /* 847133578Sharti * User hook 848133578Sharti */ 849133578Sharti hd = malloc(sizeof(*hd), M_NG_CCATM, M_NOWAIT); 850133578Sharti if (hd == NULL) 851133578Sharti return (ENOMEM); 852133578Sharti hd->is_uni = 0; 853133578Sharti hd->node = priv; 854133578Sharti hd->hook = hook; 855133578Sharti 856133578Sharti user = cc_user_create(priv->data, hd, NG_HOOK_NAME(hook)); 857133578Sharti if (user == NULL) { 858133578Sharti free(hd, M_NG_CCATM); 859133578Sharti return (ENOMEM); 860133578Sharti } 861133578Sharti 862133578Sharti hd->inst = user; 863133578Sharti NG_HOOK_SET_PRIVATE(hook, hd); 864133578Sharti NG_HOOK_FORCE_QUEUE(hook); 865133578Sharti 866133578Sharti priv->hook_cnt++; 867133578Sharti 868133578Sharti return (0); 869133578Sharti} 870133578Sharti 871133578Sharti/* 872133578Sharti * Disconnect a hook 873133578Sharti */ 874133578Shartistatic int 875133578Sharting_ccatm_disconnect(hook_p hook) 876133578Sharti{ 877133578Sharti node_p node = NG_HOOK_NODE(hook); 878133578Sharti struct ccnode *priv = NG_NODE_PRIVATE(node); 879133578Sharti struct cchook *hd = NG_HOOK_PRIVATE(hook); 880162849Snetchild struct ccdata *cc; 881133578Sharti 882133578Sharti if (hook == priv->dump) { 883133578Sharti priv->dump = NULL; 884133578Sharti 885133578Sharti } else if (hook == priv->manage) { 886133578Sharti priv->manage = NULL; 887133578Sharti cc_unmanage(priv->data); 888133578Sharti 889133578Sharti } else { 890133578Sharti if (hd->is_uni) 891133578Sharti cc_port_destroy(hd->inst, 0); 892133578Sharti else 893133578Sharti cc_user_destroy(hd->inst); 894133578Sharti 895162849Snetchild cc = hd->node->data; 896162849Snetchild 897133578Sharti free(hd, M_NG_CCATM); 898133578Sharti NG_HOOK_SET_PRIVATE(hook, NULL); 899133578Sharti 900133578Sharti priv->hook_cnt--; 901133578Sharti 902162849Snetchild cc_work(cc); 903133578Sharti } 904133578Sharti 905133578Sharti /* 906133578Sharti * When the number of hooks drops to zero, delete the node. 907133578Sharti */ 908133578Sharti if (NG_NODE_NUMHOOKS(node) == 0 && NG_NODE_IS_VALID(node)) 909133578Sharti ng_rmnode_self(node); 910133578Sharti 911133578Sharti return (0); 912133578Sharti} 913133578Sharti 914133578Sharti/************************************************************ 915133578Sharti * 916133578Sharti * Receive data from user hook 917133578Sharti */ 918133578Shartistatic int 919133578Sharting_ccatm_rcvdata(hook_p hook, item_p item) 920133578Sharti{ 921133578Sharti struct cchook *hd = NG_HOOK_PRIVATE(hook); 922133578Sharti struct uni_msg *msg; 923133578Sharti struct mbuf *m; 924133578Sharti struct ccatm_op op; 925133578Sharti int err; 926133578Sharti 927133578Sharti NGI_GET_M(item, m); 928133578Sharti NG_FREE_ITEM(item); 929133578Sharti 930133578Sharti if ((err = uni_msg_unpack_mbuf(m, &msg)) != 0) { 931133578Sharti m_freem(m); 932133578Sharti return (err); 933133578Sharti } 934133578Sharti m_freem(m); 935133578Sharti 936133578Sharti if (uni_msg_len(msg) < sizeof(op)) { 937133578Sharti printf("%s: packet too short\n", __func__); 938133578Sharti uni_msg_destroy(msg); 939133578Sharti return (EINVAL); 940133578Sharti } 941133578Sharti 942133578Sharti bcopy(msg->b_rptr, &op, sizeof(op)); 943133578Sharti msg->b_rptr += sizeof(op); 944133578Sharti 945133578Sharti err = cc_user_signal(hd->inst, op.op, msg); 946133578Sharti cc_work(hd->node->data); 947133578Sharti return (err); 948133578Sharti} 949133578Sharti 950133578Sharti/* 951133578Sharti * Pack a header and a data area into an mbuf chain 952133578Sharti */ 953133578Shartistatic struct mbuf * 954133578Shartipack_buf(void *h, size_t hlen, void *t, size_t tlen) 955133578Sharti{ 956133578Sharti struct mbuf *m, *m0, *last; 957133578Sharti u_char *buf = (u_char *)t; 958133578Sharti size_t n; 959133578Sharti 960133578Sharti /* header should fit into a normal mbuf */ 961133578Sharti MGETHDR(m0, M_NOWAIT, MT_DATA); 962133578Sharti if (m0 == NULL) 963133578Sharti return NULL; 964133578Sharti 965133578Sharti KASSERT(hlen <= MHLEN, ("hlen > MHLEN")); 966133578Sharti 967133578Sharti bcopy(h, m0->m_data, hlen); 968133578Sharti m0->m_len = hlen; 969133578Sharti m0->m_pkthdr.len = hlen; 970133578Sharti 971133578Sharti last = m0; 972133578Sharti while ((n = tlen) != 0) { 973133578Sharti if (n > MLEN) { 974133578Sharti m = m_getcl(M_NOWAIT, MT_DATA, 0); 975133578Sharti if (n > MCLBYTES) 976133578Sharti n = MCLBYTES; 977133578Sharti } else 978133578Sharti MGET(m, M_NOWAIT, MT_DATA); 979133578Sharti 980133578Sharti if(m == NULL) 981133578Sharti goto drop; 982133578Sharti 983133578Sharti last->m_next = m; 984133578Sharti last = m; 985133578Sharti 986133578Sharti bcopy(buf, m->m_data, n); 987133578Sharti buf += n; 988133578Sharti tlen -= n; 989133578Sharti m->m_len = n; 990133578Sharti m0->m_pkthdr.len += n; 991133578Sharti } 992133578Sharti 993133578Sharti return (m0); 994133578Sharti 995133578Sharti drop: 996133578Sharti m_freem(m0); 997133578Sharti return NULL; 998133578Sharti} 999133578Sharti 1000133578Sharti/* 1001133578Sharti * Send an indication to the user. 1002133578Sharti */ 1003133578Shartistatic void 1004133578Sharting_ccatm_send_user(struct ccuser *user, void *uarg, u_int op, 1005133578Sharti void *val, size_t len) 1006133578Sharti{ 1007133578Sharti struct cchook *hd = uarg; 1008133578Sharti struct mbuf *m; 1009133578Sharti struct ccatm_op h; 1010133578Sharti int error; 1011133578Sharti 1012133578Sharti h.op = op; 1013133578Sharti m = pack_buf(&h, sizeof(h), val, len); 1014133578Sharti if (m == NULL) 1015133578Sharti return; 1016133578Sharti 1017133578Sharti NG_SEND_DATA_ONLY(error, hd->hook, m); 1018133578Sharti if (error != 0) 1019133578Sharti printf("%s: error=%d\n", __func__, error); 1020133578Sharti} 1021133578Sharti 1022133578Sharti/* 1023133578Sharti * Send a response to the user. 1024133578Sharti */ 1025133578Shartistatic void 1026133578Sharting_ccatm_respond_user(struct ccuser *user, void *uarg, int err, u_int data, 1027133578Sharti void *val, size_t len) 1028133578Sharti{ 1029133578Sharti struct cchook *hd = uarg; 1030133578Sharti struct mbuf *m; 1031133578Sharti struct { 1032133578Sharti struct ccatm_op op; 1033133578Sharti struct atm_resp resp; 1034133578Sharti } resp; 1035133578Sharti int error; 1036133578Sharti 1037133578Sharti resp.op.op = ATMOP_RESP; 1038133578Sharti resp.resp.resp = err; 1039133578Sharti resp.resp.data = data; 1040133578Sharti m = pack_buf(&resp, sizeof(resp), val, len); 1041133578Sharti if (m == NULL) 1042133578Sharti return; 1043133578Sharti 1044133578Sharti NG_SEND_DATA_ONLY(error, hd->hook, m); 1045133578Sharti if (error != 0) 1046133578Sharti printf("%s: error=%d\n", __func__, error); 1047133578Sharti} 1048133578Sharti 1049133578Sharti/* 1050133578Sharti * Receive data from UNI. 1051133578Sharti */ 1052133578Shartistatic int 1053133578Sharting_ccatm_rcvuni(hook_p hook, item_p item) 1054133578Sharti{ 1055133578Sharti struct cchook *hd = NG_HOOK_PRIVATE(hook); 1056133578Sharti struct uni_msg *msg; 1057133578Sharti struct uni_arg arg; 1058133578Sharti struct mbuf *m; 1059133578Sharti int err; 1060133578Sharti 1061133578Sharti NGI_GET_M(item, m); 1062133578Sharti NG_FREE_ITEM(item); 1063133578Sharti 1064133578Sharti if ((err = uni_msg_unpack_mbuf(m, &msg)) != 0) { 1065133578Sharti m_freem(m); 1066133578Sharti return (err); 1067133578Sharti } 1068133578Sharti m_freem(m); 1069133578Sharti 1070133578Sharti if (uni_msg_len(msg) < sizeof(arg)) { 1071133578Sharti printf("%s: packet too short\n", __func__); 1072133578Sharti uni_msg_destroy(msg); 1073133578Sharti return (EINVAL); 1074133578Sharti } 1075133578Sharti 1076133578Sharti bcopy(msg->b_rptr, &arg, sizeof(arg)); 1077133578Sharti msg->b_rptr += sizeof(arg); 1078133578Sharti 1079133578Sharti if (arg.sig == UNIAPI_ERROR) { 1080133578Sharti if (uni_msg_len(msg) != sizeof(struct uniapi_error)) { 1081133578Sharti printf("%s: bad UNIAPI_ERROR size %zu\n", __func__, 1082133578Sharti uni_msg_len(msg)); 1083133578Sharti uni_msg_destroy(msg); 1084133578Sharti return (EINVAL); 1085133578Sharti } 1086133578Sharti err = cc_uni_response(hd->inst, arg.cookie, 1087133578Sharti ((struct uniapi_error *)msg->b_rptr)->reason, 1088133578Sharti ((struct uniapi_error *)msg->b_rptr)->state); 1089133578Sharti uni_msg_destroy(msg); 1090133578Sharti } else 1091133578Sharti err = cc_uni_signal(hd->inst, arg.cookie, arg.sig, msg); 1092133578Sharti 1093133578Sharti cc_work(hd->node->data); 1094133578Sharti return (err); 1095133578Sharti} 1096133578Sharti 1097133578Sharti/* 1098133578Sharti * Uarg is the port's uarg. 1099133578Sharti */ 1100133578Shartistatic void 1101133578Sharting_ccatm_send_uni(struct ccconn *conn, void *uarg, u_int op, u_int cookie, 1102133578Sharti struct uni_msg *msg) 1103133578Sharti{ 1104133578Sharti struct cchook *hd = uarg; 1105133578Sharti struct uni_arg arg; 1106133578Sharti struct mbuf *m; 1107133578Sharti int error; 1108133578Sharti 1109133578Sharti arg.sig = op; 1110133578Sharti arg.cookie = cookie; 1111133578Sharti 1112133578Sharti m = uni_msg_pack_mbuf(msg, &arg, sizeof(arg)); 1113133578Sharti uni_msg_destroy(msg); 1114133578Sharti if (m == NULL) 1115133578Sharti return; 1116133578Sharti 1117133578Sharti NG_SEND_DATA_ONLY(error, hd->hook, m); 1118133578Sharti if (error != 0) 1119133578Sharti printf("%s: error=%d\n", __func__, error); 1120133578Sharti} 1121133578Sharti 1122133578Sharti/* 1123133578Sharti * Send a global message to the UNI 1124133578Sharti */ 1125133578Shartistatic void 1126133578Sharting_ccatm_send_uni_glob(struct ccport *port, void *uarg, u_int op, u_int cookie, 1127133578Sharti struct uni_msg *msg) 1128133578Sharti{ 1129133578Sharti struct cchook *hd = uarg; 1130133578Sharti struct uni_arg arg; 1131133578Sharti struct mbuf *m; 1132133578Sharti int error; 1133133578Sharti 1134133578Sharti arg.sig = op; 1135133578Sharti arg.cookie = cookie; 1136133578Sharti 1137133578Sharti m = uni_msg_pack_mbuf(msg, &arg, sizeof(arg)); 1138133578Sharti if (msg != NULL) 1139133578Sharti uni_msg_destroy(msg); 1140133578Sharti if (m == NULL) 1141133578Sharti return; 1142133578Sharti 1143133578Sharti NG_SEND_DATA_ONLY(error, hd->hook, m); 1144133578Sharti if (error != 0) 1145133578Sharti printf("%s: error=%d\n", __func__, error); 1146133578Sharti} 1147133578Sharti/* 1148133578Sharti * Receive from ILMID 1149133578Sharti */ 1150133578Shartistatic int 1151133578Sharting_ccatm_rcvmanage(hook_p hook, item_p item) 1152133578Sharti{ 1153133578Sharti NG_FREE_ITEM(item); 1154133578Sharti return (0); 1155133578Sharti} 1156133578Sharti 1157133578Shartistatic int 1158133578Sharting_ccatm_rcvdump(hook_p hook, item_p item) 1159133578Sharti{ 1160133578Sharti NG_FREE_ITEM(item); 1161133578Sharti return (0); 1162133578Sharti} 1163133578Sharti 1164133578Shartistatic void 1165133578Sharting_ccatm_log(const char *fmt, ...) 1166133578Sharti{ 1167133578Sharti va_list ap; 1168133578Sharti 1169133578Sharti va_start(ap, fmt); 1170133578Sharti vprintf(fmt, ap); 1171133578Sharti printf("\n"); 1172133578Sharti va_end(ap); 1173133578Sharti} 1174133578Sharti 1175133578Sharti/* 1176133578Sharti * Loading and unloading of node type 1177133578Sharti */ 1178133578Shartistatic int 1179133578Sharting_ccatm_mod_event(module_t mod, int event, void *data) 1180133578Sharti{ 1181133578Sharti int error = 0; 1182133578Sharti 1183133578Sharti switch (event) { 1184133578Sharti 1185133578Sharti case MOD_LOAD: 1186133578Sharti break; 1187133578Sharti 1188133578Sharti case MOD_UNLOAD: 1189133578Sharti break; 1190133578Sharti 1191133578Sharti default: 1192133578Sharti error = EOPNOTSUPP; 1193133578Sharti break; 1194133578Sharti } 1195133578Sharti return (error); 1196133578Sharti} 1197