ng_rfc1490.c revision 220768
150477Speter/* 233548Sjkh * ng_rfc1490.c 32893Sdfr */ 42893Sdfr 533548Sjkh/*- 633548Sjkh * Copyright (c) 1996-1999 Whistle Communications, Inc. 72893Sdfr * All rights reserved. 82893Sdfr * 92893Sdfr * Subject to the following obligations and disclaimer of warranty, use and 102893Sdfr * redistribution of this software, in source or object code forms, with or 112893Sdfr * without modifications are expressly permitted by Whistle Communications; 122893Sdfr * provided, however, that: 132893Sdfr * 1. Any and all reproductions of the source or object code must include the 142893Sdfr * copyright notice above and the following disclaimer of warranties; and 152893Sdfr * 2. No rights are granted, in any manner or form, to use Whistle 162893Sdfr * Communications, Inc. trademarks, including the mark "WHISTLE 172893Sdfr * COMMUNICATIONS" on advertising, endorsements, or otherwise except as 182893Sdfr * such appears in the above copyright notice or in the software. 192893Sdfr * 202893Sdfr * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND 212893Sdfr * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO 222893Sdfr * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, 232893Sdfr * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF 242893Sdfr * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. 252893Sdfr * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY 262893Sdfr * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS 272893Sdfr * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. 282893Sdfr * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES 292893Sdfr * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING 302893Sdfr * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 312893Sdfr * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR 322893Sdfr * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY 332893Sdfr * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 342893Sdfr * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35139776Simp * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY 362893Sdfr * OF SUCH DAMAGE. 378876Srgrimes * 382893Sdfr * Author: Julian Elischer <julian@freebsd.org> 392893Sdfr * 408876Srgrimes * $FreeBSD: head/sys/netgraph/ng_rfc1490.c 220768 2011-04-18 09:12:27Z glebius $ 412893Sdfr * $Whistle: ng_rfc1490.c,v 1.22 1999/11/01 09:24:52 julian Exp $ 428876Srgrimes */ 432893Sdfr 442893Sdfr/* 452893Sdfr * This node does RFC 1490 multiplexing. 462893Sdfr * 478876Srgrimes * NOTE: RFC 1490 is updated by RFC 2427. 482893Sdfr */ 492893Sdfr 502893Sdfr#include <sys/param.h> 512893Sdfr#include <sys/systm.h> 522893Sdfr#include <sys/errno.h> 5340651Sbde#include <sys/kernel.h> 542893Sdfr#include <sys/malloc.h> 55164033Srwatson#include <sys/mbuf.h> 562893Sdfr#include <sys/errno.h> 572893Sdfr#include <sys/socket.h> 582893Sdfr 592893Sdfr#include <net/if.h> 6060041Sphk#include <netinet/in.h> 612893Sdfr#include <netinet/if_ether.h> 6224131Sbde 632893Sdfr#include <netgraph/ng_message.h> 6433548Sjkh#include <netgraph/netgraph.h> 65120492Sfjoe#include <netgraph/ng_parse.h> 66102391Sbde#include <netgraph/ng_rfc1490.h> 672893Sdfr 6877162Sru/* 6977162Sru * DEFINITIONS 70120492Sfjoe */ 7177162Sru 7277162Sru/* Q.922 stuff -- see RFC 1490 */ 7377162Sru#define HDLC_UI 0x03 742893Sdfr 75137036Sphk#define NLPID_IP 0xCC 76137036Sphk#define NLPID_PPP 0xCF 77137036Sphk#define NLPID_SNAP 0x80 78138471Sphk#define NLPID_Q933 0x08 79138471Sphk#define NLPID_CLNP 0x81 80138471Sphk#define NLPID_ESIS 0x82 81166559Srodrigc#define NLPID_ISIS 0x83 82138471Sphk 83152610Srodrigc#define ERROUT(x) do { error = (x); goto done; } while (0) 84166340Srodrigc 85138471Sphk/* Encapsulation methods we understand */ 86138471Sphkenum { 87138471Sphk NG_RFC1490_ENCAP_IETF_IP = 1, /* see RFC2427, chapter 7, table 1 */ 8856674Snyan NG_RFC1490_ENCAP_IETF_SNAP, /* see RFC2427, chapter 7, table 2 */ 8956674Snyan NG_RFC1490_ENCAP_CISCO, /* Cisco's proprietary encapsulation */ 9056674Snyan}; 9156674Snyan 9256674Snyanstruct ng_rfc1490_encap_t { 9356674Snyan u_int8_t method; 9456674Snyan const char *name; 9556674Snyan}; 9656674Snyan 9756674Snyanstatic const struct ng_rfc1490_encap_t ng_rfc1490_encaps[] = { 9856674Snyan { NG_RFC1490_ENCAP_IETF_IP, "ietf-ip" }, 99151897Srwatson { NG_RFC1490_ENCAP_IETF_SNAP, "ietf-snap" }, 100151897Srwatson { NG_RFC1490_ENCAP_CISCO, "cisco" }, 10130309Sphk { 0, NULL}, 102120492Sfjoe}; 103120492Sfjoe 104138471Sphk/* Node private data */ 105138471Sphkstruct ng_rfc1490_private { 106132023Salfred hook_p downlink; 107170188Strhodes hook_p ppp; 108138471Sphk hook_p inet; 109101777Sphk hook_p ethernet; 110101777Sphk const struct ng_rfc1490_encap_t *enc; 111101777Sphk}; 112101777Sphktypedef struct ng_rfc1490_private *priv_p; 11312338Sbde 114134345Stjr/* Netgraph node methods */ 115134345Stjrstatic ng_constructor_t ng_rfc1490_constructor; 116134345Stjrstatic ng_rcvmsg_t ng_rfc1490_rcvmsg; 11733548Sjkhstatic ng_shutdown_t ng_rfc1490_shutdown; 118166558Srodrigcstatic ng_newhook_t ng_rfc1490_newhook; 11933548Sjkhstatic ng_rcvdata_t ng_rfc1490_rcvdata; 12033548Sjkhstatic ng_disconnect_t ng_rfc1490_disconnect; 121138471Sphk 122138471Sphk/* List of commands and how to convert arguments to/from ASCII */ 12333548Sjkhstatic const struct ng_cmdlist ng_rfc1490_cmds[] = { 124138471Sphk { 125138471Sphk NGM_RFC1490_COOKIE, 126138471Sphk NGM_RFC1490_SET_ENCAP, 127138471Sphk "setencap", 128138471Sphk &ng_parse_string_type, 129138471Sphk NULL 130138471Sphk }, 131138471Sphk { 132138471Sphk NGM_RFC1490_COOKIE, 133138471Sphk NGM_RFC1490_GET_ENCAP, 134138471Sphk "getencap", 135138471Sphk NULL, 136138471Sphk &ng_parse_string_type 137138471Sphk }, 138138471Sphk { 0 } 139138471Sphk}; 140134345Stjr 141134345Stjr/* Node type descriptor */ 142134345Stjrstatic struct ng_type typestruct = { 143134345Stjr .version = NG_ABI_VERSION, 144134345Stjr .name = NG_RFC1490_NODE_TYPE, 145134345Stjr .constructor = ng_rfc1490_constructor, 146134345Stjr .rcvmsg = ng_rfc1490_rcvmsg, 147134345Stjr .shutdown = ng_rfc1490_shutdown, 148134345Stjr .newhook = ng_rfc1490_newhook, 149134345Stjr .rcvdata = ng_rfc1490_rcvdata, 150138471Sphk .disconnect = ng_rfc1490_disconnect, 151138471Sphk .cmdlist = ng_rfc1490_cmds, 152138471Sphk}; 153138471SphkNETGRAPH_INIT(rfc1490, &typestruct); 154138471Sphk 155138471Sphk/************************************************************************ 156138471Sphk NETGRAPH NODE STUFF 157138471Sphk ************************************************************************/ 158138471Sphk 159138471Sphk/* 160152595Srodrigc * Node constructor 161152595Srodrigc */ 162138471Sphkstatic int 163138471Sphkng_rfc1490_constructor(node_p node) 164152595Srodrigc{ 165152595Srodrigc priv_p priv; 166138471Sphk 167138471Sphk /* Allocate private structure */ 16833548Sjkh priv = malloc(sizeof(*priv), M_NETGRAPH, M_WAITOK | M_ZERO); 169152610Srodrigc 170152610Srodrigc /* Initialize to default encapsulation method - ietf-ip */ 171152610Srodrigc priv->enc = ng_rfc1490_encaps; 172138471Sphk 173138471Sphk NG_NODE_SET_PRIVATE(node, priv); 17433548Sjkh 17533548Sjkh /* Done */ 17633548Sjkh return (0); 17733548Sjkh} 17833548Sjkh 17933548Sjkh/* 18033548Sjkh * Give our ok for a hook to be added 18133548Sjkh */ 18233548Sjkhstatic int 18333548Sjkhng_rfc1490_newhook(node_p node, hook_p hook, const char *name) 18433548Sjkh{ 18533548Sjkh const priv_p priv = NG_NODE_PRIVATE(node); 186144058Sjeff 187144058Sjeff if (!strcmp(name, NG_RFC1490_HOOK_DOWNSTREAM)) { 18833548Sjkh if (priv->downlink) 18933548Sjkh return (EISCONN); 19033548Sjkh priv->downlink = hook; 19133548Sjkh } else if (!strcmp(name, NG_RFC1490_HOOK_PPP)) { 19233548Sjkh if (priv->ppp) 19333548Sjkh return (EISCONN); 19433548Sjkh priv->ppp = hook; 19533548Sjkh } else if (!strcmp(name, NG_RFC1490_HOOK_INET)) { 19633548Sjkh if (priv->inet) 19733548Sjkh return (EISCONN); 198138471Sphk priv->inet = hook; 199138471Sphk } else if (!strcmp(name, NG_RFC1490_HOOK_ETHERNET)) { 200138471Sphk if (priv->ethernet) 201138471Sphk return (EISCONN); 202138471Sphk priv->ethernet = hook; 203138471Sphk } else 204138471Sphk return (EINVAL); 205138471Sphk return (0); 206138471Sphk} 207138471Sphk 208138471Sphk/* 209138471Sphk * Receive a control message. 210138471Sphk */ 211138471Sphkstatic int 212138471Sphkng_rfc1490_rcvmsg(node_p node, item_p item, hook_p lasthook) 213138471Sphk{ 214138471Sphk const priv_p priv = NG_NODE_PRIVATE(node); 215138471Sphk struct ng_mesg *msg; 216138471Sphk struct ng_mesg *resp = NULL; 217138471Sphk int error = 0; 218138471Sphk 219138471Sphk NGI_GET_MSG(item, msg); 220138471Sphk 221138471Sphk if (msg->header.typecookie == NGM_RFC1490_COOKIE) { 222138471Sphk switch (msg->header.cmd) { 223138471Sphk case NGM_RFC1490_SET_ENCAP: 224138471Sphk { 225138471Sphk const struct ng_rfc1490_encap_t *enc; 226138471Sphk char *s; 227138471Sphk size_t len; 228138471Sphk 229138471Sphk if (msg->header.arglen == 0) 230138471Sphk ERROUT(EINVAL); 2312893Sdfr 2328876Srgrimes s = (char *)msg->data; 2332893Sdfr len = msg->header.arglen - 1; 2348876Srgrimes 2352893Sdfr /* Search for matching encapsulation method */ 23612144Sphk for (enc = ng_rfc1490_encaps; enc->method != 0; enc++ ) 237138471Sphk if ((strlen(enc->name) == len) && 2382893Sdfr !strncmp(enc->name, s, len)) 2392893Sdfr break; /* found */ 24033548Sjkh 24133548Sjkh if (enc->method != 0) 242132902Sphk priv->enc = enc; 243138689Sphk else 24433548Sjkh error = EINVAL; 245138471Sphk break; 2462893Sdfr } 247138471Sphk case NGM_RFC1490_GET_ENCAP: 248138471Sphk 249138471Sphk NG_MKRESPONSE(resp, msg, strlen(priv->enc->name) + 1, M_NOWAIT); 2502893Sdfr if (resp == NULL) 25133548Sjkh ERROUT(ENOMEM); 25233548Sjkh 2532893Sdfr strlcpy((char *)resp->data, priv->enc->name, 2542893Sdfr strlen(priv->enc->name) + 1); 255165836Srodrigc break; 25633548Sjkh 257138689Sphk default: 258158924Srodrigc error = EINVAL; 259165022Srodrigc break; 260165022Srodrigc } 261165022Srodrigc } else 262165022Srodrigc error = EINVAL; 263165022Srodrigc 264165022Srodrigcdone: 265165022Srodrigc NG_RESPOND_MSG(error, node, item, resp); 266138689Sphk NG_FREE_MSG(msg); 267165022Srodrigc return (error); 268138689Sphk} 269137036Sphk 270138471Sphk/* 271140048Sphk * Receive data on a hook and encapsulate according to RFC 1490. 272133287Sphk * Only those nodes marked (*) are supported by this routine so far. 273133287Sphk * 2742893Sdfr * Q.922 control 2752893Sdfr * | 2762893Sdfr * | 277132023Salfred * --------------------------------------------------------------------- 278138471Sphk * | 0x03 | | 279138471Sphk * UI I Frame Cisco 280137036Sphk * | | Encapsulation 281137036Sphk * --------------------------------- -------------- | 282137036Sphk * | 0x08 | 0x81 |0xCC |0xCF | 0x00 |..01.... |..10.... -------------- 283137036Sphk * | | | | | 0x80 | | |0x800 | 284137036Sphk * Q.933 CLNP IP(*) PPP(*) SNAP ISO 8208 ISO 8208 | | 285160939Sdelphij * | (rfc1973) | Modulo 8 Modulo 128 IP(*) Others 286160939Sdelphij * | | 287160939Sdelphij * -------------------- OUI 288160939Sdelphij * | | | 289138471Sphk * L2 ID L3 ID ------------------------- 290138471Sphk * | User |00-80-C2 |00-00-00 29133548Sjkh * | specified | | 29233548Sjkh * | 0x70 PID Ethertype 29333548Sjkh * | | | 29433548Sjkh * ------------------- -----------------... ---------- 295164033Srwatson * |0x51 |0x4E | |0x4C |0x7 |0xB | |0x806 | 296164033Srwatson * | | | | | | | | | 297164033Srwatson * 7776 Q.922 Others 802.2 802.3(*) 802.6 Others IP(*) Others 298164033Srwatson * 299164033Srwatson * 300164033Srwatson */ 301164033Srwatson 30283366Sjulian#define MAX_ENCAPS_HDR 8 303164033Srwatson#define OUICMP(P,A,B,C) ((P)[0]==(A) && (P)[1]==(B) && (P)[2]==(C)) 30433548Sjkh 305164033Srwatsonstatic int 306137036Sphkng_rfc1490_rcvdata(hook_p hook, item_p item) 307137036Sphk{ 308137036Sphk const node_p node = NG_HOOK_NODE(hook); 309137036Sphk const priv_p priv = NG_NODE_PRIVATE(node); 310137036Sphk int error = 0; 311137036Sphk struct mbuf *m; 312137036Sphk 313123963Sbde NGI_GET_M(item, m); 314165836Srodrigc if (hook == priv->downlink) { 315165836Srodrigc const u_char *start; 316165836Srodrigc const u_char *ptr; 317165836Srodrigc 318165836Srodrigc if (m->m_len < MAX_ENCAPS_HDR 319165836Srodrigc && !(m = m_pullup(m, MAX_ENCAPS_HDR))) 320165836Srodrigc ERROUT(ENOBUFS); 321165836Srodrigc ptr = start = mtod(m, const u_char *); 322123963Sbde 323123873Strhodes if (priv->enc->method == NG_RFC1490_ENCAP_CISCO) 324123873Strhodes goto switch_on_etype; 325123963Sbde 32633548Sjkh /* Must be UI frame */ 3272893Sdfr if (*ptr++ != HDLC_UI) 3282893Sdfr ERROUT(0); 32933548Sjkh 330125796Sbde /* Eat optional zero pad byte */ 3312893Sdfr if (*ptr == 0x00) 332138471Sphk ptr++; 333138471Sphk 334149720Sssouhlal /* Multiplex on NLPID */ 335132902Sphk switch (*ptr++) { 33633548Sjkh case NLPID_SNAP: 33733548Sjkh if (OUICMP(ptr, 0, 0, 0)) { /* It's an ethertype */ 338132902Sphk u_int16_t etype; 339132902Sphk 3408876Srgrimes ptr += 3; 34155756Sphkswitch_on_etype: etype = ntohs(*((const u_int16_t *)ptr)); 342149720Sssouhlal ptr += 2; 34355756Sphk m_adj(m, ptr - start); 3442893Sdfr switch (etype) { 3452893Sdfr case ETHERTYPE_IP: 34633548Sjkh NG_FWD_NEW_DATA(error, item, 34733548Sjkh priv->inet, m); 3482893Sdfr break; 349164033Srwatson case ETHERTYPE_ARP: 350164033Srwatson case ETHERTYPE_REVARP: 351164033Srwatson default: 352164033Srwatson ERROUT(0); 353164033Srwatson } 354164033Srwatson } else if (OUICMP(ptr, 0x00, 0x80, 0xc2)) { 355164033Srwatson /* 802.1 bridging */ 356164033Srwatson ptr += 3; 357164033Srwatson if (*ptr++ != 0x00) 35833548Sjkh ERROUT(0); /* unknown PID octet 0 */ 35933548Sjkh if (*ptr++ != 0x07) 360138471Sphk ERROUT(0); /* not FCS-less 802.3 */ 36133548Sjkh m_adj(m, ptr - start); 36233548Sjkh NG_FWD_NEW_DATA(error, item, priv->ethernet, m); 36333548Sjkh } else /* Other weird stuff... */ 36433548Sjkh ERROUT(0); 3652893Sdfr break; 36633548Sjkh case NLPID_IP: 3672893Sdfr m_adj(m, ptr - start); 368149720Sssouhlal NG_FWD_NEW_DATA(error, item, priv->inet, m); 3692893Sdfr break; 3702893Sdfr case NLPID_PPP: 3712893Sdfr m_adj(m, ptr - start); 37233548Sjkh NG_FWD_NEW_DATA(error, item, priv->ppp, m); 37333548Sjkh break; 37433548Sjkh case NLPID_Q933: 375138471Sphk case NLPID_CLNP: 37633548Sjkh case NLPID_ESIS: 377134345Stjr case NLPID_ISIS: 378134345Stjr ERROUT(0); 3792893Sdfr default: /* Try PPP (see RFC 1973) */ 3802893Sdfr ptr--; /* NLPID becomes PPP proto */ 381138471Sphk if ((*ptr & 0x01) == 0x01) 382138471Sphk ERROUT(0); 3832893Sdfr m_adj(m, ptr - start); 384138471Sphk NG_FWD_NEW_DATA(error, item, priv->ppp, m); 3852893Sdfr break; 38633548Sjkh } 3872893Sdfr } else if (hook == priv->ppp) { 3882893Sdfr M_PREPEND(m, 2, M_DONTWAIT); /* Prepend PPP NLPID */ 38912144Sphk if (!m) 390166558Srodrigc ERROUT(ENOBUFS); 3912893Sdfr mtod(m, u_char *)[0] = HDLC_UI; 39233548Sjkh mtod(m, u_char *)[1] = NLPID_PPP; 39333548Sjkh NG_FWD_NEW_DATA(error, item, priv->downlink, m); 394130585Sphk } else if (hook == priv->inet) { 3952893Sdfr switch (priv->enc->method) { 3962893Sdfr case NG_RFC1490_ENCAP_IETF_IP: 3972893Sdfr M_PREPEND(m, 2, M_DONTWAIT); /* Prepend IP NLPID */ 39833548Sjkh if (!m) 39933548Sjkh ERROUT(ENOBUFS); 40055188Sbp mtod(m, u_char *)[0] = HDLC_UI; 40133548Sjkh mtod(m, u_char *)[1] = NLPID_IP; 402137036Sphk break; 403137036Sphk case NG_RFC1490_ENCAP_IETF_SNAP: 4042893Sdfr /* 405138471Sphk * According to RFC2427 frame should begin with 406137036Sphk * HDLC_UI PAD NLIPID OUI PID 407137036Sphk * 03 00 80 00 00 00 08 00 408137036Sphk */ 409137036Sphk M_PREPEND(m, 8, M_DONTWAIT); 410137036Sphk if (!m) 411137036Sphk ERROUT(ENOBUFS); 41283366Sjulian mtod(m, u_char *)[0] = HDLC_UI; 4133152Sphk mtod(m, u_char *)[1] = 0x00; /* PAD */ 41433548Sjkh mtod(m, u_char *)[2] = NLPID_SNAP; 41533548Sjkh bzero((char *)(mtod(m, u_char *) + 3), 3); /* OUI 0-0-0 */ 416137036Sphk *((u_int16_t *)mtod(m, u_int16_t *) + 6/sizeof(u_int16_t)) 41733548Sjkh = htons(ETHERTYPE_IP); /* PID */ 41833548Sjkh break; 41933548Sjkh case NG_RFC1490_ENCAP_CISCO: 4202893Sdfr M_PREPEND(m, 2, M_DONTWAIT); /* Prepend IP ethertype */ 42133548Sjkh if (!m) 42233548Sjkh ERROUT(ENOBUFS); 42356674Snyan *((u_int16_t *)mtod(m, u_int16_t *)) = htons(ETHERTYPE_IP); 424171408Sbde break; 4252893Sdfr } 426171408Sbde NG_FWD_NEW_DATA(error, item, priv->downlink, m); 4273152Sphk } else if (hook == priv->ethernet) { 4282893Sdfr M_PREPEND(m, 8, M_DONTWAIT); /* Prepend NLPID, OUI, PID */ 42933548Sjkh if (!m) 43033548Sjkh ERROUT(ENOBUFS); 43133548Sjkh mtod(m, u_char *)[0] = HDLC_UI; 43233548Sjkh mtod(m, u_char *)[1] = 0x00; /* pad */ 433105655Sjhb mtod(m, u_char *)[2] = NLPID_SNAP; 43433548Sjkh mtod(m, u_char *)[3] = 0x00; /* OUI */ 43556674Snyan mtod(m, u_char *)[4] = 0x80; 43687068Sjhb mtod(m, u_char *)[5] = 0xc2; 43787068Sjhb mtod(m, u_char *)[6] = 0x00; /* PID */ 43887068Sjhb mtod(m, u_char *)[7] = 0x07; 43987068Sjhb NG_FWD_NEW_DATA(error, item, priv->downlink, m); 44087068Sjhb } else 44156674Snyan panic("%s", __func__); 4422893Sdfr 443111119Simpdone: 4442893Sdfr if (item) 445137036Sphk NG_FREE_ITEM(item); 446137036Sphk NG_FREE_M(m); 4472893Sdfr return (error); 4482893Sdfr} 449166340Srodrigc 450166340Srodrigc/* 451166340Srodrigc * Nuke node 452166340Srodrigc */ 453166340Srodrigcstatic int 454166340Srodrigcng_rfc1490_shutdown(node_p node) 455166340Srodrigc{ 456166340Srodrigc const priv_p priv = NG_NODE_PRIVATE(node); 457166340Srodrigc 458166340Srodrigc /* Take down netgraph node */ 459166340Srodrigc bzero(priv, sizeof(*priv)); 460166340Srodrigc free(priv, M_NETGRAPH); 461166340Srodrigc NG_NODE_SET_PRIVATE(node, NULL); 462166340Srodrigc NG_NODE_UNREF(node); /* let the node escape */ 463166340Srodrigc return (0); 4642893Sdfr} 4652893Sdfr 4662893Sdfr/* 4672893Sdfr * Hook disconnection 46833548Sjkh */ 4692893Sdfrstatic int 470113979Sjhbng_rfc1490_disconnect(hook_p hook) 471113979Sjhb{ 472113979Sjhb const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); 473113979Sjhb 4742893Sdfr if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0) 4752893Sdfr && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) 4762893Sdfr ng_rmnode_self(NG_HOOK_NODE(hook)); 4772893Sdfr else if (hook == priv->downlink) 4782893Sdfr priv->downlink = NULL; 4792893Sdfr else if (hook == priv->inet) 4802893Sdfr priv->inet = NULL; 48133548Sjkh else if (hook == priv->ppp) 4822893Sdfr priv->ppp = NULL; 48356674Snyan else if (hook == priv->ethernet) 48456674Snyan priv->ethernet = NULL; 48556674Snyan else 48687068Sjhb panic("%s", __func__); 48787068Sjhb return (0); 488126998Srwatson} 48916363Sasami 49087068Sjhb