summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzec <zec@FreeBSD.org>2010-05-16 14:51:36 +0000
committerzec <zec@FreeBSD.org>2010-05-16 14:51:36 +0000
commitc779c4cdfde6c60be24c795ccab20cb548f9ab2b (patch)
tree9ab65eb8d614aa5b752927e84085a05085124f08
parent5eb9806c00e622fcca05d691aa173f5da5b6e673 (diff)
downloadFreeBSD-src-c779c4cdfde6c60be24c795ccab20cb548f9ab2b.zip
FreeBSD-src-c779c4cdfde6c60be24c795ccab20cb548f9ab2b.tar.gz
MFC r207680:
Add an optional "persistent" flag to ng_hub and ng_bridge, which if set, disables automatic node shutdown when the last hook gets disconnected. Reviewed by: julian
-rw-r--r--share/man/man4/ng_bridge.410
-rw-r--r--share/man/man4/ng_hub.415
-rw-r--r--sys/netgraph/ng_bridge.c18
-rw-r--r--sys/netgraph/ng_bridge.h1
-rw-r--r--sys/netgraph/ng_hub.c74
-rw-r--r--sys/netgraph/ng_hub.h5
6 files changed, 115 insertions, 8 deletions
diff --git a/share/man/man4/ng_bridge.4 b/share/man/man4/ng_bridge.4
index 3b1dd71..8884e33 100644
--- a/share/man/man4/ng_bridge.4
+++ b/share/man/man4/ng_bridge.4
@@ -34,7 +34,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 31, 2000
+.Dd May 5, 2010
.Dt NG_BRIDGE 4
.Os
.Sh NAME
@@ -181,11 +181,17 @@ but also atomically clears the statistics as well.
.It Dv NGM_BRIDGE_GET_TABLE
Returns the current host mapping table used to direct packets, in a
.Dv "struct ng_bridge_host_ary" .
+.It Dv NGM_BRIDGE_SET_PERSISTENT
+This command sets the persistent flag on the node, and takes no arguments.
.El
.Sh SHUTDOWN
This node shuts down upon receipt of a
.Dv NGM_SHUTDOWN
-control message, or when all hooks have been disconnected.
+control message, or when all hooks have been disconnected. Setting the
+persistent flag via a
+.Dv NGM_BRIDGE_SET_PERSISTENT
+control message disables automatic node shutdown when the last hook gets
+disconnected.
.Sh FILES
.Bl -tag -width XXXXXXXX -compact
.It Pa /usr/share/examples/netgraph/ether.bridge
diff --git a/share/man/man4/ng_hub.4 b/share/man/man4/ng_hub.4
index a1ad068..c52aba0 100644
--- a/share/man/man4/ng_hub.4
+++ b/share/man/man4/ng_hub.4
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 17, 2004
+.Dd May 5, 2010
.Dt NG_HUB 4
.Os
.Sh NAME
@@ -45,11 +45,20 @@ A
node accepts any request to connect, regardless of the hook name,
as long as the name is unique.
.Sh CONTROL MESSAGES
-This node type supports only the generic control messages.
+This node type supports the generic control messages, plus the
+following:
+.Bl -tag -width foo
+.It Dv NGM_HUB_SET_PERSISTENT
+This command sets the persistent flag on the node, and takes no arguments.
+.El
.Sh SHUTDOWN
This node shuts down upon receipt of a
.Dv NGM_SHUTDOWN
-control message, or when all hooks have been disconnected.
+control message, or when all hooks have been disconnected. Setting the
+persistent flag via a
+.Dv NGM_HUB_SET_PERSISTENT
+control message disables automatic node shutdown when the last hook gets
+disconnected.
.Sh SEE ALSO
.Xr netgraph 4 ,
.Xr ng_bridge 4 ,
diff --git a/sys/netgraph/ng_bridge.c b/sys/netgraph/ng_bridge.c
index c6f4183..e28e034 100644
--- a/sys/netgraph/ng_bridge.c
+++ b/sys/netgraph/ng_bridge.c
@@ -83,7 +83,7 @@
#include <netgraph/ng_bridge.h>
#ifdef NG_SEPARATE_MALLOC
-MALLOC_DEFINE(M_NETGRAPH_BRIDGE, "netgraph_bridge", "netgraph bridge node ");
+MALLOC_DEFINE(M_NETGRAPH_BRIDGE, "netgraph_bridge", "netgraph bridge node");
#else
#define M_NETGRAPH_BRIDGE M_NETGRAPH
#endif
@@ -105,6 +105,7 @@ struct ng_bridge_private {
u_int numBuckets; /* num buckets in table */
u_int hashMask; /* numBuckets - 1 */
int numLinks; /* num connected links */
+ int persistent; /* can exist w/o hooks */
struct callout timer; /* one second periodic timer */
};
typedef struct ng_bridge_private *priv_p;
@@ -270,6 +271,13 @@ static const struct ng_cmdlist ng_bridge_cmdlist[] = {
NULL,
&ng_bridge_host_ary_type
},
+ {
+ NGM_BRIDGE_COOKIE,
+ NGM_BRIDGE_SET_PERSISTENT,
+ "setpersistent",
+ NULL,
+ NULL
+ },
{ 0 }
};
@@ -494,6 +502,11 @@ ng_bridge_rcvmsg(node_p node, item_p item, hook_p lasthook)
}
break;
}
+ case NGM_BRIDGE_SET_PERSISTENT:
+ {
+ priv->persistent = 1;
+ break;
+ }
default:
error = EINVAL;
break;
@@ -799,7 +812,8 @@ ng_bridge_disconnect(hook_p hook)
/* If no more hooks, go away */
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);
diff --git a/sys/netgraph/ng_bridge.h b/sys/netgraph/ng_bridge.h
index 0524a96..c34d27d 100644
--- a/sys/netgraph/ng_bridge.h
+++ b/sys/netgraph/ng_bridge.h
@@ -149,6 +149,7 @@ enum {
NGM_BRIDGE_CLR_STATS, /* clear link stats */
NGM_BRIDGE_GETCLR_STATS, /* atomically get & clear link stats */
NGM_BRIDGE_GET_TABLE, /* get link table */
+ NGM_BRIDGE_SET_PERSISTENT, /* set persistent mode */
};
#endif /* _NETGRAPH_NG_BRIDGE_H_ */
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);
}
diff --git a/sys/netgraph/ng_hub.h b/sys/netgraph/ng_hub.h
index a735d7b..d6b16e0 100644
--- a/sys/netgraph/ng_hub.h
+++ b/sys/netgraph/ng_hub.h
@@ -33,4 +33,9 @@
#define NG_HUB_NODE_TYPE "hub"
#define NGM_HUB_COOKIE 1082189597
+/* Netgraph control messages */
+enum {
+ NGM_HUB_SET_PERSISTENT = 1, /* set persistent mode */
+};
+
#endif /* _NETGRAPH_NG_HUB_H_ */
OpenPOWER on IntegriCloud