diff options
30 files changed, 188 insertions, 98 deletions
diff --git a/sys/dev/ar/if_ar.c b/sys/dev/ar/if_ar.c index 6f9122c..0c21d69 100644 --- a/sys/dev/ar/if_ar.c +++ b/sys/dev/ar/if_ar.c @@ -2204,8 +2204,8 @@ ngar_newhook(node_p node, hook_p hook, const char *name) * Just respond to the generic TEXT_STATUS message */ static int -ngar_rcvmsg(node_p node, - struct ng_mesg *msg, const char *retaddr, struct ng_mesg **resp) +ngar_rcvmsg(node_p node, struct ng_mesg *msg, + const char *retaddr, struct ng_mesg **resp, hook_p lasthook) { struct ar_softc * sc; int error = 0; @@ -2273,7 +2273,8 @@ ngar_rcvmsg(node_p node, * get data from another node and transmit it to the correct channel */ static int -ngar_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +ngar_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { int s; int error = 0; diff --git a/sys/dev/ar/if_ar_isa.c b/sys/dev/ar/if_ar_isa.c index 6f9122c..0c21d69 100644 --- a/sys/dev/ar/if_ar_isa.c +++ b/sys/dev/ar/if_ar_isa.c @@ -2204,8 +2204,8 @@ ngar_newhook(node_p node, hook_p hook, const char *name) * Just respond to the generic TEXT_STATUS message */ static int -ngar_rcvmsg(node_p node, - struct ng_mesg *msg, const char *retaddr, struct ng_mesg **resp) +ngar_rcvmsg(node_p node, struct ng_mesg *msg, + const char *retaddr, struct ng_mesg **resp, hook_p lasthook) { struct ar_softc * sc; int error = 0; @@ -2273,7 +2273,8 @@ ngar_rcvmsg(node_p node, * get data from another node and transmit it to the correct channel */ static int -ngar_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +ngar_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { int s; int error = 0; diff --git a/sys/dev/sr/if_sr.c b/sys/dev/sr/if_sr.c index 8d850fd..77e21eb 100644 --- a/sys/dev/sr/if_sr.c +++ b/sys/dev/sr/if_sr.c @@ -3157,8 +3157,8 @@ ngsr_newhook(node_p node, hook_p hook, const char *name) * Just respond to the generic TEXT_STATUS message */ static int -ngsr_rcvmsg(node_p node, - struct ng_mesg *msg, const char *retaddr, struct ng_mesg **resp) +ngsr_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, + struct ng_mesg **resp, hook_p lasthook) { struct sr_softc * sc; int error = 0; @@ -3228,7 +3228,8 @@ ngsr_rcvmsg(node_p node, * get data from another node and transmit it to the correct channel */ static int -ngsr_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +ngsr_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { int s; int error = 0; diff --git a/sys/dev/sr/if_sr_isa.c b/sys/dev/sr/if_sr_isa.c index 8d850fd..77e21eb 100644 --- a/sys/dev/sr/if_sr_isa.c +++ b/sys/dev/sr/if_sr_isa.c @@ -3157,8 +3157,8 @@ ngsr_newhook(node_p node, hook_p hook, const char *name) * Just respond to the generic TEXT_STATUS message */ static int -ngsr_rcvmsg(node_p node, - struct ng_mesg *msg, const char *retaddr, struct ng_mesg **resp) +ngsr_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, + struct ng_mesg **resp, hook_p lasthook) { struct sr_softc * sc; int error = 0; @@ -3228,7 +3228,8 @@ ngsr_rcvmsg(node_p node, * get data from another node and transmit it to the correct channel */ static int -ngsr_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +ngsr_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { int s; int error = 0; diff --git a/sys/i386/isa/if_ar.c b/sys/i386/isa/if_ar.c index 6f9122c..0c21d69 100644 --- a/sys/i386/isa/if_ar.c +++ b/sys/i386/isa/if_ar.c @@ -2204,8 +2204,8 @@ ngar_newhook(node_p node, hook_p hook, const char *name) * Just respond to the generic TEXT_STATUS message */ static int -ngar_rcvmsg(node_p node, - struct ng_mesg *msg, const char *retaddr, struct ng_mesg **resp) +ngar_rcvmsg(node_p node, struct ng_mesg *msg, + const char *retaddr, struct ng_mesg **resp, hook_p lasthook) { struct ar_softc * sc; int error = 0; @@ -2273,7 +2273,8 @@ ngar_rcvmsg(node_p node, * get data from another node and transmit it to the correct channel */ static int -ngar_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +ngar_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { int s; int error = 0; diff --git a/sys/i386/isa/if_sr.c b/sys/i386/isa/if_sr.c index 8d850fd..77e21eb 100644 --- a/sys/i386/isa/if_sr.c +++ b/sys/i386/isa/if_sr.c @@ -3157,8 +3157,8 @@ ngsr_newhook(node_p node, hook_p hook, const char *name) * Just respond to the generic TEXT_STATUS message */ static int -ngsr_rcvmsg(node_p node, - struct ng_mesg *msg, const char *retaddr, struct ng_mesg **resp) +ngsr_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, + struct ng_mesg **resp, hook_p lasthook) { struct sr_softc * sc; int error = 0; @@ -3228,7 +3228,8 @@ ngsr_rcvmsg(node_p node, * get data from another node and transmit it to the correct channel */ static int -ngsr_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +ngsr_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { int s; int error = 0; diff --git a/sys/netgraph/netgraph.h b/sys/netgraph/netgraph.h index d46e40c..fc7ca81 100644 --- a/sys/netgraph/netgraph.h +++ b/sys/netgraph/netgraph.h @@ -132,12 +132,14 @@ typedef struct ng_meta *meta_p; /* node method definitions */ typedef int ng_constructor_t(node_p *node); typedef int ng_rcvmsg_t(node_p node, struct ng_mesg *msg, - const char *retaddr, struct ng_mesg **resp); + const char *retaddr, struct ng_mesg **resp, + 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, struct mbuf *m, meta_p meta); +typedef int ng_rcvdata_t(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta); typedef int ng_disconnect_t(hook_p hook); /* @@ -182,7 +184,7 @@ struct ng_type { /* Send data packet with meta-data */ #define NG_SEND_DATA(error, hook, m, a) \ do { \ - (error) = ng_send_data((hook), (m), (a)); \ + (error) = ng_send_data((hook), (m), (a), NULL, NULL); \ (m) = NULL; \ (a) = NULL; \ } while (0) @@ -190,11 +192,20 @@ struct ng_type { /* Send queued data packet with meta-data */ #define NG_SEND_DATAQ(error, hook, m, a) \ do { \ - (error) = ng_send_dataq((hook), (m), (a)); \ + (error) = ng_send_dataq((hook), (m), (a), NULL, NULL); \ (m) = NULL; \ (a) = NULL; \ } while (0) +#define NG_SEND_DATA_RET(error, hook, m, a) \ + do { \ + struct mbuf *ret_m = NULL; \ + meta_p ret_meta = NULL; \ + (error) = ng_send_dataq((hook), (m), (a), &ret_m, &ret_meta);\ + (m) = ret_m; \ + (a) = ret_meta; \ + } while (0) + /* Free metadata */ #define NG_FREE_META(a) \ do { \ @@ -255,14 +266,17 @@ int ng_mod_event(module_t mod, int what, void *arg); int ng_name_node(node_p node, const char *name); int ng_newtype(struct ng_type *tp); ng_ID_t ng_node2ID(node_p node); -int ng_path2node(node_p here, const char *path, node_p *dest, char **rtnp); +int ng_path2node(node_p here, const char *path, node_p *dest, char **rtnp, + hook_p *lasthook); int ng_path_parse(char *addr, char **node, char **path, char **hook); int ng_queue_data(hook_p hook, struct mbuf *m, meta_p meta); int ng_queue_msg(node_p here, struct ng_mesg *msg, const char *address); void ng_release_node(node_p node); void ng_rmnode(node_p node); -int ng_send_data(hook_p hook, struct mbuf *m, meta_p meta); -int ng_send_dataq(hook_p hook, struct mbuf *m, meta_p meta); +int ng_send_data(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta); +int ng_send_dataq(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta); int ng_send_msg(node_p here, struct ng_mesg *msg, const char *address, struct ng_mesg **resp); void ng_unname(node_p node); diff --git a/sys/netgraph/ng_UI.c b/sys/netgraph/ng_UI.c index f4ec100..42d2bf7 100644 --- a/sys/netgraph/ng_UI.c +++ b/sys/netgraph/ng_UI.c @@ -150,7 +150,7 @@ ng_UI_newhook(node_p node, hook_p hook, const char *name) */ static int ng_UI_rcvmsg(node_p node, struct ng_mesg *msg, - const char *raddr, struct ng_mesg **rp) + const char *raddr, struct ng_mesg **rp, hook_p lasthook) { FREE(msg, M_NETGRAPH); return (EINVAL); @@ -163,7 +163,8 @@ ng_UI_rcvmsg(node_p node, struct ng_mesg *msg, * Receive a data frame */ static int -ng_UI_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +ng_UI_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { const node_p node = hook->node; const priv_p priv = node->private; diff --git a/sys/netgraph/ng_async.c b/sys/netgraph/ng_async.c index 54ab716..83f8b27 100644 --- a/sys/netgraph/ng_async.c +++ b/sys/netgraph/ng_async.c @@ -234,7 +234,8 @@ nga_newhook(node_p node, hook_p hook, const char *name) * Receive incoming data */ static int -nga_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +nga_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { const sc_p sc = hook->node->private; @@ -250,7 +251,7 @@ nga_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) */ static int nga_rcvmsg(node_p node, struct ng_mesg *msg, - const char *rtn, struct ng_mesg **rptr) + const char *rtn, struct ng_mesg **rptr, hook_p lasthook) { const sc_p sc = (sc_p) node->private; struct ng_mesg *resp = NULL; diff --git a/sys/netgraph/ng_base.c b/sys/netgraph/ng_base.c index c066580..c5c6a0e 100644 --- a/sys/netgraph/ng_base.c +++ b/sys/netgraph/ng_base.c @@ -79,7 +79,8 @@ static int ng_add_hook(node_p node, const char *name, hook_p * hookp); static int ng_connect(hook_p hook1, hook_p hook2); static void ng_disconnect_hook(hook_p hook); static int ng_generic_msg(node_p here, struct ng_mesg *msg, - const char *retaddr, struct ng_mesg ** resp); + const char *retaddr, struct ng_mesg ** resp, + hook_p hook); static ng_ID_t ng_decodeidname(const char *name); static int ngb_mod_event(module_t mod, int event, void *data); static void ngintr(void); @@ -1015,13 +1016,15 @@ ng_path_parse(char *addr, char **nodep, char **pathp, char **hookp) * return the destination node. Compute the "return address" if desired. */ int -ng_path2node(node_p here, const char *address, node_p *destp, char **rtnp) +ng_path2node(node_p here, const char *address, node_p *destp, char **rtnp, + hook_p *lasthook) { const node_p start = here; char fullpath[NG_PATHLEN + 1]; char *nodename, *path, pbuf[2]; node_p node; char *cp; + hook_p hook = NULL; /* Initialize */ if (rtnp) @@ -1057,7 +1060,6 @@ ng_path2node(node_p here, const char *address, node_p *destp, char **rtnp) /* Now follow the sequence of hooks */ for (cp = path; node != NULL && *cp != '\0'; ) { - hook_p hook; char *segment; /* @@ -1112,6 +1114,8 @@ ng_path2node(node_p here, const char *address, node_p *destp, char **rtnp) /* Done */ *destp = node; + if (lasthook && hook) + *lasthook = hook->peer; return (0); } @@ -1122,15 +1126,15 @@ ng_path2node(node_p here, const char *address, node_p *destp, char **rtnp) * call the type's message handler (if it exists) */ -#define CALL_MSG_HANDLER(error, node, msg, retaddr, resp) \ +#define CALL_MSG_HANDLER(error, node, msg, retaddr, resp, hook) \ do { \ if((msg)->header.typecookie == NGM_GENERIC_COOKIE) { \ (error) = ng_generic_msg((node), (msg), \ - (retaddr), (resp)); \ + (retaddr), (resp), (hook)); \ } else { \ if ((node)->type->rcvmsg != NULL) { \ (error) = (*(node)->type->rcvmsg)((node), \ - (msg), (retaddr), (resp)); \ + (msg), (retaddr), (resp), (hook)); \ } else { \ TRAP_ERROR; \ FREE((msg), M_NETGRAPH); \ @@ -1150,9 +1154,10 @@ ng_send_msg(node_p here, struct ng_mesg *msg, const char *address, node_p dest = NULL; char *retaddr = NULL; int error; + hook_p lasthook; /* Find the target node */ - error = ng_path2node(here, address, &dest, &retaddr); + error = ng_path2node(here, address, &dest, &retaddr, &lasthook); if (error) { FREE(msg, M_NETGRAPH); return error; @@ -1162,7 +1167,7 @@ ng_send_msg(node_p here, struct ng_mesg *msg, const char *address, if (rptr != NULL) *rptr = NULL; - CALL_MSG_HANDLER(error, dest, msg, retaddr, rptr); + CALL_MSG_HANDLER(error, dest, msg, retaddr, rptr, lasthook); /* Make sure that if there is a response, it has the RESP bit set */ if ((error == 0) && rptr && *rptr) @@ -1182,7 +1187,7 @@ ng_send_msg(node_p here, struct ng_mesg *msg, const char *address, */ static int ng_generic_msg(node_p here, struct ng_mesg *msg, const char *retaddr, - struct ng_mesg **resp) + struct ng_mesg **resp, hook_p lasthook) { int error = 0; @@ -1222,7 +1227,7 @@ ng_generic_msg(node_p here, struct ng_mesg *msg, const char *retaddr, con->path[sizeof(con->path) - 1] = '\0'; con->ourhook[sizeof(con->ourhook) - 1] = '\0'; con->peerhook[sizeof(con->peerhook) - 1] = '\0'; - error = ng_path2node(here, con->path, &node2, NULL); + error = ng_path2node(here, con->path, &node2, NULL, NULL); if (error) break; error = ng_con_nodes(here, con->ourhook, node2, con->peerhook); @@ -1597,7 +1602,8 @@ ng_generic_msg(node_p here, struct ng_mesg *msg, const char *retaddr, break; } if (here->type->rcvmsg != NULL) - return((*here->type->rcvmsg)(here, msg, retaddr, resp)); + return((*here->type->rcvmsg)(here, msg, retaddr, + resp, lasthook)); /* Fall through if rcvmsg not supported */ default: TRAP_ERROR; @@ -1612,16 +1618,18 @@ ng_generic_msg(node_p here, struct ng_mesg *msg, const char *retaddr, * 'receive data' method, then silently discard the packet. */ int -ng_send_data(hook_p hook, struct mbuf *m, meta_p meta) +ng_send_data(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { - int (*rcvdata)(hook_p, struct mbuf *, meta_p); + ng_rcvdata_t *rcvdata; int error; CHECK_DATA_MBUF(m); if (hook && (hook->flags & HK_INVALID) == 0) { rcvdata = hook->peer->node->type->rcvdata; if (rcvdata != NULL) - error = (*rcvdata)(hook->peer, m, meta); + error = (*rcvdata)(hook->peer, m, meta, + ret_m, ret_meta); else { error = 0; NG_FREE_DATA(m, meta); @@ -1639,18 +1647,27 @@ ng_send_data(hook_p hook, struct mbuf *m, meta_p meta) * 'receive queued data' method, then try the 'receive data' method above. */ int -ng_send_dataq(hook_p hook, struct mbuf *m, meta_p meta) +ng_send_dataq(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { - int (*rcvdataq)(hook_p, struct mbuf *, meta_p); + ng_rcvdata_t *rcvdata; int error; CHECK_DATA_MBUF(m); if (hook && (hook->flags & HK_INVALID) == 0) { - rcvdataq = hook->peer->node->type->rcvdataq; - if (rcvdataq != NULL) - error = (*rcvdataq)(hook->peer, m, meta); + rcvdata = hook->peer->node->type->rcvdataq; + if (rcvdata != NULL) + error = (*rcvdata)(hook->peer, m, meta, + ret_m, ret_meta); else { - error = ng_send_data(hook, m, meta); + rcvdata = hook->peer->node->type->rcvdata; + if (rcvdata != NULL) { + error = (*rcvdata)(hook->peer, m, meta, + ret_m, ret_meta); + } else { + error = 0; + NG_FREE_DATA(m, meta); + } } } else { TRAP_ERROR; @@ -1769,6 +1786,7 @@ struct ng_queue_entry { struct ng_mesg *msg_msg; node_p msg_node; void *msg_retaddr; + hook_p msg_lasthook; } msg; } body; }; @@ -1883,9 +1901,10 @@ ng_queue_msg(node_p here, struct ng_mesg *msg, const char *address) node_p dest = NULL; char *retaddr = NULL; int error; + hook_p lasthook = NULL; /* Find the target node. */ - error = ng_path2node(here, address, &dest, &retaddr); + error = ng_path2node(here, address, &dest, &retaddr, &lasthook); if (error) { FREE(msg, M_NETGRAPH); return (error); @@ -1903,7 +1922,10 @@ ng_queue_msg(node_p here, struct ng_mesg *msg, const char *address) q->body.msg.msg_node = dest; q->body.msg.msg_msg = msg; q->body.msg.msg_retaddr = retaddr; + q->body.msg.msg_lasthook = lasthook; dest->refs++; /* don't let it go away while on the queue */ + if (lasthook) + lasthook->refs++; /* same for the hook */ /* Put it on the queue */ s = splhigh(); @@ -1960,12 +1982,25 @@ ngintr(void) node = ngq->body.msg.msg_node; msg = ngq->body.msg.msg_msg; retaddr = ngq->body.msg.msg_retaddr; + hook = ngq->body.msg.msg_lasthook; RETURN_QBLK(ngq); + if (hook) { + if ((hook->refs == 1) + || (hook->flags & HK_INVALID) != 0) { + /* If the hook only has one ref left + then we can't use it */ + ng_unref_hook(hook); + hook = NULL; + } else { + ng_unref_hook(hook); + } + } + /* similarly, if the node is a zombie.. */ if (node->flags & NG_INVALID) { FREE(msg, M_NETGRAPH); } else { CALL_MSG_HANDLER(error, node, msg, - retaddr, NULL); + retaddr, NULL, hook); } ng_unref(node); if (retaddr) diff --git a/sys/netgraph/ng_bpf.c b/sys/netgraph/ng_bpf.c index f3c979f..8ec7bac 100644 --- a/sys/netgraph/ng_bpf.c +++ b/sys/netgraph/ng_bpf.c @@ -263,7 +263,7 @@ ng_bpf_newhook(node_p node, hook_p hook, const char *name) */ static int ng_bpf_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, - struct ng_mesg **rptr) + struct ng_mesg **rptr, hook_p lasthook) { struct ng_mesg *resp = NULL; int error = 0; @@ -375,7 +375,8 @@ done: * Apply the filter, and then drop or forward packet as appropriate. */ static int -ng_bpf_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +ng_bpf_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { const hinfo_p hip = hook->private; int totlen = m->m_pkthdr.len; diff --git a/sys/netgraph/ng_cisco.c b/sys/netgraph/ng_cisco.c index a65dd0c..29ba7c7 100644 --- a/sys/netgraph/ng_cisco.c +++ b/sys/netgraph/ng_cisco.c @@ -255,7 +255,7 @@ cisco_newhook(node_p node, hook_p hook, const char *name) */ static int cisco_rcvmsg(node_p node, struct ng_mesg *msg, - const char *retaddr, struct ng_mesg **rptr) + const char *retaddr, struct ng_mesg **rptr, hook_p lasthook) { const sc_p sc = node->private; struct ng_mesg *resp = NULL; @@ -353,7 +353,8 @@ cisco_rcvmsg(node_p node, struct ng_mesg *msg, * Receive data */ static int -cisco_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +cisco_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { const sc_p sc = hook->node->private; struct protoent *pep; @@ -504,7 +505,8 @@ cisco_input(sc_p sc, struct mbuf *m, meta_p meta) ng_send_msg(sc->node, msg, NG_CISCO_HOOK_INET, &resp); if (resp != NULL) - cisco_rcvmsg(sc->node, resp, ".", NULL); + cisco_rcvmsg(sc->node, resp, ".", + NULL, NULL); nomsg: /* Send reply to peer device */ diff --git a/sys/netgraph/ng_echo.c b/sys/netgraph/ng_echo.c index a6de89c..1c72114 100644 --- a/sys/netgraph/ng_echo.c +++ b/sys/netgraph/ng_echo.c @@ -82,7 +82,7 @@ NETGRAPH_INIT(echo, &typestruct); */ static int nge_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, - struct ng_mesg **rptr) + struct ng_mesg **rptr, hook_p lasthook) { if (rptr) { msg->header.flags |= NGF_RESP; @@ -97,7 +97,8 @@ nge_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, * Receive data */ static int -nge_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +nge_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { int error = 0; diff --git a/sys/netgraph/ng_frame_relay.c b/sys/netgraph/ng_frame_relay.c index 7486486..389dd95 100644 --- a/sys/netgraph/ng_frame_relay.c +++ b/sys/netgraph/ng_frame_relay.c @@ -338,7 +338,8 @@ ngfrm_addrlen(char *hdr) * Receive data packet */ static int -ngfrm_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +ngfrm_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { struct ctxinfo *const ctxp = hook->private; int error = 0; diff --git a/sys/netgraph/ng_hole.c b/sys/netgraph/ng_hole.c index 51470fa..4d6741f 100644 --- a/sys/netgraph/ng_hole.c +++ b/sys/netgraph/ng_hole.c @@ -77,7 +77,8 @@ NETGRAPH_INIT(hole, &typestruct); * Receive data */ static int -ngh_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +ngh_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { NG_FREE_DATA(m, meta); return 0; diff --git a/sys/netgraph/ng_iface.c b/sys/netgraph/ng_iface.c index d22aa2a..f67d431 100644 --- a/sys/netgraph/ng_iface.c +++ b/sys/netgraph/ng_iface.c @@ -619,7 +619,7 @@ ng_iface_newhook(node_p node, hook_p hook, const char *name) */ static int ng_iface_rcvmsg(node_p node, struct ng_mesg *msg, - const char *retaddr, struct ng_mesg **rptr) + const char *retaddr, struct ng_mesg **rptr, hook_p lasthook) { const priv_p priv = node->private; struct ifnet *const ifp = priv->ifp; @@ -722,7 +722,8 @@ ng_iface_rcvmsg(node_p node, struct ng_mesg *msg, * Recive data from a hook. Pass the packet to the correct input routine. */ static int -ng_iface_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +ng_iface_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { const priv_p priv = hook->node->private; const iffam_p iffam = get_iffam_from_hook(priv, hook); diff --git a/sys/netgraph/ng_ksocket.c b/sys/netgraph/ng_ksocket.c index 5f332d9..96a9965 100644 --- a/sys/netgraph/ng_ksocket.c +++ b/sys/netgraph/ng_ksocket.c @@ -567,7 +567,7 @@ ng_ksocket_newhook(node_p node, hook_p hook, const char *name0) */ static int ng_ksocket_rcvmsg(node_p node, struct ng_mesg *msg, - const char *raddr, struct ng_mesg **rptr) + const char *raddr, struct ng_mesg **rptr, hook_p lasthook) { struct proc *p = curproc ? curproc : &proc0; /* XXX broken */ const priv_p priv = node->private; @@ -783,7 +783,8 @@ done: * Receive incoming data on our hook. Send it out the socket. */ static int -ng_ksocket_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +ng_ksocket_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { struct proc *p = curproc ? curproc : &proc0; /* XXX broken */ const node_p node = hook->node; diff --git a/sys/netgraph/ng_lmi.c b/sys/netgraph/ng_lmi.c index 3a3afc9..775c3b8 100644 --- a/sys/netgraph/ng_lmi.c +++ b/sys/netgraph/ng_lmi.c @@ -452,7 +452,7 @@ ngauto_state_machine(sc_p sc) */ static int nglmi_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, - struct ng_mesg **resp) + struct ng_mesg **resp, hook_p lasthook) { int error = 0; sc_p sc = node->private; @@ -559,7 +559,8 @@ nglmi_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, * Anything coming in on the debug port is discarded. */ static int -nglmi_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +nglmi_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { sc_p sc = hook->node->private; u_char *data; diff --git a/sys/netgraph/ng_message.h b/sys/netgraph/ng_message.h index c9607fe..036cb22 100644 --- a/sys/netgraph/ng_message.h +++ b/sys/netgraph/ng_message.h @@ -83,7 +83,7 @@ struct ng_mesg { } /* Negraph type binary compatibility field */ -#define NG_VERSION 2 +#define NG_VERSION 3 /* Flags field flags */ #define NGF_ORIG 0x0000 /* the msg is the original request */ diff --git a/sys/netgraph/ng_mppc.c b/sys/netgraph/ng_mppc.c index af2030a..3710058 100644 --- a/sys/netgraph/ng_mppc.c +++ b/sys/netgraph/ng_mppc.c @@ -226,7 +226,7 @@ ng_mppc_newhook(node_p node, hook_p hook, const char *name) */ static int ng_mppc_rcvmsg(node_p node, struct ng_mesg *msg, - const char *raddr, struct ng_mesg **rptr) + const char *raddr, struct ng_mesg **rptr, hook_p lasthook) { const priv_p priv = node->private; struct ng_mesg *resp = NULL; @@ -348,7 +348,8 @@ done: * Receive incoming data on our hook. */ static int -ng_mppc_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +ng_mppc_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { const node_p node = hook->node; const priv_p priv = node->private; diff --git a/sys/netgraph/ng_ppp.c b/sys/netgraph/ng_ppp.c index 146bd99..db4dcbc 100644 --- a/sys/netgraph/ng_ppp.c +++ b/sys/netgraph/ng_ppp.c @@ -394,7 +394,7 @@ ng_ppp_newhook(node_p node, hook_p hook, const char *name) */ static int ng_ppp_rcvmsg(node_p node, struct ng_mesg *msg, - const char *raddr, struct ng_mesg **rptr) + const char *raddr, struct ng_mesg **rptr, hook_p lasthook) { const priv_p priv = node->private; struct ng_mesg *resp = NULL; @@ -458,8 +458,10 @@ ng_ppp_rcvmsg(node_p node, struct ng_mesg *msg, { char path[NG_PATHLEN + 1]; node_p origNode; + hook_p lasthook; - if ((error = ng_path2node(node, raddr, &origNode, NULL)) != 0) + if ((error = ng_path2node(node, raddr, &origNode, + NULL, &lasthook)) != 0) ERROUT(error); snprintf(path, sizeof(path), "[%lx]:%s", (long) node, NG_PPP_HOOK_VJC_IP); @@ -484,7 +486,8 @@ done: * Receive data on a hook */ static int -ng_ppp_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +ng_ppp_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { const node_p node = hook->node; const priv_p priv = node->private; diff --git a/sys/netgraph/ng_pppoe.c b/sys/netgraph/ng_pppoe.c index 09df976..248d383 100644 --- a/sys/netgraph/ng_pppoe.c +++ b/sys/netgraph/ng_pppoe.c @@ -535,8 +535,8 @@ AAA * Always free the message. */ static int -ng_pppoe_rcvmsg(node_p node, - struct ng_mesg *msg, const char *retaddr, struct ng_mesg **rptr) +ng_pppoe_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, + struct ng_mesg **rptr, hook_p lasthook) { priv_p privp = node->private; struct ngpppoe_init_data *ourmsg = NULL; @@ -760,7 +760,8 @@ AAA * if we use up this data or abort we must free BOTH of these. */ static int -ng_pppoe_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +ng_pppoe_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { node_p node = hook->node; const priv_p privp = node->private; @@ -1091,9 +1092,12 @@ AAA /* * Now we have gone to Connected mode, * Free all resources needed for - * negotiation. + * negotiation. Be paranoid about + * whether there may be a timeout. */ m_freem(sp->neg->m); + untimeout(pppoe_ticker, sendhook, + sp->neg->timeout_handle); FREE(sp->neg, M_NETGRAPH); sp->neg = NULL; } else { @@ -1257,6 +1261,7 @@ ng_pppoe_disconnect(hook_p hook) int hooks; AAA + hooks = node->numhooks; /* this one already not counted */ if (hook->private == &privp->debug_hook) { privp->debug_hook = NULL; } else if (hook->private == &privp->ethernet_hook) { @@ -1267,6 +1272,11 @@ AAA if (sp->state != PPPOE_SNONE ) { pppoe_send_event(sp, NGM_PPPOE_CLOSE); } + /* + * According to the spec, if we are connected, + * we should send a DISC packet if we are shutting down + * a session. + */ if ((privp->ethernet_hook) && ((sp->state == PPPOE_CONNECTED) || (sp->state == PPPOE_NEWCONNECTED))) { @@ -1307,6 +1317,10 @@ AAA dummy); } } + /* + * As long as we have somewhere to store teh timeout handle, + * we may have a timeout pending.. get rid of it. + */ if (sp->neg) { untimeout(pppoe_ticker, hook, sp->neg->timeout_handle); if (sp->neg->m) @@ -1317,11 +1331,8 @@ AAA hook->private = NULL; /* work out how many session hooks there are */ /* Node goes away on last session hook removal */ - hooks = node->numhooks; /* this one already not counted */ if (privp->ethernet_hook) hooks -= 1; if (privp->debug_hook) hooks -= 1; - if (hooks == 0) - ng_rmnode(node); } if (node->numhooks == 0) ng_rmnode(node); diff --git a/sys/netgraph/ng_pptpgre.c b/sys/netgraph/ng_pptpgre.c index 1bc9c1d..7a90e6d 100644 --- a/sys/netgraph/ng_pptpgre.c +++ b/sys/netgraph/ng_pptpgre.c @@ -289,7 +289,7 @@ ng_pptpgre_newhook(node_p node, hook_p hook, const char *name) */ static int ng_pptpgre_rcvmsg(node_p node, struct ng_mesg *msg, - const char *raddr, struct ng_mesg **rptr) + const char *raddr, struct ng_mesg **rptr, hook_p lasthook) { const priv_p priv = node->private; struct ng_mesg *resp = NULL; @@ -339,7 +339,8 @@ done: * Receive incoming data on a hook. */ static int -ng_pptpgre_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +ng_pptpgre_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { const node_p node = hook->node; const priv_p priv = node->private; diff --git a/sys/netgraph/ng_rfc1490.c b/sys/netgraph/ng_rfc1490.c index f14e74b..bc7edb8 100644 --- a/sys/netgraph/ng_rfc1490.c +++ b/sys/netgraph/ng_rfc1490.c @@ -172,7 +172,7 @@ ng_rfc1490_newhook(node_p node, hook_p hook, const char *name) */ static int ng_rfc1490_rcvmsg(node_p node, struct ng_mesg *msg, - const char *raddr, struct ng_mesg **rp) + const char *raddr, struct ng_mesg **rp, hook_p lasthook) { FREE(msg, M_NETGRAPH); return (EINVAL); @@ -215,7 +215,8 @@ ng_rfc1490_rcvmsg(node_p node, struct ng_mesg *msg, #define OUICMP(P,A,B,C) ((P)[0]==(A) && (P)[1]==(B) && (P)[2]==(C)) static int -ng_rfc1490_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +ng_rfc1490_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { const node_p node = hook->node; const priv_p priv = node->private; diff --git a/sys/netgraph/ng_sample.c b/sys/netgraph/ng_sample.c index 5269954..9b03060 100644 --- a/sys/netgraph/ng_sample.c +++ b/sys/netgraph/ng_sample.c @@ -257,8 +257,8 @@ ng_xxx_newhook(node_p node, hook_p hook, const char *name) * (so that old userland programs could continue to work). */ static int -ng_xxx_rcvmsg(node_p node, - struct ng_mesg *msg, const char *retaddr, struct ng_mesg **rptr) +ng_xxx_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, + struct ng_mesg **rptr, hook_p lasthook) { const xxx_p xxxp = node->private; struct ng_mesg *resp = NULL; @@ -321,7 +321,8 @@ ng_xxx_rcvmsg(node_p node, * at the netgraph NETISR time. (at which time it will be entered using ng_xxx_rcvdataq(). */ static int -ng_xxx_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +ng_xxx_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { int dlci = -2; @@ -343,7 +344,8 @@ ng_xxx_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) * Always accept the data. This version of rcvdata is called from the dequeueing routine. */ static int -ng_xxx_rcvdataq(hook_p hook, struct mbuf *m, meta_p meta) +ng_xxx_rcvdataq(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { const xxx_p xxxp = hook->node->private; int chan = -2; diff --git a/sys/netgraph/ng_socket.c b/sys/netgraph/ng_socket.c index 52ccf8e..6a3266c 100644 --- a/sys/netgraph/ng_socket.c +++ b/sys/netgraph/ng_socket.c @@ -612,7 +612,7 @@ ng_connect_data(struct sockaddr *nam, struct ngpcb *pcbp) /* Find the target (victim) and check it doesn't already have a data * socket. Also check it is a 'socket' type node. */ sap = (struct sockaddr_ng *) nam; - if ((error = ng_path2node(NULL, sap->sg_data, &farnode, NULL))) + if ((error = ng_path2node(NULL, sap->sg_data, &farnode, NULL, NULL))) return (error); if (strcmp(farnode->type->name, NG_SOCKET_NODE_TYPE) != 0) @@ -740,7 +740,7 @@ ngs_newhook(node_p node, hook_p hook, const char *name) */ static int ngs_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, - struct ng_mesg **resp) + struct ng_mesg **resp, hook_p lasthook) { struct ngsock *const sockdata = node->private; struct ngpcb *const pcbp = sockdata->ctlsock; @@ -795,7 +795,8 @@ ngs_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, * Receive data on a hook */ static int -ngs_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +ngs_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { struct ngsock *const sockdata = hook->node->private; struct ngpcb *const pcbp = sockdata->datasock; diff --git a/sys/netgraph/ng_tee.c b/sys/netgraph/ng_tee.c index ec774f2..1553c60 100644 --- a/sys/netgraph/ng_tee.c +++ b/sys/netgraph/ng_tee.c @@ -194,7 +194,7 @@ ngt_newhook(node_p node, hook_p hook, const char *name) */ static int ngt_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, - struct ng_mesg **rptr) + struct ng_mesg **rptr, hook_p lasthook) { const sc_p sc = node->private; struct ng_mesg *resp = NULL; @@ -262,7 +262,8 @@ done: * from the other side. */ static int -ngt_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +ngt_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { const sc_p sc = hook->node->private; struct hookinfo *const hinfo = (struct hookinfo *) hook->private; diff --git a/sys/netgraph/ng_tty.c b/sys/netgraph/ng_tty.c index c96edab..ef2cc5d 100644 --- a/sys/netgraph/ng_tty.c +++ b/sys/netgraph/ng_tty.c @@ -568,7 +568,8 @@ ngt_shutdown(node_p node) * output queue and start output if necessary. */ static int -ngt_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +ngt_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { const sc_p sc = hook->node->private; int s, error = 0; @@ -599,7 +600,7 @@ done: */ static int ngt_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, - struct ng_mesg **rptr) + struct ng_mesg **rptr, hook_p lasthook) { const sc_p sc = (sc_p) node->private; struct ng_mesg *resp = NULL; diff --git a/sys/netgraph/ng_vjc.c b/sys/netgraph/ng_vjc.c index 216b2df..9a85dd6 100644 --- a/sys/netgraph/ng_vjc.c +++ b/sys/netgraph/ng_vjc.c @@ -179,7 +179,7 @@ ng_vjc_newhook(node_p node, hook_p hook, const char *name) */ static int ng_vjc_rcvmsg(node_p node, struct ng_mesg *msg, - const char *raddr, struct ng_mesg **rptr) + const char *raddr, struct ng_mesg **rptr, hook_p lasthook) { const priv_p priv = (priv_p) node->private; struct ng_mesg *resp = NULL; @@ -254,7 +254,8 @@ done: * Receive data */ static int -ng_vjc_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +ng_vjc_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { const node_p node = hook->node; const priv_p priv = (priv_p) node->private; diff --git a/sys/pci/if_mn.c b/sys/pci/if_mn.c index 5382bd2..0e0bb4a 100644 --- a/sys/pci/if_mn.c +++ b/sys/pci/if_mn.c @@ -283,7 +283,7 @@ ngmn_shutdown(node_p nodep) } static int -ngmn_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, struct ng_mesg **resp) +ngmn_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, struct ng_mesg **resp, hook_p lasthook) { struct softc *sc; struct schan *sch; @@ -497,7 +497,8 @@ mn_fmt_ts(char *p, u_int32_t ts) */ static int -ngmn_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) +ngmn_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, + struct mbuf **ret_m, meta_p *ret_meta) { struct mbuf *m2; struct trxd *dp, *dp2; |