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
This commit is contained in:
Marko Zec 2010-05-05 22:06:05 +00:00
parent e4b50334ec
commit f8aab721b2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=207680
6 changed files with 115 additions and 8 deletions

View File

@ -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

View File

@ -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 ,

View File

@ -84,7 +84,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
@ -106,6 +106,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;
@ -271,6 +272,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 }
};
@ -495,6 +503,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;
@ -800,7 +813,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);

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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_ */