ng_split.c revision 80304
1258945Sroberto/*- 2280849Scy * 3258945Sroberto * Copyright (c) 1999-2000, Vitaly V Belekhov 4258945Sroberto * All rights reserved. 5258945Sroberto * 6258945Sroberto * Redistribution and use in source and binary forms, with or without 7258945Sroberto * modification, are permitted provided that the following conditions 8258945Sroberto * are met: 9258945Sroberto * 1. Redistributions of source code must retain the above copyright 10258945Sroberto * notice unmodified, this list of conditions, and the following 11258945Sroberto * disclaimer. 12258945Sroberto * 2. Redistributions in binary form must reproduce the above copyright 13258945Sroberto * notice, this list of conditions and the following disclaimer in the 14258945Sroberto * documentation and/or other materials provided with the distribution. 15258945Sroberto * 16258945Sroberto * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17258945Sroberto * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18280849Scy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19258945Sroberto * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20258945Sroberto * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21258945Sroberto * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22258945Sroberto * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23258945Sroberto * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24258945Sroberto * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25258945Sroberto * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26258945Sroberto * SUCH DAMAGE. 27258945Sroberto * 28258945Sroberto * $FreeBSD: head/sys/netgraph/ng_split.c 80304 2001-07-24 23:33:06Z brooks $ 29258945Sroberto * 30258945Sroberto */ 31258945Sroberto 32258945Sroberto#include <sys/param.h> 33258945Sroberto#include <sys/systm.h> 34258945Sroberto#include <sys/errno.h> 35258945Sroberto#include <sys/kernel.h> 36258945Sroberto#include <sys/malloc.h> 37258945Sroberto#include <sys/mbuf.h> 38258945Sroberto#include <sys/errno.h> 39258945Sroberto#include <sys/sockio.h> 40258945Sroberto#include <sys/socket.h> 41258945Sroberto#include <sys/syslog.h> 42258945Sroberto 43258945Sroberto#include <netgraph/ng_message.h> 44258945Sroberto#include <netgraph/netgraph.h> 45258945Sroberto#include <netgraph/ng_split.h> 46258945Sroberto 47258945Sroberto/* Netgraph methods */ 48258945Srobertostatic ng_constructor_t ng_split_constructor; 49258945Srobertostatic ng_shutdown_t ng_split_shutdown; 50258945Srobertostatic ng_newhook_t ng_split_newhook; 51258945Srobertostatic ng_rcvdata_t ng_split_rcvdata; 52258945Srobertostatic ng_disconnect_t ng_split_disconnect; 53258945Sroberto 54258945Sroberto/* Node type descriptor */ 55258945Srobertostatic struct ng_type typestruct = { 56258945Sroberto NG_ABI_VERSION, 57258945Sroberto NG_SPLIT_NODE_TYPE, 58258945Sroberto NULL, 59258945Sroberto ng_split_constructor, 60258945Sroberto NULL, 61258945Sroberto ng_split_shutdown, 62258945Sroberto ng_split_newhook, 63258945Sroberto NULL, 64258945Sroberto NULL, 65258945Sroberto ng_split_rcvdata, 66258945Sroberto ng_split_disconnect, 67258945Sroberto NULL 68258945Sroberto}; 69258945SrobertoNETGRAPH_INIT(ng_split, &typestruct); 70258945Sroberto 71258945Sroberto/* Node private data */ 72258945Srobertostruct ng_split_private { 73258945Sroberto hook_p out; 74258945Sroberto hook_p in; 75258945Sroberto hook_p mixed; 76258945Sroberto node_p node; /* Our netgraph node */ 77258945Sroberto}; 78258945Srobertotypedef struct ng_split_private *priv_p; 79258945Sroberto 80258945Sroberto/************************************************************************ 81258945Sroberto NETGRAPH NODE STUFF 82258945Sroberto ************************************************************************/ 83258945Sroberto 84258945Sroberto/* 85258945Sroberto * Constructor for a node 86258945Sroberto */ 87258945Srobertostatic int 88258945Srobertong_split_constructor(node_p node) 89258945Sroberto{ 90258945Sroberto priv_p priv; 91258945Sroberto 92258945Sroberto /* Allocate node */ 93258945Sroberto MALLOC(priv, priv_p, sizeof(*priv), M_NETGRAPH, M_ZERO | M_NOWAIT); 94258945Sroberto if (priv == NULL) 95258945Sroberto return (ENOMEM); 96258945Sroberto bzero(priv, sizeof(*priv)); 97258945Sroberto 98258945Sroberto /* Link together node and private info */ 99258945Sroberto NG_NODE_SET_PRIVATE(node, priv); 100258945Sroberto priv->node = node; 101258945Sroberto 102258945Sroberto /* Done */ 103258945Sroberto return (0); 104258945Sroberto} 105258945Sroberto 106258945Sroberto/* 107258945Sroberto * Give our ok for a hook to be added 108258945Sroberto */ 109258945Srobertostatic int 110258945Srobertong_split_newhook(node_p node, hook_p hook, const char *name) 111258945Sroberto{ 112258945Sroberto priv_p priv = NG_NODE_PRIVATE(node); 113258945Sroberto hook_p *localhook; 114258945Sroberto 115258945Sroberto if (strcmp(name, NG_SPLIT_HOOK_MIXED) == 0) { 116258945Sroberto localhook = &priv->mixed; 117258945Sroberto } else if (strcmp(name, NG_SPLIT_HOOK_IN) == 0) { 118258945Sroberto localhook = &priv->in; 119258945Sroberto } else if (strcmp(name, NG_SPLIT_HOOK_OUT) == 0) { 120258945Sroberto localhook = &priv->out; 121258945Sroberto } else { 122258945Sroberto return (EPFNOSUPPORT); 123258945Sroberto } 124258945Sroberto 125258945Sroberto if (*localhook != NULL) 126258945Sroberto return (EISCONN); 127258945Sroberto *localhook = hook; 128258945Sroberto NG_HOOK_SET_PRIVATE(hook, localhook); 129258945Sroberto 130258945Sroberto return (0); 131258945Sroberto} 132258945Sroberto 133258945Sroberto/* 134258945Sroberto * Recive data from a hook. 135258945Sroberto */ 136258945Srobertostatic int 137258945Srobertong_split_rcvdata(hook_p hook, item_p item) 138258945Sroberto{ 139258945Sroberto const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); 140258945Sroberto int error = 0; 141258945Sroberto 142258945Sroberto if (hook == priv->out) { 143258945Sroberto printf("ng_split: got packet from out hook!\n"); 144258945Sroberto NG_FREE_ITEM(item); 145258945Sroberto error = EINVAL; 146258945Sroberto } else if ((hook == priv->in) && (priv->mixed != NULL)) { 147258945Sroberto NG_FWD_ITEM_HOOK(error, item, priv->mixed); 148258945Sroberto } else if ((hook == priv->mixed) && (priv->out != NULL)) { 149258945Sroberto NG_FWD_ITEM_HOOK(error, item, priv->out); 150258945Sroberto } 151258945Sroberto 152258945Sroberto return (error); 153258945Sroberto} 154258945Sroberto 155258945Srobertostatic int 156258945Srobertong_split_shutdown(node_p node) 157258945Sroberto{ 158258945Sroberto const priv_p priv = NG_NODE_PRIVATE(node); 159258945Sroberto 160258945Sroberto NG_NODE_SET_PRIVATE(node, NULL); 161258945Sroberto NG_NODE_UNREF(node); 162258945Sroberto FREE(priv, M_NETGRAPH); 163258945Sroberto 164258945Sroberto return (0); 165258945Sroberto} 166258945Sroberto 167258945Sroberto/* 168258945Sroberto * Hook disconnection 169258945Sroberto */ 170258945Srobertostatic int 171258945Srobertong_split_disconnect(hook_p hook) 172258945Sroberto{ 173258945Sroberto hook_p *localhook = NG_HOOK_PRIVATE(hook); 174258945Sroberto 175258945Sroberto KASSERT(localhook != NULL, ("%s: null info", __FUNCTION__)); 176258945Sroberto *localhook = NULL; 177258945Sroberto if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0) 178258945Sroberto && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) { 179258945Sroberto ng_rmnode_self(NG_HOOK_NODE(hook)); 180258945Sroberto } 181258945Sroberto 182258945Sroberto return (0); 183258945Sroberto} 184258945Sroberto