ng_split.c revision 149577
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 149577 2005-08-29 13:47:08Z glebius $ 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 = { 56129823Sjulian .version = NG_ABI_VERSION, 57129823Sjulian .name = NG_SPLIT_NODE_TYPE, 58129823Sjulian .constructor = ng_split_constructor, 59129823Sjulian .shutdown = ng_split_shutdown, 60129823Sjulian .newhook = ng_split_newhook, 61129823Sjulian .rcvdata = ng_split_rcvdata, 62129823Sjulian .disconnect = ng_split_disconnect, 6372909Sjulian}; 6472909SjulianNETGRAPH_INIT(ng_split, &typestruct); 6572909Sjulian 6672909Sjulian/* Node private data */ 6772909Sjulianstruct ng_split_private { 6880304Sbrooks hook_p out; 6980304Sbrooks hook_p in; 7080304Sbrooks hook_p mixed; 7172909Sjulian node_p node; /* Our netgraph node */ 7272909Sjulian}; 7372909Sjuliantypedef struct ng_split_private *priv_p; 7472909Sjulian 7572909Sjulian/************************************************************************ 7672909Sjulian NETGRAPH NODE STUFF 7772909Sjulian ************************************************************************/ 7872909Sjulian 7972909Sjulian/* 8072909Sjulian * Constructor for a node 8172909Sjulian */ 8272909Sjulianstatic int 8372909Sjulianng_split_constructor(node_p node) 8472909Sjulian{ 8580304Sbrooks priv_p priv; 8672909Sjulian 8772909Sjulian /* Allocate node */ 8872909Sjulian MALLOC(priv, priv_p, sizeof(*priv), M_NETGRAPH, M_ZERO | M_NOWAIT); 8972909Sjulian if (priv == NULL) 9072909Sjulian return (ENOMEM); 9172909Sjulian 9272909Sjulian /* Link together node and private info */ 9372909Sjulian NG_NODE_SET_PRIVATE(node, priv); 9472909Sjulian priv->node = node; 9572909Sjulian 9672909Sjulian /* Done */ 9772909Sjulian return (0); 9872909Sjulian} 9972909Sjulian 10072909Sjulian/* 10172909Sjulian * Give our ok for a hook to be added 10272909Sjulian */ 10372909Sjulianstatic int 10472909Sjulianng_split_newhook(node_p node, hook_p hook, const char *name) 10572909Sjulian{ 10680304Sbrooks priv_p priv = NG_NODE_PRIVATE(node); 10780304Sbrooks hook_p *localhook; 10872909Sjulian 10980304Sbrooks if (strcmp(name, NG_SPLIT_HOOK_MIXED) == 0) { 11080304Sbrooks localhook = &priv->mixed; 11180304Sbrooks } else if (strcmp(name, NG_SPLIT_HOOK_IN) == 0) { 11280304Sbrooks localhook = &priv->in; 11380304Sbrooks } else if (strcmp(name, NG_SPLIT_HOOK_OUT) == 0) { 11480304Sbrooks localhook = &priv->out; 115146544Sglebius } else 116146544Sglebius return (EINVAL); 11772909Sjulian 11880304Sbrooks if (*localhook != NULL) 11980304Sbrooks return (EISCONN); 12080304Sbrooks *localhook = hook; 12180304Sbrooks NG_HOOK_SET_PRIVATE(hook, localhook); 12280304Sbrooks 12372909Sjulian return (0); 12472909Sjulian} 12572909Sjulian 12672909Sjulian/* 12772909Sjulian * Recive data from a hook. 12872909Sjulian */ 12972909Sjulianstatic int 13072909Sjulianng_split_rcvdata(hook_p hook, item_p item) 13172909Sjulian{ 13280304Sbrooks const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); 13380304Sbrooks int error = 0; 13472909Sjulian 13580304Sbrooks if (hook == priv->out) { 13680304Sbrooks printf("ng_split: got packet from out hook!\n"); 13772909Sjulian NG_FREE_ITEM(item); 13880304Sbrooks error = EINVAL; 13980304Sbrooks } else if ((hook == priv->in) && (priv->mixed != NULL)) { 14072909Sjulian NG_FWD_ITEM_HOOK(error, item, priv->mixed); 14180304Sbrooks } else if ((hook == priv->mixed) && (priv->out != NULL)) { 14280304Sbrooks NG_FWD_ITEM_HOOK(error, item, priv->out); 14372909Sjulian } 14480304Sbrooks 145149577Sglebius if (item) 146149577Sglebius NG_FREE_ITEM(item); 147149577Sglebius 14872909Sjulian return (error); 14972909Sjulian} 15072909Sjulian 15172909Sjulianstatic int 15280304Sbrooksng_split_shutdown(node_p node) 15372909Sjulian{ 15480304Sbrooks const priv_p priv = NG_NODE_PRIVATE(node); 15572909Sjulian 15672909Sjulian NG_NODE_SET_PRIVATE(node, NULL); 15772909Sjulian NG_NODE_UNREF(node); 15872909Sjulian FREE(priv, M_NETGRAPH); 15972909Sjulian 16072909Sjulian return (0); 16172909Sjulian} 16272909Sjulian 16372909Sjulian/* 16472909Sjulian * Hook disconnection 16572909Sjulian */ 16672909Sjulianstatic int 16772909Sjulianng_split_disconnect(hook_p hook) 16872909Sjulian{ 16980304Sbrooks hook_p *localhook = NG_HOOK_PRIVATE(hook); 17080304Sbrooks 17187599Sobrien KASSERT(localhook != NULL, ("%s: null info", __func__)); 17280304Sbrooks *localhook = NULL; 17372909Sjulian if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0) 17480304Sbrooks && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) { 17580304Sbrooks ng_rmnode_self(NG_HOOK_NODE(hook)); 17672909Sjulian } 17772909Sjulian 17872909Sjulian return (0); 17972909Sjulian} 180