summaryrefslogtreecommitdiffstats
path: root/sys/netgraph
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netgraph')
-rw-r--r--sys/netgraph/netgraph.h3
-rw-r--r--sys/netgraph/ng_base.c33
-rw-r--r--sys/netgraph/ng_socket.c2
3 files changed, 28 insertions, 10 deletions
diff --git a/sys/netgraph/netgraph.h b/sys/netgraph/netgraph.h
index 69559ce..e0b53d1 100644
--- a/sys/netgraph/netgraph.h
+++ b/sys/netgraph/netgraph.h
@@ -608,6 +608,7 @@ struct ng_apply_info {
ng_apply_t *apply;
void *context;
int refs;
+ int error;
};
struct ng_item {
u_long el_flags;
@@ -634,7 +635,7 @@ struct ng_item {
* and its context.
*/
struct ng_apply_info *apply;
- void *PAD1;
+ uintptr_t depth;
#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/
char *lastfile;
int lastline;
diff --git a/sys/netgraph/ng_base.c b/sys/netgraph/ng_base.c
index 10eca62..cde7fdb 100644
--- a/sys/netgraph/ng_base.c
+++ b/sys/netgraph/ng_base.c
@@ -2250,9 +2250,13 @@ ng_flush_input_queue(struct ng_queue * ngq)
NG_QUEUE_UNLOCK(ngq);
/* If the item is supplying a callback, call it with an error */
- if (item->apply != NULL &&
- refcount_release(&item->apply->refs)) {
- (*item->apply->apply)(item->apply->context, ENOENT);
+ if (item->apply != NULL) {
+ if (item->depth == 1)
+ item->apply->error = ENOENT;
+ if (refcount_release(&item->apply->refs)) {
+ (*item->apply->apply)(item->apply->context,
+ item->apply->error);
+ }
}
NG_FREE_ITEM(item);
NG_QUEUE_LOCK(ngq);
@@ -2367,6 +2371,7 @@ ng_snd_item(item_p item, int flags)
#ifdef NETGRAPH_DEBUG
_ngi_check(item, __FILE__, __LINE__);
#endif
+ item->depth = 1;
NG_QUEUE_LOCK(ngq);
ng_queue_rw(ngq, item, rw);
NG_QUEUE_UNLOCK(ngq);
@@ -2394,6 +2399,7 @@ ng_snd_item(item_p item, int flags)
NGI_GET_NODE(item, node); /* zaps stored node */
+ item->depth++;
error = ng_apply_item(node, item, rw); /* drops r/w lock when done */
/*
@@ -2413,8 +2419,14 @@ ng_snd_item(item_p item, int flags)
done:
/* If was not sent, apply callback here. */
- if (item->apply != NULL && refcount_release(&item->apply->refs))
- (*item->apply->apply)(item->apply->context, error);
+ if (item->apply != NULL) {
+ if (item->depth == 0 && error != 0)
+ item->apply->error = error;
+ if (refcount_release(&item->apply->refs)) {
+ (*item->apply->apply)(item->apply->context,
+ item->apply->error);
+ }
+ }
NG_FREE_ITEM(item);
return (error);
@@ -2430,10 +2442,10 @@ static int
ng_apply_item(node_p node, item_p item, int rw)
{
hook_p hook;
- int error = 0;
ng_rcvdata_t *rcvdata;
ng_rcvmsg_t *rcvmsg;
struct ng_apply_info *apply;
+ int error = 0, depth;
/* Node and item are never optional. */
KASSERT(node != NULL, ("ng_apply_item: node is NULL"));
@@ -2445,6 +2457,7 @@ ng_apply_item(node_p node, item_p item, int rw)
#endif
apply = item->apply;
+ depth = item->depth;
switch (item->el_flags & NGQF_TYPE) {
case NGQF_DATA:
@@ -2552,8 +2565,12 @@ ng_apply_item(node_p node, item_p item, int rw)
ng_leave_write(&node->nd_input_queue);
/* Apply callback. */
- if (apply != NULL && refcount_release(&apply->refs))
- (*apply->apply)(apply->context, error);
+ if (apply != NULL) {
+ if (depth == 1 && error != 0)
+ apply->error = error;
+ if (refcount_release(&apply->refs))
+ (*apply->apply)(apply->context, apply->error);
+ }
return (error);
}
diff --git a/sys/netgraph/ng_socket.c b/sys/netgraph/ng_socket.c
index b444794..410c2d9 100644
--- a/sys/netgraph/ng_socket.c
+++ b/sys/netgraph/ng_socket.c
@@ -919,7 +919,7 @@ ngs_rcvmsg(node_p node, item_p item, hook_p lasthook)
if (sbappendaddr(&so->so_rcv, (struct sockaddr *)&addr, m, NULL) == 0) {
TRAP_ERROR;
m_freem(m);
- error = so->so_error = ENOBUFS;
+ return (ENOBUFS);
}
sorwakeup(so);
OpenPOWER on IntegriCloud