summaryrefslogtreecommitdiffstats
path: root/sys/netgraph/ng_hub.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netgraph/ng_hub.c')
-rw-r--r--sys/netgraph/ng_hub.c74
1 files changed, 73 insertions, 1 deletions
diff --git a/sys/netgraph/ng_hub.c b/sys/netgraph/ng_hub.c
index ba298e5..0770745 100644
--- a/sys/netgraph/ng_hub.c
+++ b/sys/netgraph/ng_hub.c
@@ -36,16 +36,46 @@
#include <netgraph/ng_hub.h>
#include <netgraph/netgraph.h>
+#ifdef NG_SEPARATE_MALLOC
+MALLOC_DEFINE(M_NETGRAPH_HUB, "netgraph_hub", "netgraph hub node");
+#else
+#define M_NETGRAPH_HUB M_NETGRAPH
+#endif
+
+/* Per-node private data */
+struct ng_hub_private {
+ int persistent; /* can exist w/o hooks */
+};
+typedef struct ng_hub_private *priv_p;
+
+/* Netgraph node methods */
static ng_constructor_t ng_hub_constructor;
+static ng_rcvmsg_t ng_hub_rcvmsg;
+static ng_shutdown_t ng_hub_shutdown;
static ng_rcvdata_t ng_hub_rcvdata;
static ng_disconnect_t ng_hub_disconnect;
+/* List of commands and how to convert arguments to/from ASCII */
+static const struct ng_cmdlist ng_hub_cmdlist[] = {
+ {
+ NGM_HUB_COOKIE,
+ NGM_HUB_SET_PERSISTENT,
+ "setpersistent",
+ NULL,
+ NULL
+ },
+ { 0 }
+};
+
static struct ng_type ng_hub_typestruct = {
.version = NG_ABI_VERSION,
.name = NG_HUB_NODE_TYPE,
.constructor = ng_hub_constructor,
+ .rcvmsg = ng_hub_rcvmsg,
+ .shutdown = ng_hub_shutdown,
.rcvdata = ng_hub_rcvdata,
.disconnect = ng_hub_disconnect,
+ .cmdlist = ng_hub_cmdlist,
};
NETGRAPH_INIT(hub, &ng_hub_typestruct);
@@ -53,10 +83,39 @@ NETGRAPH_INIT(hub, &ng_hub_typestruct);
static int
ng_hub_constructor(node_p node)
{
+ priv_p priv;
+
+ /* Allocate and initialize private info */
+ priv = malloc(sizeof(*priv), M_NETGRAPH_HUB, M_NOWAIT | M_ZERO);
+ if (priv == NULL)
+ return (ENOMEM);
+ NG_NODE_SET_PRIVATE(node, priv);
return (0);
}
+/*
+ * Receive a control message
+ */
+static int
+ng_hub_rcvmsg(node_p node, item_p item, hook_p lasthook)
+{
+ const priv_p priv = NG_NODE_PRIVATE(node);
+ int error = 0;
+ struct ng_mesg *msg;
+
+ NGI_GET_MSG(item, msg);
+ if (msg->header.typecookie == NGM_HUB_COOKIE &&
+ msg->header.cmd == NGM_HUB_SET_PERSISTENT) {
+ priv->persistent = 1;
+ } else {
+ error = EINVAL;
+ }
+
+ NG_FREE_MSG(msg);
+ return (error);
+}
+
static int
ng_hub_rcvdata(hook_p hook, item_p item)
{
@@ -89,12 +148,25 @@ ng_hub_rcvdata(hook_p hook, item_p item)
return (error);
}
+/*
+ * Shutdown node
+ */
+static int
+ng_hub_shutdown(node_p node)
+{
+ const priv_p priv = NG_NODE_PRIVATE(node);
+
+ free(priv, M_NETGRAPH_HUB);
+ return (0);
+}
+
static int
ng_hub_disconnect(hook_p hook)
{
+ const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
if (NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0 &&
- NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))
+ NG_NODE_IS_VALID(NG_HOOK_NODE(hook)) && !priv->persistent)
ng_rmnode_self(NG_HOOK_NODE(hook));
return (0);
}
OpenPOWER on IntegriCloud