summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>2001-01-31 20:46:00 +0000
committerjulian <julian@FreeBSD.org>2001-01-31 20:46:00 +0000
commitd9ff7e1523af98d6d0fa4183f279fd6fa15ddfe8 (patch)
treed1ecad86a28ed4a79630ad373a615d5b86bef163 /sys
parent1904591561496046db76a7fed4aeeca690042d13 (diff)
downloadFreeBSD-src-d9ff7e1523af98d6d0fa4183f279fd6fa15ddfe8.zip
FreeBSD-src-d9ff7e1523af98d6d0fa4183f279fd6fa15ddfe8.tar.gz
Add the ability to declare ore-ride methods on a per-hook basis
for the rcvdata() and rcvmsg() methods. Also bring the man page up to sync with my last commit. (and this one)
Diffstat (limited to 'sys')
-rw-r--r--sys/netgraph/netgraph.h49
-rw-r--r--sys/netgraph/ng_base.c47
2 files changed, 70 insertions, 26 deletions
diff --git a/sys/netgraph/netgraph.h b/sys/netgraph/netgraph.h
index 78f095a..c3c93eb 100644
--- a/sys/netgraph/netgraph.h
+++ b/sys/netgraph/netgraph.h
@@ -80,6 +80,17 @@ typedef struct ng_item *item_p;
typedef struct ng_node *node_p;
typedef struct ng_hook *hook_p;
+/* node method definitions */
+typedef int ng_constructor_t(node_p node);
+typedef int ng_shutdown_t(node_p node);
+typedef int ng_newhook_t(node_p node, hook_p hook, const char *name);
+typedef hook_p ng_findhook_t(node_p node, const char *name);
+typedef int ng_connect_t(hook_p hook);
+typedef int ng_rcvmsg_t(node_p node, item_p item, hook_p lasthook);
+typedef int ng_rcvdata_t(hook_p hook, item_p item);
+typedef int ng_disconnect_t(hook_p hook);
+typedef int ng_rcvitem (node_p node, hook_p hook, item_p item);
+
/***********************************************************************
***************** Hook Structure and Methods **************************
***********************************************************************
@@ -94,6 +105,8 @@ struct ng_hook {
struct ng_hook *hk_peer; /* the other end of this link */
struct ng_node *hk_node; /* The node this hook is attached to */
LIST_ENTRY(ng_hook) hk_hooks; /* linked list of all hooks on node */
+ ng_rcvmsg_t *hk_rcvmsg; /* control messages come here */
+ ng_rcvdata_t *hk_rcvdata; /* data comes here */
#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/
#define HK_MAGIC 0x78573011
int hk_magic;
@@ -117,6 +130,8 @@ void ng_unref_hook(hook_p hook); /* don't move this */
#define _NG_HOOK_NAME(hook) ((hook)->hk_name)
#define _NG_HOOK_UNREF(hook) ng_unref_hook(hook)
#define _NG_HOOK_SET_PRIVATE(hook, val) do {(hook)->hk_private = val;} while (0)
+#define _NG_HOOK_SET_RCVMSG(hook, val) do {(hook)->hk_rcvmsg = val;} while (0)
+#define _NG_HOOK_SET_RCVDATA(hook, val) do {(hook)->hk_rcvdata = val;} while (0)
#define _NG_HOOK_PRIVATE(hook) ((hook)->hk_private)
#define _NG_HOOK_NOT_VALID(hook) ((hook)->hk_flags & HK_INVALID)
#define _NG_HOOK_IS_VALID(hook) (!(hook)->hk_flags & HK_INVALID)
@@ -139,7 +154,11 @@ static __inline void _ng_hook_ref(hook_p hook, char * file, int line);
static __inline char * _ng_hook_name(hook_p hook, char * file, int line);
static __inline void _ng_hook_unref(hook_p hook, char * file, int line);
static __inline void _ng_hook_set_private(hook_p hook,
- void * val, char * file, int line);
+ void * val, char * file, int line);
+static __inline void _ng_hook_set_rcvmsg(hook_p hook,
+ ng_rcvmsg_t *val, char * file, int line);
+static __inline void _ng_hook_set_rcvdata(hook_p hook,
+ ng_rcvdata_t *val, char * file, int line);
static __inline void * _ng_hook_private(hook_p hook, char * file, int line);
static __inline int _ng_hook_not_valid(hook_p hook, char * file, int line);
static __inline int _ng_hook_is_valid(hook_p hook, char * file, int line);
@@ -188,6 +207,20 @@ _ng_hook_set_private(hook_p hook, void *val, char * file, int line)
_NG_HOOK_SET_PRIVATE(hook, val);
}
+static __inline void
+_ng_hook_set_rcvmsg(hook_p hook, ng_rcvmsg_t *val, char * file, int line)
+{
+ _chkhook(hook, file, line);
+ _NG_HOOK_SET_RCVMSG(hook, val);
+}
+
+static __inline void
+_ng_hook_set_rcvdata(hook_p hook, ng_rcvdata_t *val, char * file, int line)
+{
+ _chkhook(hook, file, line);
+ _NG_HOOK_SET_RCVDATA(hook, val);
+}
+
static __inline void *
_ng_hook_private(hook_p hook, char * file, int line)
{
@@ -242,6 +275,8 @@ _ng_hook_force_queue(hook_p hook, char * file, int line)
#define NG_HOOK_NAME(hook) _ng_hook_name(hook, _NN_)
#define NG_HOOK_UNREF(hook) _ng_hook_unref(hook, _NN_)
#define NG_HOOK_SET_PRIVATE(hook, val) _ng_hook_set_private(hook, val, _NN_)
+#define NG_HOOK_SET_RCVMSG(hook, val) _ng_hook_set_rcvmsg(hook, val, _NN_)
+#define NG_HOOK_SET_RCVDATA(hook, val) _ng_hook_set_rcvdata(hook, val, _NN_)
#define NG_HOOK_PRIVATE(hook) _ng_hook_private(hook, _NN_)
#define NG_HOOK_NOT_VALID(hook) _ng_hook_not_valid(hook, _NN_)
#define NG_HOOK_IS_VALID(hook) _ng_hook_is_valid(hook, _NN_)
@@ -256,6 +291,8 @@ _ng_hook_force_queue(hook_p hook, char * file, int line)
#define NG_HOOK_NAME(hook) _NG_HOOK_NAME(hook)
#define NG_HOOK_UNREF(hook) _NG_HOOK_UNREF(hook)
#define NG_HOOK_SET_PRIVATE(hook, val) _NG_HOOK_SET_PRIVATE(hook, val)
+#define NG_HOOK_SET_RCVMSG(hook, val) _NG_HOOK_SET_RCVMSG(hook, val)
+#define NG_HOOK_SET_RCVDATA(hook, val) _NG_HOOK_SET_RCVDATA(hook, val)
#define NG_HOOK_PRIVATE(hook) _NG_HOOK_PRIVATE(hook)
#define NG_HOOK_NOT_VALID(hook) _NG_HOOK_NOT_VALID(hook)
#define NG_HOOK_IS_VALID(hook) _NG_HOOK_IS_VALID(hook)
@@ -1007,16 +1044,6 @@ _ngi_hook(item_p item, char *file, int line)
* type.
*/
-/* node method definitions */
-typedef int ng_constructor_t(node_p node);
-typedef int ng_rcvmsg_t(node_p node, item_p item, hook_p lasthook);
-typedef int ng_shutdown_t(node_p node);
-typedef int ng_newhook_t(node_p node, hook_p hook, const char *name);
-typedef hook_p ng_findhook_t(node_p node, const char *name);
-typedef int ng_connect_t(hook_p hook);
-typedef int ng_rcvdata_t(hook_p hook, item_p item);
-typedef int ng_disconnect_t(hook_p hook);
-typedef int ng_rcvitem (node_p node, hook_p hook, item_p item);
/*
* Command list -- each node type specifies the command that it knows
* how to convert between ASCII and binary using an array of these.
diff --git a/sys/netgraph/ng_base.c b/sys/netgraph/ng_base.c
index d5c456f..3e4e174 100644
--- a/sys/netgraph/ng_base.c
+++ b/sys/netgraph/ng_base.c
@@ -136,6 +136,8 @@ struct ng_hook ng_deadhook = {
&ng_deadhook, /* Peer is self */
&ng_deadnode, /* attached to deadnode */
{}, /* hooks list */
+ NULL, /* override rcvmsg() */
+ NULL, /* override rcvdata() */
#ifdef NETGRAPH_DEBUG
HK_MAGIC,
__FILE__,
@@ -2298,6 +2300,7 @@ ng_apply_item(item_p item)
int was_reader = ((item->el_flags & NGQF_RW));
int error = 0;
ng_rcvdata_t *rcvdata;
+ ng_rcvmsg_t *rcvmsg;
NGI_GET_HOOK(item, hook); /* clears stored hook */
NGI_GET_NODE(item, node); /* clears stored node */
@@ -2309,16 +2312,24 @@ ng_apply_item(item_p item)
/*
* Check things are still ok as when we were queued.
*/
-
if ((hook == NULL)
|| NG_HOOK_NOT_VALID(hook)
- || NG_NODE_NOT_VALID(node)
- || ((rcvdata = NG_HOOK_NODE(hook)->nd_type->rcvdata) == NULL)) {
+ || NG_NODE_NOT_VALID(node) ) {
error = EIO;
NG_FREE_ITEM(item);
- } else {
- error = (*rcvdata)(hook, item);
+ break;
}
+ /*
+ * If no receive method, just silently drop it.
+ * Give preference to the hook over-ride method
+ */
+ if ((!(rcvdata = hook->hk_rcvdata))
+ && (!(rcvdata = NG_HOOK_NODE(hook)->nd_type->rcvdata))) {
+ error = 0;
+ NG_FREE_ITEM(item);
+ break;
+ }
+ error = (*rcvdata)(hook, item);
break;
case NGQF_MESG:
if (hook) {
@@ -2355,20 +2366,26 @@ ng_apply_item(item_p item)
struct ng_mesg *msg = NGI_MSG(item);
+ /*
+ * check if the generic handler owns it.
+ */
if ((msg->header.typecookie == NGM_GENERIC_COOKIE)
&& ((msg->header.flags & NGF_RESP) == 0)) {
error = ng_generic_msg(node, item, hook);
- } else {
- if ((node)->nd_type->rcvmsg != NULL) {
- error = (*(node)->nd_type->rcvmsg)((node),
- (item), (hook));
- } else {
- TRAP_ERROR();
- error = EINVAL; /* XXX */
- NG_FREE_ITEM(item);
- }
+ break;
+ }
+ /*
+ * Now see if there is a handler (hook or node specific)
+ * in the target node. If none, silently discard.
+ */
+ if (((!hook) || (!(rcvmsg = hook->hk_rcvmsg)))
+ && (!(rcvmsg = node->nd_type->rcvmsg))) {
+ TRAP_ERROR();
+ error = 0;
+ NG_FREE_ITEM(item);
+ break;
}
- /* item is now invalid */
+ error = (*rcvmsg)(node, item, hook);
}
break;
case NGQF_FN:
OpenPOWER on IntegriCloud