1b462702fSRuslan Ermilov /*- 2b462702fSRuslan Ermilov * Copyright (c) 2004 Ruslan Ermilov 3b462702fSRuslan Ermilov * All rights reserved. 4b462702fSRuslan Ermilov * 5b462702fSRuslan Ermilov * Redistribution and use in source and binary forms, with or without 6b462702fSRuslan Ermilov * modification, are permitted provided that the following conditions 7b462702fSRuslan Ermilov * are met: 8b462702fSRuslan Ermilov * 1. Redistributions of source code must retain the above copyright 9b462702fSRuslan Ermilov * notice, this list of conditions and the following disclaimer. 10b462702fSRuslan Ermilov * 2. Redistributions in binary form must reproduce the above copyright 11b462702fSRuslan Ermilov * notice, this list of conditions and the following disclaimer in the 12b462702fSRuslan Ermilov * documentation and/or other materials provided with the distribution. 13b462702fSRuslan Ermilov * 14b462702fSRuslan Ermilov * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15b462702fSRuslan Ermilov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16b462702fSRuslan Ermilov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17b462702fSRuslan Ermilov * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18b462702fSRuslan Ermilov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19b462702fSRuslan Ermilov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20b462702fSRuslan Ermilov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21b462702fSRuslan Ermilov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22b462702fSRuslan Ermilov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23b462702fSRuslan Ermilov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24b462702fSRuslan Ermilov * SUCH DAMAGE. 25b462702fSRuslan Ermilov * 26b462702fSRuslan Ermilov * $FreeBSD$ 27b462702fSRuslan Ermilov */ 28b462702fSRuslan Ermilov 29b462702fSRuslan Ermilov #include <sys/param.h> 30b462702fSRuslan Ermilov #include <sys/errno.h> 31b462702fSRuslan Ermilov #include <sys/kernel.h> 32b462702fSRuslan Ermilov #include <sys/mbuf.h> 33b462702fSRuslan Ermilov #include <sys/systm.h> 34b462702fSRuslan Ermilov 35b462702fSRuslan Ermilov #include <netgraph/ng_message.h> 36b462702fSRuslan Ermilov #include <netgraph/ng_hub.h> 37b462702fSRuslan Ermilov #include <netgraph/netgraph.h> 38b462702fSRuslan Ermilov 39b462702fSRuslan Ermilov static ng_constructor_t ng_hub_constructor; 40b462702fSRuslan Ermilov static ng_rcvdata_t ng_hub_rcvdata; 41b462702fSRuslan Ermilov static ng_disconnect_t ng_hub_disconnect; 42b462702fSRuslan Ermilov 43b462702fSRuslan Ermilov static struct ng_type ng_hub_typestruct = { 44b462702fSRuslan Ermilov .version = NG_ABI_VERSION, 45b462702fSRuslan Ermilov .name = NG_HUB_NODE_TYPE, 46b462702fSRuslan Ermilov .constructor = ng_hub_constructor, 47b462702fSRuslan Ermilov .rcvdata = ng_hub_rcvdata, 48b462702fSRuslan Ermilov .disconnect = ng_hub_disconnect, 49b462702fSRuslan Ermilov }; 50b462702fSRuslan Ermilov NETGRAPH_INIT(hub, &ng_hub_typestruct); 51b462702fSRuslan Ermilov 52b462702fSRuslan Ermilov 53b462702fSRuslan Ermilov static int 54b462702fSRuslan Ermilov ng_hub_constructor(node_p node) 55b462702fSRuslan Ermilov { 56b462702fSRuslan Ermilov 57b462702fSRuslan Ermilov return (0); 58b462702fSRuslan Ermilov } 59b462702fSRuslan Ermilov 60b462702fSRuslan Ermilov static int 61b462702fSRuslan Ermilov ng_hub_rcvdata(hook_p hook, item_p item) 62b462702fSRuslan Ermilov { 63b462702fSRuslan Ermilov const node_p node = NG_HOOK_NODE(hook); 64b462702fSRuslan Ermilov int error = 0; 65b462702fSRuslan Ermilov hook_p hook2; 66b462702fSRuslan Ermilov struct mbuf * const m = NGI_M(item), *m2; 67b462702fSRuslan Ermilov int nhooks; 68b462702fSRuslan Ermilov 69b462702fSRuslan Ermilov if ((nhooks = NG_NODE_NUMHOOKS(node)) == 1) { 70b462702fSRuslan Ermilov NG_FREE_ITEM(item); 71b462702fSRuslan Ermilov return (0); 72b462702fSRuslan Ermilov } 73b462702fSRuslan Ermilov LIST_FOREACH(hook2, &node->nd_hooks, hk_hooks) { 74b462702fSRuslan Ermilov if (hook2 == hook) 75b462702fSRuslan Ermilov continue; 76b462702fSRuslan Ermilov if (--nhooks == 1) 77b462702fSRuslan Ermilov NG_FWD_ITEM_HOOK(error, item, hook2); 78b462702fSRuslan Ermilov else { 79b462702fSRuslan Ermilov if ((m2 = m_dup(m, M_DONTWAIT)) == NULL) { 80b462702fSRuslan Ermilov NG_FREE_ITEM(item); 81b462702fSRuslan Ermilov return (ENOBUFS); 82b462702fSRuslan Ermilov } 833ca24c28SJulian Elischer NG_SEND_DATA_ONLY(error, hook2, m2); 84b462702fSRuslan Ermilov if (error) 85dfa515f2SRuslan Ermilov continue; /* don't give up */ 86b462702fSRuslan Ermilov } 87b462702fSRuslan Ermilov } 88b462702fSRuslan Ermilov 89b462702fSRuslan Ermilov return (error); 90b462702fSRuslan Ermilov } 91b462702fSRuslan Ermilov 92b462702fSRuslan Ermilov static int 93b462702fSRuslan Ermilov ng_hub_disconnect(hook_p hook) 94b462702fSRuslan Ermilov { 95b462702fSRuslan Ermilov 96b462702fSRuslan Ermilov if (NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0 && 97b462702fSRuslan Ermilov NG_NODE_IS_VALID(NG_HOOK_NODE(hook))) 98b462702fSRuslan Ermilov ng_rmnode_self(NG_HOOK_NODE(hook)); 99b462702fSRuslan Ermilov return (0); 100b462702fSRuslan Ermilov } 101