ng_split.c revision 87599
1208963Srdivacky/*- 2208963Srdivacky * 3265420Simp * Copyright (c) 1999-2000, Vitaly V Belekhov 4231057Sdim * All rights reserved. 5214562Srpaulo * 6265831Simp * Redistribution and use in source and binary forms, with or without 7246259Sdim * modification, are permitted provided that the following conditions 8246259Sdim * are met: 9246259Sdim * 1. Redistributions of source code must retain the above copyright 10246259Sdim * notice unmodified, this list of conditions, and the following 11246259Sdim * disclaimer. 12246259Sdim * 2. Redistributions in binary form must reproduce the above copyright 13255722Semaste * notice, this list of conditions and the following disclaimer in the 14246259Sdim * documentation and/or other materials provided with the distribution. 15208963Srdivacky * 16246259Sdim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17208963Srdivacky * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18208963Srdivacky * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19208963Srdivacky * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20208963Srdivacky * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21234353Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22208963Srdivacky * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23212904Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24208963Srdivacky * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25208963Srdivacky * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26276479Sdim * SUCH DAMAGE. 27276479Sdim * 28208963Srdivacky * $FreeBSD: head/sys/netgraph/ng_split.c 87599 2001-12-10 08:09:49Z obrien $ 29212904Sdim * 30246259Sdim */ 31208963Srdivacky 32208963Srdivacky#include <sys/param.h> 33210299Sed#include <sys/systm.h> 34208963Srdivacky#include <sys/errno.h> 35208963Srdivacky#include <sys/kernel.h> 36208963Srdivacky#include <sys/malloc.h> 37208963Srdivacky#include <sys/mbuf.h> 38221345Sdim#include <sys/errno.h> 39208963Srdivacky#include <sys/sockio.h> 40221345Sdim#include <sys/socket.h> 41208963Srdivacky#include <sys/syslog.h> 42249423Sdim 43234353Sdim#include <netgraph/ng_message.h> 44208963Srdivacky#include <netgraph/netgraph.h> 45280031Sdim#include <netgraph/ng_split.h> 46208963Srdivacky 47249423Sdim/* Netgraph methods */ 48234353Sdimstatic ng_constructor_t ng_split_constructor; 49261991Sdimstatic ng_shutdown_t ng_split_shutdown; 50276479Sdimstatic ng_newhook_t ng_split_newhook; 51208963Srdivackystatic ng_rcvdata_t ng_split_rcvdata; 52208963Srdivackystatic ng_disconnect_t ng_split_disconnect; 53208963Srdivacky 54226633Sdim/* Node type descriptor */ 55208963Srdivackystatic struct ng_type typestruct = { 56208963Srdivacky NG_ABI_VERSION, 57234353Sdim NG_SPLIT_NODE_TYPE, 58208963Srdivacky NULL, 59276783Sdim ng_split_constructor, 60296417Sdim NULL, 61276783Sdim ng_split_shutdown, 62276783Sdim ng_split_newhook, 63276783Sdim NULL, 64276783Sdim NULL, 65208963Srdivacky ng_split_rcvdata, 66296417Sdim ng_split_disconnect, 67208963Srdivacky NULL 68224145Sdim}; 69208963SrdivackyNETGRAPH_INIT(ng_split, &typestruct); 70234353Sdim 71296417Sdim/* Node private data */ 72208963Srdivackystruct ng_split_private { 73224145Sdim hook_p out; 74208963Srdivacky hook_p in; 75259473Sdim hook_p mixed; 76296417Sdim node_p node; /* Our netgraph node */ 77208963Srdivacky}; 78224145Sdimtypedef struct ng_split_private *priv_p; 79208963Srdivacky 80262613Sdim/************************************************************************ 81296417Sdim NETGRAPH NODE STUFF 82262613Sdim ************************************************************************/ 83262613Sdim 84262613Sdim/* 85208963Srdivacky * Constructor for a node 86296417Sdim */ 87208963Srdivackystatic int 88224145Sdimng_split_constructor(node_p node) 89218893Sdim{ 90218893Sdim priv_p priv; 91231057Sdim 92231057Sdim /* Allocate node */ 93301993Sbdrewery MALLOC(priv, priv_p, sizeof(*priv), M_NETGRAPH, M_ZERO | M_NOWAIT); 94301993Sbdrewery if (priv == NULL) 95301993Sbdrewery return (ENOMEM); 96288943Sdim bzero(priv, sizeof(*priv)); 97291495Sbdrewery 98288943Sdim /* Link together node and private info */ 99291495Sbdrewery NG_NODE_SET_PRIVATE(node, priv); 100288943Sdim priv->node = node; 101296417Sdim 102296417Sdim /* Done */ 103255722Semaste return (0); 104296417Sdim} 105255722Semaste 106296417Sdim/* 107296417Sdim * Give our ok for a hook to be added 108296417Sdim */ 109231057Sdimstatic int 110231057Sdimng_split_newhook(node_p node, hook_p hook, const char *name) 111288943Sdim{ 112296417Sdim priv_p priv = NG_NODE_PRIVATE(node); 113288943Sdim hook_p *localhook; 114288943Sdim 115288943Sdim if (strcmp(name, NG_SPLIT_HOOK_MIXED) == 0) { 116255722Semaste localhook = &priv->mixed; 117255722Semaste } else if (strcmp(name, NG_SPLIT_HOOK_IN) == 0) { 118265831Simp localhook = &priv->in; 119255722Semaste } else if (strcmp(name, NG_SPLIT_HOOK_OUT) == 0) { 120255722Semaste localhook = &priv->out; 121255722Semaste } else { 122255722Semaste return (EPFNOSUPPORT); 123255722Semaste } 124255722Semaste 125255722Semaste if (*localhook != NULL) 126255722Semaste return (EISCONN); 127255722Semaste *localhook = hook; 128255722Semaste NG_HOOK_SET_PRIVATE(hook, localhook); 129276479Sdim 130288943Sdim return (0); 131255722Semaste} 132255722Semaste 133255722Semaste/* 134255722Semaste * Recive data from a hook. 135255722Semaste */ 136288943Sdimstatic int 137288943Sdimng_split_rcvdata(hook_p hook, item_p item) 138288943Sdim{ 139288943Sdim const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); 140288943Sdim int error = 0; 141280031Sdim 142280031Sdim if (hook == priv->out) { 143255722Semaste printf("ng_split: got packet from out hook!\n"); 144255722Semaste NG_FREE_ITEM(item); 145255722Semaste error = EINVAL; 146255722Semaste } else if ((hook == priv->in) && (priv->mixed != NULL)) { 147255722Semaste NG_FWD_ITEM_HOOK(error, item, priv->mixed); 148296417Sdim } else if ((hook == priv->mixed) && (priv->out != NULL)) { 149296417Sdim NG_FWD_ITEM_HOOK(error, item, priv->out); 150255722Semaste } 151276479Sdim 152288943Sdim return (error); 153288943Sdim} 154280031Sdim 155276479Sdimstatic int 156296417Sdimng_split_shutdown(node_p node) 157296417Sdim{ 158280031Sdim const priv_p priv = NG_NODE_PRIVATE(node); 159255722Semaste 160255722Semaste NG_NODE_SET_PRIVATE(node, NULL); 161276479Sdim NG_NODE_UNREF(node); 162255722Semaste FREE(priv, M_NETGRAPH); 163255722Semaste 164255722Semaste return (0); 165255722Semaste} 166255722Semaste 167255722Semaste/* 168255722Semaste * Hook disconnection 169296417Sdim */ 170255722Semastestatic int 171255722Semasteng_split_disconnect(hook_p hook) 172255722Semaste{ 173255722Semaste hook_p *localhook = NG_HOOK_PRIVATE(hook); 174255722Semaste 175265831Simp KASSERT(localhook != NULL, ("%s: null info", __func__)); 176255722Semaste *localhook = NULL; 177246259Sdim if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0) 178208963Srdivacky && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) { 179214562Srpaulo ng_rmnode_self(NG_HOOK_NODE(hook)); 180214562Srpaulo } 181263778Sdim 182263778Sdim return (0); 183208963Srdivacky} 184