1139823Simp/*- 2121461Sharti * Copyright (c) 2001-2003 3121461Sharti * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4121461Sharti * All rights reserved. 5121461Sharti * 6121461Sharti * Redistribution and use in source and binary forms, with or without 7121461Sharti * modification, are permitted provided that the following conditions 8121461Sharti * are met: 9121461Sharti * 1. Redistributions of source code must retain the above copyright 10121461Sharti * notice, this list of conditions and the following disclaimer. 11121461Sharti * 2. Redistributions in binary form must reproduce the above copyright 12121461Sharti * notice, this list of conditions and the following disclaimer in the 13121461Sharti * documentation and/or other materials provided with the distribution. 14121461Sharti * 15121461Sharti * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16121461Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17121461Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18121461Sharti * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19121461Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20121461Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21121461Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22121461Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23121461Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24121461Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25121461Sharti * SUCH DAMAGE. 26121461Sharti * 27121461Sharti * Author: Hartmut Brandt <harti@freebsd.org> 28121461Sharti * 29121461Sharti * Netgraph module for ITU-T Q.2120 UNI SSCF. 30121461Sharti */ 31121461Sharti 32121461Sharti#include <sys/cdefs.h> 33121461Sharti__FBSDID("$FreeBSD$"); 34121461Sharti 35121461Sharti#include <sys/param.h> 36121461Sharti#include <sys/systm.h> 37121461Sharti#include <sys/kernel.h> 38121461Sharti#include <sys/malloc.h> 39121461Sharti#include <sys/mbuf.h> 40121461Sharti#include <sys/errno.h> 41121461Sharti#include <sys/syslog.h> 42121461Sharti#include <sys/socket.h> 43121461Sharti#include <sys/socketvar.h> 44121461Sharti#include <sys/sbuf.h> 45121461Sharti#include <machine/stdarg.h> 46121461Sharti 47121461Sharti#include <netgraph/ng_message.h> 48121461Sharti#include <netgraph/netgraph.h> 49121461Sharti#include <netgraph/ng_parse.h> 50121461Sharti#include <netnatm/saal/sscopdef.h> 51121461Sharti#include <netnatm/saal/sscfudef.h> 52121461Sharti#include <netgraph/atm/ng_sscop.h> 53121461Sharti#include <netgraph/atm/ng_sscfu.h> 54121461Sharti#include <netgraph/atm/sscfu/ng_sscfu_cust.h> 55121461Sharti#include <netnatm/saal/sscfu.h> 56121461Sharti 57121461ShartiMALLOC_DEFINE(M_NG_SSCFU, "netgraph_sscfu", "netgraph uni sscf node"); 58121461Sharti 59121461ShartiMODULE_DEPEND(ng_sscfu, ngatmbase, 1, 1, 1); 60121461Sharti 61121461Sharti/* 62121461Sharti * Private data 63121461Sharti */ 64121461Shartistruct priv { 65121461Sharti hook_p upper; /* SAAL interface */ 66121461Sharti hook_p lower; /* SSCOP interface */ 67121461Sharti struct sscfu *sscf; /* the instance */ 68121461Sharti int enabled; 69121461Sharti}; 70121461Sharti 71121461Sharti/* 72121461Sharti * PARSING 73121461Sharti */ 74121461Sharti/* 75121461Sharti * Parse PARAM type 76121461Sharti */ 77121461Shartistatic const struct ng_parse_struct_field ng_sscop_param_type_info[] = 78121461Sharti NG_SSCOP_PARAM_INFO; 79121461Sharti 80121461Shartistatic const struct ng_parse_type ng_sscop_param_type = { 81121461Sharti &ng_parse_struct_type, 82121461Sharti ng_sscop_param_type_info 83121461Sharti}; 84121461Sharti 85121461Shartistatic const struct ng_parse_struct_field ng_sscfu_getdefparam_type_info[] = 86121461Sharti NG_SSCFU_GETDEFPARAM_INFO; 87121461Sharti 88121461Shartistatic const struct ng_parse_type ng_sscfu_getdefparam_type = { 89121461Sharti &ng_parse_struct_type, 90121461Sharti ng_sscfu_getdefparam_type_info 91121461Sharti}; 92121461Sharti 93121461Sharti 94121461Shartistatic const struct ng_cmdlist ng_sscfu_cmdlist[] = { 95121461Sharti { 96121461Sharti NGM_SSCFU_COOKIE, 97121461Sharti NGM_SSCFU_GETDEFPARAM, 98121461Sharti "getdefparam", 99121461Sharti NULL, 100121461Sharti &ng_sscfu_getdefparam_type 101121461Sharti }, 102121461Sharti { 103121461Sharti NGM_SSCFU_COOKIE, 104121461Sharti NGM_SSCFU_ENABLE, 105121461Sharti "enable", 106121461Sharti NULL, 107121461Sharti NULL 108121461Sharti }, 109121461Sharti { 110121461Sharti NGM_SSCFU_COOKIE, 111121461Sharti NGM_SSCFU_DISABLE, 112121461Sharti "disable", 113121461Sharti NULL, 114121461Sharti NULL 115121461Sharti }, 116121461Sharti { 117121461Sharti NGM_SSCFU_COOKIE, 118121461Sharti NGM_SSCFU_GETDEBUG, 119121461Sharti "getdebug", 120121461Sharti NULL, 121121461Sharti &ng_parse_hint32_type 122121461Sharti }, 123121461Sharti { 124121461Sharti NGM_SSCFU_COOKIE, 125121461Sharti NGM_SSCFU_SETDEBUG, 126121461Sharti "setdebug", 127121461Sharti &ng_parse_hint32_type, 128121461Sharti NULL 129121461Sharti }, 130121461Sharti { 131121461Sharti NGM_SSCFU_COOKIE, 132121461Sharti NGM_SSCFU_GETSTATE, 133121461Sharti "getstate", 134121461Sharti NULL, 135121461Sharti &ng_parse_uint32_type 136121461Sharti }, 137121461Sharti { 0 } 138121461Sharti}; 139121461Sharti 140121461Shartistatic ng_constructor_t ng_sscfu_constructor; 141121461Shartistatic ng_shutdown_t ng_sscfu_shutdown; 142121461Shartistatic ng_rcvmsg_t ng_sscfu_rcvmsg; 143121461Shartistatic ng_newhook_t ng_sscfu_newhook; 144121461Shartistatic ng_disconnect_t ng_sscfu_disconnect; 145121461Shartistatic ng_rcvdata_t ng_sscfu_rcvupper; 146121461Shartistatic ng_rcvdata_t ng_sscfu_rcvlower; 147121461Sharti 148121461Shartistatic int ng_sscfu_mod_event(module_t, int, void *); 149121461Sharti 150121461Shartistatic struct ng_type ng_sscfu_typestruct = { 151129823Sjulian .version = NG_ABI_VERSION, 152129823Sjulian .name = NG_SSCFU_NODE_TYPE, 153129823Sjulian .mod_event = ng_sscfu_mod_event, 154129823Sjulian .constructor = ng_sscfu_constructor, 155129823Sjulian .rcvmsg = ng_sscfu_rcvmsg, 156129823Sjulian .shutdown = ng_sscfu_shutdown, 157129823Sjulian .newhook = ng_sscfu_newhook, 158129823Sjulian .rcvdata = ng_sscfu_rcvupper, 159129823Sjulian .disconnect = ng_sscfu_disconnect, 160129823Sjulian .cmdlist = ng_sscfu_cmdlist, 161121461Sharti}; 162121461ShartiNETGRAPH_INIT(sscfu, &ng_sscfu_typestruct); 163121461Sharti 164121461Shartistatic void sscfu_send_upper(struct sscfu *, void *, enum saal_sig, 165121461Sharti struct mbuf *); 166121461Shartistatic void sscfu_send_lower(struct sscfu *, void *, enum sscop_aasig, 167121461Sharti struct mbuf *, u_int); 168121461Shartistatic void sscfu_window(struct sscfu *, void *, u_int); 169121461Shartistatic void sscfu_verbose(struct sscfu *, void *, const char *, ...) 170121461Sharti __printflike(3, 4); 171121461Sharti 172121461Shartistatic const struct sscfu_funcs sscfu_funcs = { 173121461Sharti sscfu_send_upper, 174121461Sharti sscfu_send_lower, 175121461Sharti sscfu_window, 176121461Sharti sscfu_verbose 177121461Sharti}; 178121461Sharti 179121461Sharti/************************************************************/ 180121461Sharti/* 181121461Sharti * CONTROL MESSAGES 182121461Sharti */ 183121461Shartistatic int 184121461Shartitext_status(node_p node, struct priv *priv, char *arg, u_int len) 185121461Sharti{ 186121461Sharti struct sbuf sbuf; 187121461Sharti 188121461Sharti sbuf_new(&sbuf, arg, len, 0); 189121461Sharti 190121461Sharti if (priv->upper) 191121461Sharti sbuf_printf(&sbuf, "upper hook: %s connected to %s:%s\n", 192121461Sharti NG_HOOK_NAME(priv->upper), 193121461Sharti NG_NODE_NAME(NG_HOOK_NODE(NG_HOOK_PEER(priv->upper))), 194121461Sharti NG_HOOK_NAME(NG_HOOK_PEER(priv->upper))); 195121461Sharti else 196121461Sharti sbuf_printf(&sbuf, "upper hook: <not connected>\n"); 197121461Sharti 198121461Sharti if (priv->lower) 199121461Sharti sbuf_printf(&sbuf, "lower hook: %s connected to %s:%s\n", 200121461Sharti NG_HOOK_NAME(priv->lower), 201121461Sharti NG_NODE_NAME(NG_HOOK_NODE(NG_HOOK_PEER(priv->lower))), 202121461Sharti NG_HOOK_NAME(NG_HOOK_PEER(priv->lower))); 203121461Sharti else 204121461Sharti sbuf_printf(&sbuf, "lower hook: <not connected>\n"); 205121461Sharti 206121461Sharti sbuf_printf(&sbuf, "sscf state: %s\n", 207123812Salfred priv->enabled == 0 ? "<disabled>" : 208121461Sharti sscfu_statename(sscfu_getstate(priv->sscf))); 209121461Sharti 210121461Sharti sbuf_finish(&sbuf); 211121461Sharti return (sbuf_len(&sbuf)); 212121461Sharti} 213121461Sharti 214121461Shartistatic int 215121461Sharting_sscfu_rcvmsg(node_p node, item_p item, hook_p lasthook) 216121461Sharti{ 217121461Sharti struct priv *priv = NG_NODE_PRIVATE(node); 218121461Sharti struct ng_mesg *resp = NULL; 219121461Sharti struct ng_mesg *msg; 220121461Sharti int error = 0; 221121461Sharti 222121461Sharti NGI_GET_MSG(item, msg); 223121461Sharti 224121461Sharti switch (msg->header.typecookie) { 225121461Sharti 226121461Sharti case NGM_GENERIC_COOKIE: 227121461Sharti switch (msg->header.cmd) { 228121461Sharti 229121461Sharti case NGM_TEXT_STATUS: 230121461Sharti NG_MKRESPONSE(resp, msg, NG_TEXTRESPONSE, M_NOWAIT); 231121461Sharti if (resp == NULL) { 232121461Sharti error = ENOMEM; 233121461Sharti break; 234121461Sharti } 235121461Sharti resp->header.arglen = text_status(node, priv, 236121461Sharti (char *)resp->data, resp->header.arglen) + 1; 237121461Sharti break; 238121461Sharti 239121461Sharti default: 240121461Sharti error = EINVAL; 241121461Sharti break; 242121461Sharti } 243121461Sharti break; 244121461Sharti 245121461Sharti case NGM_SSCFU_COOKIE: 246121461Sharti switch (msg->header.cmd) { 247121461Sharti 248121461Sharti case NGM_SSCFU_GETDEFPARAM: 249121461Sharti { 250121461Sharti struct ng_sscfu_getdefparam *p; 251121461Sharti 252121461Sharti if (msg->header.arglen != 0) { 253121461Sharti error = EINVAL; 254121461Sharti break; 255121461Sharti } 256121461Sharti NG_MKRESPONSE(resp, msg, sizeof(*p), M_NOWAIT); 257121461Sharti if (resp == NULL) { 258121461Sharti error = ENOMEM; 259121461Sharti break; 260121461Sharti } 261121461Sharti p = (struct ng_sscfu_getdefparam *)resp->data; 262121461Sharti p->mask = sscfu_getdefparam(&p->param); 263121461Sharti break; 264121461Sharti } 265121461Sharti 266121461Sharti case NGM_SSCFU_ENABLE: 267121461Sharti if (msg->header.arglen != 0) { 268121461Sharti error = EINVAL; 269121461Sharti break; 270121461Sharti } 271121461Sharti if (priv->enabled) { 272121461Sharti error = EISCONN; 273121461Sharti break; 274121461Sharti } 275121461Sharti priv->enabled = 1; 276121461Sharti break; 277121461Sharti 278121461Sharti case NGM_SSCFU_DISABLE: 279121461Sharti if (msg->header.arglen != 0) { 280121461Sharti error = EINVAL; 281121461Sharti break; 282121461Sharti } 283121461Sharti if (!priv->enabled) { 284121461Sharti error = ENOTCONN; 285121461Sharti break; 286121461Sharti } 287121461Sharti priv->enabled = 0; 288121461Sharti sscfu_reset(priv->sscf); 289121461Sharti break; 290121461Sharti 291121461Sharti case NGM_SSCFU_GETSTATE: 292121461Sharti if (msg->header.arglen != 0) { 293121461Sharti error = EINVAL; 294121461Sharti break; 295121461Sharti } 296121461Sharti NG_MKRESPONSE(resp, msg, sizeof(uint32_t), M_NOWAIT); 297121461Sharti if(resp == NULL) { 298121461Sharti error = ENOMEM; 299121461Sharti break; 300121461Sharti } 301121461Sharti *(uint32_t *)resp->data = 302121461Sharti priv->enabled ? (sscfu_getstate(priv->sscf) + 1) 303121461Sharti : 0; 304121461Sharti break; 305121461Sharti 306121461Sharti case NGM_SSCFU_GETDEBUG: 307121461Sharti if (msg->header.arglen != 0) { 308121461Sharti error = EINVAL; 309121461Sharti break; 310121461Sharti } 311121461Sharti NG_MKRESPONSE(resp, msg, sizeof(uint32_t), M_NOWAIT); 312121461Sharti if(resp == NULL) { 313121461Sharti error = ENOMEM; 314121461Sharti break; 315121461Sharti } 316121461Sharti *(uint32_t *)resp->data = sscfu_getdebug(priv->sscf); 317121461Sharti break; 318121461Sharti 319121461Sharti case NGM_SSCFU_SETDEBUG: 320121461Sharti if (msg->header.arglen != sizeof(uint32_t)) { 321121461Sharti error = EINVAL; 322121461Sharti break; 323121461Sharti } 324121461Sharti sscfu_setdebug(priv->sscf, *(uint32_t *)msg->data); 325121461Sharti break; 326121461Sharti 327121461Sharti default: 328121461Sharti error = EINVAL; 329121461Sharti break; 330121461Sharti } 331121461Sharti break; 332121461Sharti 333121461Sharti default: 334121461Sharti error = EINVAL; 335121461Sharti break; 336121461Sharti } 337121461Sharti 338121461Sharti NG_RESPOND_MSG(error, node, item, resp); 339121461Sharti NG_FREE_MSG(msg); 340121461Sharti 341121461Sharti return (error); 342121461Sharti} 343121461Sharti 344121461Sharti/************************************************************/ 345121461Sharti/* 346121461Sharti * HOOK MANAGEMENT 347121461Sharti */ 348121461Shartistatic int 349121461Sharting_sscfu_newhook(node_p node, hook_p hook, const char *name) 350121461Sharti{ 351121461Sharti struct priv *priv = NG_NODE_PRIVATE(node); 352121461Sharti 353121461Sharti if (strcmp(name, "upper") == 0) 354121461Sharti priv->upper = hook; 355121461Sharti else if (strcmp(name, "lower") == 0) { 356121461Sharti priv->lower = hook; 357121461Sharti NG_HOOK_SET_RCVDATA(hook, ng_sscfu_rcvlower); 358121461Sharti } else 359121461Sharti return (EINVAL); 360121461Sharti return (0); 361121461Sharti} 362121461Sharti 363121461Shartistatic int 364121461Sharting_sscfu_disconnect(hook_p hook) 365121461Sharti{ 366121461Sharti node_p node = NG_HOOK_NODE(hook); 367121461Sharti struct priv *priv = NG_NODE_PRIVATE(node); 368121461Sharti 369121461Sharti if (hook == priv->upper) 370121461Sharti priv->upper = NULL; 371121461Sharti else if (hook == priv->lower) 372121461Sharti priv->lower = NULL; 373121461Sharti else { 374121461Sharti log(LOG_ERR, "bogus hook"); 375121461Sharti return (EINVAL); 376121461Sharti } 377121461Sharti 378121461Sharti if (NG_NODE_NUMHOOKS(node) == 0) { 379121461Sharti if (NG_NODE_IS_VALID(node)) 380121461Sharti ng_rmnode_self(node); 381121461Sharti } else { 382121461Sharti /* 383121461Sharti * Because there are no timeouts reset the protocol 384121461Sharti * if the lower layer is disconnected. 385121461Sharti */ 386121461Sharti if (priv->lower == NULL && 387121461Sharti priv->enabled && 388121461Sharti sscfu_getstate(priv->sscf) != SSCFU_RELEASED) 389121461Sharti sscfu_reset(priv->sscf); 390121461Sharti } 391121461Sharti return (0); 392121461Sharti} 393121461Sharti 394121461Sharti/************************************************************/ 395121461Sharti/* 396121461Sharti * DATA 397121461Sharti */ 398121461Shartistatic int 399121461Sharting_sscfu_rcvupper(hook_p hook, item_p item) 400121461Sharti{ 401121461Sharti node_p node = NG_HOOK_NODE(hook); 402121461Sharti struct priv *priv = NG_NODE_PRIVATE(node); 403121461Sharti struct mbuf *m; 404121461Sharti struct sscfu_arg a; 405121461Sharti 406121461Sharti if (!priv->enabled || priv->lower == NULL) { 407121461Sharti NG_FREE_ITEM(item); 408121461Sharti return (0); 409121461Sharti } 410121461Sharti 411121461Sharti NGI_GET_M(item, m); 412121461Sharti NG_FREE_ITEM(item); 413121461Sharti 414121461Sharti if (!(m->m_flags & M_PKTHDR)) { 415121461Sharti printf("no pkthdr\n"); 416121461Sharti m_freem(m); 417121461Sharti return (EINVAL); 418121461Sharti } 419121461Sharti if (m->m_len < (int)sizeof(a) && (m = m_pullup(m, sizeof(a))) == NULL) 420121461Sharti return (ENOMEM); 421121461Sharti bcopy((caddr_t)mtod(m, struct sscfu_arg *), &a, sizeof(a)); 422121461Sharti m_adj(m, sizeof(a)); 423121461Sharti 424121461Sharti return (sscfu_saalsig(priv->sscf, a.sig, m)); 425121461Sharti} 426121461Sharti 427121461Shartistatic void 428121461Shartisscfu_send_upper(struct sscfu *sscf, void *p, enum saal_sig sig, struct mbuf *m) 429121461Sharti{ 430121461Sharti node_p node = (node_p)p; 431121461Sharti struct priv *priv = NG_NODE_PRIVATE(node); 432121461Sharti int error; 433121461Sharti struct sscfu_arg *a; 434121461Sharti 435121461Sharti if (priv->upper == NULL) { 436121461Sharti if (m != NULL) 437121461Sharti m_freem(m); 438121461Sharti return; 439121461Sharti } 440121461Sharti if (m == NULL) { 441121461Sharti MGETHDR(m, M_NOWAIT, MT_DATA); 442121461Sharti if (m == NULL) 443121461Sharti return; 444121461Sharti m->m_len = sizeof(struct sscfu_arg); 445121461Sharti m->m_pkthdr.len = m->m_len; 446121461Sharti } else { 447121461Sharti M_PREPEND(m, sizeof(struct sscfu_arg), M_NOWAIT); 448121461Sharti if (m == NULL) 449121461Sharti return; 450121461Sharti } 451121461Sharti a = mtod(m, struct sscfu_arg *); 452121461Sharti a->sig = sig; 453121461Sharti 454121461Sharti NG_SEND_DATA_ONLY(error, priv->upper, m); 455121461Sharti} 456121461Sharti 457121461Shartistatic int 458121461Sharting_sscfu_rcvlower(hook_p hook, item_p item) 459121461Sharti{ 460121461Sharti node_p node = NG_HOOK_NODE(hook); 461121461Sharti struct priv *priv = NG_NODE_PRIVATE(node); 462121461Sharti struct mbuf *m; 463121461Sharti struct sscop_arg a; 464121461Sharti 465121461Sharti if (!priv->enabled || priv->upper == NULL) { 466121461Sharti NG_FREE_ITEM(item); 467121461Sharti return (0); 468121461Sharti } 469121461Sharti 470121461Sharti NGI_GET_M(item, m); 471121461Sharti NG_FREE_ITEM(item); 472121461Sharti 473121461Sharti if (!(m->m_flags & M_PKTHDR)) { 474121461Sharti printf("no pkthdr\n"); 475121461Sharti m_freem(m); 476121461Sharti return (EINVAL); 477121461Sharti } 478121461Sharti 479121461Sharti /* 480121461Sharti * Strip of the SSCOP header. 481121461Sharti */ 482121461Sharti if (m->m_len < (int)sizeof(a) && (m = m_pullup(m, sizeof(a))) == NULL) 483121461Sharti return (ENOMEM); 484121461Sharti bcopy((caddr_t)mtod(m, struct sscop_arg *), &a, sizeof(a)); 485121461Sharti m_adj(m, sizeof(a)); 486121461Sharti 487121461Sharti sscfu_input(priv->sscf, a.sig, m, a.arg); 488121461Sharti 489121461Sharti return (0); 490121461Sharti} 491121461Sharti 492121461Shartistatic void 493121461Shartisscfu_send_lower(struct sscfu *sscf, void *p, enum sscop_aasig sig, 494121461Sharti struct mbuf *m, u_int arg) 495121461Sharti{ 496121461Sharti node_p node = (node_p)p; 497121461Sharti struct priv *priv = NG_NODE_PRIVATE(node); 498121461Sharti int error; 499121461Sharti struct sscop_arg *a; 500121461Sharti 501121461Sharti if (priv->lower == NULL) { 502121461Sharti if (m != NULL) 503121461Sharti m_freem(m); 504121461Sharti return; 505121461Sharti } 506121461Sharti if (m == NULL) { 507121461Sharti MGETHDR(m, M_NOWAIT, MT_DATA); 508121461Sharti if (m == NULL) 509121461Sharti return; 510121461Sharti m->m_len = sizeof(struct sscop_arg); 511121461Sharti m->m_pkthdr.len = m->m_len; 512121461Sharti } else { 513121461Sharti M_PREPEND(m, sizeof(struct sscop_arg), M_NOWAIT); 514121461Sharti if (m == NULL) 515121461Sharti return; 516121461Sharti } 517121461Sharti a = mtod(m, struct sscop_arg *); 518121461Sharti a->sig = sig; 519121461Sharti a->arg = arg; 520121461Sharti 521121461Sharti NG_SEND_DATA_ONLY(error, priv->lower, m); 522121461Sharti} 523121461Sharti 524121461Sharti/* 525121461Sharti * Window is handled by ng_sscop so make this a NOP. 526121461Sharti */ 527121461Shartistatic void 528121461Shartisscfu_window(struct sscfu *sscfu, void *arg, u_int w) 529121461Sharti{ 530121461Sharti} 531121461Sharti 532121461Sharti/************************************************************/ 533121461Sharti/* 534121461Sharti * NODE MANAGEMENT 535121461Sharti */ 536121461Shartistatic int 537121461Sharting_sscfu_constructor(node_p node) 538121461Sharti{ 539121461Sharti struct priv *priv; 540121461Sharti 541220768Sglebius priv = malloc(sizeof(*priv), M_NG_SSCFU, M_WAITOK | M_ZERO); 542121461Sharti 543121461Sharti if ((priv->sscf = sscfu_create(node, &sscfu_funcs)) == NULL) { 544121461Sharti free(priv, M_NG_SSCFU); 545121461Sharti return (ENOMEM); 546121461Sharti } 547121461Sharti 548121461Sharti NG_NODE_SET_PRIVATE(node, priv); 549121461Sharti 550121461Sharti return (0); 551121461Sharti} 552121461Sharti 553121461Shartistatic int 554121461Sharting_sscfu_shutdown(node_p node) 555121461Sharti{ 556121461Sharti struct priv *priv = NG_NODE_PRIVATE(node); 557121461Sharti 558121461Sharti sscfu_destroy(priv->sscf); 559121461Sharti 560121461Sharti free(priv, M_NG_SSCFU); 561121461Sharti NG_NODE_SET_PRIVATE(node, NULL); 562121461Sharti 563121461Sharti NG_NODE_UNREF(node); 564121461Sharti 565121461Sharti return (0); 566121461Sharti} 567121461Sharti 568121461Shartistatic void 569121461Shartisscfu_verbose(struct sscfu *sscfu, void *arg, const char *fmt, ...) 570121461Sharti{ 571121461Sharti va_list ap; 572121461Sharti 573121461Sharti va_start(ap, fmt); 574121461Sharti printf("sscfu(%p): ", sscfu); 575121461Sharti vprintf(fmt, ap); 576121461Sharti va_end(ap); 577121461Sharti printf("\n"); 578121461Sharti} 579121461Sharti 580121461Sharti/************************************************************/ 581121461Sharti/* 582121461Sharti * INITIALISATION 583121461Sharti */ 584121461Sharti/* 585121461Sharti * Loading and unloading of node type 586121461Sharti */ 587121461Shartistatic int 588121461Sharting_sscfu_mod_event(module_t mod, int event, void *data) 589121461Sharti{ 590121461Sharti int s; 591121461Sharti int error = 0; 592121461Sharti 593121461Sharti s = splnet(); 594121461Sharti switch (event) { 595121461Sharti 596121461Sharti case MOD_LOAD: 597121461Sharti break; 598121461Sharti 599121461Sharti case MOD_UNLOAD: 600121461Sharti break; 601121461Sharti 602121461Sharti default: 603121461Sharti error = EOPNOTSUPP; 604121461Sharti break; 605121461Sharti } 606121461Sharti splx(s); 607121461Sharti return (error); 608121461Sharti} 609