1178c5ad4SNuno Antunes /*-
2178c5ad4SNuno Antunes * Copyright (c) 2004 Ruslan Ermilov
3178c5ad4SNuno Antunes * All rights reserved.
4178c5ad4SNuno Antunes *
5178c5ad4SNuno Antunes * Redistribution and use in source and binary forms, with or without
6178c5ad4SNuno Antunes * modification, are permitted provided that the following conditions
7178c5ad4SNuno Antunes * are met:
8178c5ad4SNuno Antunes * 1. Redistributions of source code must retain the above copyright
9178c5ad4SNuno Antunes * notice, this list of conditions and the following disclaimer.
10178c5ad4SNuno Antunes * 2. Redistributions in binary form must reproduce the above copyright
11178c5ad4SNuno Antunes * notice, this list of conditions and the following disclaimer in the
12178c5ad4SNuno Antunes * documentation and/or other materials provided with the distribution.
13178c5ad4SNuno Antunes *
14178c5ad4SNuno Antunes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15178c5ad4SNuno Antunes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16178c5ad4SNuno Antunes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17178c5ad4SNuno Antunes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18178c5ad4SNuno Antunes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19178c5ad4SNuno Antunes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20178c5ad4SNuno Antunes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21178c5ad4SNuno Antunes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22178c5ad4SNuno Antunes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23178c5ad4SNuno Antunes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24178c5ad4SNuno Antunes * SUCH DAMAGE.
25178c5ad4SNuno Antunes *
26178c5ad4SNuno Antunes * $FreeBSD: src/sys/netgraph/ng_hub.c,v 1.3 2004/06/26 22:24:16 julian Exp $
27178c5ad4SNuno Antunes */
28178c5ad4SNuno Antunes
29178c5ad4SNuno Antunes #include <sys/param.h>
30178c5ad4SNuno Antunes #include <sys/errno.h>
31178c5ad4SNuno Antunes #include <sys/kernel.h>
32*805c8e8eSzrj #include <sys/malloc.h>
33178c5ad4SNuno Antunes #include <sys/mbuf.h>
34178c5ad4SNuno Antunes #include <sys/systm.h>
35178c5ad4SNuno Antunes
36178c5ad4SNuno Antunes #include <netgraph7/ng_message.h>
37178c5ad4SNuno Antunes #include <netgraph7/netgraph.h>
38178c5ad4SNuno Antunes #include "ng_hub.h"
39178c5ad4SNuno Antunes
40178c5ad4SNuno Antunes static ng_constructor_t ng_hub_constructor;
41178c5ad4SNuno Antunes static ng_rcvdata_t ng_hub_rcvdata;
42178c5ad4SNuno Antunes static ng_disconnect_t ng_hub_disconnect;
43178c5ad4SNuno Antunes
44178c5ad4SNuno Antunes static struct ng_type ng_hub_typestruct = {
45178c5ad4SNuno Antunes .version = NG_ABI_VERSION,
46178c5ad4SNuno Antunes .name = NG_HUB_NODE_TYPE,
47178c5ad4SNuno Antunes .constructor = ng_hub_constructor,
48178c5ad4SNuno Antunes .rcvdata = ng_hub_rcvdata,
49178c5ad4SNuno Antunes .disconnect = ng_hub_disconnect,
50178c5ad4SNuno Antunes };
51178c5ad4SNuno Antunes NETGRAPH_INIT(hub, &ng_hub_typestruct);
52178c5ad4SNuno Antunes
53178c5ad4SNuno Antunes
54178c5ad4SNuno Antunes static int
ng_hub_constructor(node_p node)55178c5ad4SNuno Antunes ng_hub_constructor(node_p node)
56178c5ad4SNuno Antunes {
57178c5ad4SNuno Antunes
58178c5ad4SNuno Antunes return (0);
59178c5ad4SNuno Antunes }
60178c5ad4SNuno Antunes
61178c5ad4SNuno Antunes static int
ng_hub_rcvdata(hook_p hook,item_p item)62178c5ad4SNuno Antunes ng_hub_rcvdata(hook_p hook, item_p item)
63178c5ad4SNuno Antunes {
64178c5ad4SNuno Antunes const node_p node = NG_HOOK_NODE(hook);
65178c5ad4SNuno Antunes int error = 0;
66178c5ad4SNuno Antunes hook_p hook2;
67178c5ad4SNuno Antunes struct mbuf * const m = NGI_M(item), *m2;
68178c5ad4SNuno Antunes int nhooks;
69178c5ad4SNuno Antunes
70178c5ad4SNuno Antunes if ((nhooks = NG_NODE_NUMHOOKS(node)) == 1) {
71178c5ad4SNuno Antunes NG_FREE_ITEM(item);
72178c5ad4SNuno Antunes return (0);
73178c5ad4SNuno Antunes }
74178c5ad4SNuno Antunes LIST_FOREACH(hook2, &node->nd_hooks, hk_hooks) {
75178c5ad4SNuno Antunes if (hook2 == hook)
76178c5ad4SNuno Antunes continue;
77178c5ad4SNuno Antunes if (--nhooks == 1)
78178c5ad4SNuno Antunes NG_FWD_ITEM_HOOK(error, item, hook2);
79178c5ad4SNuno Antunes else {
80b5523eacSSascha Wildner if ((m2 = m_dup(m, M_NOWAIT)) == NULL) {
81178c5ad4SNuno Antunes NG_FREE_ITEM(item);
82178c5ad4SNuno Antunes return (ENOBUFS);
83178c5ad4SNuno Antunes }
84178c5ad4SNuno Antunes NG_SEND_DATA_ONLY(error, hook2, m2);
85178c5ad4SNuno Antunes if (error)
86178c5ad4SNuno Antunes continue; /* don't give up */
87178c5ad4SNuno Antunes }
88178c5ad4SNuno Antunes }
89178c5ad4SNuno Antunes
90178c5ad4SNuno Antunes return (error);
91178c5ad4SNuno Antunes }
92178c5ad4SNuno Antunes
93178c5ad4SNuno Antunes static int
ng_hub_disconnect(hook_p hook)94178c5ad4SNuno Antunes ng_hub_disconnect(hook_p hook)
95178c5ad4SNuno Antunes {
96178c5ad4SNuno Antunes
97178c5ad4SNuno Antunes if (NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0 &&
98178c5ad4SNuno Antunes NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))
99178c5ad4SNuno Antunes ng_rmnode_self(NG_HOOK_NODE(hook));
100178c5ad4SNuno Antunes return (0);
101178c5ad4SNuno Antunes }
102