summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorru <ru@FreeBSD.org>2004-05-19 11:26:33 +0000
committerru <ru@FreeBSD.org>2004-05-19 11:26:33 +0000
commit63a58dc2d2db4c7d8f82237a7e949a7d09c4fc23 (patch)
tree813a70bb3f57fe0d147478e182c21ed456c78183
parentdb8317e9835a860ed49308bf8be0b919371d1faa (diff)
downloadFreeBSD-src-63a58dc2d2db4c7d8f82237a7e949a7d09c4fc23.zip
FreeBSD-src-63a58dc2d2db4c7d8f82237a7e949a7d09c4fc23.tar.gz
Maintain statistics about the received frames.
-rw-r--r--share/man/man4/ng_hole.423
-rw-r--r--sys/netgraph/ng_hole.c130
-rw-r--r--sys/netgraph/ng_hole.h20
3 files changed, 167 insertions, 6 deletions
diff --git a/share/man/man4/ng_hole.4 b/share/man/man4/ng_hole.4
index 65a6a09..fd956ad 100644
--- a/share/man/man4/ng_hole.4
+++ b/share/man/man4/ng_hole.4
@@ -35,7 +35,7 @@
.\" $FreeBSD$
.\" $Whistle: ng_hole.8,v 1.4 1999/01/25 23:46:26 archie Exp $
.\"
-.Dd January 19, 1999
+.Dd May 19, 2004
.Dt NG_HOLE 4
.Os
.Sh NAME
@@ -54,8 +54,25 @@ 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.
-Other control messages are silently discarded.
+This node type supports the generic control messages, plus the
+following:
+.Bl -tag -width indent
+.It Dv NGM_BPF_GET_STATS
+This command takes an
+.Tn ASCII
+string argument, the hook name, and returns the statistics
+associated with the hook as a
+.Vt "struct ng_hole_hookstat" .
+.It Dv NGM_BPF_CLR_STATS
+This command takes an
+.Tn ASCII
+string argument, the hook name, and clears the statistics
+associated with the hook.
+.It Dv NGM_BPF_GETCLR_STATS
+This command is identical to
+.Dv NGM_BPF_GET_STATS ,
+except that the statistics are also atomically cleared.
+.El
.Sh SHUTDOWN
This node shuts down upon receipt of a
.Dv NGM_SHUTDOWN
diff --git a/sys/netgraph/ng_hole.c b/sys/netgraph/ng_hole.c
index 8b4df29..b1fc95d 100644
--- a/sys/netgraph/ng_hole.c
+++ b/sys/netgraph/ng_hole.c
@@ -51,10 +51,53 @@
#include <sys/mbuf.h>
#include <netgraph/ng_message.h>
#include <netgraph/netgraph.h>
+#include <netgraph/ng_parse.h>
#include <netgraph/ng_hole.h>
+/* Per hook private info. */
+struct ng_hole_hookinfo {
+ struct ng_hole_hookstat stats;
+};
+typedef struct ng_hole_hookinfo *hinfo_p;
+
+/* Parse type for struct ng_hole_hookstat. */
+static const struct ng_parse_struct_field ng_hole_hookstat_type_fields[] =
+ NG_HOLE_HOOKSTAT_TYPE_INFO;
+static const struct ng_parse_type ng_hole_hookstat_type = {
+ &ng_parse_struct_type,
+ &ng_hole_hookstat_type_fields
+};
+
+/* List of commands and how to convert arguments to/from ASCII. */
+static const struct ng_cmdlist ng_hole_cmdlist[] = {
+ {
+ NGM_HOLE_COOKIE,
+ NGM_HOLE_GET_STATS,
+ "getstats",
+ &ng_parse_hookbuf_type,
+ &ng_hole_hookstat_type
+ },
+ {
+ NGM_HOLE_COOKIE,
+ NGM_HOLE_CLR_STATS,
+ "clrstats",
+ &ng_parse_hookbuf_type,
+ NULL
+ },
+ {
+ NGM_HOLE_COOKIE,
+ NGM_HOLE_GETCLR_STATS,
+ "getclrstats",
+ &ng_parse_hookbuf_type,
+ &ng_hole_hookstat_type
+ },
+ { 0 }
+};
+
/* Netgraph methods */
static ng_constructor_t ngh_cons;
+static ng_rcvmsg_t ngh_rcvmsg;
+static ng_newhook_t ngh_newhook;
static ng_rcvdata_t ngh_rcvdata;
static ng_disconnect_t ngh_disconnect;
@@ -63,14 +106,14 @@ static struct ng_type typestruct = {
NG_HOLE_NODE_TYPE,
NULL, /* modeventhand_t */
ngh_cons, /* ng_constructor_t */
- NULL, /* ng_rcvmsg_t */
+ ngh_rcvmsg, /* ng_rcvmsg_t */
NULL, /* ng_shutdown_t */
- NULL, /* ng_newhook_t */
+ ngh_newhook, /* ng_newhook_t */
NULL, /* ng_findhook_t */
NULL, /* ng_connect_t */
ngh_rcvdata, /* ng_rcvdata_t */
ngh_disconnect, /* ng_disconnect_t */
- NULL /* ng_cmdlist */
+ ng_hole_cmdlist /* ng_cmdlist */
};
NETGRAPH_INIT(hole, &typestruct);
@@ -84,11 +127,90 @@ ngh_cons(node_p node)
}
/*
+ * Add a hook.
+ */
+static int
+ngh_newhook(node_p node, hook_p hook, const char *name)
+{
+ hinfo_p hip;
+
+ /* Create hook private structure. */
+ MALLOC(hip, hinfo_p, sizeof(*hip), M_NETGRAPH, M_NOWAIT | M_ZERO);
+ if (hip == NULL)
+ return (ENOMEM);
+ NG_HOOK_SET_PRIVATE(hook, hip);
+ return (0);
+}
+
+/*
+ * Receive a control message.
+ */
+static int
+ngh_rcvmsg(node_p node, item_p item, hook_p lasthook)
+{
+ struct ng_mesg *msg;
+ struct ng_mesg *resp = NULL;
+ int error = 0;
+ struct ng_hole_hookstat *stats;
+ hook_p hook;
+
+ NGI_GET_MSG(item, msg);
+ switch (msg->header.typecookie) {
+ case NGM_HOLE_COOKIE:
+ switch (msg->header.cmd) {
+ case NGM_HOLE_GET_STATS:
+ case NGM_HOLE_CLR_STATS:
+ case NGM_HOLE_GETCLR_STATS:
+ /* Sanity check. */
+ if (msg->header.arglen != NG_HOOKLEN + 1) {
+ error = EINVAL;
+ break;
+ }
+ /* Find hook. */
+ hook = ng_findhook(node, (char *)msg->data);
+ if (hook == NULL) {
+ error = ENOENT;
+ break;
+ }
+ stats = &((hinfo_p)NG_HOOK_PRIVATE(hook))->stats;
+ /* Build response (if desired). */
+ if (msg->header.cmd != NGM_HOLE_CLR_STATS) {
+ NG_MKRESPONSE(resp, msg, sizeof(*stats),
+ M_NOWAIT);
+ if (resp == NULL) {
+ error = ENOMEM;
+ break;
+ }
+ bcopy(stats, resp->data, sizeof(*stats));
+ }
+ /* Clear stats (if desired). */
+ if (msg->header.cmd != NGM_HOLE_GET_STATS)
+ bzero(stats, sizeof(*stats));
+ break;
+ default: /* Unknown command. */
+ error = EINVAL;
+ break;
+ }
+ break;
+ default: /* Unknown type cookie. */
+ error = EINVAL;
+ break;
+ }
+ NG_RESPOND_MSG(error, node, item, resp);
+ NG_FREE_MSG(msg);
+ return (error);
+}
+
+/*
* Receive data
*/
static int
ngh_rcvdata(hook_p hook, item_p item)
{
+ const hinfo_p hip = NG_HOOK_PRIVATE(hook);
+
+ hip->stats.frames++;
+ hip->stats.octets += NGI_M(item)->m_pkthdr.len;
NG_FREE_ITEM(item);
return 0;
}
@@ -99,6 +221,8 @@ ngh_rcvdata(hook_p hook, item_p item)
static int
ngh_disconnect(hook_p hook)
{
+
+ NG_HOOK_SET_PRIVATE(hook, NULL);
if (NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0)
ng_rmnode_self(NG_HOOK_NODE(hook));
return (0);
diff --git a/sys/netgraph/ng_hole.h b/sys/netgraph/ng_hole.h
index cff47aa..d2da2d2 100644
--- a/sys/netgraph/ng_hole.h
+++ b/sys/netgraph/ng_hole.h
@@ -46,5 +46,25 @@
/* Node type name and magic cookie */
#define NG_HOLE_NODE_TYPE "hole"
#define NGM_HOLE_COOKIE 915433206
+
+/* Statistics structure for one hook. */
+struct ng_hole_hookstat {
+ uint64_t frames;
+ uint64_t octets;
+};
+
+/* Keep this in sync with the above structure definition. */
+#define NG_HOLE_HOOKSTAT_TYPE_INFO { \
+ { "frames", &ng_parse_uint64_type }, \
+ { "octets", &ng_parse_uint64_type }, \
+ { NULL } \
+}
+
+/* Netgraph commands. */
+enum {
+ NGM_HOLE_GET_STATS = 1,
+ NGM_HOLE_CLR_STATS,
+ NGM_HOLE_GETCLR_STATS,
+};
#endif /* _NETGRAPH_NG_HOLE_H_ */
OpenPOWER on IntegriCloud