ng_sscfu.c revision 123812
1121461Sharti/* 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: head/sys/netgraph/atm/sscfu/ng_sscfu.c 123812 2003-12-24 18:51:01Z alfred $"); 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 = { 151121461Sharti NG_ABI_VERSION, 152121461Sharti NG_SSCFU_NODE_TYPE, 153121461Sharti ng_sscfu_mod_event, /* Module event handler (optional) */ 154121461Sharti ng_sscfu_constructor, /* Node constructor */ 155121461Sharti ng_sscfu_rcvmsg, /* control messages come here */ 156121461Sharti ng_sscfu_shutdown, /* reset, and free resources */ 157121461Sharti ng_sscfu_newhook, /* first notification of new hook */ 158121461Sharti NULL, /* findhook */ 159121461Sharti NULL, /* connect */ 160121461Sharti ng_sscfu_rcvupper, /* rcvdata */ 161121461Sharti ng_sscfu_disconnect, /* notify on disconnect */ 162121461Sharti ng_sscfu_cmdlist, 163121461Sharti}; 164121461ShartiNETGRAPH_INIT(sscfu, &ng_sscfu_typestruct); 165121461Sharti 166121461Shartistatic void sscfu_send_upper(struct sscfu *, void *, enum saal_sig, 167121461Sharti struct mbuf *); 168121461Shartistatic void sscfu_send_lower(struct sscfu *, void *, enum sscop_aasig, 169121461Sharti struct mbuf *, u_int); 170121461Shartistatic void sscfu_window(struct sscfu *, void *, u_int); 171121461Shartistatic void sscfu_verbose(struct sscfu *, void *, const char *, ...) 172121461Sharti __printflike(3, 4); 173121461Sharti 174121461Shartistatic const struct sscfu_funcs sscfu_funcs = { 175121461Sharti sscfu_send_upper, 176121461Sharti sscfu_send_lower, 177121461Sharti sscfu_window, 178121461Sharti sscfu_verbose 179121461Sharti}; 180121461Sharti 181121461Sharti/************************************************************/ 182121461Sharti/* 183121461Sharti * CONTROL MESSAGES 184121461Sharti */ 185121461Shartistatic int 186121461Shartitext_status(node_p node, struct priv *priv, char *arg, u_int len) 187121461Sharti{ 188121461Sharti struct sbuf sbuf; 189121461Sharti 190121461Sharti sbuf_new(&sbuf, arg, len, 0); 191121461Sharti 192121461Sharti if (priv->upper) 193121461Sharti sbuf_printf(&sbuf, "upper hook: %s connected to %s:%s\n", 194121461Sharti NG_HOOK_NAME(priv->upper), 195121461Sharti NG_NODE_NAME(NG_HOOK_NODE(NG_HOOK_PEER(priv->upper))), 196121461Sharti NG_HOOK_NAME(NG_HOOK_PEER(priv->upper))); 197121461Sharti else 198121461Sharti sbuf_printf(&sbuf, "upper hook: <not connected>\n"); 199121461Sharti 200121461Sharti if (priv->lower) 201121461Sharti sbuf_printf(&sbuf, "lower hook: %s connected to %s:%s\n", 202121461Sharti NG_HOOK_NAME(priv->lower), 203121461Sharti NG_NODE_NAME(NG_HOOK_NODE(NG_HOOK_PEER(priv->lower))), 204121461Sharti NG_HOOK_NAME(NG_HOOK_PEER(priv->lower))); 205121461Sharti else 206121461Sharti sbuf_printf(&sbuf, "lower hook: <not connected>\n"); 207121461Sharti 208121461Sharti sbuf_printf(&sbuf, "sscf state: %s\n", 209123812Salfred priv->enabled == 0 ? "<disabled>" : 210121461Sharti sscfu_statename(sscfu_getstate(priv->sscf))); 211121461Sharti 212121461Sharti sbuf_finish(&sbuf); 213121461Sharti return (sbuf_len(&sbuf)); 214121461Sharti} 215121461Sharti 216121461Shartistatic int 217121461Sharting_sscfu_rcvmsg(node_p node, item_p item, hook_p lasthook) 218121461Sharti{ 219121461Sharti struct priv *priv = NG_NODE_PRIVATE(node); 220121461Sharti struct ng_mesg *resp = NULL; 221121461Sharti struct ng_mesg *msg; 222121461Sharti int error = 0; 223121461Sharti 224121461Sharti NGI_GET_MSG(item, msg); 225121461Sharti 226121461Sharti switch (msg->header.typecookie) { 227121461Sharti 228121461Sharti case NGM_GENERIC_COOKIE: 229121461Sharti switch (msg->header.cmd) { 230121461Sharti 231121461Sharti case NGM_TEXT_STATUS: 232121461Sharti NG_MKRESPONSE(resp, msg, NG_TEXTRESPONSE, M_NOWAIT); 233121461Sharti if (resp == NULL) { 234121461Sharti error = ENOMEM; 235121461Sharti break; 236121461Sharti } 237121461Sharti resp->header.arglen = text_status(node, priv, 238121461Sharti (char *)resp->data, resp->header.arglen) + 1; 239121461Sharti break; 240121461Sharti 241121461Sharti default: 242121461Sharti error = EINVAL; 243121461Sharti break; 244121461Sharti } 245121461Sharti break; 246121461Sharti 247121461Sharti case NGM_SSCFU_COOKIE: 248121461Sharti switch (msg->header.cmd) { 249121461Sharti 250121461Sharti case NGM_SSCFU_GETDEFPARAM: 251121461Sharti { 252121461Sharti struct ng_sscfu_getdefparam *p; 253121461Sharti 254121461Sharti if (msg->header.arglen != 0) { 255121461Sharti error = EINVAL; 256121461Sharti break; 257121461Sharti } 258121461Sharti NG_MKRESPONSE(resp, msg, sizeof(*p), M_NOWAIT); 259121461Sharti if (resp == NULL) { 260121461Sharti error = ENOMEM; 261121461Sharti break; 262121461Sharti } 263121461Sharti p = (struct ng_sscfu_getdefparam *)resp->data; 264121461Sharti p->mask = sscfu_getdefparam(&p->param); 265121461Sharti break; 266121461Sharti } 267121461Sharti 268121461Sharti case NGM_SSCFU_ENABLE: 269121461Sharti if (msg->header.arglen != 0) { 270121461Sharti error = EINVAL; 271121461Sharti break; 272121461Sharti } 273121461Sharti if (priv->enabled) { 274121461Sharti error = EISCONN; 275121461Sharti break; 276121461Sharti } 277121461Sharti priv->enabled = 1; 278121461Sharti break; 279121461Sharti 280121461Sharti case NGM_SSCFU_DISABLE: 281121461Sharti if (msg->header.arglen != 0) { 282121461Sharti error = EINVAL; 283121461Sharti break; 284121461Sharti } 285121461Sharti if (!priv->enabled) { 286121461Sharti error = ENOTCONN; 287121461Sharti break; 288121461Sharti } 289121461Sharti priv->enabled = 0; 290121461Sharti sscfu_reset(priv->sscf); 291121461Sharti break; 292121461Sharti 293121461Sharti case NGM_SSCFU_GETSTATE: 294121461Sharti if (msg->header.arglen != 0) { 295121461Sharti error = EINVAL; 296121461Sharti break; 297121461Sharti } 298121461Sharti NG_MKRESPONSE(resp, msg, sizeof(uint32_t), M_NOWAIT); 299121461Sharti if(resp == NULL) { 300121461Sharti error = ENOMEM; 301121461Sharti break; 302121461Sharti } 303121461Sharti *(uint32_t *)resp->data = 304121461Sharti priv->enabled ? (sscfu_getstate(priv->sscf) + 1) 305121461Sharti : 0; 306121461Sharti break; 307121461Sharti 308121461Sharti case NGM_SSCFU_GETDEBUG: 309121461Sharti if (msg->header.arglen != 0) { 310121461Sharti error = EINVAL; 311121461Sharti break; 312121461Sharti } 313121461Sharti NG_MKRESPONSE(resp, msg, sizeof(uint32_t), M_NOWAIT); 314121461Sharti if(resp == NULL) { 315121461Sharti error = ENOMEM; 316121461Sharti break; 317121461Sharti } 318121461Sharti *(uint32_t *)resp->data = sscfu_getdebug(priv->sscf); 319121461Sharti break; 320121461Sharti 321121461Sharti case NGM_SSCFU_SETDEBUG: 322121461Sharti if (msg->header.arglen != sizeof(uint32_t)) { 323121461Sharti error = EINVAL; 324121461Sharti break; 325121461Sharti } 326121461Sharti sscfu_setdebug(priv->sscf, *(uint32_t *)msg->data); 327121461Sharti break; 328121461Sharti 329121461Sharti default: 330121461Sharti error = EINVAL; 331121461Sharti break; 332121461Sharti } 333121461Sharti break; 334121461Sharti 335121461Sharti default: 336121461Sharti error = EINVAL; 337121461Sharti break; 338121461Sharti } 339121461Sharti 340121461Sharti NG_RESPOND_MSG(error, node, item, resp); 341121461Sharti NG_FREE_MSG(msg); 342121461Sharti 343121461Sharti return (error); 344121461Sharti} 345121461Sharti 346121461Sharti/************************************************************/ 347121461Sharti/* 348121461Sharti * HOOK MANAGEMENT 349121461Sharti */ 350121461Shartistatic int 351121461Sharting_sscfu_newhook(node_p node, hook_p hook, const char *name) 352121461Sharti{ 353121461Sharti struct priv *priv = NG_NODE_PRIVATE(node); 354121461Sharti 355121461Sharti if (strcmp(name, "upper") == 0) 356121461Sharti priv->upper = hook; 357121461Sharti else if (strcmp(name, "lower") == 0) { 358121461Sharti priv->lower = hook; 359121461Sharti NG_HOOK_SET_RCVDATA(hook, ng_sscfu_rcvlower); 360121461Sharti } else 361121461Sharti return (EINVAL); 362121461Sharti return (0); 363121461Sharti} 364121461Sharti 365121461Shartistatic int 366121461Sharting_sscfu_disconnect(hook_p hook) 367121461Sharti{ 368121461Sharti node_p node = NG_HOOK_NODE(hook); 369121461Sharti struct priv *priv = NG_NODE_PRIVATE(node); 370121461Sharti 371121461Sharti if (hook == priv->upper) 372121461Sharti priv->upper = NULL; 373121461Sharti else if (hook == priv->lower) 374121461Sharti priv->lower = NULL; 375121461Sharti else { 376121461Sharti log(LOG_ERR, "bogus hook"); 377121461Sharti return (EINVAL); 378121461Sharti } 379121461Sharti 380121461Sharti if (NG_NODE_NUMHOOKS(node) == 0) { 381121461Sharti if (NG_NODE_IS_VALID(node)) 382121461Sharti ng_rmnode_self(node); 383121461Sharti } else { 384121461Sharti /* 385121461Sharti * Because there are no timeouts reset the protocol 386121461Sharti * if the lower layer is disconnected. 387121461Sharti */ 388121461Sharti if (priv->lower == NULL && 389121461Sharti priv->enabled && 390121461Sharti sscfu_getstate(priv->sscf) != SSCFU_RELEASED) 391121461Sharti sscfu_reset(priv->sscf); 392121461Sharti } 393121461Sharti return (0); 394121461Sharti} 395121461Sharti 396121461Sharti/************************************************************/ 397121461Sharti/* 398121461Sharti * DATA 399121461Sharti */ 400121461Shartistatic int 401121461Sharting_sscfu_rcvupper(hook_p hook, item_p item) 402121461Sharti{ 403121461Sharti node_p node = NG_HOOK_NODE(hook); 404121461Sharti struct priv *priv = NG_NODE_PRIVATE(node); 405121461Sharti struct mbuf *m; 406121461Sharti struct sscfu_arg a; 407121461Sharti 408121461Sharti if (!priv->enabled || priv->lower == NULL) { 409121461Sharti NG_FREE_ITEM(item); 410121461Sharti return (0); 411121461Sharti } 412121461Sharti 413121461Sharti NGI_GET_M(item, m); 414121461Sharti NG_FREE_ITEM(item); 415121461Sharti 416121461Sharti if (!(m->m_flags & M_PKTHDR)) { 417121461Sharti printf("no pkthdr\n"); 418121461Sharti m_freem(m); 419121461Sharti return (EINVAL); 420121461Sharti } 421121461Sharti if (m->m_len < (int)sizeof(a) && (m = m_pullup(m, sizeof(a))) == NULL) 422121461Sharti return (ENOMEM); 423121461Sharti bcopy((caddr_t)mtod(m, struct sscfu_arg *), &a, sizeof(a)); 424121461Sharti m_adj(m, sizeof(a)); 425121461Sharti 426121461Sharti return (sscfu_saalsig(priv->sscf, a.sig, m)); 427121461Sharti} 428121461Sharti 429121461Shartistatic void 430121461Shartisscfu_send_upper(struct sscfu *sscf, void *p, enum saal_sig sig, struct mbuf *m) 431121461Sharti{ 432121461Sharti node_p node = (node_p)p; 433121461Sharti struct priv *priv = NG_NODE_PRIVATE(node); 434121461Sharti int error; 435121461Sharti struct sscfu_arg *a; 436121461Sharti 437121461Sharti if (priv->upper == NULL) { 438121461Sharti if (m != NULL) 439121461Sharti m_freem(m); 440121461Sharti return; 441121461Sharti } 442121461Sharti if (m == NULL) { 443121461Sharti MGETHDR(m, M_NOWAIT, MT_DATA); 444121461Sharti if (m == NULL) 445121461Sharti return; 446121461Sharti m->m_len = sizeof(struct sscfu_arg); 447121461Sharti m->m_pkthdr.len = m->m_len; 448121461Sharti } else { 449121461Sharti M_PREPEND(m, sizeof(struct sscfu_arg), M_NOWAIT); 450121461Sharti if (m == NULL) 451121461Sharti return; 452121461Sharti } 453121461Sharti a = mtod(m, struct sscfu_arg *); 454121461Sharti a->sig = sig; 455121461Sharti 456121461Sharti NG_SEND_DATA_ONLY(error, priv->upper, m); 457121461Sharti} 458121461Sharti 459121461Shartistatic int 460121461Sharting_sscfu_rcvlower(hook_p hook, item_p item) 461121461Sharti{ 462121461Sharti node_p node = NG_HOOK_NODE(hook); 463121461Sharti struct priv *priv = NG_NODE_PRIVATE(node); 464121461Sharti struct mbuf *m; 465121461Sharti struct sscop_arg a; 466121461Sharti 467121461Sharti if (!priv->enabled || priv->upper == NULL) { 468121461Sharti NG_FREE_ITEM(item); 469121461Sharti return (0); 470121461Sharti } 471121461Sharti 472121461Sharti NGI_GET_M(item, m); 473121461Sharti NG_FREE_ITEM(item); 474121461Sharti 475121461Sharti if (!(m->m_flags & M_PKTHDR)) { 476121461Sharti printf("no pkthdr\n"); 477121461Sharti m_freem(m); 478121461Sharti return (EINVAL); 479121461Sharti } 480121461Sharti 481121461Sharti /* 482121461Sharti * Strip of the SSCOP header. 483121461Sharti */ 484121461Sharti if (m->m_len < (int)sizeof(a) && (m = m_pullup(m, sizeof(a))) == NULL) 485121461Sharti return (ENOMEM); 486121461Sharti bcopy((caddr_t)mtod(m, struct sscop_arg *), &a, sizeof(a)); 487121461Sharti m_adj(m, sizeof(a)); 488121461Sharti 489121461Sharti sscfu_input(priv->sscf, a.sig, m, a.arg); 490121461Sharti 491121461Sharti return (0); 492121461Sharti} 493121461Sharti 494121461Shartistatic void 495121461Shartisscfu_send_lower(struct sscfu *sscf, void *p, enum sscop_aasig sig, 496121461Sharti struct mbuf *m, u_int arg) 497121461Sharti{ 498121461Sharti node_p node = (node_p)p; 499121461Sharti struct priv *priv = NG_NODE_PRIVATE(node); 500121461Sharti int error; 501121461Sharti struct sscop_arg *a; 502121461Sharti 503121461Sharti if (priv->lower == NULL) { 504121461Sharti if (m != NULL) 505121461Sharti m_freem(m); 506121461Sharti return; 507121461Sharti } 508121461Sharti if (m == NULL) { 509121461Sharti MGETHDR(m, M_NOWAIT, MT_DATA); 510121461Sharti if (m == NULL) 511121461Sharti return; 512121461Sharti m->m_len = sizeof(struct sscop_arg); 513121461Sharti m->m_pkthdr.len = m->m_len; 514121461Sharti } else { 515121461Sharti M_PREPEND(m, sizeof(struct sscop_arg), M_NOWAIT); 516121461Sharti if (m == NULL) 517121461Sharti return; 518121461Sharti } 519121461Sharti a = mtod(m, struct sscop_arg *); 520121461Sharti a->sig = sig; 521121461Sharti a->arg = arg; 522121461Sharti 523121461Sharti NG_SEND_DATA_ONLY(error, priv->lower, m); 524121461Sharti} 525121461Sharti 526121461Sharti/* 527121461Sharti * Window is handled by ng_sscop so make this a NOP. 528121461Sharti */ 529121461Shartistatic void 530121461Shartisscfu_window(struct sscfu *sscfu, void *arg, u_int w) 531121461Sharti{ 532121461Sharti} 533121461Sharti 534121461Sharti/************************************************************/ 535121461Sharti/* 536121461Sharti * NODE MANAGEMENT 537121461Sharti */ 538121461Shartistatic int 539121461Sharting_sscfu_constructor(node_p node) 540121461Sharti{ 541121461Sharti struct priv *priv; 542121461Sharti 543121461Sharti if ((priv = malloc(sizeof(*priv), M_NG_SSCFU, M_NOWAIT|M_ZERO)) == NULL) 544121461Sharti return (ENOMEM); 545121461Sharti 546121461Sharti if ((priv->sscf = sscfu_create(node, &sscfu_funcs)) == NULL) { 547121461Sharti free(priv, M_NG_SSCFU); 548121461Sharti return (ENOMEM); 549121461Sharti } 550121461Sharti 551121461Sharti NG_NODE_SET_PRIVATE(node, priv); 552121461Sharti 553121461Sharti return (0); 554121461Sharti} 555121461Sharti 556121461Shartistatic int 557121461Sharting_sscfu_shutdown(node_p node) 558121461Sharti{ 559121461Sharti struct priv *priv = NG_NODE_PRIVATE(node); 560121461Sharti 561121461Sharti sscfu_destroy(priv->sscf); 562121461Sharti 563121461Sharti free(priv, M_NG_SSCFU); 564121461Sharti NG_NODE_SET_PRIVATE(node, NULL); 565121461Sharti 566121461Sharti NG_NODE_UNREF(node); 567121461Sharti 568121461Sharti return (0); 569121461Sharti} 570121461Sharti 571121461Shartistatic void 572121461Shartisscfu_verbose(struct sscfu *sscfu, void *arg, const char *fmt, ...) 573121461Sharti{ 574121461Sharti va_list ap; 575121461Sharti 576121461Sharti va_start(ap, fmt); 577121461Sharti printf("sscfu(%p): ", sscfu); 578121461Sharti vprintf(fmt, ap); 579121461Sharti va_end(ap); 580121461Sharti printf("\n"); 581121461Sharti} 582121461Sharti 583121461Sharti/************************************************************/ 584121461Sharti/* 585121461Sharti * INITIALISATION 586121461Sharti */ 587121461Sharti/* 588121461Sharti * Loading and unloading of node type 589121461Sharti */ 590121461Shartistatic int 591121461Sharting_sscfu_mod_event(module_t mod, int event, void *data) 592121461Sharti{ 593121461Sharti int s; 594121461Sharti int error = 0; 595121461Sharti 596121461Sharti s = splnet(); 597121461Sharti switch (event) { 598121461Sharti 599121461Sharti case MOD_LOAD: 600121461Sharti break; 601121461Sharti 602121461Sharti case MOD_UNLOAD: 603121461Sharti break; 604121461Sharti 605121461Sharti default: 606121461Sharti error = EOPNOTSUPP; 607121461Sharti break; 608121461Sharti } 609121461Sharti splx(s); 610121461Sharti return (error); 611121461Sharti} 612