ng_split.c revision 80304
172909Sjulian/*- 272909Sjulian * 372909Sjulian * Copyright (c) 1999-2000, Vitaly V Belekhov 472909Sjulian * All rights reserved. 572909Sjulian * 672909Sjulian * Redistribution and use in source and binary forms, with or without 772909Sjulian * modification, are permitted provided that the following conditions 872909Sjulian * are met: 972909Sjulian * 1. Redistributions of source code must retain the above copyright 1072909Sjulian * notice unmodified, this list of conditions, and the following 1172909Sjulian * disclaimer. 1272909Sjulian * 2. Redistributions in binary form must reproduce the above copyright 1372909Sjulian * notice, this list of conditions and the following disclaimer in the 1472909Sjulian * documentation and/or other materials provided with the distribution. 1572909Sjulian * 1672909Sjulian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1772909Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1872909Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1972909Sjulian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2072909Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2172909Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2272909Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2372909Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2472909Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2572909Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2672909Sjulian * SUCH DAMAGE. 2772909Sjulian * 2880304Sbrooks * $FreeBSD: head/sys/netgraph/ng_split.c 80304 2001-07-24 23:33:06Z brooks $ 2972909Sjulian * 3072909Sjulian */ 3172909Sjulian 3272909Sjulian#include <sys/param.h> 3372909Sjulian#include <sys/systm.h> 3472909Sjulian#include <sys/errno.h> 3572909Sjulian#include <sys/kernel.h> 3672909Sjulian#include <sys/malloc.h> 3772909Sjulian#include <sys/mbuf.h> 3872909Sjulian#include <sys/errno.h> 3972909Sjulian#include <sys/sockio.h> 4072909Sjulian#include <sys/socket.h> 4172909Sjulian#include <sys/syslog.h> 4272909Sjulian 4372909Sjulian#include <netgraph/ng_message.h> 4472909Sjulian#include <netgraph/netgraph.h> 4572909Sjulian#include <netgraph/ng_split.h> 4672909Sjulian 4772909Sjulian/* Netgraph methods */ 4872909Sjulianstatic ng_constructor_t ng_split_constructor; 4980304Sbrooksstatic ng_shutdown_t ng_split_shutdown; 5072909Sjulianstatic ng_newhook_t ng_split_newhook; 5172909Sjulianstatic ng_rcvdata_t ng_split_rcvdata; 5272909Sjulianstatic ng_disconnect_t ng_split_disconnect; 5372909Sjulian 5472909Sjulian/* Node type descriptor */ 5572909Sjulianstatic struct ng_type typestruct = { 5672909Sjulian NG_ABI_VERSION, 5772909Sjulian NG_SPLIT_NODE_TYPE, 5872909Sjulian NULL, 5972909Sjulian ng_split_constructor, 6080304Sbrooks NULL, 6180304Sbrooks ng_split_shutdown, 6272909Sjulian ng_split_newhook, 6372909Sjulian NULL, 6480304Sbrooks NULL, 6572909Sjulian ng_split_rcvdata, 6672909Sjulian ng_split_disconnect, 6772909Sjulian NULL 6872909Sjulian}; 6972909SjulianNETGRAPH_INIT(ng_split, &typestruct); 7072909Sjulian 7172909Sjulian/* Node private data */ 7272909Sjulianstruct ng_split_private { 7380304Sbrooks hook_p out; 7480304Sbrooks hook_p in; 7580304Sbrooks hook_p mixed; 7672909Sjulian node_p node; /* Our netgraph node */ 7772909Sjulian}; 7872909Sjuliantypedef struct ng_split_private *priv_p; 7972909Sjulian 8072909Sjulian/************************************************************************ 8172909Sjulian NETGRAPH NODE STUFF 8272909Sjulian ************************************************************************/ 8372909Sjulian 8472909Sjulian/* 8572909Sjulian * Constructor for a node 8672909Sjulian */ 8772909Sjulianstatic int 8872909Sjulianng_split_constructor(node_p node) 8972909Sjulian{ 9080304Sbrooks priv_p priv; 9172909Sjulian 9272909Sjulian /* Allocate node */ 9372909Sjulian MALLOC(priv, priv_p, sizeof(*priv), M_NETGRAPH, M_ZERO | M_NOWAIT); 9472909Sjulian if (priv == NULL) 9572909Sjulian return (ENOMEM); 9672909Sjulian bzero(priv, sizeof(*priv)); 9772909Sjulian 9872909Sjulian /* Link together node and private info */ 9972909Sjulian NG_NODE_SET_PRIVATE(node, priv); 10072909Sjulian priv->node = node; 10172909Sjulian 10272909Sjulian /* Done */ 10372909Sjulian return (0); 10472909Sjulian} 10572909Sjulian 10672909Sjulian/* 10772909Sjulian * Give our ok for a hook to be added 10872909Sjulian */ 10972909Sjulianstatic int 11072909Sjulianng_split_newhook(node_p node, hook_p hook, const char *name) 11172909Sjulian{ 11280304Sbrooks priv_p priv = NG_NODE_PRIVATE(node); 11380304Sbrooks hook_p *localhook; 11472909Sjulian 11580304Sbrooks if (strcmp(name, NG_SPLIT_HOOK_MIXED) == 0) { 11680304Sbrooks localhook = &priv->mixed; 11780304Sbrooks } else if (strcmp(name, NG_SPLIT_HOOK_IN) == 0) { 11880304Sbrooks localhook = &priv->in; 11980304Sbrooks } else if (strcmp(name, NG_SPLIT_HOOK_OUT) == 0) { 12080304Sbrooks localhook = &priv->out; 12172909Sjulian } else { 12280304Sbrooks return (EPFNOSUPPORT); 12372909Sjulian } 12472909Sjulian 12580304Sbrooks if (*localhook != NULL) 12680304Sbrooks return (EISCONN); 12780304Sbrooks *localhook = hook; 12880304Sbrooks NG_HOOK_SET_PRIVATE(hook, localhook); 12980304Sbrooks 13072909Sjulian return (0); 13172909Sjulian} 13272909Sjulian 13372909Sjulian/* 13472909Sjulian * Recive data from a hook. 13572909Sjulian */ 13672909Sjulianstatic int 13772909Sjulianng_split_rcvdata(hook_p hook, item_p item) 13872909Sjulian{ 13980304Sbrooks const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); 14080304Sbrooks int error = 0; 14172909Sjulian 14280304Sbrooks if (hook == priv->out) { 14380304Sbrooks printf("ng_split: got packet from out hook!\n"); 14472909Sjulian NG_FREE_ITEM(item); 14580304Sbrooks error = EINVAL; 14680304Sbrooks } else if ((hook == priv->in) && (priv->mixed != NULL)) { 14772909Sjulian NG_FWD_ITEM_HOOK(error, item, priv->mixed); 14880304Sbrooks } else if ((hook == priv->mixed) && (priv->out != NULL)) { 14980304Sbrooks NG_FWD_ITEM_HOOK(error, item, priv->out); 15072909Sjulian } 15180304Sbrooks 15272909Sjulian return (error); 15372909Sjulian} 15472909Sjulian 15572909Sjulianstatic int 15680304Sbrooksng_split_shutdown(node_p node) 15772909Sjulian{ 15880304Sbrooks const priv_p priv = NG_NODE_PRIVATE(node); 15972909Sjulian 16072909Sjulian NG_NODE_SET_PRIVATE(node, NULL); 16172909Sjulian NG_NODE_UNREF(node); 16272909Sjulian FREE(priv, M_NETGRAPH); 16372909Sjulian 16472909Sjulian return (0); 16572909Sjulian} 16672909Sjulian 16772909Sjulian/* 16872909Sjulian * Hook disconnection 16972909Sjulian */ 17072909Sjulianstatic int 17172909Sjulianng_split_disconnect(hook_p hook) 17272909Sjulian{ 17380304Sbrooks hook_p *localhook = NG_HOOK_PRIVATE(hook); 17480304Sbrooks 17580304Sbrooks KASSERT(localhook != NULL, ("%s: null info", __FUNCTION__)); 17680304Sbrooks *localhook = NULL; 17772909Sjulian if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0) 17880304Sbrooks && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) { 17980304Sbrooks ng_rmnode_self(NG_HOOK_NODE(hook)); 18072909Sjulian } 18172909Sjulian 18272909Sjulian return (0); 18372909Sjulian} 184